cbor2
Version:
Encode and parse data in the Concise Binary Object Representation (CBOR) data format (RFC8949).
4 lines (3 loc) • 7.75 kB
JavaScript
import{MT as R,TAG as a}from"./constants.js";import{box as L,getEncoded as q}from"./box.js";import{base64ToBytes as C,base64UrlToBytes as v,isBigEndian as V,u8toHex as A}from"./utils.js";import{encode as b,registerEncoder as s,writeInt as W,writeLength as k,writeTag as F,writeUnknown as P}from"./encoder.js";import{CBORcontainer as M}from"./container.js";import{Tag as i}from"./tag.js";import{Wtf8Decoder as B}from"@cto.af/wtf8";import{comment as K}from"./comment.js";const S=!V();function O(e){if(typeof e=="object"&&e){if(e.constructor!==Number)throw new Error(`Expected number: ${e}`)}else if(typeof e!="number")throw new Error(`Expected number: ${e}`)}function E(e){if(typeof e=="object"&&e){if(e.constructor!==String)throw new Error(`Expected string: ${e}`)}else if(typeof e!="string")throw new Error(`Expected string: ${e}`)}function f(e){if(!(e instanceof Uint8Array))throw new Error(`Expected Uint8Array: ${e}`)}function U(e){if(!Array.isArray(e))throw new Error(`Expected Array: ${e}`)}s(Map,(e,r,n)=>{const t=[...e.entries()].map(o=>[o[0],o[1],b(o[0],n)]);if(n.rejectDuplicateKeys){const o=new Set;for(const[d,u,y]of t){const g=A(y);if(o.has(g))throw new Error(`Duplicate map key: 0x${g}`);o.add(g)}}n.sortKeys&&t.sort(n.sortKeys),k(e,e.size,R.MAP,r,n);for(const[o,d,u]of t)r.write(u),P(d,r,n)});function h(e){return E(e.contents),new Date(e.contents)}h.comment=e=>(E(e.contents),`(String Date) ${new Date(e.contents).toISOString()}`),i.registerDecoder(a.DATE_STRING,h);function N(e){return O(e.contents),new Date(e.contents*1e3)}N.comment=e=>(O(e.contents),`(Epoch Date) ${new Date(e.contents*1e3).toISOString()}`),i.registerDecoder(a.DATE_EPOCH,N),s(Date,e=>[a.DATE_EPOCH,e.valueOf()/1e3]);function T(e,r,n){if(f(r.contents),n.rejectBigInts)throw new Error(`Decoding unwanted big integer: ${r}(h'${A(r.contents)}')`);if(n.requirePreferred&&r.contents[0]===0)throw new Error(`Decoding overly-large bigint: ${r.tag}(h'${A(r.contents)})`);let t=r.contents.reduce((o,d)=>o<<8n|BigInt(d),0n);if(e&&(t=-1n-t),n.requirePreferred&&t>=Number.MIN_SAFE_INTEGER&&t<=Number.MAX_SAFE_INTEGER)throw new Error(`Decoding bigint that could have been int: ${t}n`);return n.boxed?L(t,r.contents):t}const _=T.bind(null,!1),$=T.bind(null,!0);_.comment=(e,r)=>`(Positive BigInt) ${T(!1,e,r)}n`,$.comment=(e,r)=>`(Negative BigInt) ${T(!0,e,r)}n`,i.registerDecoder(a.POS_BIGINT,_),i.registerDecoder(a.NEG_BIGINT,$);function D(e,r){return f(e.contents),e}D.comment=(e,r,n)=>{f(e.contents);const t={...r,initialDepth:n+2,noPrefixHex:!0},o=q(e);let u=2**((o[0]&31)-24)+1;const y=o[u]&31;let g=A(o.subarray(u,++u));y>=24&&(g+=" ",g+=A(o.subarray(u,u+2**(y-24)))),t.minCol=Math.max(t.minCol,(n+1)*2+g.length);const p=K(e.contents,t);let I=`Embedded CBOR
`;return I+=`${"".padStart((n+1)*2," ")}${g}`.padEnd(t.minCol+1," "),I+=`-- Bytes (Length: ${e.contents.length})
`,I+=p,I},D.noChildren=!0,i.registerDecoder(a.CBOR,D),i.registerDecoder(a.URI,e=>(E(e.contents),new URL(e.contents)),"URI"),s(URL,e=>[a.URI,e.toString()]),i.registerDecoder(a.BASE64URL,e=>(E(e.contents),v(e.contents)),"Base64url-encoded"),i.registerDecoder(a.BASE64,e=>(E(e.contents),C(e.contents)),"Base64-encoded"),i.registerDecoder(35,e=>(E(e.contents),new RegExp(e.contents)),"RegExp"),i.registerDecoder(21065,e=>{E(e.contents);const r=`^(?:${e.contents})$`;return new RegExp(r,"u")},"I-RegExp"),i.registerDecoder(a.REGEXP,e=>{if(U(e.contents),e.contents.length<1||e.contents.length>2)throw new Error(`Invalid RegExp Array: ${e.contents}`);return new RegExp(e.contents[0],e.contents[1])},"RegExp"),s(RegExp,e=>[a.REGEXP,[e.source,e.flags]]),i.registerDecoder(64,e=>(f(e.contents),e.contents),"uint8 Typed Array");function c(e,r,n){f(e.contents);let t=e.contents.length;if(t%r.BYTES_PER_ELEMENT!==0)throw new Error(`Number of bytes must be divisible by ${r.BYTES_PER_ELEMENT}, got: ${t}`);t/=r.BYTES_PER_ELEMENT;const o=new r(t),d=new DataView(e.contents.buffer,e.contents.byteOffset,e.contents.byteLength),u=d[`get${r.name.replace(/Array/,"")}`].bind(d);for(let y=0;y<t;y++)o[y]=u(y*r.BYTES_PER_ELEMENT,n);return o}function l(e,r,n,t,o){const d=o.forceEndian??S;if(F(d?r:n,e,o),W(t.byteLength,e,R.BYTE_STRING),S===d)e.write(new Uint8Array(t.buffer,t.byteOffset,t.byteLength));else{const y=`write${t.constructor.name.replace(/Array/,"")}`,g=e[y].bind(e);for(const p of t)g(p,d)}}i.registerDecoder(65,e=>c(e,Uint16Array,!1),"uint16, big endian, Typed Array"),i.registerDecoder(66,e=>c(e,Uint32Array,!1),"uint32, big endian, Typed Array"),i.registerDecoder(67,e=>c(e,BigUint64Array,!1),"uint64, big endian, Typed Array"),i.registerDecoder(68,e=>(f(e.contents),new Uint8ClampedArray(e.contents)),"uint8 Typed Array, clamped arithmetic"),s(Uint8ClampedArray,e=>[68,new Uint8Array(e.buffer,e.byteOffset,e.byteLength)]),i.registerDecoder(69,e=>c(e,Uint16Array,!0),"uint16, little endian, Typed Array"),s(Uint16Array,(e,r,n)=>l(r,69,65,e,n)),i.registerDecoder(70,e=>c(e,Uint32Array,!0),"uint32, little endian, Typed Array"),s(Uint32Array,(e,r,n)=>l(r,70,66,e,n)),i.registerDecoder(71,e=>c(e,BigUint64Array,!0),"uint64, little endian, Typed Array"),s(BigUint64Array,(e,r,n)=>l(r,71,67,e,n)),i.registerDecoder(72,e=>(f(e.contents),new Int8Array(e.contents)),"sint8 Typed Array"),s(Int8Array,e=>[72,new Uint8Array(e.buffer,e.byteOffset,e.byteLength)]),i.registerDecoder(73,e=>c(e,Int16Array,!1),"sint16, big endian, Typed Array"),i.registerDecoder(74,e=>c(e,Int32Array,!1),"sint32, big endian, Typed Array"),i.registerDecoder(75,e=>c(e,BigInt64Array,!1),"sint64, big endian, Typed Array"),i.registerDecoder(77,e=>c(e,Int16Array,!0),"sint16, little endian, Typed Array"),s(Int16Array,(e,r,n)=>l(r,77,73,e,n)),i.registerDecoder(78,e=>c(e,Int32Array,!0),"sint32, little endian, Typed Array"),s(Int32Array,(e,r,n)=>l(r,78,74,e,n)),i.registerDecoder(79,e=>c(e,BigInt64Array,!0),"sint64, little endian, Typed Array"),s(BigInt64Array,(e,r,n)=>l(r,79,75,e,n)),i.registerDecoder(81,e=>c(e,Float32Array,!1),"IEEE 754 binary32, big endian, Typed Array"),i.registerDecoder(82,e=>c(e,Float64Array,!1),"IEEE 754 binary64, big endian, Typed Array"),i.registerDecoder(85,e=>c(e,Float32Array,!0),"IEEE 754 binary32, little endian, Typed Array"),s(Float32Array,(e,r,n)=>l(r,85,81,e,n)),i.registerDecoder(86,e=>c(e,Float64Array,!0),"IEEE 754 binary64, big endian, Typed Array"),s(Float64Array,(e,r,n)=>l(r,86,82,e,n)),i.registerDecoder(a.SET,(e,r)=>{if(U(e.contents),r.sortKeys){const n=M.decodeToEncodeOpts(r);let t=null;for(const o of e.contents){const d=[o,void 0,b(o,n)];if(t&&r.sortKeys(t,d)>=0)throw new Error(`Set items out of order in tag #${a.SET}`);t=d}}return new Set(e.contents)},"Set"),s(Set,(e,r,n)=>{let t=[...e];if(n.sortKeys){const o=t.map(d=>[d,void 0,b(d,n)]);o.sort(n.sortKeys),t=o.map(([d])=>d)}return[a.SET,t]}),i.registerDecoder(a.JSON,e=>(E(e.contents),JSON.parse(e.contents)),"JSON-encoded");function x(e){return f(e.contents),new B().decode(e.contents)}x.comment=e=>{f(e.contents);const r=new B;return`(WTF8 string): ${JSON.stringify(r.decode(e.contents))}`},i.registerDecoder(a.WTF8,x),i.registerDecoder(a.SELF_DESCRIBED,e=>e.contents,"Self-Described"),i.registerDecoder(a.INVALID_16,()=>{throw new Error(`Tag always invalid: ${a.INVALID_16}`)},"Invalid"),i.registerDecoder(a.INVALID_32,()=>{throw new Error(`Tag always invalid: ${a.INVALID_32}`)},"Invalid"),i.registerDecoder(a.INVALID_64,()=>{throw new Error(`Tag always invalid: ${a.INVALID_64}`)},"Invalid");function w(e){throw new Error(`Encoding ${e.constructor.name} intentionally unimplmented. It is not concrete enough to interoperate. Convert to Uint8Array first.`)}s(ArrayBuffer,w),s(DataView,w),typeof SharedArrayBuffer<"u"&&s(SharedArrayBuffer,w);function m(e){return[NaN,e.valueOf()]}s(Boolean,m),s(Number,m),s(String,m),s(BigInt,m);