import { Buffer } from '@stacks/common' ; import { SmartBuffer , SmartBufferOptions } from 'smart-buffer' ; function createEnumChecker < T extends string , TEnumValue extends number > ( enumVariable ) { const enumValues = Object . values < number > ( enumVariable ) . filter ( v => typeof v === 'number' ) ; const enumValueSet = new Set < number > ( enumValues ) ; return ( value ) : value is TEnumValue => enumValueSet . has ( value ) ; } const enumCheckFunctions = new Map < object , ( value : number ) => boolean > ( ) ; param enumVariable param value example export function isEnum < T extends string , TEnumValue extends number > ( enumVariable , value ) { const checker = enumCheckFunctions . get ( enumVariable ) ; if ( checker !== undefined ) { return checker ( value ) ; } const newChecker = createEnumChecker ( enumVariable ) ; enumCheckFunctions . set ( enumVariable , newChecker ) ; return isEnum ( enumVariable , value ) ; } export class BufferReader { smartBuffer : SmartBuffer ; static fromBuffer ( buffer ) { return new BufferReader ( { buff : buffer } ) ; } constructor ( options ? ) { if ( Buffer . isBuffer ( options ) ) { this . smartBuffer = new SmartBuffer ( { buff : options } ) ; } else { this . smartBuffer = new SmartBuffer ( options ) ; } } readBuffer ( length ) { return this . smartBuffer . readBuffer ( length ) ; } readUInt32BE ( offset ? ) { return this . smartBuffer . readUInt32BE ( offset ) ; } readUInt8 ( ) { return this . smartBuffer . readUInt8 ( ) ; } readUInt16BE ( ) { return this . smartBuffer . readUInt16BE ( ) ; } readBigUIntLE ( length ) { const buffer = Buffer . from ( this . smartBuffer . readBuffer ( length ) ) . reverse ( ) ; const hex = buffer . toString ( ) ; const num = BigInt ( `0x${ hex }` ) ; return num ; } readBigUIntBE ( length ) { const buffer = this . smartBuffer . readBuffer ( length ) ; const hex = buffer . toString ( 'hex' ) ; const num = BigInt ( `0x${ hex }` ) ; return num ; } readBigUInt64BE ( ) { return this . smartBuffer . readBigUInt64BE ( ) ; } readString ( arg ? , encoding ? ) { return this . smartBuffer . readString ( arg , encoding ) ; } get readOffset ( ) : number { return this . smartBuffer . readOffset ; } set readOffset ( val ) { this . smartBuffer . readOffset = val ; } get internalBuffer ( ) : Buffer { return this . smartBuffer . internalBuffer ; } readUInt8Enum < T extends string , TEnumValue extends number > ( enumVariable , invalidEnumErrorFormatter ) { const num = this . smartBuffer . readUInt8 ( ) ; if ( isEnum ( enumVariable , num ) ) { return num ; } else { throw invalidEnumErrorFormatter ( num ) ; } } }