author liangqin.fan gmail import { seal_clear_storage , seal_get_storage , seal_set_storage , ReturnCode , } from "as-contract-runtime" ; import { Codec , Hash , PackableCodec , ScaleString } from "as-scale-codec" ; import { ReadBuffer } from "../primitives/readbuffer" ; import { WriteBuffer } from "../primitives/writebuffer" ; export const MaxStorageSize = 16 * 1024 ; export const NullHash = new Hash ( ( new Array < u8 > ( 32 ) ) . fill ( 0x00 ) ) ; export enum StoreMode { W = 0 , R = 1 , WR = 2 } export class Storage { private static sStoreMode : StoreMode = StoreMode . WR ; static set mode ( mode ) { Storage . sStoreMode = mode ; } private key : Hash ; constructor ( _key = NullHash ) { this . key = _key ; } updateKey ( key ) { this . key = key ; } store < T extends Codec > ( value ) { assert ( Storage . sStoreMode != StoreMode . R , "Storage: only read allowed" ) ; const valueBytes = value . toU8a ( ) ; const buf = new WriteBuffer ( valueBytes ) ; seal_set_storage ( this . hashKey ( ) , buf . buffer , buf . size ) ; return ReturnCode . Success ; } storePacked < U extends PackableCodec > ( value ) { assert ( Storage . sStoreMode != StoreMode . R , "Storage: only read allowed" ) ; const valueBytes = value . toU8aPacked ( ) ; const buf = new WriteBuffer ( valueBytes ) ; seal_set_storage ( this . hashKey ( ) , buf . buffer , buf . size ) ; return ReturnCode . Success ; } load < T extends Codec > ( ) { const value = instantiate < T > ( ) ; const readBuf = new ReadBuffer ( MaxStorageSize ) ; const status = seal_get_storage ( this . hashKey ( ) , readBuf . valueBuffer , readBuf . sizeBuffer ) ; if ( status == ReturnCode . Success ) { value . populateFromBytes ( readBuf . valueBytes , 0 ) ; return value ; } return null ; } loadPacked < U extends PackableCodec > ( ) { const value = instantiate < U > ( ) ; let len = value . encodedLengthPacked ( ) ; if ( len == 0 || value instanceof ScaleString ) len = MaxStorageSize ; const readBuf = new ReadBuffer ( len ) ; const status = seal_get_storage ( this . hashKey ( ) , readBuf . valueBuffer , readBuf . sizeBuffer ) ; if ( status == ReturnCode . Success && readBuf . readSize <= len ) { value . populateFromPackedBytes ( readBuf . valueBytes , 0 ) ; return value ; } return null ; } storeRaw ( data ) { assert ( Storage . sStoreMode != StoreMode . R , "Storage: only read allowed" ) ; const buf = new WriteBuffer ( data ) ; seal_set_storage ( this . hashKey ( ) , buf . buffer , buf . size ) ; } loadRaw ( size ) { let readBuf = new ReadBuffer ( size ) ; const status = seal_get_storage ( this . hashKey ( ) , readBuf . valueBuffer , readBuf . sizeBuffer ) ; if ( status == ReturnCode . Success && readBuf . readSize <= size ) { return readBuf . valueBytes ; } return [ ] ; } clear ( ) { seal_clear_storage ( this . hashKey ( ) ) ; } private hashKey ( ) { return this . key . toU8a ( ) . dataStart ; } }