@@ -40,6 +40,7 @@ import {
4040} from '@deepkit/type' ;
4141import { seekElementSize } from './continuation.js' ;
4242import { BSONType , digitByteSize , isSerializable } from './utils.js' ;
43+ import { BaseParser } from './bson-parser.js' ;
4344
4445function getNameComparator ( name : string ) : string {
4546 //todo: support utf8 names
@@ -74,55 +75,49 @@ export function deserializeAny(type: Type, state: TemplateState) {
7475 ` ) ;
7576}
7677
77- export function deserializeNumber ( type : Type , state : TemplateState ) {
78- const readBigInt = type . kind === ReflectionKind . bigint ? `state.parser.parseBinaryBigInt()` : `Number(state.parser.parseBinaryBigInt())` ;
78+ const numberParsers = createParserLookup ( ( ) => 0 , [
79+ [ BSONType . INT , parser => parser . parseInt ( ) ] ,
80+ [ BSONType . NUMBER , parser => parser . parseNumber ( ) ] ,
81+ [ BSONType . LONG , parser => parser . parseLong ( ) ] ,
82+ [ BSONType . TIMESTAMP , parser => parser . parseLong ( ) ] ,
83+ [ BSONType . BOOLEAN , parser => parser . parseBoolean ( ) ? 1 : 0 ] ,
84+ [ BSONType . BINARY , parser => Number ( parser . parseBinaryBigInt ( ) ) ] ,
85+ [ BSONType . STRING , parser => Number ( parser . parseString ( ) ) ] ,
86+ ] ) ;
7987
88+ export function deserializeNumber ( type : Type , state : TemplateState ) {
89+ state . setContext ( { numberParsers } ) ;
8090 state . addCode ( `
81- if (state.elementType === ${ BSONType . INT } ) {
82- ${ state . setter } = state.parser.parseInt();
83- } else if (state.elementType === ${ BSONType . NULL } || state.elementType === ${ BSONType . UNDEFINED } ) {
84- ${ state . setter } = 0;
85- } else if (state.elementType === ${ BSONType . NUMBER } ) {
86- ${ state . setter } = state.parser.parseNumber();
87- } else if (state.elementType === ${ BSONType . LONG } || state.elementType === ${ BSONType . TIMESTAMP } ) {
88- ${ state . setter } = state.parser.parseLong();
89- } else if (state.elementType === ${ BSONType . BOOLEAN } ) {
90- ${ state . setter } = state.parser.parseBoolean() ? 1 : 0;
91- } else if (state.elementType === ${ BSONType . BINARY } ) {
92- ${ state . setter } = ${ readBigInt } ;
93- } else if (state.elementType === ${ BSONType . STRING } ) {
94- ${ state . setter } = Number(state.parser.parseString());
95- if (isNaN(${ state . setter } )) {
96- ${ throwInvalidBsonType ( type , state ) }
97- }
98- } else {
91+ ${ state . setter } = numberParsers[state.elementType](state.parser);
92+ if (isNaN(${ state . setter } )) {
9993 ${ throwInvalidBsonType ( type , state ) }
10094 }
10195 ` ) ;
10296}
10397
98+ const bigIntParsers = createParserLookup ( ( ) => 0n , [
99+ [ BSONType . INT , parser => BigInt ( parser . parseInt ( ) ) ] ,
100+ [ BSONType . NUMBER , parser => BigInt ( parser . parseNumber ( ) ) ] ,
101+ [ BSONType . LONG , parser => BigInt ( parser . parseLong ( ) ) ] ,
102+ [ BSONType . TIMESTAMP , parser => BigInt ( parser . parseLong ( ) ) ] ,
103+ [ BSONType . BOOLEAN , parser => BigInt ( parser . parseBoolean ( ) ? 1 : 0 ) ] ,
104+ [ BSONType . BINARY , parser => parser . parseBinaryBigInt ( ) ] ,
105+ [ BSONType . STRING , parser => BigInt ( parser . parseString ( ) ) ] ,
106+ ] ) ;
107+
104108export function deserializeBigInt ( type : Type , state : TemplateState ) {
105109 const binaryBigInt = binaryBigIntAnnotation . getFirst ( type ) ;
106- const parseBigInt = binaryBigInt === BinaryBigIntType . signed ? 'parseSignedBinaryBigInt' : 'parseBinaryBigInt' ;
110+
111+ state . setContext ( { bigIntParsers } ) ;
112+ let lookup = 'bigIntParsers' ;
113+ if ( binaryBigInt === BinaryBigIntType . signed ) {
114+ const customLookup = bigIntParsers . slice ( ) ;
115+ customLookup [ BSONType . BINARY ] = parser => parser . parseSignedBinaryBigInt ( ) ;
116+ lookup = state . setVariable ( 'lookup' , customLookup ) ;
117+ }
107118
108119 state . addCode ( `
109- if (state.elementType === ${ BSONType . INT } ) {
110- ${ state . setter } = BigInt(state.parser.parseInt());
111- } else if (state.elementType === ${ BSONType . NULL } || state.elementType === ${ BSONType . UNDEFINED } ) {
112- ${ state . setter } = 0n;
113- } else if (state.elementType === ${ BSONType . NUMBER } ) {
114- ${ state . setter } = BigInt(state.parser.parseNumber());
115- } else if (state.elementType === ${ BSONType . LONG } || state.elementType === ${ BSONType . TIMESTAMP } ) {
116- ${ state . setter } = BigInt(state.parser.parseLong());
117- } else if (state.elementType === ${ BSONType . BOOLEAN } ) {
118- ${ state . setter } = BigInt(state.parser.parseBoolean() ? 1 : 0);
119- } else if (state.elementType === ${ BSONType . BINARY } && ${ binaryBigInt } !== undefined) {
120- ${ state . setter } = state.parser.${ parseBigInt } ();
121- } else if (state.elementType === ${ BSONType . STRING } ) {
122- ${ state . setter } = BigInt(state.parser.parseString());
123- } else {
124- ${ throwInvalidBsonType ( type , state ) }
125- }
120+ ${ state . setter } = ${ lookup } [state.elementType](state.parser);
126121 ` ) ;
127122}
128123
@@ -205,21 +200,36 @@ export function deserializeUndefined(type: Type, state: TemplateState) {
205200 ` ) ;
206201}
207202
203+ type Parse = ( parser : BaseParser ) => any ;
204+
205+ function createParserLookup ( defaultParse : Parse , parsers : [ elementType : BSONType , fn : Parse ] [ ] ) : Parse [ ] {
206+ const result = [
207+ defaultParse , defaultParse , defaultParse , defaultParse , defaultParse ,
208+ defaultParse , defaultParse , defaultParse , defaultParse , defaultParse ,
209+ defaultParse , defaultParse , defaultParse , defaultParse , defaultParse ,
210+ defaultParse , defaultParse , defaultParse , defaultParse , defaultParse ,
211+ ] ;
212+ for ( const [ index , parse ] of parsers ) {
213+ result [ index ] = parse ;
214+ }
215+ return result ;
216+ }
217+
218+ const booleanParsers = createParserLookup ( ( ) => 0 , [
219+ [ BSONType . BOOLEAN , parser => parser . parseBoolean ( ) ] ,
220+ [ BSONType . NULL , parser => 0 ] ,
221+ [ BSONType . UNDEFINED , parser => 0 ] ,
222+ [ BSONType . INT , parser => ! ! parser . parseInt ( ) ] ,
223+ [ BSONType . NUMBER , parser => ! ! parser . parseNumber ( ) ] ,
224+ [ BSONType . LONG , parser => ! ! parser . parseLong ( ) ] ,
225+ [ BSONType . TIMESTAMP , parser => ! ! parser . parseLong ( ) ] ,
226+ [ BSONType . STRING , parser => ! ! Number ( parser . parseString ( ) ) ] ,
227+ ] ) ;
228+
208229export function deserializeBoolean ( type : Type , state : TemplateState ) {
230+ state . setContext ( { booleanParsers } ) ;
209231 state . addCode ( `
210- if (state.elementType === ${ BSONType . BOOLEAN } ) {
211- ${ state . setter } = state.parser.parseBoolean();
212- } else if (state.elementType === ${ BSONType . NULL } || state.elementType === ${ BSONType . UNDEFINED } ) {
213- ${ state . setter } = false;
214- } else if (state.elementType === ${ BSONType . INT } ) {
215- ${ state . setter } = state.parser.parseInt() ? true : false;
216- } else if (state.elementType === ${ BSONType . NUMBER } ) {
217- ${ state . setter } = state.parser.parseNumber() ? true : false;
218- } else if (state.elementType === ${ BSONType . LONG } || state.elementType === ${ BSONType . TIMESTAMP } ) {
219- ${ state . setter } = state.parser.parseLong() ? true : false;
220- } else {
221- ${ throwInvalidBsonType ( type , state ) }
222- }
232+ ${ state . setter } = booleanParsers[state.elementType](state.parser);
223233 ` ) ;
224234}
225235
@@ -538,7 +548,10 @@ export function deserializeArray(type: TypeArray, state: TemplateState) {
538548 state . setContext ( { digitByteSize } ) ;
539549
540550 state . addCode ( `
541- if (state.elementType && state.elementType !== ${ BSONType . ARRAY } ) ${ throwInvalidBsonType ( { kind : ReflectionKind . array , type : elementType } , state ) }
551+ if (state.elementType && state.elementType !== ${ BSONType . ARRAY } ) ${ throwInvalidBsonType ( {
552+ kind : ReflectionKind . array ,
553+ type : elementType ,
554+ } , state ) }
542555 {
543556 var ${ result } = [];
544557 const end = state.parser.eatUInt32() + state.parser.offset;
0 commit comments