@@ -91,8 +91,9 @@ static PyTypeObject* REType = NULL;
9191static PyObject * elements_to_dict (const char * string , int max ,
9292 PyObject * as_class , unsigned char tz_aware );
9393
94- static int _write_element_to_buffer (buffer_t buffer , int type_byte , PyObject * value ,
95- unsigned char check_keys , unsigned char first_attempt );
94+ static int _write_element_to_buffer (buffer_t buffer , int type_byte ,
95+ PyObject * value , unsigned char check_keys ,
96+ unsigned char uuid_subtype , unsigned char first_attempt );
9697
9798/* Date stuff */
9899static PyObject * datetime_from_millis (long long millis ) {
@@ -212,12 +213,13 @@ static int _reload_python_objects(void) {
212213
213214static int write_element_to_buffer (buffer_t buffer , int type_byte ,
214215 PyObject * value , unsigned char check_keys ,
216+ unsigned char uuid_subtype ,
215217 unsigned char first_attempt ) {
216218 int result ;
217219 if (Py_EnterRecursiveCall (" while encoding an object to BSON " ))
218220 return 0 ;
219221 result = _write_element_to_buffer (buffer , type_byte , value ,
220- check_keys , first_attempt );
222+ check_keys , uuid_subtype , first_attempt );
221223 Py_LeaveRecursiveCall ();
222224 return result ;
223225}
@@ -227,8 +229,9 @@ static int write_element_to_buffer(buffer_t buffer, int type_byte,
227229 * space has already been reserved.
228230 *
229231 * returns 0 on failure */
230- static int _write_element_to_buffer (buffer_t buffer , int type_byte , PyObject * value ,
231- unsigned char check_keys , unsigned char first_attempt ) {
232+ static int _write_element_to_buffer (buffer_t buffer , int type_byte ,
233+ PyObject * value , unsigned char check_keys ,
234+ unsigned char uuid_subtype , unsigned char first_attempt ) {
232235 if (PyBool_Check (value )) {
233236 const long bool = PyInt_AsLong (value );
234237 const char c = bool ? 0x01 : 0x00 ;
@@ -270,7 +273,7 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
270273 return 1 ;
271274 } else if (PyDict_Check (value )) {
272275 * (buffer_get_buffer (buffer ) + type_byte ) = 0x03 ;
273- return write_dict (buffer , value , check_keys , 0 );
276+ return write_dict (buffer , value , check_keys , uuid_subtype , 0 );
274277 } else if (PyList_Check (value ) || PyTuple_Check (value )) {
275278 int start_position ,
276279 length_location ,
@@ -310,7 +313,8 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
310313 free (name );
311314
312315 item_value = PySequence_GetItem (value , i );
313- if (!write_element_to_buffer (buffer , list_type_byte , item_value , check_keys , 1 )) {
316+ if (!write_element_to_buffer (buffer , list_type_byte ,
317+ item_value , check_keys , uuid_subtype , 1 )) {
314318 Py_DECREF (item_value );
315319 return 0 ;
316320 }
@@ -371,7 +375,7 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
371375
372376 // UUID is always 16 bytes, subtype 3
373377 int length = 16 ;
374- const char subtype = 4 ;
378+ const char subtype = ( const char ) uuid_subtype ;
375379
376380 PyObject * bytes ;
377381
@@ -417,7 +421,7 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
417421 if (!scope ) {
418422 return 0 ;
419423 }
420- if (!write_dict (buffer , scope , 0 , 0 )) {
424+ if (!write_dict (buffer , scope , 0 , uuid_subtype , 0 )) {
421425 Py_DECREF (scope );
422426 return 0 ;
423427 }
@@ -494,7 +498,7 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
494498 if (!as_doc ) {
495499 return 0 ;
496500 }
497- if (!write_dict (buffer , as_doc , 0 , 0 )) {
501+ if (!write_dict (buffer , as_doc , 0 , uuid_subtype , 0 )) {
498502 Py_DECREF (as_doc );
499503 return 0 ;
500504 }
@@ -631,7 +635,7 @@ static int _write_element_to_buffer(buffer_t buffer, int type_byte, PyObject* va
631635 if (_reload_python_objects ()) {
632636 return 0 ;
633637 }
634- return write_element_to_buffer (buffer , type_byte , value , check_keys , 0 );
638+ return write_element_to_buffer (buffer , type_byte , value , check_keys , uuid_subtype , 0 );
635639 }
636640 {
637641 PyObject * errmsg = PyString_FromString ("Cannot encode object: " );
@@ -673,7 +677,8 @@ static int check_key_name(const char* name,
673677 *
674678 * Returns 0 on failure */
675679int write_pair (buffer_t buffer , const char * name , Py_ssize_t name_length ,
676- PyObject * value , unsigned char check_keys , unsigned char allow_id ) {
680+ PyObject * value , unsigned char check_keys ,
681+ unsigned char uuid_subtype , unsigned char allow_id ) {
677682 int type_byte ;
678683
679684 /* Don't write any _id elements unless we're explicitly told to -
@@ -694,15 +699,17 @@ int write_pair(buffer_t buffer, const char* name, Py_ssize_t name_length,
694699 if (!buffer_write_bytes (buffer , name , name_length + 1 )) {
695700 return 0 ;
696701 }
697- if (!write_element_to_buffer (buffer , type_byte , value , check_keys , 1 )) {
702+ if (!write_element_to_buffer (buffer , type_byte , value ,
703+ check_keys , uuid_subtype , 1 )) {
698704 return 0 ;
699705 }
700706 return 1 ;
701707}
702708
703709int decode_and_write_pair (buffer_t buffer ,
704710 PyObject * key , PyObject * value ,
705- unsigned char check_keys , unsigned char top_level ) {
711+ unsigned char check_keys ,
712+ unsigned char uuid_subtype , unsigned char top_level ) {
706713 PyObject * encoded ;
707714 if (PyUnicode_Check (key )) {
708715 result_t status ;
@@ -754,7 +761,8 @@ int decode_and_write_pair(buffer_t buffer,
754761
755762 /* If top_level is True, don't allow writing _id here - it was already written. */
756763 if (!write_pair (buffer , PyString_AsString (encoded ),
757- PyString_Size (encoded ), value , check_keys , !top_level )) {
764+ PyString_Size (encoded ), value ,
765+ check_keys , uuid_subtype , !top_level )) {
758766 Py_DECREF (encoded );
759767 return 0 ;
760768 }
@@ -764,7 +772,8 @@ int decode_and_write_pair(buffer_t buffer,
764772}
765773
766774/* returns 0 on failure */
767- int write_dict (buffer_t buffer , PyObject * dict , unsigned char check_keys , unsigned char top_level ) {
775+ int write_dict (buffer_t buffer , PyObject * dict ,
776+ unsigned char check_keys , unsigned char uuid_subtype , unsigned char top_level ) {
768777 PyObject * key ;
769778 PyObject * iter ;
770779 char zero = 0 ;
@@ -792,7 +801,7 @@ int write_dict(buffer_t buffer, PyObject* dict, unsigned char check_keys, unsign
792801 if (_id ) {
793802 /* Don't bother checking keys, but do make sure we're allowed to
794803 * write _id */
795- if (!write_pair (buffer , "_id" , 3 , _id , 0 , 1 )) {
804+ if (!write_pair (buffer , "_id" , 3 , _id , 0 , uuid_subtype , 1 )) {
796805 return 0 ;
797806 }
798807 }
@@ -810,7 +819,8 @@ int write_dict(buffer_t buffer, PyObject* dict, unsigned char check_keys, unsign
810819 Py_DECREF (iter );
811820 return 0 ;
812821 }
813- if (!decode_and_write_pair (buffer , key , value , check_keys , top_level )) {
822+ if (!decode_and_write_pair (buffer , key , value ,
823+ check_keys , uuid_subtype , top_level )) {
814824 Py_DECREF (key );
815825 Py_DECREF (iter );
816826 return 0 ;
@@ -832,9 +842,10 @@ static PyObject* _cbson_dict_to_bson(PyObject* self, PyObject* args) {
832842 PyObject * dict ;
833843 PyObject * result ;
834844 unsigned char check_keys ;
845+ unsigned char uuid_subtype ;
835846 buffer_t buffer ;
836847
837- if (!PyArg_ParseTuple (args , "Ob " , & dict , & check_keys )) {
848+ if (!PyArg_ParseTuple (args , "Obb " , & dict , & check_keys , & uuid_subtype )) {
838849 return NULL ;
839850 }
840851
@@ -844,7 +855,7 @@ static PyObject* _cbson_dict_to_bson(PyObject* self, PyObject* args) {
844855 return NULL ;
845856 }
846857
847- if (!write_dict (buffer , dict , check_keys , 1 )) {
858+ if (!write_dict (buffer , dict , check_keys , uuid_subtype , 1 )) {
848859 buffer_free (buffer );
849860 return NULL ;
850861 }
0 commit comments