@surrealdb/cbor
Version:
CBOR encoder and decoder for SurrealDB.
3 lines (2 loc) • 11.8 kB
JavaScript
var POW_2_53=9007199254740992,POW_2_64=BigInt(18446744073709552e3);var Encoded=class{constructor(encoded){this.encoded=encoded}};var CborError=class{message;constructor(message){this.message=message}},CborNumberError=class extends CborError{name="CborNumberError"},CborRangeError=class extends CborError{name="CborRangeError"},CborInvalidMajorError=class extends CborError{name="CborInvalidMajorError"},CborBreak=class extends CborError{name="CborBreak";constructor(){super("Came across a break which was not intercepted by the decoder")}},CborPartialDisabled=class extends CborError{name="CborPartialDisabled";constructor(){super("Tried to insert a Gap into a CBOR value, while partial mode is not enabled")}},CborFillMissing=class extends CborError{name="CborFillMissing";constructor(){super("Fill for a gap is missing, and gap has no default")}};var Gap=class{args=[];constructor(...args){this.args=args}fill(value){return[this,value]}hasDefault(){return this.args.length===1}get default(){return this.args[0]}};var Writer=class{constructor(byteLength=256){this.byteLength=byteLength;this._buf=new ArrayBuffer(this.byteLength),this._view=new DataView(this._buf),this._byte=new Uint8Array(this._buf)}_chunks=[];_pos=0;_buf;_view;_byte;chunk(gap){this._chunks.push([this._byte.subarray(0,this._pos),gap]),this._buf=new ArrayBuffer(this.byteLength),this._view=new DataView(this._buf),this._byte=new Uint8Array(this._buf),this._pos=0}get chunks(){return this._chunks}get buffer(){return this._byte.subarray(0,this._pos)}claim(length){let pos=this._pos;if(this._pos+=length,this._pos<=this._buf.byteLength)return pos;let newLen=this._buf.byteLength<<1;for(;newLen<this._pos;)newLen<<=1;let oldb=this._byte;return this._buf=new ArrayBuffer(newLen),this._view=new DataView(this._buf),this._byte=new Uint8Array(this._buf),this._byte.set(oldb),pos}writeUint8(value){let pos=this.claim(1);this._byte[pos]=value}writeUint16(value){let pos=this.claim(2);this._view.setUint16(pos,value,!1)}writeUint32(value){let pos=this.claim(4);this._view.setUint32(pos,value,!1)}writeUint64(value){let pos=this.claim(8);this._view.setBigUint64(pos,value,!1)}writeFloat32(value){let pos=this.claim(4);this._view.setFloat32(pos,value,!1)}writeFloat64(value){let pos=this.claim(8);this._view.setFloat64(pos,value,!1)}writeUint8Array(data){if(data.byteLength===0)return;let pos=this.claim(data.byteLength);this._byte.set(data,pos)}writePartiallyEncoded(data){for(let[buf,gap]of data.chunks)this.writeUint8Array(buf),this.chunk(gap);this.writeUint8Array(data.end)}writeMajor(type,length){let base=type<<5;typeof length=="number"?length<24?this.writeUint8(base+length):length<256?(this.writeUint8(base+24),this.writeUint8(length)):length<65536?(this.writeUint8(base+25),this.writeUint16(length)):length<4294967296?(this.writeUint8(base+26),this.writeUint32(length)):(this.writeUint8(base+27),this.writeUint64(BigInt(length))):length<24n?this.writeUint8(base+Number(length)):length<0x100n?(this.writeUint8(base+24),this.writeUint8(Number(length))):length<0x10000n?(this.writeUint8(base+25),this.writeUint16(Number(length))):length<0x100000000n?(this.writeUint8(base+26),this.writeUint32(Number(length))):(this.writeUint8(base+27),this.writeUint64(length))}output(partial=!1,replacer){return partial?new PartiallyEncoded(this._chunks,this.buffer,replacer):this.buffer}};var PartiallyEncoded=class{constructor(chunks,end,replacer){this.chunks=chunks;this.end=end;this.replacer=replacer}build(fills,partial){let writer=new Writer,map=new Map(fills);for(let[buffer,gap]of this.chunks){let hasValue=map.has(gap)||gap.hasDefault();if(!partial&&!hasValue)throw new CborFillMissing;if(writer.writeUint8Array(buffer),hasValue){let data=map.get(gap)??gap.default;encode(data,{writer,replacer:this.replacer})}else writer.chunk(gap)}return writer.writeUint8Array(this.end),partial?writer.output(!0,this.replacer):writer.output(!1,this.replacer)}};function partiallyEncodeObject(object,options){return Object.fromEntries(Object.entries(object).map(([k,v])=>[k,encode(v,{...options,partial:!0})]))}var Tagged=class{constructor(tag,value){this.tag=tag;this.value=value}};var textEncoder=new TextEncoder;function encode(input,options={}){let w=options.writer??new Writer,fillsMap=new Map(options.fills??[]);function inner(input2){if(input2=options.replacer?.(input2)??input2,input2===void 0)return w.writeUint8(247);if(input2===null)return w.writeUint8(246);if(input2===!0)return w.writeUint8(245);if(input2===!1)return w.writeUint8(244);switch(typeof input2){case"number":{if(Number.isInteger(input2))if(input2>=0&&input2<=9007199254740992)w.writeMajor(0,input2);else if(input2<0&&input2>=-9007199254740992)w.writeMajor(1,-(input2+1));else throw new CborNumberError("Number too big to be encoded");else w.writeUint8(251),w.writeFloat64(input2);return}case"bigint":{if(input2>=0&&input2<POW_2_64)w.writeMajor(0,input2);else if(input2<=0&&input2>=-POW_2_64)w.writeMajor(1,-(input2+1n));else throw new CborNumberError("BigInt too big to be encoded");return}case"string":{let encoded=textEncoder.encode(input2);w.writeMajor(3,encoded.byteLength),w.writeUint8Array(encoded);return}default:{if(Array.isArray(input2)){w.writeMajor(4,input2.length);for(let v of input2)inner(v);return}if(input2 instanceof Tagged){w.writeMajor(6,input2.tag),inner(input2.value);return}if(input2 instanceof Encoded){w.writeUint8Array(input2.encoded);return}if(input2 instanceof Gap){if(fillsMap.has(input2))inner(fillsMap.get(input2));else if(options.partial)w.chunk(input2);else throw new CborPartialDisabled;return}if(input2 instanceof PartiallyEncoded){let res=options.partial?input2.build(options.fills??[],!0):input2.build(options.fills??[],!1);res instanceof PartiallyEncoded?w.writePartiallyEncoded(res):w.writeUint8Array(res);return}if(input2 instanceof Uint8Array||input2 instanceof Uint16Array||input2 instanceof Uint32Array||input2 instanceof Int8Array||input2 instanceof Int16Array||input2 instanceof Int32Array||input2 instanceof Float32Array||input2 instanceof Float64Array||input2 instanceof ArrayBuffer){let v=input2 instanceof Uint8Array?input2:new Uint8Array(input2);w.writeMajor(2,v.byteLength),w.writeUint8Array(v);return}if(input2 instanceof Map){w.writeMajor(5,input2.size);for(let[k,v]of input2)inner(k),inner(v)}else{let entries=Object.entries(input2);w.writeMajor(5,entries.length);for(let[k,v]of entries)inner(k),inner(v)}}}}return inner(input),options.partial?w.output(!0,options.replacer):w.output(!1,options.replacer)}var F16_SIGN_MASK=32768,F16_EXP_MASK=31744,F16_FRAC_MASK=1023,F16_EXP_SHIFT=10,F16_EXP_BIAS=15,F16_EXP_INF_NAN=31,F16_FRAC_SCALE=1024,F16_SUBNORMAL_SCALE=2**-14,FLOAT16_EXP_LUT=Array.from({length:31},(_,e)=>2**(e-F16_EXP_BIAS)),Reader=class{_view;_byte;_pos=0;constructor(buffer){this._byte=buffer,this._view=new DataView(buffer.buffer,buffer.byteOffset,buffer.byteLength)}skip(amount=1){let pos=this._pos;if(this._byte.length-pos<amount)throw new CborRangeError("Tried to read 1 byte beyond buffer bounds");this._pos=pos+amount}peekUint8(){let pos=this._pos;if(this._byte.length-pos<1)throw new CborRangeError("Tried to read 1 byte beyond buffer bounds");return this._view.getUint8(pos)}readUint8(){let pos=this._pos;if(this._byte.length-pos<1)throw new CborRangeError("Tried to read 1 byte beyond buffer bounds");let val=this._view.getUint8(pos);return this._pos=pos+1,val}readUint16(){let pos=this._pos;if(this._byte.length-pos<2)throw new CborRangeError("Tried to read 2 bytes beyond buffer bounds");let val=this._view.getUint16(pos);return this._pos=pos+2,val}readUint32(){let pos=this._pos;if(this._byte.length-pos<4)throw new CborRangeError("Tried to read 4 bytes beyond buffer bounds");let val=this._view.getUint32(pos);return this._pos=pos+4,val}readUint64(){let pos=this._pos;if(this._byte.length-pos<8)throw new CborRangeError("Tried to read 8 bytes beyond buffer bounds");let val=this._view.getBigUint64(pos);return this._pos=pos+8,val}readFloat16(){let val=this.readUint16(),sign=val&F16_SIGN_MASK?-1:1,exp=(val&F16_EXP_MASK)>>F16_EXP_SHIFT,frac=val&F16_FRAC_MASK;return exp===0?sign*(frac/F16_FRAC_SCALE)*F16_SUBNORMAL_SCALE:exp===F16_EXP_INF_NAN?frac?Number.NaN:sign*Number.POSITIVE_INFINITY:sign*(1+frac/F16_FRAC_SCALE)*FLOAT16_EXP_LUT[exp]}readFloat32(){let pos=this._pos;if(this._byte.length-pos<4)throw new CborRangeError("Tried to read 4 bytes for float32 beyond buffer bounds");let val=this._view.getFloat32(pos);return this._pos=pos+4,val}readFloat64(){let pos=this._pos;if(this._byte.length-pos<8)throw new CborRangeError("Tried to read 8 bytes for float64 beyond buffer bounds");let val=this._view.getFloat64(pos);return this._pos=pos+8,val}readBytes(amount){let pos=this._pos;if(this._byte.length-pos<amount)throw new CborRangeError(`Tried to read ${amount} bytes beyond buffer`);return this._pos=pos+amount,this._byte.subarray(pos,this._pos)}readMajor(){let byte=this.readUint8(),major=byte>>5;if(major<0||major>7)throw new CborInvalidMajorError("Received invalid major type");return[major,byte&31]}readMajorLength(length){if(length<=23)return length;if(length===24)return this.readUint8();if(length===25)return this.readUint16();if(length===26)return this.readUint32();if(length===27){let read=this.readUint64();return read>9007199254740992?read:Number(read)}throw new CborRangeError("Expected a final length")}};function infiniteBytes(r,forMajor){let w=new Writer;for(;;){let[major,len]=r.readMajor();if(major===7&&len===31)break;if(major!==forMajor)throw new CborInvalidMajorError(`Expected a resource of the same major (${forMajor}) while processing an infinite resource`);if(len===31)throw new CborRangeError("Expected a finite resource while processing an infinite resource");w.writeUint8Array(r.readBytes(Number(r.readMajorLength(len))))}return w.buffer.buffer}var textDecoder=new TextDecoder;function decode(input,options={}){let r=input instanceof Reader?input:new Reader(input);return decodeValue(r,options)}function decodeValue(r,options){let[major,len]=r.readMajor();switch(major){case 0:return r.readMajorLength(len);case 1:{let l=r.readMajorLength(len);return typeof l=="bigint"?-(l+1n):-(l+1)}case 2:return len!==31?new Uint8Array(r.readBytes(Number(r.readMajorLength(len)))).buffer:infiniteBytes(r,2);case 3:{let encoded=len!==31?r.readBytes(Number(r.readMajorLength(len))):infiniteBytes(r,3);return textDecoder.decode(encoded)}case 4:{if(len!==31){let l=r.readMajorLength(len),arr2=Array(l);for(let i=0;i<l;i++)arr2[i]=decodeValue(r,options);return arr2}let arr=[];for(;;){if(r.peekUint8()===255){r.skip();break}arr.push(decodeValue(r,options))}return arr}case 5:{if(options.map==="map"){let map=new Map;if(len!==31){let l=r.readMajorLength(len);for(let i=0;i<l;i++)map.set(decodeValue(r,options),decodeValue(r,options))}else for(;;){if(r.peekUint8()===255){r.skip();break}map.set(decodeValue(r,options),decodeValue(r,options))}return map}let obj={};if(len!==31){let l=r.readMajorLength(len);for(let i=0;i<l;i++)obj[decodeValue(r,options)]=decodeValue(r,options)}else for(;;){if(r.peekUint8()===255){r.skip();break}obj[decodeValue(r,options)]=decodeValue(r,options)}return obj}case 6:{let tag=Number(r.readMajorLength(len)),value=decodeValue(r,options),replacer=options.tagged?.[tag];return replacer?replacer(value):new Tagged(tag,value)}case 7:switch(len){case 20:return!1;case 21:return!0;case 22:return null;case 23:return;case 25:return r.readFloat16();case 26:return r.readFloat32();case 27:return r.readFloat64();case 31:throw new CborBreak}}throw new CborInvalidMajorError(`Unable to decode value with major tag ${major}`)}export{CborBreak,CborError,CborFillMissing,CborInvalidMajorError,CborNumberError,CborPartialDisabled,CborRangeError,Encoded,Gap,POW_2_53,POW_2_64,PartiallyEncoded,Reader,Tagged,Writer,decode,encode,infiniteBytes,partiallyEncodeObject};
//# sourceMappingURL=index.mjs.map