1
- import { Virtual } from "as-virtual/assembly" ;
2
- import { containsCodePoint , unsafeCharCodeAt } from "../../custom/util" ;
3
- import { CHAR_A , BACK_SLASH , COLON , COMMA , CHAR_E , CHAR_F , CHAR_L , BRACE_LEFT , BRACKET_LEFT , CHAR_N , QUOTE , CHAR_R , BRACE_RIGHT , BRACKET_RIGHT , CHAR_S , CHAR_T , CHAR_U } from "../../custom/chars" ;
4
- import { deserializeBoolean } from "./bool" ;
5
1
import { JSON } from "../.." ;
6
- import { deserializeString } from "./string " ;
2
+ import { BACK_SLASH , COMMA , CHAR_F , BRACE_LEFT , BRACKET_LEFT , CHAR_N , QUOTE , BRACE_RIGHT , BRACKET_RIGHT , CHAR_T , COLON } from "../../custom/chars " ;
7
3
import { isSpace } from "../../util" ;
8
- import { deserializeInteger } from "./integer" ;
9
- import { deserializeFloat } from "./float" ;
10
4
11
- // @ts -ignore: Decorator valid here
12
- @inline export function deserializeMap < T extends Map > ( data : string ) : T {
13
- const map : nonnull < T > = changetype < nonnull < T > > ( __new ( offsetof < nonnull < T > > ( ) , idof < nonnull < T > > ( ) ) ) ;
5
+ export function deserializeMap < T extends Map < any , any > > ( srcStart : usize , srcEnd : usize , dst : T | null = null ) : T {
6
+ // @ts -ignore: type
7
+ if ( ! isString < indexof < T > > ( ) && ! isInteger < indexof < T > > ( ) ) ERROR ( "Map key must be of type string | number!" ) ;
8
+ dst = dst || changetype < nonnull < T > > ( __new ( offsetof < nonnull < T > > ( ) , idof < nonnull < T > > ( ) ) ) ;
9
+ console . log ( "Data: " + str ( srcStart , srcEnd ) ) ;
14
10
15
- const key = Virtual . createEmpty < string > ( ) ;
11
+ const srcPtr = srcStart ;
12
+ let key : string | null = null ;
16
13
let isKey = false ;
17
14
let depth = 0 ;
18
- let outerLoopIndex = 1 ;
19
- for ( ; outerLoopIndex < data . length - 1 ; outerLoopIndex ++ ) {
20
- const char = unsafeCharCodeAt ( data , outerLoopIndex ) ;
21
- if ( char == BRACKET_LEFT ) {
22
- for ( let arrayValueIndex = outerLoopIndex ; arrayValueIndex < data . length - 1 ; arrayValueIndex ++ ) {
23
- const char = unsafeCharCodeAt ( data , arrayValueIndex ) ;
24
- if ( char == BRACKET_LEFT ) {
25
- depth ++ ;
26
- } else if ( char == BRACKET_RIGHT ) {
27
- depth -- ;
28
- if ( depth == 0 ) {
29
- ++ arrayValueIndex ;
30
- map . set ( deserializeMapKey < indexof < T > > ( key ) , JSON . parse < valueof < T > > ( data . slice ( outerLoopIndex , arrayValueIndex ) ) ) ;
31
- outerLoopIndex = arrayValueIndex ;
32
- isKey = false ;
33
- break ;
15
+ let lastIndex = 0 ;
16
+
17
+ // while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
18
+ // while (srcEnd > srcStart && isSpace(load<u16>(srcEnd))) srcEnd -= 2;
19
+
20
+ while ( srcStart < srcEnd ) {
21
+ let code = load < u16 > ( srcStart ) ; // while (isSpace(code)) code = load<u16>(srcStart += 2);
22
+ if ( key == null ) {
23
+ if ( code == QUOTE && load < u16 > ( srcStart - 2 ) !== BACK_SLASH ) {
24
+ if ( isKey ) {
25
+ key = sliceTo ( lastIndex , srcStart ) ;
26
+ console . log ( "Key: " + key ) ;
27
+ while ( isSpace ( ( code = load < u16 > ( ( srcStart += 2 ) ) ) ) ) {
28
+ /* empty */
34
29
}
30
+ if ( code !== COLON ) throw new Error ( "Expected ':' after key at position " + ( srcStart - srcPtr ) . toString ( ) ) ;
31
+ isKey = false ;
32
+ } else {
33
+ isKey = true ; // i don't like this
34
+ lastIndex = srcStart + 2 ;
35
35
}
36
36
}
37
- } else if ( char == BRACE_LEFT ) {
38
- for ( let objectValueIndex = outerLoopIndex ; objectValueIndex < data . length - 1 ; objectValueIndex ++ ) {
39
- const char = unsafeCharCodeAt ( data , objectValueIndex ) ;
40
- if ( char == BRACE_LEFT ) {
41
- depth ++ ;
42
- } else if ( char == BRACE_RIGHT ) {
43
- depth -- ;
44
- if ( depth == 0 ) {
45
- ++ objectValueIndex ;
46
- map . set ( deserializeMapKey < indexof < T > > ( key ) , JSON . parse < valueof < T > > ( data . slice ( outerLoopIndex , objectValueIndex ) ) ) ;
47
- outerLoopIndex = objectValueIndex ;
48
- isKey = false ;
37
+ // isKey = !isKey;
38
+ srcStart += 2 ;
39
+ } else {
40
+ if ( code == QUOTE ) {
41
+ lastIndex = srcStart ;
42
+ srcStart += 2 ;
43
+ while ( srcStart < srcEnd ) {
44
+ const code = load < u16 > ( srcStart ) ;
45
+ if ( code == QUOTE && load < u16 > ( srcStart - 2 ) !== BACK_SLASH ) {
46
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
47
+ /* empty */
48
+ }
49
+ console . log ( "Value (string): " + str ( lastIndex , srcStart ) ) ;
50
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( lastIndex , srcStart ) ) ;
51
+ key = null ;
49
52
break ;
50
53
}
54
+ srcStart += 2 ;
51
55
}
52
- }
53
- } else if ( char == QUOTE ) {
54
- let escaping = false ;
55
- for ( let stringValueIndex = ++ outerLoopIndex ; stringValueIndex < data . length - 1 ; stringValueIndex ++ ) {
56
- const char = unsafeCharCodeAt ( data , stringValueIndex ) ;
57
- if ( char == BACK_SLASH && ! escaping ) {
58
- escaping = true ;
59
- } else {
60
- if ( char == QUOTE && ! escaping ) {
61
- if ( isKey == false ) {
62
- // perf: we can avoid creating a new string here if the key doesn't contain any escape sequences
63
- if ( containsCodePoint ( data , BACK_SLASH , outerLoopIndex , stringValueIndex ) ) {
64
- key . reinst ( deserializeString ( data , outerLoopIndex - 1 , stringValueIndex ) ) ;
65
- } else {
66
- key . reinst ( data , outerLoopIndex , stringValueIndex ) ;
67
- }
68
- isKey = true ;
69
- } else {
70
- if ( isString < valueof < T > > ( ) ) {
71
- const value = deserializeString ( data , outerLoopIndex - 1 , stringValueIndex ) ;
72
- map . set ( deserializeMapKey < indexof < T > > ( key ) , value ) ;
73
- }
74
- isKey = false ;
56
+ } else if ( code - 48 <= 9 || code == 45 ) {
57
+ lastIndex = srcStart ;
58
+ srcStart += 2 ;
59
+ while ( srcStart < srcEnd ) {
60
+ const code = load < u16 > ( srcStart ) ;
61
+ if ( code == COMMA || isSpace ( code ) || code == BRACE_RIGHT ) {
62
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( lastIndex , srcStart ) ) ;
63
+ console . log ( "Value (number): " + str ( lastIndex , srcStart ) ) ;
64
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
65
+ /* empty */
75
66
}
76
- outerLoopIndex = ++ stringValueIndex ;
67
+ key = null ;
77
68
break ;
78
69
}
79
- escaping = false ;
70
+ srcStart += 2 ;
80
71
}
81
- }
82
- } else if ( char == CHAR_N && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_U && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_L && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_L ) {
83
- if ( isNullable < valueof < T > > ( ) ) {
84
- map . set ( deserializeMapKey < indexof < T > > ( key ) , null ) ;
85
- }
86
- isKey = false ;
87
- } else if ( char == CHAR_T && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_R && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_U && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_E ) {
88
- if ( isBoolean < valueof < T > > ( ) ) {
89
- map . set ( deserializeMapKey < indexof < T > > ( key ) , true ) ;
90
- }
91
- isKey = false ;
92
- } else if ( char == CHAR_F && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_A && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_L && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_S && unsafeCharCodeAt ( data , ++ outerLoopIndex ) == CHAR_E ) {
93
- if ( isBoolean < valueof < T > > ( ) ) {
94
- map . set ( deserializeMapKey < indexof < T > > ( key ) , false ) ;
95
- }
96
- isKey = false ;
97
- } else if ( ( char >= 48 && char <= 57 ) || char == 45 ) {
98
- let numberValueIndex = ++ outerLoopIndex ;
99
- for ( ; numberValueIndex < data . length ; numberValueIndex ++ ) {
100
- const char = unsafeCharCodeAt ( data , numberValueIndex ) ;
101
- if ( char == COLON || char == COMMA || char == BRACE_RIGHT || isSpace ( char ) ) {
102
- if ( isInteger < valueof < T > > ( ) ) {
103
- map . set ( deserializeMapKey < indexof < T > > ( key ) , deserializeInteger < valueof < T > > ( data . slice ( outerLoopIndex - 1 , numberValueIndex ) ) ) ;
104
- } else if ( isFloat < valueof < T > > ( ) ) {
105
- map . set ( deserializeMapKey < indexof < T > > ( key ) , deserializeFloat < valueof < T > > ( data . slice ( outerLoopIndex - 1 , numberValueIndex ) ) ) ;
72
+ } else if ( code == BRACE_LEFT ) {
73
+ lastIndex = srcStart ;
74
+ depth ++ ;
75
+ srcStart += 2 ;
76
+ while ( srcStart < srcEnd ) {
77
+ const code = load < u16 > ( srcStart ) ;
78
+ if ( ( ( code ^ BRACE_RIGHT ) | ( code ^ BRACKET_RIGHT ) ) == 32 ) {
79
+ if ( -- depth == 0 ) {
80
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( lastIndex , srcStart ) ) ;
81
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
82
+ /* empty */
83
+ }
84
+ key = null ;
85
+ break ;
86
+ }
87
+ } else if ( ( ( code ^ BRACE_LEFT ) | ( code ^ BRACKET_LEFT ) ) == 220 ) depth ++ ;
88
+ srcStart += 2 ;
89
+ }
90
+ } else if ( code == CHAR_T ) {
91
+ if ( load < u64 > ( srcStart ) == 28429475166421108 ) {
92
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( srcStart , srcStart += 8 ) ) ;
93
+ console . log ( "Value (bool): " + str ( srcStart - 8 , srcStart ) ) ;
94
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
95
+ /* empty */
96
+ }
97
+ key = null ;
98
+ }
99
+ } else if ( code == CHAR_F ) {
100
+ if ( load < u64 > ( srcStart , 2 ) == 28429466576093281 ) {
101
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( srcStart , srcStart += 10 ) ) ;
102
+ console . log ( "Value (bool): " + str ( srcStart - 10 , srcStart ) ) ;
103
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
104
+ /* empty */
105
+ }
106
+ key = null ;
107
+ }
108
+ } else if ( code == CHAR_N ) {
109
+ if ( load < u64 > ( srcStart ) == 30399761348886638 ) {
110
+ dst . set ( key , JSON . __deserialize < valueof < T > > ( srcStart , srcStart += 8 ) ) ;
111
+ console . log ( "Value (null): " + str ( srcStart - 8 , srcStart ) ) ;
112
+ while ( isSpace ( load < u16 > ( ( srcStart += 2 ) ) ) ) {
113
+ /* empty */
106
114
}
107
- outerLoopIndex = numberValueIndex ;
108
- isKey = false ;
109
- break ;
110
115
}
111
116
}
112
117
}
113
118
}
114
-
115
- return map ;
119
+ return dst ;
116
120
}
117
121
118
- //@ts -ignore: Decorator
119
- function deserializeMapKey < T > ( key : Virtual < string > ) : T {
120
- const k = key . copyOut ( ) ;
121
- if ( isString < T > ( ) ) {
122
- return k as T ;
123
- } else if ( isBoolean < T > ( ) ) {
124
- return deserializeBoolean ( k ) as T ;
125
- } else if ( isInteger < T > ( ) ) {
126
- return deserializeInteger < T > ( k ) ;
127
- } else if ( isFloat < T > ( ) ) {
128
- return deserializeFloat < T > ( k ) ;
129
- }
130
-
131
- throw new Error ( `JSON: Cannot parse JSON object to a Map with a key of type ${ nameof < T > ( ) } ` ) ;
122
+ function str ( start : usize , end : usize ) : string {
123
+ const size = end - start ;
124
+ const out = __new ( size , idof < string > ( ) ) ;
125
+ memory . copy ( out , start , size ) ;
126
+ return changetype < string > ( out ) ;
132
127
}
128
+
129
+ // @ts -ignore: Decorator valid here
130
+ @inline function sliceTo ( srcStart : usize , srcEnd : usize ) : string {
131
+ const dstSize = srcEnd - srcStart ;
132
+ const dst = __new ( dstSize , idof < string > ( ) ) ;
133
+ memory . copy ( dst , srcStart , dstSize ) ;
134
+ return changetype < string > ( dst ) ;
135
+ }
0 commit comments