@@ -15,6 +15,7 @@ export class Encoder<ContextType = undefined> {
1515 public constructor (
1616 private readonly extensionCodec : ExtensionCodecType < ContextType > = ExtensionCodec . defaultCodec as any ,
1717 private readonly context : ContextType = undefined as any ,
18+ private readonly useBigInt64 = false ,
1819 private readonly maxDepth = DEFAULT_MAX_DEPTH ,
1920 private readonly initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE ,
2021 private readonly sortKeys = false ,
@@ -57,9 +58,15 @@ export class Encoder<ContextType = undefined> {
5758 } else if ( typeof object === "boolean" ) {
5859 this . encodeBoolean ( object ) ;
5960 } else if ( typeof object === "number" ) {
60- this . encodeNumber ( object ) ;
61+ if ( ! this . forceIntegerToFloat ) {
62+ this . encodeNumber ( object ) ;
63+ } else {
64+ this . encodeNumberAsFloat ( object ) ;
65+ }
6166 } else if ( typeof object === "string" ) {
6267 this . encodeString ( object ) ;
68+ } else if ( this . useBigInt64 && typeof object === "bigint" ) {
69+ this . encodeBigInt64 ( object ) ;
6370 } else {
6471 this . encodeObject ( object , depth ) ;
6572 }
@@ -95,8 +102,9 @@ export class Encoder<ContextType = undefined> {
95102 this . writeU8 ( 0xc3 ) ;
96103 }
97104 }
98- private encodeNumber ( object : number ) {
99- if ( Number . isSafeInteger ( object ) && ! this . forceIntegerToFloat ) {
105+
106+ private encodeNumber ( object : number ) : void {
107+ if ( ! this . forceIntegerToFloat && Number . isSafeInteger ( object ) ) {
100108 if ( object >= 0 ) {
101109 if ( object < 0x80 ) {
102110 // positive fixint
@@ -113,10 +121,12 @@ export class Encoder<ContextType = undefined> {
113121 // uint 32
114122 this . writeU8 ( 0xce ) ;
115123 this . writeU32 ( object ) ;
116- } else {
124+ } else if ( ! this . useBigInt64 ) {
117125 // uint 64
118126 this . writeU8 ( 0xcf ) ;
119127 this . writeU64 ( object ) ;
128+ } else {
129+ this . encodeNumberAsFloat ( object ) ;
120130 }
121131 } else {
122132 if ( object >= - 0x20 ) {
@@ -134,23 +144,40 @@ export class Encoder<ContextType = undefined> {
134144 // int 32
135145 this . writeU8 ( 0xd2 ) ;
136146 this . writeI32 ( object ) ;
137- } else {
147+ } else if ( ! this . useBigInt64 ) {
138148 // int 64
139149 this . writeU8 ( 0xd3 ) ;
140150 this . writeI64 ( object ) ;
151+ } else {
152+ this . encodeNumberAsFloat ( object ) ;
141153 }
142154 }
143155 } else {
144- // non-integer numbers
145- if ( this . forceFloat32 ) {
146- // float 32
147- this . writeU8 ( 0xca ) ;
148- this . writeF32 ( object ) ;
149- } else {
150- // float 64
151- this . writeU8 ( 0xcb ) ;
152- this . writeF64 ( object ) ;
153- }
156+ this . encodeNumberAsFloat ( object ) ;
157+ }
158+ }
159+
160+ private encodeNumberAsFloat ( object : number ) : void {
161+ if ( this . forceFloat32 ) {
162+ // float 32
163+ this . writeU8 ( 0xca ) ;
164+ this . writeF32 ( object ) ;
165+ } else {
166+ // float 64
167+ this . writeU8 ( 0xcb ) ;
168+ this . writeF64 ( object ) ;
169+ }
170+ }
171+
172+ private encodeBigInt64 ( object : bigint ) : void {
173+ if ( object >= BigInt ( 0 ) ) {
174+ // uint 64
175+ this . writeU8 ( 0xcf ) ;
176+ this . writeBigUint64 ( object ) ;
177+ } else {
178+ // int 64
179+ this . writeU8 ( 0xd3 ) ;
180+ this . writeBigInt64 ( object ) ;
154181 }
155182 }
156183
@@ -377,12 +404,14 @@ export class Encoder<ContextType = undefined> {
377404
378405 private writeF32 ( value : number ) {
379406 this . ensureBufferSizeToWrite ( 4 ) ;
407+
380408 this . view . setFloat32 ( this . pos , value ) ;
381409 this . pos += 4 ;
382410 }
383411
384412 private writeF64 ( value : number ) {
385413 this . ensureBufferSizeToWrite ( 8 ) ;
414+
386415 this . view . setFloat64 ( this . pos , value ) ;
387416 this . pos += 8 ;
388417 }
@@ -400,4 +429,18 @@ export class Encoder<ContextType = undefined> {
400429 setInt64 ( this . view , this . pos , value ) ;
401430 this . pos += 8 ;
402431 }
432+
433+ private writeBigUint64 ( value : bigint ) {
434+ this . ensureBufferSizeToWrite ( 8 ) ;
435+
436+ this . view . setBigUint64 ( this . pos , value ) ;
437+ this . pos += 8 ;
438+ }
439+
440+ private writeBigInt64 ( value : bigint ) {
441+ this . ensureBufferSizeToWrite ( 8 ) ;
442+
443+ this . view . setBigInt64 ( this . pos , value ) ;
444+ this . pos += 8 ;
445+ }
403446}
0 commit comments