PYTHON-1025 - C extensions big endian support
This commit is contained in:
parent
1ee5e27f9a
commit
c4e8d22544
@ -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 */
|
||||
|
||||
@ -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
234
bson/bson-endian.h
Normal 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
259
bson/bson-stdint-win32.h
Normal 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_ ]
|
||||
@ -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",
|
||||
|
||||
8
setup.py
8
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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user