@@ -80,57 +80,77 @@ class Packer {
80
80
this . _ch = channel ;
81
81
}
82
82
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 ) {
84
90
if ( x === null ) {
85
- this . _ch . writeUInt8 ( NULL ) ;
91
+ return ( ) => this . _ch . writeUInt8 ( NULL ) ;
86
92
} else if ( x === true ) {
87
- this . _ch . writeUInt8 ( TRUE ) ;
93
+ return ( ) => this . _ch . writeUInt8 ( TRUE ) ;
88
94
} else if ( x === false ) {
89
- this . _ch . writeUInt8 ( FALSE ) ;
95
+ return ( ) => this . _ch . writeUInt8 ( FALSE ) ;
90
96
} else if ( typeof ( x ) == "number" ) {
91
- this . packFloat ( x ) ;
97
+ return ( ) => this . packFloat ( x ) ;
92
98
} else if ( typeof ( x ) == "string" ) {
93
- this . packString ( x ) ;
99
+ return ( ) => this . packString ( x , onError ) ;
94
100
} else if ( x instanceof Integer ) {
95
- this . packInteger ( x ) ;
101
+ return ( ) => this . packInteger ( x ) ;
96
102
} 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
+ }
100
108
}
101
109
} 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 ) ;
103
115
} else if ( typeof ( x ) == "object" ) {
104
- let keys = Object . keys ( x ) ;
116
+ return ( ) => {
117
+ let keys = Object . keys ( x ) ;
105
118
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
+ }
110
124
}
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
+ }
119
132
}
120
- }
133
+ } ;
121
134
} else {
122
- throw newError ( "Cannot pack this value: " + x ) ;
135
+ if ( onError ) {
136
+ onError ( newError ( "Cannot pack this value: " + x ) ) ;
137
+ }
138
+ return ( ) => undefined ;
123
139
}
124
140
}
125
141
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 ] ( ) ;
131
152
}
132
153
}
133
-
134
154
packInteger ( x ) {
135
155
var high = x . high ,
136
156
low = x . low ;
@@ -156,13 +176,12 @@ class Packer {
156
176
this . _ch . writeInt32 ( low ) ;
157
177
}
158
178
}
159
-
160
179
packFloat ( x ) {
161
180
this . _ch . writeUInt8 ( FLOAT_64 ) ;
162
181
this . _ch . writeFloat64 ( x ) ;
163
182
}
164
183
165
- packString ( x ) {
184
+ packString ( x , onError ) {
166
185
let bytes = utf8 . encode ( x ) ;
167
186
let size = bytes . length ;
168
187
if ( size < 0x10 ) {
@@ -185,11 +204,11 @@ class Packer {
185
204
this . _ch . writeUInt8 ( size % 256 ) ;
186
205
this . _ch . writeBytes ( bytes ) ;
187
206
} 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" ) ) ;
189
208
}
190
209
}
191
210
192
- packListHeader ( size ) {
211
+ packListHeader ( size , onError ) {
193
212
if ( size < 0x10 ) {
194
213
this . _ch . writeUInt8 ( TINY_LIST | size ) ;
195
214
} else if ( size < 0x100 ) {
@@ -206,11 +225,11 @@ class Packer {
206
225
this . _ch . writeUInt8 ( ( size / 256 >> 0 ) % 256 ) ;
207
226
this . _ch . writeUInt8 ( size % 256 ) ;
208
227
} else {
209
- throw newError ( "Lists of size " + size + " are not supported" ) ;
228
+ onError ( newError ( "Lists of size " + size + " are not supported" ) ) ;
210
229
}
211
230
}
212
231
213
- packMapHeader ( size ) {
232
+ packMapHeader ( size , onError ) {
214
233
if ( size < 0x10 ) {
215
234
this . _ch . writeUInt8 ( TINY_MAP | size ) ;
216
235
} else if ( size < 0x100 ) {
@@ -227,11 +246,11 @@ class Packer {
227
246
this . _ch . writeUInt8 ( ( size / 256 >> 0 ) % 256 ) ;
228
247
this . _ch . writeUInt8 ( size % 256 ) ;
229
248
} else {
230
- throw newError ( "Maps of size " + size + " are not supported" ) ;
249
+ onError ( newError ( "Maps of size " + size + " are not supported" ) ) ;
231
250
}
232
251
}
233
252
234
- packStructHeader ( size , signature ) {
253
+ packStructHeader ( size , signature , onError ) {
235
254
if ( size < 0x10 ) {
236
255
this . _ch . writeUInt8 ( TINY_STRUCT | size ) ;
237
256
this . _ch . writeUInt8 ( signature ) ;
@@ -244,7 +263,7 @@ class Packer {
244
263
this . _ch . writeUInt8 ( size / 256 >> 0 ) ;
245
264
this . _ch . writeUInt8 ( size % 256 ) ;
246
265
} else {
247
- throw newError ( "Structures of size " + size + " are not supported" ) ;
266
+ onError ( newError ( "Structures of size " + size + " are not supported" ) ) ;
248
267
}
249
268
}
250
269
}
0 commit comments