PYTHON-1025 - C extensions big endian support

This commit is contained in:
Bernie Hackett 2016-06-24 16:38:47 -07:00
parent 1ee5e27f9a
commit c4e8d22544
6 changed files with 651 additions and 79 deletions

View File

@ -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 */

View File

@ -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

234
bson/bson-endian.h Normal file
View File

@ -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 <sys/byteorder.h>
#endif
#ifdef _MSC_VER
# include "bson-stdint-win32.h"
# define BSON_INLINE __inline
#else
# include <stdint.h>
# 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 */

259
bson/bson-stdint-win32.h Normal file
View File

@ -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 <stdint.h>
#else // ] _MSC_VER >= 1600 [
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> 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 <wchar.h>
#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 <wchar.h>
#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 <boost/cstdint.hpp>.
// 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_ ]

View File

@ -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",

View File

@ -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