1- import {
2- ConNode ,
3- JsonNode ,
4- ValNode ,
5- ArrNode ,
6- ArrChunk ,
7- BinNode ,
8- BinChunk ,
9- ObjNode ,
10- StrNode ,
11- StrChunk ,
12- } from '../../../nodes' ;
1+ import * as nodes from '../../../nodes' ;
132import { ClockTable } from '../../../../json-crdt-patch/codec/clock/ClockTable' ;
143import { CrdtReader } from '../../../../json-crdt-patch/util/binary/CrdtReader' ;
154import { IndexedFields , FieldName , IndexedNodeFields } from './types' ;
165import { ITimestampStruct , IVectorClock , Timestamp , VectorClock } from '../../../../json-crdt-patch/clock' ;
176import { Model , UNDEFINED } from '../../../model/Model' ;
18- import { MsgPackDecoderFast } from '../../../../json-pack/msgpack' ;
7+ import { CborDecoderBase } from '../../../../json-pack/cbor/CborDecoderBase' ;
8+ import { CRDT_MAJOR } from '../../structural/binary/constants' ;
199
2010export class Decoder {
21- public readonly dec = new MsgPackDecoderFast < CrdtReader > ( new CrdtReader ( ) ) ;
11+ public readonly dec : CborDecoderBase < CrdtReader > ;
2212 protected doc ! : Model ;
2313 protected clockTable ?: ClockTable ;
2414
15+ constructor ( reader ?: CrdtReader ) {
16+ this . dec = new CborDecoderBase < CrdtReader > ( reader || new CrdtReader ( ) ) ;
17+ }
18+
2519 public decode < M extends Model > (
2620 fields : IndexedFields ,
2721 ModelConstructor : new ( clock : IVectorClock ) => M = Model as unknown as new ( clock : IVectorClock ) => M ,
@@ -47,14 +41,17 @@ export class Decoder {
4741 const rootValue = this . ts ( ) ;
4842 doc . root . set ( rootValue ) ;
4943 }
50- const docIndex = doc . index ;
51- for ( const field in fields ) {
44+ const index = doc . index ;
45+ const keys = Object . keys ( fields ) ;
46+ const length = keys . length ;
47+ for ( let i = 0 ; i < length ; i ++ ) {
48+ const field = keys [ i ] ;
5249 if ( field . length < 3 ) continue ; // Skip "c" and "r".
5350 const arr = fields [ field as FieldName ] ;
5451 const id = clockTable . parseField ( field as FieldName ) ;
5552 reader . reset ( arr ) ;
5653 const node = this . decodeNode ( id ) ;
57- docIndex . set ( node . id , node ) ;
54+ index . set ( id , node ) ;
5855 }
5956 return doc ;
6057 }
@@ -64,107 +61,117 @@ export class Decoder {
6461 return new Timestamp ( this . clockTable ! . byIdx [ sessionIndex ] . sid , timeDiff ) ;
6562 }
6663
67- protected decodeNode ( id : ITimestampStruct ) : JsonNode {
64+ protected decodeNode ( id : ITimestampStruct ) : nodes . JsonNode {
6865 const reader = this . dec . reader ;
69- const byte = reader . u8 ( ) ;
70- if ( byte <= 0b10001111 ) return this . cObj ( id , byte & 0b1111 ) ;
71- else if ( byte <= 0b10011111 ) return this . cArr ( id , byte & 0b1111 ) ;
72- else if ( byte <= 0b10111111 ) return this . cStr ( id , byte & 0b11111 ) ;
73- else {
74- switch ( byte ) {
75- case 0xc4 :
76- return this . cBin ( id , reader . u8 ( ) ) ;
77- case 0xc5 :
78- return this . cBin ( id , reader . u16 ( ) ) ;
79- case 0xc6 :
80- return this . cBin ( id , reader . u32 ( ) ) ;
81- case 0xd4 :
82- return this . cConst ( id ) ;
83- case 0xd5 :
84- return new ConNode ( id , this . ts ( ) ) ;
85- case 0xd6 :
86- return this . cVal ( id ) ;
87- case 0xde :
88- return this . cObj ( id , reader . u16 ( ) ) ;
89- case 0xdf :
90- return this . cObj ( id , reader . u32 ( ) ) ;
91- case 0xdc :
92- return this . cArr ( id , reader . u16 ( ) ) ;
93- case 0xdd :
94- return this . cArr ( id , reader . u32 ( ) ) ;
95- case 0xd9 :
96- return this . cStr ( id , reader . u8 ( ) ) ;
97- case 0xda :
98- return this . cStr ( id , reader . u16 ( ) ) ;
99- case 0xdb :
100- return this . cStr ( id , reader . u32 ( ) ) ;
101- }
66+ const octet = reader . u8 ( ) ;
67+ const major = octet >> 5 ;
68+ const minor = octet & 0b11111 ;
69+ const length = minor < 24 ? minor : minor === 24 ? reader . u8 ( ) : minor === 25 ? reader . u16 ( ) : reader . u32 ( ) ;
70+ switch ( major ) {
71+ case CRDT_MAJOR . CON :
72+ return this . decodeCon ( id , length ) ;
73+ case CRDT_MAJOR . VAL :
74+ return this . decodeVal ( id ) ;
75+ case CRDT_MAJOR . OBJ :
76+ return this . decodeObj ( id , length ) ;
77+ case CRDT_MAJOR . VEC :
78+ return this . decodeVec ( id , length ) ;
79+ case CRDT_MAJOR . STR :
80+ return this . decodeStr ( id , length ) ;
81+ case CRDT_MAJOR . BIN :
82+ return this . decodeBin ( id , length ) ;
83+ case CRDT_MAJOR . ARR :
84+ return this . decodeArr ( id , length ) ;
10285 }
103-
10486 return UNDEFINED ;
10587 }
10688
107- public cConst ( id : ITimestampStruct ) : ConNode {
108- const val = this . dec . val ( ) ;
109- return new ConNode ( id , val ) ;
89+ public decodeCon ( id : ITimestampStruct , length : number ) : nodes . ConNode {
90+ const decoder = this . dec ;
91+ const data = ! length ? decoder . val ( ) : this . ts ( ) ;
92+ const node = new nodes . ConNode ( id , data ) ;
93+ return node ;
11094 }
11195
112- public cVal ( id : ITimestampStruct ) : ValNode {
96+ public decodeVal ( id : ITimestampStruct ) : nodes . ValNode {
11397 const val = this . ts ( ) ;
114- return new ValNode ( this . doc , id , val ) ;
98+ const node = new nodes . ValNode ( this . doc , id , val ) ;
99+ return node ;
115100 }
116101
117- public cObj ( id : ITimestampStruct , length : number ) : ObjNode {
102+ public decodeObj ( id : ITimestampStruct , length : number ) : nodes . ObjNode {
118103 const decoder = this . dec ;
119- const obj = new ObjNode ( this . doc , id ) ;
104+ const obj = new nodes . ObjNode ( this . doc , id ) ;
120105 const keys = obj . keys ;
121106 for ( let i = 0 ; i < length ; i ++ ) {
122- const key = String ( decoder . val ( ) ) ;
107+ const key = decoder . val ( ) + '' ;
123108 const val = this . ts ( ) ;
124109 keys . set ( key , val ) ;
125110 }
126111 return obj ;
127112 }
128113
129- protected cStr ( id : ITimestampStruct , length : number ) : StrNode {
130- const decoder = this . dec ;
131- const node = new StrNode ( id ) ;
132- node . ingest ( length , ( ) => {
133- const chunkId = this . ts ( ) ;
134- const val = decoder . val ( ) ;
135- if ( typeof val === 'number' ) return new StrChunk ( chunkId , val , '' ) ;
136- const data = String ( val ) ;
137- return new StrChunk ( chunkId , data . length , data ) ;
138- } ) ;
114+ public decodeVec ( id : ITimestampStruct , length : number ) : nodes . VecNode {
115+ const reader = this . dec . reader ;
116+ const node = new nodes . VecNode ( this . doc , id ) ;
117+ const elements = node . elements ;
118+ for ( let i = 0 ; i < length ; i ++ ) {
119+ const octet = reader . u8 ( ) ;
120+ if ( ! octet ) elements . push ( undefined ) ;
121+ else elements . push ( this . ts ( ) ) ;
122+ }
139123 return node ;
140124 }
141125
142- protected cBin ( id : ITimestampStruct , length : number ) : BinNode {
143- const decoder = this . dec ;
144- const reader = decoder . reader ;
145- const node = new BinNode ( id ) ;
146- node . ingest ( length , ( ) => {
147- const chunkId = this . ts ( ) ;
148- const [ deleted , length ] = reader . b1vu28 ( ) ;
149- if ( deleted ) return new BinChunk ( chunkId , length , undefined ) ;
150- const data = reader . buf ( length ) ;
151- return new BinChunk ( chunkId , length , data ) ;
152- } ) ;
126+ protected decodeStr ( id : ITimestampStruct , length : number ) : nodes . StrNode {
127+ const node = new nodes . StrNode ( id ) ;
128+ node . ingest ( length , this . decodeStrChunk ) ;
153129 return node ;
154130 }
155131
156- protected cArr ( id : ITimestampStruct , length : number ) : ArrNode {
132+ private decodeStrChunk = ( ) : nodes . StrChunk => {
157133 const decoder = this . dec ;
158134 const reader = decoder . reader ;
159- const node = new ArrNode ( this . doc , id ) ;
160- node . ingest ( length , ( ) => {
161- const chunkId = this . ts ( ) ;
162- const [ deleted , length ] = reader . b1vu28 ( ) ;
163- if ( deleted ) return new ArrChunk ( chunkId , length , undefined ) ;
164- const data : ITimestampStruct [ ] = [ ] ;
165- for ( let i = 0 ; i < length ; i ++ ) data . push ( this . ts ( ) ) ;
166- return new ArrChunk ( chunkId , length , data ) ;
167- } ) ;
135+ const id = this . ts ( ) ;
136+ const isTombstone = reader . uint8 [ reader . x ] === 0 ;
137+ if ( isTombstone ) {
138+ reader . x ++ ;
139+ const length = reader . vu39 ( ) ;
140+ return new nodes . StrChunk ( id , length , '' ) ;
141+ }
142+ const text : string = decoder . readAsStr ( ) as string ;
143+ return new nodes . StrChunk ( id , text . length , text ) ;
144+ } ;
145+
146+ protected decodeBin ( id : ITimestampStruct , length : number ) : nodes . BinNode {
147+ const node = new nodes . BinNode ( id ) ;
148+ node . ingest ( length , this . decodeBinChunk ) ;
149+ return node ;
150+ }
151+
152+ private decodeBinChunk = ( ) : nodes . BinChunk => {
153+ const id = this . ts ( ) ;
154+ const reader = this . dec . reader ;
155+ const [ deleted , length ] = reader . b1vu56 ( ) ;
156+ if ( deleted ) return new nodes . BinChunk ( id , length , undefined ) ;
157+ else return new nodes . BinChunk ( id , length , reader . buf ( length ) ) ;
158+ } ;
159+
160+ protected decodeArr ( id : ITimestampStruct , length : number ) : nodes . ArrNode {
161+ const node = new nodes . ArrNode ( this . doc , id ) ;
162+ node . ingest ( length , this . decodeArrChunk ) ;
168163 return node ;
169164 }
165+
166+ private decodeArrChunk = ( ) : nodes . ArrChunk => {
167+ const id = this . ts ( ) ;
168+ const reader = this . dec . reader ;
169+ const [ deleted , length ] = reader . b1vu56 ( ) ;
170+ if ( deleted ) return new nodes . ArrChunk ( id , length , undefined ) ;
171+ else {
172+ const data : ITimestampStruct [ ] = [ ] ;
173+ for ( let i = 0 ; i < length ; i ++ ) data . push ( this . ts ( ) ) ;
174+ return new nodes . ArrChunk ( id , length , data ) ;
175+ }
176+ } ;
170177}
0 commit comments