diff --git a/bson/_cbsonmodule.c b/bson/_cbsonmodule.c index 9a0f297b8..aea7387b2 100644 --- a/bson/_cbsonmodule.c +++ b/bson/_cbsonmodule.c @@ -190,6 +190,28 @@ int buffer_write_bytes(buffer_t buffer, const char* data, int size) { return 1; } +int buffer_write_double(buffer_t buffer, double data) { + double data_le = BSON_DOUBLE_TO_LE(data); + return buffer_write_bytes(buffer, (const char*)&data_le, 8); +} + +int buffer_write_int32(buffer_t buffer, int32_t data) { + uint32_t data_le = BSON_UINT32_TO_LE(data); + return buffer_write_bytes(buffer, (const char*)&data_le, 4); +} + +int buffer_write_int64(buffer_t buffer, int64_t data) { + uint64_t data_le = BSON_UINT64_TO_LE(data); + return buffer_write_bytes(buffer, (const char*)&data_le, 8); +} + +void buffer_write_int32_at_position(buffer_t buffer, + int position, + int32_t data) { + uint32_t data_le = BSON_UINT32_TO_LE(data); + memcpy(buffer_get_buffer(buffer) + position, &data_le, 4); +} + static int write_unicode(buffer_t buffer, PyObject* py_string) { int size; const char* data; @@ -212,7 +234,7 @@ static int write_unicode(buffer_t buffer, PyObject* py_string) { #endif goto unicodefail; - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) + if (!buffer_write_int32(buffer, (int32_t)size)) goto unicodefail; if (!buffer_write_bytes(buffer, data, size)) @@ -249,7 +271,7 @@ static int write_string(buffer_t buffer, PyObject* py_string) { #endif return 0; - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) { + if (!buffer_write_int32(buffer, (int32_t)size)) { return 0; } if (!buffer_write_bytes(buffer, data, size)) { @@ -654,7 +676,6 @@ static int _write_regex_to_buffer( return 1; } -/* TODO our platform better be little-endian w/ 4-byte ints! */ /* Write a single value to the buffer (also write its type_byte, for which * space has already been reserved. * @@ -681,7 +702,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, { /* Binary */ PyObject* subtype_object; - long subtype; + char subtype; const char* data; int size; @@ -691,9 +712,9 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, return 0; } #if PY_MAJOR_VERSION >= 3 - subtype = PyLong_AsLong(subtype_object); + subtype = (char)PyLong_AsLong(subtype_object); #else - subtype = PyInt_AsLong(subtype_object); + subtype = (char)PyInt_AsLong(subtype_object); #endif if (subtype == -1) { Py_DECREF(subtype_object); @@ -718,18 +739,18 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, #endif if (other_size == -1) return 0; - if (!buffer_write_bytes(buffer, (const char*)&other_size, 4)) { + if (!buffer_write_int32(buffer, other_size)) { return 0; } - if (!buffer_write_bytes(buffer, (const char*)&subtype, 1)) { + if (!buffer_write_bytes(buffer, &subtype, 1)) { return 0; } } - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) { + if (!buffer_write_int32(buffer, size)) { return 0; } if (subtype != 2) { - if (!buffer_write_bytes(buffer, (const char*)&subtype, 1)) { + if (!buffer_write_bytes(buffer, &subtype, 1)) { return 0; } } @@ -817,7 +838,8 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, Py_DECREF(scope); length = buffer_get_position(buffer) - start_position; - memcpy(buffer_get_buffer(buffer) + length_location, &length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)length); return 1; } case 17: @@ -836,7 +858,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, i = PyInt_AsLong(obj); #endif Py_DECREF(obj); - if (!buffer_write_bytes(buffer, (const char*)&i, 4)) { + if (!buffer_write_int32(buffer, (int32_t)i)) { return 0; } @@ -850,7 +872,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, i = PyInt_AsLong(obj); #endif Py_DECREF(obj); - if (!buffer_write_bytes(buffer, (const char*)&i, 4)) { + if (!buffer_write_int32(buffer, (int32_t)i)) { return 0; } @@ -866,7 +888,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, "MongoDB can only handle up to 8-byte ints"); return 0; } - if (!buffer_write_bytes(buffer, (const char*)&ll, 8)) { + if (!buffer_write_int64(buffer, (int64_t)ll)) { return 0; } *(buffer_get_buffer(buffer) + type_byte) = 0x12; @@ -970,10 +992,10 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, return 0; } *(buffer_get_buffer(buffer) + type_byte) = 0x12; - return buffer_write_bytes(buffer, (const char*)&long_long_value, 8); + return buffer_write_int64(buffer, (int64_t)long_long_value); } *(buffer_get_buffer(buffer) + type_byte) = 0x10; - return buffer_write_bytes(buffer, (const char*)&int_value, 4); + return buffer_write_int32(buffer, (int32_t)int_value); #if PY_MAJOR_VERSION < 3 } else if (PyLong_Check(value)) { const long long long_long_value = PyLong_AsLongLong(value); @@ -983,12 +1005,12 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, return 0; } *(buffer_get_buffer(buffer) + type_byte) = 0x12; - return buffer_write_bytes(buffer, (const char*)&long_long_value, 8); + return buffer_write_int64(buffer, (int64_t)long_long_value); #endif } else if (PyFloat_Check(value)) { const double d = PyFloat_AsDouble(value); *(buffer_get_buffer(buffer) + type_byte) = 0x01; - return buffer_write_bytes(buffer, (const char*)&d, 8); + return buffer_write_double(buffer, d); } else if (value == Py_None) { *(buffer_get_buffer(buffer) + type_byte) = 0x0A; return 1; @@ -1050,12 +1072,13 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, return 0; } length = buffer_get_position(buffer) - start_position; - memcpy(buffer_get_buffer(buffer) + length_location, &length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)length); return 1; #if PY_MAJOR_VERSION >= 3 /* Python3 special case. Store bytes as BSON binary subtype 0. */ } else if (PyBytes_Check(value)) { - int subtype = 0; + char subtype = 0; int size; const char* data = PyBytes_AS_STRING(value); if (!data) @@ -1063,10 +1086,10 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, if ((size = _downcast_and_check(PyBytes_GET_SIZE(value), 0)) == -1) return 0; *(buffer_get_buffer(buffer) + type_byte) = 0x05; - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) { + if (!buffer_write_int32(buffer, (int32_t)size)) { return 0; } - if (!buffer_write_bytes(buffer, (const char*)&subtype, 1)) { + if (!buffer_write_bytes(buffer, &subtype, 1)) { return 0; } if (!buffer_write_bytes(buffer, data, size)) { @@ -1111,7 +1134,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, } return 0; } - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) { + if (!buffer_write_int32(buffer, (int32_t)size)) { return 0; } if (!buffer_write_bytes(buffer, data, size)) { @@ -1139,7 +1162,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, millis = millis_from_datetime(value); } *(buffer_get_buffer(buffer) + type_byte) = 0x09; - return buffer_write_bytes(buffer, (const char*)&millis, 8); + return buffer_write_int64(buffer, (int64_t)millis); } else if (PyObject_TypeCheck(value, state->REType)) { return _write_regex_to_buffer(buffer, type_byte, value); } @@ -1168,7 +1191,7 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, const char* data; /* UUID is always 16 bytes */ int size = 16; - int subtype; + char subtype; Py_DECREF(uuid_type); /* PyObject_IsInstance returns -1 on error */ @@ -1185,10 +1208,10 @@ static int _write_element_to_buffer(PyObject* self, buffer_t buffer, } *(buffer_get_buffer(buffer) + type_byte) = 0x05; - if (!buffer_write_bytes(buffer, (const char*)&size, 4)) { + if (!buffer_write_int32(buffer, (int32_t)size)) { return 0; } - if (!buffer_write_bytes(buffer, (const char*)&subtype, 1)) { + if (!buffer_write_bytes(buffer, &subtype, 1)) { return 0; } @@ -1563,7 +1586,8 @@ int write_dict(PyObject* self, buffer_t buffer, return 0; } length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)length); return 1; } @@ -1663,18 +1687,19 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, goto invalid; } memcpy(&d, buffer + *position, 8); - value = PyFloat_FromDouble(d); + value = PyFloat_FromDouble(BSON_DOUBLE_FROM_LE(d)); *position += 8; break; } case 2: case 14: { - unsigned value_length; + uint32_t value_length; if (max < 4) { goto invalid; } memcpy(&value_length, buffer + *position, 4); + value_length = BSON_UINT32_FROM_LE(value_length); /* Encoded string length + string */ if (!value_length || max < value_length || max < 4 + value_length) { goto invalid; @@ -1696,12 +1721,13 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, case 3: { PyObject* collection; - unsigned size; + uint32_t size; if (max < 4) { goto invalid; } memcpy(&size, buffer + *position, 4); + size = BSON_UINT32_FROM_LE(size); if (size < BSON_MIN_SIZE || max < size) { goto invalid; } @@ -1783,12 +1809,13 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 4: { - unsigned size, end; + uint32_t size, end; if (max < 4) { goto invalid; } memcpy(&size, buffer + *position, 4); + size = BSON_UINT32_FROM_LE(size); if (size < BSON_MIN_SIZE || max < size) { goto invalid; } @@ -1841,13 +1868,14 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, PyObject* data; PyObject* st; PyObject* type_to_create; - unsigned length; + uint32_t length; unsigned char subtype; if (max < 5) { goto invalid; } memcpy(&length, buffer + *position, 4); + length = BSON_UINT32_FROM_LE(length); if (max < length) { goto invalid; } @@ -2004,11 +2032,12 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, PyObject* args; PyObject* kwargs; PyObject* astimezone; - long long millis; + int64_t millis; if (max < 8) { goto invalid; } memcpy(&millis, buffer + *position, 8); + millis = (int64_t)BSON_UINT64_FROM_LE(millis); naive = datetime_from_millis(millis); *position += 8; if (!options->tz_aware) { /* In the naive case, we're done here. */ @@ -2126,7 +2155,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 12: { - unsigned coll_length; + uint32_t coll_length; PyObject* collection; PyObject* id = NULL; PyObject* objectid_type; @@ -2136,6 +2165,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, goto invalid; } memcpy(&coll_length, buffer + *position, 4); + coll_length = BSON_UINT32_FROM_LE(coll_length); /* Encoded string length + string + 12 byte ObjectId */ if (!coll_length || max < coll_length || max < 4 + coll_length + 12) { goto invalid; @@ -2179,11 +2209,12 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, { PyObject* code; PyObject* code_type; - unsigned value_length; + uint32_t value_length; if (max < 4) { goto invalid; } memcpy(&value_length, buffer + *position, 4); + value_length = BSON_UINT32_FROM_LE(value_length); /* Encoded string length + string */ if (!value_length || max < value_length || max < 4 + value_length) { goto invalid; @@ -2209,9 +2240,9 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 15: { - unsigned c_w_s_size; - unsigned code_size; - unsigned scope_size; + uint32_t c_w_s_size; + uint32_t code_size; + uint32_t scope_size; PyObject* code; PyObject* scope; PyObject* code_type; @@ -2221,6 +2252,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } memcpy(&c_w_s_size, buffer + *position, 4); + c_w_s_size = BSON_UINT32_FROM_LE(c_w_s_size); *position += 4; if (max < c_w_s_size) { @@ -2228,6 +2260,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } memcpy(&code_size, buffer + *position, 4); + code_size = BSON_UINT32_FROM_LE(code_size); /* code_w_scope length + code length + code + scope length */ if (!code_size || max < code_size || max < 4 + 4 + code_size + 4) { goto invalid; @@ -2246,6 +2279,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, *position += code_size; memcpy(&scope_size, buffer + *position, 4); + scope_size = BSON_UINT32_FROM_LE(scope_size); if (scope_size < BSON_MIN_SIZE) { Py_DECREF(code); goto invalid; @@ -2278,11 +2312,12 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 16: { - int i; + int32_t i; if (max < 4) { goto invalid; } memcpy(&i, buffer + *position, 4); + i = (int32_t)BSON_UINT32_FROM_LE(i); #if PY_MAJOR_VERSION >= 3 value = PyLong_FromLong(i); #else @@ -2296,13 +2331,15 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 17: { - unsigned int time, inc; + uint32_t time, inc; PyObject* timestamp_type; if (max < 8) { goto invalid; } memcpy(&inc, buffer + *position, 4); memcpy(&time, buffer + *position + 4, 4); + inc = BSON_UINT32_FROM_LE(inc); + time = BSON_UINT32_FROM_LE(time); if ((timestamp_type = _get_object(state->Timestamp, "bson.timestamp", "Timestamp"))) { value = PyObject_CallFunction(timestamp_type, "II", time, inc); Py_DECREF(timestamp_type); @@ -2312,7 +2349,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, } case 18: { - long long ll; + int64_t ll; PyObject* bson_int64_type = _get_object(state->BSONInt64, "bson.int64", "Int64"); if (!bson_int64_type) @@ -2322,6 +2359,7 @@ static PyObject* get_value(PyObject* self, PyObject* name, const char* buffer, goto invalid; } memcpy(&ll, buffer + *position, 8); + ll = (int64_t)BSON_UINT64_FROM_LE(ll); value = PyObject_CallFunction(bson_int64_type, "L", ll); *position += 8; Py_DECREF(bson_int64_type); @@ -2587,7 +2625,7 @@ static PyObject* elements_to_dict(PyObject* self, const char* string, } static PyObject* _cbson_bson_to_dict(PyObject* self, PyObject* args) { - int size; + int32_t size; Py_ssize_t total_size; const char* string; PyObject* bson; @@ -2637,6 +2675,7 @@ static PyObject* _cbson_bson_to_dict(PyObject* self, PyObject* args) { } memcpy(&size, string, 4); + size = (int32_t)BSON_UINT32_FROM_LE(size); if (size < BSON_MIN_SIZE) { PyObject* InvalidBSON = _error("InvalidBSON"); if (InvalidBSON) { @@ -2680,7 +2719,7 @@ static PyObject* _cbson_bson_to_dict(PyObject* self, PyObject* args) { } static PyObject* _cbson_decode_all(PyObject* self, PyObject* args) { - int size; + int32_t size; Py_ssize_t total_size; const char* string; PyObject* bson; @@ -2741,6 +2780,7 @@ static PyObject* _cbson_decode_all(PyObject* self, PyObject* args) { } memcpy(&size, string, 4); + size = (int32_t)BSON_UINT32_FROM_LE(size); if (size < BSON_MIN_SIZE) { PyObject* InvalidBSON = _error("InvalidBSON"); if (InvalidBSON) { @@ -2882,6 +2922,11 @@ init_cbson(void) _cbson_API[_cbson_decode_and_write_pair_INDEX] = (void *) decode_and_write_pair; _cbson_API[_cbson_convert_codec_options_INDEX] = (void *) convert_codec_options; _cbson_API[_cbson_destroy_codec_options_INDEX] = (void *) destroy_codec_options; + _cbson_API[_cbson_buffer_write_double_INDEX] = (void *) buffer_write_double; + _cbson_API[_cbson_buffer_write_int32_INDEX] = (void *) buffer_write_int32; + _cbson_API[_cbson_buffer_write_int64_INDEX] = (void *) buffer_write_int64; + _cbson_API[_cbson_buffer_write_int32_at_position_INDEX] = + (void *) buffer_write_int32_at_position; #if PY_VERSION_HEX >= 0x03010000 /* PyCapsule is new in python 3.1 */ diff --git a/bson/_cbsonmodule.h b/bson/_cbsonmodule.h index e76079198..e46e6b381 100644 --- a/bson/_cbsonmodule.h +++ b/bson/_cbsonmodule.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "bson-endian.h" + #ifndef _CBSONMODULE_H #define _CBSONMODULE_H @@ -93,8 +95,24 @@ typedef struct codec_options_t { #define _cbson_destroy_codec_options_RETURN void #define _cbson_destroy_codec_options_PROTO (codec_options_t* options) +#define _cbson_buffer_write_double_INDEX 6 +#define _cbson_buffer_write_double_RETURN int +#define _cbson_buffer_write_double_PROTO (buffer_t buffer, double data) + +#define _cbson_buffer_write_int32_INDEX 7 +#define _cbson_buffer_write_int32_RETURN int +#define _cbson_buffer_write_int32_PROTO (buffer_t buffer, int32_t data) + +#define _cbson_buffer_write_int64_INDEX 8 +#define _cbson_buffer_write_int64_RETURN int +#define _cbson_buffer_write_int64_PROTO (buffer_t buffer, int64_t data) + +#define _cbson_buffer_write_int32_at_position_INDEX 9 +#define _cbson_buffer_write_int32_at_position_RETURN void +#define _cbson_buffer_write_int32_at_position_PROTO (buffer_t buffer, int position, int32_t data) + /* Total number of C API pointers */ -#define _cbson_API_POINTER_COUNT 6 +#define _cbson_API_POINTER_COUNT 10 #ifdef _CBSON_MODULE /* This section is used when compiling _cbsonmodule */ @@ -111,6 +129,14 @@ static _cbson_convert_codec_options_RETURN convert_codec_options _cbson_convert_ static _cbson_destroy_codec_options_RETURN destroy_codec_options _cbson_destroy_codec_options_PROTO; +static _cbson_buffer_write_double_RETURN buffer_write_double _cbson_buffer_write_double_PROTO; + +static _cbson_buffer_write_int32_RETURN buffer_write_int32 _cbson_buffer_write_int32_PROTO; + +static _cbson_buffer_write_int64_RETURN buffer_write_int64 _cbson_buffer_write_int64_PROTO; + +static _cbson_buffer_write_int32_at_position_RETURN buffer_write_int32_at_position _cbson_buffer_write_int32_at_position_PROTO; + #else /* This section is used in modules that use _cbsonmodule's API */ @@ -128,6 +154,14 @@ static void **_cbson_API; #define destroy_codec_options (*(_cbson_destroy_codec_options_RETURN (*)_cbson_destroy_codec_options_PROTO) _cbson_API[_cbson_destroy_codec_options_INDEX]) +#define buffer_write_double (*(_cbson_buffer_write_double_RETURN (*)_cbson_buffer_write_double_PROTO) _cbson_API[_cbson_buffer_write_double_INDEX]) + +#define buffer_write_int32 (*(_cbson_buffer_write_int32_RETURN (*)_cbson_buffer_write_int32_PROTO) _cbson_API[_cbson_buffer_write_int32_INDEX]) + +#define buffer_write_int64 (*(_cbson_buffer_write_int64_RETURN (*)_cbson_buffer_write_int64_PROTO) _cbson_API[_cbson_buffer_write_int64_INDEX]) + +#define buffer_write_int32_at_position (*(_cbson_buffer_write_int32_at_position_RETURN (*)_cbson_buffer_write_int32_at_position_PROTO) _cbson_API[_cbson_buffer_write_int32_at_position_INDEX]) + #define _cbson_IMPORT _cbson_API = (void **)PyCapsule_Import("_cbson._C_API", 0) #endif diff --git a/bson/bson-endian.h b/bson/bson-endian.h new file mode 100644 index 000000000..c34a58dde --- /dev/null +++ b/bson/bson-endian.h @@ -0,0 +1,234 @@ +/* + * Copyright 2013-2016 MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef BSON_ENDIAN_H +#define BSON_ENDIAN_H + + +#if defined(__sun) +# include +#endif + + +#ifdef _MSC_VER +# include "bson-stdint-win32.h" +# define BSON_INLINE __inline +#else +# include +# define BSON_INLINE __inline__ +#endif + + +#define BSON_BIG_ENDIAN 4321 +#define BSON_LITTLE_ENDIAN 1234 + + +/* WORDS_BIGENDIAN from pyconfig.h / Python.h */ +#ifdef WORDS_BIGENDIAN +# define BSON_BYTE_ORDER BSON_BIG_ENDIAN +#else +# define BSON_BYTE_ORDER BSON_LITTLE_ENDIAN +#endif + + +#if defined(__sun) +# define BSON_UINT16_SWAP_LE_BE(v) BSWAP_16((uint16_t)v) +# define BSON_UINT32_SWAP_LE_BE(v) BSWAP_32((uint32_t)v) +# define BSON_UINT64_SWAP_LE_BE(v) BSWAP_64((uint64_t)v) +#elif defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) && \ + (__clang_major__ >= 3) && (__clang_minor__ >= 1) +# if __has_builtin(__builtin_bswap16) +# define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16(v) +# endif +# if __has_builtin(__builtin_bswap32) +# define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32(v) +# endif +# if __has_builtin(__builtin_bswap64) +# define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64(v) +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) +# if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3 +# define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t)v) +# define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t)v) +# endif +# if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 8 +# define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t)v) +# endif +#endif + + +#ifndef BSON_UINT16_SWAP_LE_BE +# define BSON_UINT16_SWAP_LE_BE(v) __bson_uint16_swap_slow ((uint16_t)v) +#endif + + +#ifndef BSON_UINT32_SWAP_LE_BE +# define BSON_UINT32_SWAP_LE_BE(v) __bson_uint32_swap_slow ((uint32_t)v) +#endif + + +#ifndef BSON_UINT64_SWAP_LE_BE +# define BSON_UINT64_SWAP_LE_BE(v) __bson_uint64_swap_slow ((uint64_t)v) +#endif + + +#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN +# define BSON_UINT16_FROM_LE(v) ((uint16_t)v) +# define BSON_UINT16_TO_LE(v) ((uint16_t)v) +# define BSON_UINT16_FROM_BE(v) BSON_UINT16_SWAP_LE_BE (v) +# define BSON_UINT16_TO_BE(v) BSON_UINT16_SWAP_LE_BE (v) +# define BSON_UINT32_FROM_LE(v) ((uint32_t)v) +# define BSON_UINT32_TO_LE(v) ((uint32_t)v) +# define BSON_UINT32_FROM_BE(v) BSON_UINT32_SWAP_LE_BE (v) +# define BSON_UINT32_TO_BE(v) BSON_UINT32_SWAP_LE_BE (v) +# define BSON_UINT64_FROM_LE(v) ((uint64_t)v) +# define BSON_UINT64_TO_LE(v) ((uint64_t)v) +# define BSON_UINT64_FROM_BE(v) BSON_UINT64_SWAP_LE_BE (v) +# define BSON_UINT64_TO_BE(v) BSON_UINT64_SWAP_LE_BE (v) +# define BSON_DOUBLE_FROM_LE(v) ((double)v) +# define BSON_DOUBLE_TO_LE(v) ((double)v) +#elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN +# define BSON_UINT16_FROM_LE(v) BSON_UINT16_SWAP_LE_BE (v) +# define BSON_UINT16_TO_LE(v) BSON_UINT16_SWAP_LE_BE (v) +# define BSON_UINT16_FROM_BE(v) ((uint16_t)v) +# define BSON_UINT16_TO_BE(v) ((uint16_t)v) +# define BSON_UINT32_FROM_LE(v) BSON_UINT32_SWAP_LE_BE (v) +# define BSON_UINT32_TO_LE(v) BSON_UINT32_SWAP_LE_BE (v) +# define BSON_UINT32_FROM_BE(v) ((uint32_t)v) +# define BSON_UINT32_TO_BE(v) ((uint32_t)v) +# define BSON_UINT64_FROM_LE(v) BSON_UINT64_SWAP_LE_BE (v) +# define BSON_UINT64_TO_LE(v) BSON_UINT64_SWAP_LE_BE (v) +# define BSON_UINT64_FROM_BE(v) ((uint64_t)v) +# define BSON_UINT64_TO_BE(v) ((uint64_t)v) +# define BSON_DOUBLE_FROM_LE(v) (__bson_double_swap_slow (v)) +# define BSON_DOUBLE_TO_LE(v) (__bson_double_swap_slow (v)) +#else +# error "The endianness of target architecture is unknown." +#endif + + +/* + *-------------------------------------------------------------------------- + * + * __bson_uint16_swap_slow -- + * + * Fallback endianness conversion for 16-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static BSON_INLINE uint16_t +__bson_uint16_swap_slow (uint16_t v) /* IN */ +{ + return ((v & 0x00FF) << 8) | + ((v & 0xFF00) >> 8); +} + + +/* + *-------------------------------------------------------------------------- + * + * __bson_uint32_swap_slow -- + * + * Fallback endianness conversion for 32-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static BSON_INLINE uint32_t +__bson_uint32_swap_slow (uint32_t v) /* IN */ +{ + return ((v & 0x000000FFU) << 24) | + ((v & 0x0000FF00U) << 8) | + ((v & 0x00FF0000U) >> 8) | + ((v & 0xFF000000U) >> 24); +} + + +/* + *-------------------------------------------------------------------------- + * + * __bson_uint64_swap_slow -- + * + * Fallback endianness conversion for 64-bit integers. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +static BSON_INLINE uint64_t +__bson_uint64_swap_slow (uint64_t v) /* IN */ +{ + return ((v & 0x00000000000000FFULL) << 56) | + ((v & 0x000000000000FF00ULL) << 40) | + ((v & 0x0000000000FF0000ULL) << 24) | + ((v & 0x00000000FF000000ULL) << 8) | + ((v & 0x000000FF00000000ULL) >> 8) | + ((v & 0x0000FF0000000000ULL) >> 24) | + ((v & 0x00FF000000000000ULL) >> 40) | + ((v & 0xFF00000000000000ULL) >> 56); +} + + +/* + *-------------------------------------------------------------------------- + * + * __bson_double_swap_slow -- + * + * Fallback endianness conversion for double floating point. + * + * Returns: + * The endian swapped version. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + + +static BSON_INLINE double +__bson_double_swap_slow (double v) /* IN */ +{ + uint64_t uv; + + memcpy(&uv, &v, sizeof(v)); + uv = BSON_UINT64_SWAP_LE_BE(uv); + memcpy(&v, &uv, sizeof(v)); + + return v; +} + + +#endif /* BSON_ENDIAN_H */ diff --git a/bson/bson-stdint-win32.h b/bson/bson-stdint-win32.h new file mode 100644 index 000000000..cb2acd938 --- /dev/null +++ b/bson/bson-stdint-win32.h @@ -0,0 +1,259 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if _MSC_VER >= 1600 // [ +#include +#else // ] _MSC_VER >= 1600 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/pymongo/_cmessagemodule.c b/pymongo/_cmessagemodule.c index dcef2ce87..d0e29645d 100644 --- a/pymongo/_cmessagemodule.c +++ b/pymongo/_cmessagemodule.c @@ -85,7 +85,7 @@ static int add_last_error(PyObject* self, buffer_t buffer, PyErr_NoMemory(); return 0; } - if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || + if (!buffer_write_int32(buffer, (int32_t)request_id) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" /* responseTo */ "\xd4\x07\x00\x00" /* opcode */ @@ -134,8 +134,10 @@ static int add_last_error(PyObject* self, buffer_t buffer, message_length = buffer_get_position(buffer) - message_start; document_length = buffer_get_position(buffer) - document_start; - memcpy(buffer_get_buffer(buffer) + message_start, &message_length, 4); - memcpy(buffer_get_buffer(buffer) + document_start, &document_length, 4); + buffer_write_int32_at_position( + buffer, message_start, (int32_t)message_length); + buffer_write_int32_at_position( + buffer, document_start, (int32_t)document_length); return 1; } @@ -147,12 +149,12 @@ static int init_insert_buffer(buffer_t buffer, int request_id, int options, PyErr_NoMemory(); return length_location; } - if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || + if (!buffer_write_int32(buffer, (int32_t)request_id) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" "\xd2\x07\x00\x00", 8) || - !buffer_write_bytes(buffer, (const char*)&options, 4) || + !buffer_write_int32(buffer, (int32_t)options) || !buffer_write_bytes(buffer, coll_name, coll_name_len + 1)) { @@ -266,7 +268,8 @@ static PyObject* _cbson_insert_message(PyObject* self, PyObject* args) { } message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); if (safe) { if (!add_last_error(self, buffer, request_id, collection_name, @@ -344,7 +347,7 @@ static PyObject* _cbson_update_message(PyObject* self, PyObject* args) { PyErr_NoMemory(); return NULL; } - if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || + if (!buffer_write_int32(buffer, (int32_t)request_id) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" "\xd1\x07\x00\x00" @@ -353,7 +356,7 @@ static PyObject* _cbson_update_message(PyObject* self, PyObject* args) { !buffer_write_bytes(buffer, collection_name, collection_name_length + 1) || - !buffer_write_bytes(buffer, (const char*)&flags, 4)) { + !buffer_write_int32(buffer, (int32_t)flags)) { destroy_codec_options(&options); buffer_free(buffer); PyMem_Free(collection_name); @@ -381,7 +384,8 @@ static PyObject* _cbson_update_message(PyObject* self, PyObject* args) { max_size = (cur_size > max_size) ? cur_size : max_size; message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); if (safe) { if (!add_last_error(self, buffer, request_id, collection_name, @@ -451,13 +455,13 @@ static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { PyErr_NoMemory(); return NULL; } - if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || + if (!buffer_write_int32(buffer, (int32_t)request_id) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00\xd4\x07\x00\x00", 8) || - !buffer_write_bytes(buffer, (const char*)&flags, 4) || + !buffer_write_int32(buffer, (int32_t)flags) || !buffer_write_bytes(buffer, collection_name, collection_name_length + 1) || - !buffer_write_bytes(buffer, (const char*)&num_to_skip, 4) || - !buffer_write_bytes(buffer, (const char*)&num_to_return, 4)) { + !buffer_write_int32(buffer, (int32_t)num_to_skip) || + !buffer_write_int32(buffer, (int32_t)num_to_return)) { destroy_codec_options(&options); buffer_free(buffer); PyMem_Free(collection_name); @@ -489,7 +493,8 @@ static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { PyMem_Free(collection_name); message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); /* objectify buffer */ result = Py_BuildValue("i" BYTES_FORMAT_STRING "i", request_id, @@ -534,7 +539,7 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { PyErr_NoMemory(); return NULL; } - if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || + if (!buffer_write_int32(buffer, (int32_t)request_id) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" "\xd5\x07\x00\x00" @@ -542,8 +547,8 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { !buffer_write_bytes(buffer, collection_name, collection_name_length + 1) || - !buffer_write_bytes(buffer, (const char*)&num_to_return, 4) || - !buffer_write_bytes(buffer, (const char*)&cursor_id, 8)) { + !buffer_write_int32(buffer, (int32_t)num_to_return) || + !buffer_write_int64(buffer, (int64_t)cursor_id)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; @@ -552,7 +557,8 @@ static PyObject* _cbson_get_more_message(PyObject* self, PyObject* args) { PyMem_Free(collection_name); message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); /* objectify buffer */ result = Py_BuildValue("i" BYTES_FORMAT_STRING, request_id, @@ -721,8 +727,8 @@ static PyObject* _cbson_do_batched_insert(PyObject* self, PyObject* args) { if (!empty) { buffer_update_position(buffer, before); message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, - &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); result = _send_insert(self, ctx, last_error_args, buffer, collection_name, collection_name_length, request_id, send_safe, &options, @@ -765,7 +771,8 @@ static PyObject* _cbson_do_batched_insert(PyObject* self, PyObject* args) { /* Roll back to the beginning of this document. */ buffer_update_position(buffer, before); message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); result = _send_insert(self, ctx, last_error_args, buffer, collection_name, collection_name_length, @@ -850,7 +857,8 @@ static PyObject* _cbson_do_batched_insert(PyObject* self, PyObject* args) { } message_length = buffer_get_position(buffer) - length_location; - memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); + buffer_write_int32_at_position( + buffer, length_location, (int32_t)message_length); /* Send the last (or only) batch */ result = _send_insert(self, ctx, last_error_args, buffer, @@ -902,11 +910,11 @@ _send_write_command(PyObject* ctx, buffer_t buffer, int lst_len_loc, int request_id = rand(); int position = buffer_get_position(buffer); int length = position - lst_len_loc - 1; - memcpy(buffer_get_buffer(buffer) + lst_len_loc, &length, 4); + buffer_write_int32_at_position(buffer, lst_len_loc, (int32_t)length); length = position - cmd_len_loc; - memcpy(buffer_get_buffer(buffer) + cmd_len_loc, &length, 4); - memcpy(buffer_get_buffer(buffer), &position, 4); - memcpy(buffer_get_buffer(buffer) + 4, &request_id, 4); + buffer_write_int32_at_position(buffer, cmd_len_loc, (int32_t)length); + buffer_write_int32_at_position(buffer, 0, (int32_t)position); + buffer_write_int32_at_position(buffer, 4, (int32_t)request_id); /* Send the current batch */ result = PyObject_CallMethod(ctx, "write_command", diff --git a/setup.py b/setup.py index e19ca2c22..15c84f865 100755 --- a/setup.py +++ b/setup.py @@ -275,14 +275,6 @@ The optional C extensions are currently not supported\n by this python implementation.\n *****************************************************\n """) -elif sys.byteorder == "big": - sys.stdout.write(""" -*****************************************************\n -The optional C extensions are currently not supported\n -on big endian platforms and will not be built.\n -Performance may be degraded.\n -*****************************************************\n -""") else: extra_opts['ext_modules'] = ext_modules