@@ -91,205 +91,131 @@ impl error::Error for DecoderError {
91
91
92
92
pub type DecoderResult < T > = Result < T , DecoderError > ;
93
93
94
- pub struct Decoder < ' a > {
95
- reader : & ' a mut Read ,
96
- }
97
-
98
- impl < ' a > Decoder < ' a > {
99
- pub fn new ( r : & ' a mut Read ) -> Decoder < ' a > {
100
- Decoder {
101
- reader : r,
102
- }
103
- }
104
-
105
- fn read_string ( & mut self ) -> Result < String , DecoderError > {
106
- let len = try!( self . reader . read_i32 :: < LittleEndian > ( ) ) ;
107
-
108
- let mut s = String :: new ( ) ;
109
- try!( self . reader . take ( len as u64 - 1 ) . read_to_string ( & mut s) ) ;
110
- try!( self . reader . read_u8 ( ) ) ; // The last 0x00
111
-
112
- Ok ( s)
113
- }
114
-
115
- fn read_cstring ( & mut self ) -> Result < String , DecoderError > {
116
- let mut v = Vec :: new ( ) ;
117
-
118
- loop {
119
- let c = try!( self . reader . read_u8 ( ) ) ;
120
- if c == 0 { break ; }
121
- v. push ( c) ;
122
- }
123
-
124
- Ok ( try!( str:: from_utf8 ( & v) ) . to_owned ( ) )
125
- }
126
-
127
- pub fn decode_floating_point ( & mut self ) -> Result < f64 , DecoderError > {
128
- self . reader . read_f64 :: < LittleEndian > ( ) . map_err ( From :: from)
129
- }
130
-
131
- pub fn decode_utf8_string ( & mut self ) -> Result < String , DecoderError > {
132
- self . read_string ( )
133
- }
134
-
135
- pub fn decode_binary_data ( & mut self ) -> Result < ( BinarySubtype , Vec < u8 > ) , DecoderError > {
136
- let len = try!( self . reader . read_i32 :: < LittleEndian > ( ) ) ;
137
- let t = BinarySubtype :: from ( try!( self . reader . read_u8 ( ) ) ) ;
138
- let mut data = Vec :: new ( ) ;
139
- try!( self . reader . take ( len as u64 ) . read_to_end ( & mut data) ) ;
140
-
141
- Ok ( ( t, data) )
142
- }
143
-
144
- pub fn decode_objectid ( & mut self ) -> Result < [ u8 ; 12 ] , DecoderError > {
145
- let mut objid = [ 0u8 ; 12 ] ;
146
-
147
- for x in objid. iter_mut ( ) {
148
- * x = try!( self . reader . read_u8 ( ) ) ;
149
- }
150
-
151
- Ok ( objid)
152
- }
153
-
154
- pub fn decode_boolean ( & mut self ) -> Result < bool , DecoderError > {
155
- let x = try!( self . reader . read_u8 ( ) ) ;
156
- Ok ( x != 0x00 )
157
- }
158
-
159
- pub fn decode_regexp ( & mut self ) -> Result < ( String , String ) , DecoderError > {
160
- let pat = try!( self . read_cstring ( ) ) ;
161
- let opt = try!( self . read_cstring ( ) ) ;
162
-
163
- Ok ( ( pat, opt) )
164
- }
94
+ fn read_string < R : Read + ?Sized > ( reader : & mut R ) -> DecoderResult < String > {
95
+ let len = try!( reader. read_i32 :: < LittleEndian > ( ) ) ;
165
96
166
- pub fn decode_javascript_code ( & mut self ) -> Result < String , DecoderError > {
167
- self . read_string ( )
168
- }
169
-
170
- pub fn decode_javascript_code_with_scope ( & mut self ) -> Result < ( String , Document ) , DecoderError > {
171
- let code = try!( self . read_string ( ) ) ;
172
- let doc = try!( self . decode_document ( ) ) ;
173
- Ok ( ( code, doc) )
174
- }
97
+ let mut s = String :: with_capacity ( len as usize - 1 ) ;
98
+ try!( reader. take ( len as u64 - 1 ) . read_to_string ( & mut s) ) ;
99
+ try!( reader. read_u8 ( ) ) ; // The last 0x00
175
100
176
- pub fn decode_integer_32bit ( & mut self ) -> Result < i32 , DecoderError > {
177
- self . reader . read_i32 :: < LittleEndian > ( ) . map_err ( From :: from)
178
- }
101
+ Ok ( s)
102
+ }
179
103
180
- pub fn decode_integer_64bit ( & mut self ) -> Result < i64 , DecoderError > {
181
- self . reader . read_i64 :: < LittleEndian > ( ) . map_err ( From :: from)
182
- }
104
+ fn read_cstring < R : Read + ?Sized > ( reader : & mut R ) -> DecoderResult < String > {
105
+ let mut v = Vec :: new ( ) ;
183
106
184
- pub fn decode_timestamp ( & mut self ) -> Result < i64 , DecoderError > {
185
- self . reader . read_i64 :: < LittleEndian > ( ) . map_err ( From :: from)
186
- }
107
+ loop {
108
+ let c = try!( reader. read_u8 ( ) ) ;
109
+ if c == 0 { break ; }
110
+ v. push ( c) ;
111
+ }
187
112
188
- pub fn decode_utc_datetime ( & mut self ) -> Result < DateTime < UTC > , DecoderError > {
189
- let x = try! ( self . reader . read_i64 :: < LittleEndian > ( ) ) ;
113
+ Ok ( try! ( str :: from_utf8 ( & v ) ) . to_owned ( ) )
114
+ }
190
115
191
- let d = DateTime :: from_utc ( NaiveDateTime :: from_timestamp ( x, 0 ) , UTC ) ;
116
+ fn read_i32 < R : Read + ?Sized > ( reader : & mut R ) -> DecoderResult < i32 > {
117
+ reader. read_i32 :: < LittleEndian > ( ) . map_err ( From :: from)
118
+ }
192
119
193
- Ok ( d)
194
- }
120
+ fn read_i64 < R : Read + ?Sized > ( reader : & mut R ) -> DecoderResult < i64 > {
121
+ reader. read_i64 :: < LittleEndian > ( ) . map_err ( From :: from)
122
+ }
195
123
196
- pub fn decode_document ( & mut self ) -> Result < Document , DecoderError > {
197
- let mut doc = Document :: new ( ) ;
124
+ pub fn decode_document < R : Read + ? Sized > ( reader : & mut R ) -> DecoderResult < Document > {
125
+ let mut doc = Document :: new ( ) ;
198
126
199
- try!( self . reader . read_i32 :: < LittleEndian > ( ) ) ; // Total length, we don't need it
127
+ // disregard the length: using Read::take causes infinite type recursion
128
+ try!( read_i32 ( reader) ) ;
200
129
201
- loop {
202
- let t = try!( self . reader . read_u8 ( ) ) ;
130
+ loop {
131
+ let tag = try!( reader. read_u8 ( ) ) ;
203
132
204
- if t == 0 {
205
- break ;
206
- }
133
+ if tag == 0 {
134
+ break ;
135
+ }
207
136
208
- let k = try!( self . read_cstring ( ) ) ;
209
- let v = try!( self . decode_bson ( t ) ) ;
137
+ let key = try!( read_cstring ( reader ) ) ;
138
+ let val = try!( decode_bson ( reader , tag ) ) ;
210
139
211
- doc. insert ( k , v ) ;
212
- }
140
+ doc. insert ( key , val ) ;
141
+ }
213
142
214
- Ok ( doc)
215
- }
143
+ Ok ( doc)
144
+ }
216
145
217
- pub fn decode_array ( & mut self ) -> Result < Array , DecoderError > {
218
- let mut arr = Array :: new ( ) ;
146
+ fn decode_array < R : Read + ? Sized > ( reader : & mut R ) -> DecoderResult < Array > {
147
+ let mut arr = Array :: new ( ) ;
219
148
220
- try!( self . reader . read_i32 :: < LittleEndian > ( ) ) ; // Total length, we don't need it
149
+ // disregard the length: using Read::take causes infinite type recursion
150
+ try!( read_i32 ( reader) ) ;
221
151
222
- loop {
223
- let t = try!( self . reader . read_u8 ( ) ) ;
224
- if t == 0 {
225
- break ;
226
- }
152
+ loop {
153
+ let tag = try!( reader. read_u8 ( ) ) ;
154
+ if tag == 0 {
155
+ break ;
156
+ }
227
157
228
- let k = try! ( self . read_cstring ( ) ) ;
229
- if k != & arr . len ( ) . to_string ( ) [ .. ] {
230
- return Err ( DecoderError :: InvalidArrayKey ( arr. len ( ) , k ) ) ;
231
- }
232
- let v = try! ( self . decode_bson ( t ) ) ;
158
+ // check that the key is as expected
159
+ let key = try! ( read_cstring ( reader ) ) ;
160
+ if key != & arr. len ( ) . to_string ( ) [ .. ] {
161
+ return Err ( DecoderError :: InvalidArrayKey ( arr . len ( ) , key ) ) ;
162
+ }
233
163
234
- arr. push ( v)
235
- }
164
+ let val = try!( decode_bson ( reader, tag) ) ;
165
+ arr. push ( val)
166
+ }
236
167
237
- Ok ( arr)
238
- }
168
+ Ok ( arr)
169
+ }
239
170
240
- fn decode_bson ( & mut self , tag : u8 ) -> Result < Bson , DecoderError > {
241
- match tag {
242
- spec:: ELEMENT_TYPE_FLOATING_POINT => {
243
- self . decode_floating_point ( ) . map ( Bson :: FloatingPoint )
244
- } ,
245
- spec:: ELEMENT_TYPE_UTF8_STRING => {
246
- self . decode_utf8_string ( ) . map ( Bson :: String )
247
- } ,
248
- spec:: ELEMENT_TYPE_EMBEDDED_DOCUMENT => {
249
- self . decode_document ( ) . map ( Bson :: Document )
250
- } ,
251
- spec:: ELEMENT_TYPE_ARRAY => {
252
- self . decode_array ( ) . map ( Bson :: Array )
253
- } ,
254
- spec:: ELEMENT_TYPE_BINARY => {
255
- self . decode_binary_data ( ) . map ( |( t, dat) | Bson :: Binary ( t, dat) )
256
- } ,
257
- spec:: ELEMENT_TYPE_OBJECT_ID => {
258
- self . decode_objectid ( ) . map ( Bson :: ObjectId )
259
- } ,
260
- spec:: ELEMENT_TYPE_BOOLEAN => {
261
- self . decode_boolean ( ) . map ( Bson :: Boolean )
262
- } ,
263
- spec:: ELEMENT_TYPE_NULL_VALUE => {
264
- Ok ( Bson :: Null )
265
- } ,
266
- spec:: ELEMENT_TYPE_REGULAR_EXPRESSION => {
267
- self . decode_regexp ( ) . map ( |( pat, opt) | Bson :: RegExp ( pat, opt) )
268
- } ,
269
- spec:: ELEMENT_TYPE_JAVASCRIPT_CODE => {
270
- self . decode_javascript_code ( ) . map ( Bson :: JavaScriptCode )
271
- } ,
272
- spec:: ELEMENT_TYPE_JAVASCRIPT_CODE_WITH_SCOPE => {
273
- self . decode_javascript_code_with_scope ( ) . map (
274
- |( code, scope) | Bson :: JavaScriptCodeWithScope ( code, scope)
275
- )
276
- } ,
277
- spec:: ELEMENT_TYPE_DEPRECATED => {
278
- Ok ( Bson :: Deprecated )
279
- } ,
280
- spec:: ELEMENT_TYPE_32BIT_INTEGER => {
281
- self . decode_integer_32bit ( ) . map ( Bson :: I32 )
282
- } ,
283
- spec:: ELEMENT_TYPE_64BIT_INTEGER => {
284
- self . decode_integer_64bit ( ) . map ( Bson :: I64 )
285
- } ,
286
- spec:: ELEMENT_TYPE_TIMESTAMP => {
287
- self . decode_timestamp ( ) . map ( Bson :: TimeStamp )
288
- } ,
289
- spec:: ELEMENT_TYPE_UTC_DATETIME => {
290
- self . decode_utc_datetime ( ) . map ( Bson :: UtcDatetime )
291
- } ,
292
- _ => Err ( DecoderError :: UnrecognizedElementType ( tag) ) ,
293
- }
294
- }
171
+ fn decode_bson < R : Read + ?Sized > ( reader : & mut R , tag : u8 ) -> DecoderResult < Bson > {
172
+ use spec:: ElementType :: * ;
173
+ match spec:: ElementType :: from ( tag) {
174
+ Some ( FloatingPoint ) => {
175
+ Ok ( Bson :: FloatingPoint ( try!( reader. read_f64 :: < LittleEndian > ( ) ) ) )
176
+ } ,
177
+ Some ( Utf8String ) => read_string ( reader) . map ( Bson :: String ) ,
178
+ Some ( EmbeddedDocument ) => decode_document ( reader) . map ( Bson :: Document ) ,
179
+ Some ( Array ) => decode_array ( reader) . map ( Bson :: Array ) ,
180
+ Some ( Binary ) => {
181
+ let len = try!( read_i32 ( reader) ) ;
182
+ let subtype = BinarySubtype :: from ( try!( reader. read_u8 ( ) ) ) ;
183
+ let mut data = Vec :: with_capacity ( len as usize ) ;
184
+ try!( reader. take ( len as u64 ) . read_to_end ( & mut data) ) ;
185
+ Ok ( Bson :: Binary ( subtype, data) )
186
+ }
187
+ Some ( ObjectId ) => {
188
+ let mut objid = [ 0 ; 12 ] ;
189
+ for x in & mut objid {
190
+ * x = try!( reader. read_u8 ( ) ) ;
191
+ }
192
+ Ok ( Bson :: ObjectId ( objid) )
193
+ }
194
+ Some ( Boolean ) => Ok ( Bson :: Boolean ( try!( reader. read_u8 ( ) ) != 0 ) ) ,
195
+ Some ( NullValue ) => Ok ( Bson :: Null ) ,
196
+ Some ( RegularExpression ) => {
197
+ let pat = try!( read_cstring ( reader) ) ;
198
+ let opt = try!( read_cstring ( reader) ) ;
199
+ Ok ( Bson :: RegExp ( pat, opt) )
200
+ } ,
201
+ Some ( JavaScriptCode ) => read_string ( reader) . map ( Bson :: JavaScriptCode ) ,
202
+ Some ( JavaScriptCodeWithScope ) => {
203
+ let code = try!( read_string ( reader) ) ;
204
+ let scope = try!( decode_document ( reader) ) ;
205
+ Ok ( Bson :: JavaScriptCodeWithScope ( code, scope) )
206
+ } ,
207
+ Some ( Deprecated ) => Ok ( Bson :: Deprecated ) ,
208
+ Some ( Integer32Bit ) => read_i32 ( reader) . map ( Bson :: I32 ) ,
209
+ Some ( Integer64Bit ) => read_i64 ( reader) . map ( Bson :: I64 ) ,
210
+ Some ( TimeStamp ) => read_i64 ( reader) . map ( Bson :: TimeStamp ) ,
211
+ Some ( UtcDatetime ) => {
212
+ let time = try!( read_i64 ( reader) ) ;
213
+ Ok ( Bson :: UtcDatetime ( DateTime :: from_utc ( NaiveDateTime :: from_timestamp ( time, 0 ) , UTC ) ) )
214
+ } ,
215
+ Some ( Undefined ) |
216
+ Some ( DbPointer ) |
217
+ Some ( MaxKey ) |
218
+ Some ( MinKey ) |
219
+ None => Err ( DecoderError :: UnrecognizedElementType ( tag) )
220
+ }
295
221
}
0 commit comments