3131 JAVA_LEGACY , CSHARP_LEGACY ,
3232 UUIDLegacy )
3333from bson .code import Code
34- from bson .codec_options import CodecOptions , DEFAULT_CODEC_OPTIONS
34+ from bson .codec_options import (
35+ CodecOptions , DEFAULT_CODEC_OPTIONS , _raw_document_class )
3536from bson .dbref import DBRef
3637from bson .errors import (InvalidBSON ,
3738 InvalidDocument ,
@@ -132,6 +133,10 @@ def _get_object(data, position, obj_end, opts):
132133 raise InvalidBSON ("bad eoo" )
133134 if end >= obj_end :
134135 raise InvalidBSON ("invalid object length" )
136+ if _raw_document_class (opts .document_class ):
137+ return (opts .document_class (data [position :end + 1 ], opts ),
138+ position + obj_size )
139+
135140 obj = _elements_to_dict (data , position + 4 , end , opts )
136141
137142 position += obj_size
@@ -147,6 +152,7 @@ def _get_array(data, position, obj_end, opts):
147152 end = position + size - 1
148153 if data [end :end + 1 ] != b"\x00 " :
149154 raise InvalidBSON ("bad eoo" )
155+
150156 position += 4
151157 end -= 1
152158 result = []
@@ -304,14 +310,21 @@ def _element_to_dict(data, position, obj_end, opts):
304310 value , position = _ELEMENT_GETTER [element_type ](data ,
305311 position , obj_end , opts )
306312 return element_name , value , position
313+ if _USE_C :
314+ _element_to_dict = _cbson ._element_to_dict
307315
308316
309- def _elements_to_dict (data , position , obj_end , opts ):
310- """Decode a BSON document."""
311- result = opts .document_class ()
317+ def _iterate_elements (data , position , obj_end , opts ):
312318 end = obj_end - 1
313319 while position < end :
314320 (key , value , position ) = _element_to_dict (data , position , obj_end , opts )
321+ yield key , value
322+
323+
324+ def _elements_to_dict (data , position , obj_end , opts ):
325+ """Decode a BSON document."""
326+ result = opts .document_class ()
327+ for key , value in _iterate_elements (data , position , obj_end , opts ):
315328 result [key ] = value
316329 return result
317330
@@ -327,6 +340,8 @@ def _bson_to_dict(data, opts):
327340 if data [obj_size - 1 :obj_size ] != b"\x00 " :
328341 raise InvalidBSON ("bad eoo" )
329342 try :
343+ if _raw_document_class (opts .document_class ):
344+ return opts .document_class (data , opts )
330345 return _elements_to_dict (data , 4 , obj_size - 1 , opts )
331346 except InvalidBSON :
332347 raise
@@ -429,6 +444,8 @@ def _encode_bytes(name, value, dummy0, dummy1):
429444
430445def _encode_mapping (name , value , check_keys , opts ):
431446 """Encode a mapping type."""
447+ if _raw_document_class (value ):
448+ return b'\x03 ' + name + value .raw
432449 data = b"" .join ([_element_to_bson (key , val , check_keys , opts )
433450 for key , val in iteritems (value )])
434451 return b"\x03 " + name + _PACK_INT (len (data ) + 5 ) + data + b"\x00 "
@@ -694,6 +711,8 @@ def _element_to_bson(key, value, check_keys, opts):
694711
695712def _dict_to_bson (doc , check_keys , opts , top_level = True ):
696713 """Encode a document to BSON."""
714+ if _raw_document_class (doc ):
715+ return doc .raw
697716 try :
698717 elements = []
699718 if top_level and "_id" in doc :
@@ -751,6 +770,7 @@ def decode_all(data, codec_options=DEFAULT_CODEC_OPTIONS):
751770 docs = []
752771 position = 0
753772 end = len (data ) - 1
773+ use_raw = _raw_document_class (codec_options .document_class )
754774 try :
755775 while position < end :
756776 obj_size = _UNPACK_INT (data [position :position + 4 ])[0 ]
@@ -759,10 +779,15 @@ def decode_all(data, codec_options=DEFAULT_CODEC_OPTIONS):
759779 obj_end = position + obj_size - 1
760780 if data [obj_end :position + obj_size ] != b"\x00 " :
761781 raise InvalidBSON ("bad eoo" )
762- docs .append (_elements_to_dict (data ,
763- position + 4 ,
764- obj_end ,
765- codec_options ))
782+ if use_raw :
783+ docs .append (
784+ codec_options .document_class (
785+ data [position :obj_end + 1 ], codec_options ))
786+ else :
787+ docs .append (_elements_to_dict (data ,
788+ position + 4 ,
789+ obj_end ,
790+ codec_options ))
766791 position += obj_size
767792 return docs
768793 except InvalidBSON :
0 commit comments