def _elements_to_dict( data: Any, view: Any, position: int, obj_end: int, opts: CodecOptions, result: Any = None ) -> Any: """Decode a BSON document into result.""" if result is None: result = opts.document_class() end = obj_end - 1 while position < end: key, value, position = _element_to_dict(data, view, position, obj_end, opts) result[key] = value if position != obj_end: raise InvalidBSON("bad object or element length") return result
def _bson_to_dict(data: Any, opts: CodecOptions) -> Any: """Decode a BSON string to document_class.""" data, view = get_data_and_view(data) try: if _raw_document_class(opts.document_class): return opts.document_class(data, opts) _, end = _get_object_size(data, 0, len(data)) return _elements_to_dict(data, view, 4, end, opts) except InvalidBSON: raise except Exception: # Change exception type to InvalidBSON but preserve traceback. _, exc_value, exc_tb = sys.exc_info() raise InvalidBSON(str(exc_value)).with_traceback(exc_tb)
def _get_object( data: Any, view: Any, position: int, obj_end: int, opts: CodecOptions, dummy: Any ) -> Tuple[Any, int]: """Decode a BSON subdocument to opts.document_class or bson.dbref.DBRef.""" obj_size, end = _get_object_size(data, position, obj_end) if _raw_document_class(opts.document_class): return (opts.document_class(data[position : end + 1], opts), position + obj_size) obj = _elements_to_dict(data, view, position + 4, end, opts) position += obj_size # If DBRef validation fails, return a normal doc. if ( isinstance(obj.get("$ref"), str) and "$id" in obj and isinstance(obj.get("$db"), (str, type(None))) ): return (DBRef(obj.pop("$ref"), obj.pop("$id", None), obj.pop("$db", None), obj), position) return obj, position