@@ -80,57 +80,77 @@ class Packer {
8080 this . _ch = channel ;
8181 }
8282
83- pack ( x ) {
83+ /**
84+ * Creates a packable function out of the provided value
85+ * @param x the value to pack
86+ * @param onError callback for the case when value cannot be packed
87+ * @returns Function
88+ */
89+ packable ( x , onError ) {
8490 if ( x === null ) {
85- this . _ch . writeUInt8 ( NULL ) ;
91+ return ( ) => this . _ch . writeUInt8 ( NULL ) ;
8692 } else if ( x === true ) {
87- this . _ch . writeUInt8 ( TRUE ) ;
93+ return ( ) => this . _ch . writeUInt8 ( TRUE ) ;
8894 } else if ( x === false ) {
89- this . _ch . writeUInt8 ( FALSE ) ;
95+ return ( ) => this . _ch . writeUInt8 ( FALSE ) ;
9096 } else if ( typeof ( x ) == "number" ) {
91- this . packFloat ( x ) ;
97+ return ( ) => this . packFloat ( x ) ;
9298 } else if ( typeof ( x ) == "string" ) {
93- this . packString ( x ) ;
99+ return ( ) => this . packString ( x , onError ) ;
94100 } else if ( x instanceof Integer ) {
95- this . packInteger ( x ) ;
101+ return ( ) => this . packInteger ( x ) ;
96102 } else if ( x instanceof Array ) {
97- this . packListHeader ( x . length ) ;
98- for ( let i = 0 ; i < x . length ; i ++ ) {
99- this . pack ( x [ i ] === undefined ? null : x [ i ] ) ;
103+ return ( ) => {
104+ this . packListHeader ( x . length , onError ) ;
105+ for ( let i = 0 ; i < x . length ; i ++ ) {
106+ this . packable ( x [ i ] === undefined ? null : x [ i ] , onError ) ( ) ;
107+ }
100108 }
101109 } else if ( x instanceof Structure ) {
102- this . packStruct ( x . signature , x . fields ) ;
110+ var packableFields = [ ] ;
111+ for ( var i = 0 ; i < x . fields . length ; i ++ ) {
112+ packableFields [ i ] = this . packable ( x . fields [ i ] , onError ) ;
113+ }
114+ return ( ) => this . packStruct ( x . signature , packableFields ) ;
103115 } else if ( typeof ( x ) == "object" ) {
104- let keys = Object . keys ( x ) ;
116+ return ( ) => {
117+ let keys = Object . keys ( x ) ;
105118
106- let count = 0 ;
107- for ( let i = 0 ; i < keys . length ; i ++ ) {
108- if ( x [ keys [ i ] ] !== undefined ) {
109- count ++ ;
119+ let count = 0 ;
120+ for ( let i = 0 ; i < keys . length ; i ++ ) {
121+ if ( x [ keys [ i ] ] !== undefined ) {
122+ count ++ ;
123+ }
110124 }
111- }
112-
113- this . packMapHeader ( count ) ;
114- for ( let i = 0 ; i < keys . length ; i ++ ) {
115- let key = keys [ i ] ;
116- if ( x [ key ] !== undefined ) {
117- this . packString ( key ) ;
118- this . pack ( x [ key ] ) ;
125+ this . packMapHeader ( count , onError ) ;
126+ for ( let i = 0 ; i < keys . length ; i ++ ) {
127+ let key = keys [ i ] ;
128+ if ( x [ key ] !== undefined ) {
129+ this . packString ( key ) ;
130+ this . packable ( x [ key ] , onError ) ( ) ;
131+ }
119132 }
120- }
133+ } ;
121134 } else {
122- throw newError ( "Cannot pack this value: " + x ) ;
135+ if ( onError ) {
136+ onError ( newError ( "Cannot pack this value: " + x ) ) ;
137+ }
138+ return ( ) => undefined ;
123139 }
124140 }
125141
126- packStruct ( signature , fields ) {
127- fields = fields || [ ] ;
128- this . packStructHeader ( fields . length , signature ) ;
129- for ( let i = 0 ; i < fields . length ; i ++ ) {
130- this . pack ( fields [ i ] ) ;
142+ /**
143+ * Packs a struct
144+ * @param signature the signature of the struct
145+ * @param packableFields the fields of the struct, make sure you call `packable on all fields`
146+ */
147+ packStruct ( signature , packableFields , onError ) {
148+ packableFields = packableFields || [ ] ;
149+ this . packStructHeader ( packableFields . length , signature , onError ) ;
150+ for ( let i = 0 ; i < packableFields . length ; i ++ ) {
151+ packableFields [ i ] ( ) ;
131152 }
132153 }
133-
134154 packInteger ( x ) {
135155 var high = x . high ,
136156 low = x . low ;
@@ -156,13 +176,12 @@ class Packer {
156176 this . _ch . writeInt32 ( low ) ;
157177 }
158178 }
159-
160179 packFloat ( x ) {
161180 this . _ch . writeUInt8 ( FLOAT_64 ) ;
162181 this . _ch . writeFloat64 ( x ) ;
163182 }
164183
165- packString ( x ) {
184+ packString ( x , onError ) {
166185 let bytes = utf8 . encode ( x ) ;
167186 let size = bytes . length ;
168187 if ( size < 0x10 ) {
@@ -185,11 +204,11 @@ class Packer {
185204 this . _ch . writeUInt8 ( size % 256 ) ;
186205 this . _ch . writeBytes ( bytes ) ;
187206 } else {
188- throw newError ( "UTF-8 strings of size " + size + " are not supported" ) ;
207+ onError ( newError ( "UTF-8 strings of size " + size + " are not supported" ) ) ;
189208 }
190209 }
191210
192- packListHeader ( size ) {
211+ packListHeader ( size , onError ) {
193212 if ( size < 0x10 ) {
194213 this . _ch . writeUInt8 ( TINY_LIST | size ) ;
195214 } else if ( size < 0x100 ) {
@@ -206,11 +225,11 @@ class Packer {
206225 this . _ch . writeUInt8 ( ( size / 256 >> 0 ) % 256 ) ;
207226 this . _ch . writeUInt8 ( size % 256 ) ;
208227 } else {
209- throw newError ( "Lists of size " + size + " are not supported" ) ;
228+ onError ( newError ( "Lists of size " + size + " are not supported" ) ) ;
210229 }
211230 }
212231
213- packMapHeader ( size ) {
232+ packMapHeader ( size , onError ) {
214233 if ( size < 0x10 ) {
215234 this . _ch . writeUInt8 ( TINY_MAP | size ) ;
216235 } else if ( size < 0x100 ) {
@@ -227,11 +246,11 @@ class Packer {
227246 this . _ch . writeUInt8 ( ( size / 256 >> 0 ) % 256 ) ;
228247 this . _ch . writeUInt8 ( size % 256 ) ;
229248 } else {
230- throw newError ( "Maps of size " + size + " are not supported" ) ;
249+ onError ( newError ( "Maps of size " + size + " are not supported" ) ) ;
231250 }
232251 }
233252
234- packStructHeader ( size , signature ) {
253+ packStructHeader ( size , signature , onError ) {
235254 if ( size < 0x10 ) {
236255 this . _ch . writeUInt8 ( TINY_STRUCT | size ) ;
237256 this . _ch . writeUInt8 ( signature ) ;
@@ -244,7 +263,7 @@ class Packer {
244263 this . _ch . writeUInt8 ( size / 256 >> 0 ) ;
245264 this . _ch . writeUInt8 ( size % 256 ) ;
246265 } else {
247- throw newError ( "Structures of size " + size + " are not supported" ) ;
266+ onError ( newError ( "Structures of size " + size + " are not supported" ) ) ;
248267 }
249268 }
250269}
0 commit comments