Add compilation of c files
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,4 +10,6 @@ _trial_temp/
|
|||||||
*.iws
|
*.iws
|
||||||
.idea
|
.idea
|
||||||
venv
|
venv
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
*.egg-info
|
||||||
|
|||||||
12
README.rst
12
README.rst
@@ -15,6 +15,18 @@ Docs and examples
|
|||||||
=================
|
=================
|
||||||
There are some examples in the *examples/* directory.
|
There are some examples in the *examples/* directory.
|
||||||
|
|
||||||
|
Features
|
||||||
|
========
|
||||||
|
- Works for the asyncio (PEP3156) event loop
|
||||||
|
- No dependencies
|
||||||
|
- Connection pooling
|
||||||
|
- Automatic conversion from unicode (Python) to bytes (inside Redis.)
|
||||||
|
- Bytes and str protocols.
|
||||||
|
- Completely tested
|
||||||
|
- Blocking calls and transactions supported
|
||||||
|
- Streaming of some multi bulk replies
|
||||||
|
- Pubsub support
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
=======
|
=======
|
||||||
Thanks to (in no particular order):
|
Thanks to (in no particular order):
|
||||||
|
|||||||
Binary file not shown.
2509
asyncio_mongo/_bson/_cbsonmodule.c
Normal file
2509
asyncio_mongo/_bson/_cbsonmodule.c
Normal file
File diff suppressed because it is too large
Load Diff
103
asyncio_mongo/_bson/_cbsonmodule.h
Normal file
103
asyncio_mongo/_bson/_cbsonmodule.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 10gen, 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 _CBSONMODULE_H
|
||||||
|
#define _CBSONMODULE_H
|
||||||
|
|
||||||
|
/* Py_ssize_t was new in python 2.5. See conversion
|
||||||
|
* guidlines in http://www.python.org/dev/peps/pep-0353
|
||||||
|
* */
|
||||||
|
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
|
||||||
|
typedef int Py_ssize_t;
|
||||||
|
#define PY_SSIZE_T_MAX INT_MAX
|
||||||
|
#define PY_SSIZE_T_MIN INT_MIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_MSC_VER)
|
||||||
|
/*
|
||||||
|
* This macro is basically an implementation of asprintf for win32
|
||||||
|
* We print to the provided buffer to get the string value as an int.
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
#define INT2STRING(buffer, i) \
|
||||||
|
_snprintf_s((buffer), \
|
||||||
|
_scprintf("%d", (i)) + 1, \
|
||||||
|
_scprintf("%d", (i)) + 1, \
|
||||||
|
"%d", \
|
||||||
|
(i))
|
||||||
|
#define STRCAT(dest, n, src) strcat_s((dest), (n), (src))
|
||||||
|
#else
|
||||||
|
#define INT2STRING(buffer, i) \
|
||||||
|
_snprintf((buffer), \
|
||||||
|
_scprintf("%d", (i)) + 1, \
|
||||||
|
"%d", \
|
||||||
|
(i))
|
||||||
|
#define STRCAT(dest, n, src) strcat((dest), (src))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define INT2STRING(buffer, i) snprintf((buffer), sizeof((buffer)), "%d", (i))
|
||||||
|
#define STRCAT(dest, n, src) strcat((dest), (src))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* C API functions */
|
||||||
|
#define _cbson_buffer_write_bytes_INDEX 0
|
||||||
|
#define _cbson_buffer_write_bytes_RETURN int
|
||||||
|
#define _cbson_buffer_write_bytes_PROTO (buffer_t buffer, const char* data, int size)
|
||||||
|
|
||||||
|
#define _cbson_write_dict_INDEX 1
|
||||||
|
#define _cbson_write_dict_RETURN int
|
||||||
|
#define _cbson_write_dict_PROTO (PyObject* self, buffer_t buffer, PyObject* dict, unsigned char check_keys, unsigned char uuid_subtype, unsigned char top_level)
|
||||||
|
|
||||||
|
#define _cbson_write_pair_INDEX 2
|
||||||
|
#define _cbson_write_pair_RETURN int
|
||||||
|
#define _cbson_write_pair_PROTO (PyObject* self, buffer_t buffer, const char* name, int name_length, PyObject* value, unsigned char check_keys, unsigned char uuid_subtype, unsigned char allow_id)
|
||||||
|
|
||||||
|
#define _cbson_decode_and_write_pair_INDEX 3
|
||||||
|
#define _cbson_decode_and_write_pair_RETURN int
|
||||||
|
#define _cbson_decode_and_write_pair_PROTO (PyObject* self, buffer_t buffer, PyObject* key, PyObject* value, unsigned char check_keys, unsigned char uuid_subtype, unsigned char top_level)
|
||||||
|
|
||||||
|
/* Total number of C API pointers */
|
||||||
|
#define _cbson_API_POINTER_COUNT 4
|
||||||
|
|
||||||
|
#ifdef _CBSON_MODULE
|
||||||
|
/* This section is used when compiling _cbsonmodule */
|
||||||
|
|
||||||
|
static _cbson_buffer_write_bytes_RETURN buffer_write_bytes _cbson_buffer_write_bytes_PROTO;
|
||||||
|
|
||||||
|
static _cbson_write_dict_RETURN write_dict _cbson_write_dict_PROTO;
|
||||||
|
|
||||||
|
static _cbson_write_pair_RETURN write_pair _cbson_write_pair_PROTO;
|
||||||
|
|
||||||
|
static _cbson_decode_and_write_pair_RETURN decode_and_write_pair _cbson_decode_and_write_pair_PROTO;
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* This section is used in modules that use _cbsonmodule's API */
|
||||||
|
|
||||||
|
static void **_cbson_API;
|
||||||
|
|
||||||
|
#define buffer_write_bytes (*(_cbson_buffer_write_bytes_RETURN (*)_cbson_buffer_write_bytes_PROTO) _cbson_API[_cbson_buffer_write_bytes_INDEX])
|
||||||
|
|
||||||
|
#define write_dict (*(_cbson_write_dict_RETURN (*)_cbson_write_dict_PROTO) _cbson_API[_cbson_write_dict_INDEX])
|
||||||
|
|
||||||
|
#define write_pair (*(_cbson_write_pair_RETURN (*)_cbson_write_pair_PROTO) _cbson_API[_cbson_write_pair_INDEX])
|
||||||
|
|
||||||
|
#define decode_and_write_pair (*(_cbson_decode_and_write_pair_RETURN (*)_cbson_decode_and_write_pair_PROTO) _cbson_API[_cbson_decode_and_write_pair_INDEX])
|
||||||
|
|
||||||
|
#define _cbson_IMPORT _cbson_API = (void **)PyCapsule_Import("_cbson._C_API", 0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _CBSONMODULE_H
|
||||||
146
asyncio_mongo/_bson/buffer.c
Normal file
146
asyncio_mongo/_bson/buffer.c
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2012 10gen, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#define INITIAL_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
struct buffer {
|
||||||
|
char* buffer;
|
||||||
|
int size;
|
||||||
|
int position;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Allocate and return a new buffer.
|
||||||
|
* Return NULL on allocation failure. */
|
||||||
|
buffer_t buffer_new(void) {
|
||||||
|
buffer_t buffer;
|
||||||
|
buffer = (buffer_t)malloc(sizeof(struct buffer));
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->size = INITIAL_BUFFER_SIZE;
|
||||||
|
buffer->position = 0;
|
||||||
|
buffer->buffer = (char*)malloc(sizeof(char) * INITIAL_BUFFER_SIZE);
|
||||||
|
if (buffer->buffer == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the memory allocated for `buffer`.
|
||||||
|
* Return non-zero on failure. */
|
||||||
|
int buffer_free(buffer_t buffer) {
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
free(buffer->buffer);
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grow `buffer` to at least `min_length`.
|
||||||
|
* Return non-zero on allocation failure. */
|
||||||
|
static int buffer_grow(buffer_t buffer, int min_length) {
|
||||||
|
int old_size = 0;
|
||||||
|
int size = buffer->size;
|
||||||
|
char* old_buffer = buffer->buffer;
|
||||||
|
if (size >= min_length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (size < min_length) {
|
||||||
|
old_size = size;
|
||||||
|
size *= 2;
|
||||||
|
if (size <= old_size) {
|
||||||
|
/* Size did not increase. Could be an overflow
|
||||||
|
* or size < 1. Just go with min_length. */
|
||||||
|
size = min_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer->buffer = (char*)realloc(buffer->buffer, sizeof(char) * size);
|
||||||
|
if (buffer->buffer == NULL) {
|
||||||
|
free(old_buffer);
|
||||||
|
free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
buffer->size = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assure that `buffer` has at least `size` free bytes (and grow if needed).
|
||||||
|
* Return non-zero on allocation failure. */
|
||||||
|
static int buffer_assure_space(buffer_t buffer, int size) {
|
||||||
|
if (buffer->position + size <= buffer->size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return buffer_grow(buffer, buffer->position + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save `size` bytes from the current position in `buffer` (and grow if needed).
|
||||||
|
* Return offset for writing, or -1 on allocation failure. */
|
||||||
|
buffer_position buffer_save_space(buffer_t buffer, int size) {
|
||||||
|
int position = buffer->position;
|
||||||
|
if (buffer_assure_space(buffer, size) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buffer->position += size;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write `size` bytes from `data` to `buffer` (and grow if needed).
|
||||||
|
* Return non-zero on allocation failure. */
|
||||||
|
int buffer_write(buffer_t buffer, const char* data, int size) {
|
||||||
|
if (buffer_assure_space(buffer, size) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer->buffer + buffer->position, data, size);
|
||||||
|
buffer->position += size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write `size` bytes from `data` to `buffer` at position `position`.
|
||||||
|
* Does not change the internal position of `buffer`.
|
||||||
|
* Return non-zero if buffer isn't large enough for write. */
|
||||||
|
int buffer_write_at_position(buffer_t buffer, buffer_position position,
|
||||||
|
const char* data, int size) {
|
||||||
|
if (position + size > buffer->size) {
|
||||||
|
buffer_free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer->buffer + position, data, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int buffer_get_position(buffer_t buffer) {
|
||||||
|
return buffer->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* buffer_get_buffer(buffer_t buffer) {
|
||||||
|
return buffer->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer_update_position(buffer_t buffer, buffer_position new_position) {
|
||||||
|
buffer->position = new_position;
|
||||||
|
}
|
||||||
56
asyncio_mongo/_bson/buffer.h
Normal file
56
asyncio_mongo/_bson/buffer.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2012 10gen, 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 BUFFER_H
|
||||||
|
#define BUFFER_H
|
||||||
|
|
||||||
|
/* Note: if any of these functions return a failure condition then the buffer
|
||||||
|
* has already been freed. */
|
||||||
|
|
||||||
|
/* A buffer */
|
||||||
|
typedef struct buffer* buffer_t;
|
||||||
|
/* A position in the buffer */
|
||||||
|
typedef int buffer_position;
|
||||||
|
|
||||||
|
/* Allocate and return a new buffer.
|
||||||
|
* Return NULL on allocation failure. */
|
||||||
|
buffer_t buffer_new(void);
|
||||||
|
|
||||||
|
/* Free the memory allocated for `buffer`.
|
||||||
|
* Return non-zero on failure. */
|
||||||
|
int buffer_free(buffer_t buffer);
|
||||||
|
|
||||||
|
/* Save `size` bytes from the current position in `buffer` (and grow if needed).
|
||||||
|
* Return offset for writing, or -1 on allocation failure. */
|
||||||
|
buffer_position buffer_save_space(buffer_t buffer, int size);
|
||||||
|
|
||||||
|
/* Write `size` bytes from `data` to `buffer` (and grow if needed).
|
||||||
|
* Return non-zero on allocation failure. */
|
||||||
|
int buffer_write(buffer_t buffer, const char* data, int size);
|
||||||
|
|
||||||
|
/* Write `size` bytes from `data` to `buffer` at position `position`.
|
||||||
|
* Does not change the internal position of `buffer`.
|
||||||
|
* Return non-zero if buffer isn't large enough for write. */
|
||||||
|
int buffer_write_at_position(buffer_t buffer, buffer_position position, const char* data, int size);
|
||||||
|
|
||||||
|
/* Getters for the internals of a buffer_t.
|
||||||
|
* Should try to avoid using these as much as possible
|
||||||
|
* since they break the abstraction. */
|
||||||
|
buffer_position buffer_get_position(buffer_t buffer);
|
||||||
|
char* buffer_get_buffer(buffer_t buffer);
|
||||||
|
void buffer_update_position(buffer_t buffer, buffer_position new_position);
|
||||||
|
|
||||||
|
#endif
|
||||||
118
asyncio_mongo/_bson/encoding_helpers.c
Normal file
118
asyncio_mongo/_bson/encoding_helpers.c
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2012 10gen, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "encoding_helpers.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright 2001 Unicode, Inc.
|
||||||
|
*
|
||||||
|
* Disclaimer
|
||||||
|
*
|
||||||
|
* This source code is provided as is by Unicode, Inc. No claims are
|
||||||
|
* made as to fitness for any particular purpose. No warranties of any
|
||||||
|
* kind are expressed or implied. The recipient agrees to determine
|
||||||
|
* applicability of information provided. If this file has been
|
||||||
|
* purchased on magnetic or optical media from Unicode, Inc., the
|
||||||
|
* sole remedy for any claim will be exchange of defective media
|
||||||
|
* within 90 days of receipt.
|
||||||
|
*
|
||||||
|
* Limitations on Rights to Redistribute This Code
|
||||||
|
*
|
||||||
|
* Unicode, Inc. hereby grants the right to freely use the information
|
||||||
|
* supplied in this file in the creation of products supporting the
|
||||||
|
* Unicode Standard, and to make copies of this file in any form
|
||||||
|
* for internal or external distribution as long as this notice
|
||||||
|
* remains attached.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Index into the table below with the first byte of a UTF-8 sequence to
|
||||||
|
* get the number of trailing bytes that are supposed to follow it.
|
||||||
|
*/
|
||||||
|
static const char trailingBytesForUTF8[256] = {
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
|
||||||
|
* This must be called with the length pre-determined by the first byte.
|
||||||
|
* The length can be set by:
|
||||||
|
* length = trailingBytesForUTF8[*source]+1;
|
||||||
|
* and the sequence is illegal right away if there aren't that many bytes
|
||||||
|
* available.
|
||||||
|
* If presented with a length > 4, this returns 0. The Unicode
|
||||||
|
* definition of UTF-8 goes up to 4-byte sequences.
|
||||||
|
*/
|
||||||
|
static unsigned char isLegalUTF8(const unsigned char* source, int length) {
|
||||||
|
unsigned char a;
|
||||||
|
const unsigned char* srcptr = source + length;
|
||||||
|
switch (length) {
|
||||||
|
default: return 0;
|
||||||
|
/* Everything else falls through when "true"... */
|
||||||
|
case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
||||||
|
case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
|
||||||
|
case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
|
||||||
|
switch (*source) {
|
||||||
|
/* no fall-through in this inner switch */
|
||||||
|
case 0xE0: if (a < 0xA0) return 0; break;
|
||||||
|
case 0xF0: if (a < 0x90) return 0; break;
|
||||||
|
case 0xF4: if (a > 0x8F) return 0; break;
|
||||||
|
default: if (a < 0x80) return 0;
|
||||||
|
}
|
||||||
|
case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
|
||||||
|
if (*source > 0xF4) return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result_t check_string(const unsigned char* string, const int length,
|
||||||
|
const char check_utf8, const char check_null) {
|
||||||
|
int position = 0;
|
||||||
|
/* By default we go character by character. Will be different for checking
|
||||||
|
* UTF-8 */
|
||||||
|
int sequence_length = 1;
|
||||||
|
|
||||||
|
if (!check_utf8 && !check_null) {
|
||||||
|
return VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (position < length) {
|
||||||
|
if (check_null && *(string + position) == 0) {
|
||||||
|
return HAS_NULL;
|
||||||
|
}
|
||||||
|
if (check_utf8) {
|
||||||
|
sequence_length = trailingBytesForUTF8[*(string + position)] + 1;
|
||||||
|
if ((position + sequence_length) > length) {
|
||||||
|
return NOT_UTF_8;
|
||||||
|
}
|
||||||
|
if (!isLegalUTF8(string + position, sequence_length)) {
|
||||||
|
return NOT_UTF_8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position += sequence_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VALID;
|
||||||
|
}
|
||||||
29
asyncio_mongo/_bson/encoding_helpers.h
Normal file
29
asyncio_mongo/_bson/encoding_helpers.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2012 10gen, 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 ENCODING_HELPERS_H
|
||||||
|
#define ENCODING_HELPERS_H
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VALID,
|
||||||
|
NOT_UTF_8,
|
||||||
|
HAS_NULL
|
||||||
|
} result_t;
|
||||||
|
|
||||||
|
result_t check_string(const unsigned char* string, const int length,
|
||||||
|
const char check_utf8, const char check_null);
|
||||||
|
|
||||||
|
#endif
|
||||||
789
asyncio_mongo/_bson/time64.c
Normal file
789
asyncio_mongo/_bson/time64.c
Normal file
@@ -0,0 +1,789 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2007-2010 Michael G Schwern
|
||||||
|
|
||||||
|
This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
|
||||||
|
|
||||||
|
The MIT License:
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Programmers who have available to them 64-bit time values as a 'long
|
||||||
|
long' type can use localtime64_r() and gmtime64_r() which correctly
|
||||||
|
converts the time even on 32-bit systems. Whether you have 64-bit time
|
||||||
|
values will depend on the operating system.
|
||||||
|
|
||||||
|
localtime64_r() is a 64-bit equivalent of localtime_r().
|
||||||
|
|
||||||
|
gmtime64_r() is a 64-bit equivalent of gmtime_r().
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "time64.h"
|
||||||
|
#include "time64_limits.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Spec says except for stftime() and the _r() functions, these
|
||||||
|
all return static memory. Stabbings! */
|
||||||
|
static struct TM Static_Return_Date;
|
||||||
|
|
||||||
|
static const int days_in_month[2][12] = {
|
||||||
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int julian_days_by_month[2][12] = {
|
||||||
|
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
|
||||||
|
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int length_of_year[2] = { 365, 366 };
|
||||||
|
|
||||||
|
/* Some numbers relating to the gregorian cycle */
|
||||||
|
static const Year years_in_gregorian_cycle = 400;
|
||||||
|
#define days_in_gregorian_cycle ((365 * 400) + 100 - 4 + 1)
|
||||||
|
static const Time64_T seconds_in_gregorian_cycle = days_in_gregorian_cycle * 60LL * 60LL * 24LL;
|
||||||
|
|
||||||
|
/* Year range we can trust the time funcitons with */
|
||||||
|
#define MAX_SAFE_YEAR 2037
|
||||||
|
#define MIN_SAFE_YEAR 1971
|
||||||
|
|
||||||
|
/* 28 year Julian calendar cycle */
|
||||||
|
#define SOLAR_CYCLE_LENGTH 28
|
||||||
|
|
||||||
|
/* Year cycle from MAX_SAFE_YEAR down. */
|
||||||
|
static const int safe_years_high[SOLAR_CYCLE_LENGTH] = {
|
||||||
|
2016, 2017, 2018, 2019,
|
||||||
|
2020, 2021, 2022, 2023,
|
||||||
|
2024, 2025, 2026, 2027,
|
||||||
|
2028, 2029, 2030, 2031,
|
||||||
|
2032, 2033, 2034, 2035,
|
||||||
|
2036, 2037, 2010, 2011,
|
||||||
|
2012, 2013, 2014, 2015
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Year cycle from MIN_SAFE_YEAR up */
|
||||||
|
static const int safe_years_low[SOLAR_CYCLE_LENGTH] = {
|
||||||
|
1996, 1997, 1998, 1971,
|
||||||
|
1972, 1973, 1974, 1975,
|
||||||
|
1976, 1977, 1978, 1979,
|
||||||
|
1980, 1981, 1982, 1983,
|
||||||
|
1984, 1985, 1986, 1987,
|
||||||
|
1988, 1989, 1990, 1991,
|
||||||
|
1992, 1993, 1994, 1995,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This isn't used, but it's handy to look at */
|
||||||
|
static const int dow_year_start[SOLAR_CYCLE_LENGTH] = {
|
||||||
|
5, 0, 1, 2, /* 0 2016 - 2019 */
|
||||||
|
3, 5, 6, 0, /* 4 */
|
||||||
|
1, 3, 4, 5, /* 8 1996 - 1998, 1971*/
|
||||||
|
6, 1, 2, 3, /* 12 1972 - 1975 */
|
||||||
|
4, 6, 0, 1, /* 16 */
|
||||||
|
2, 4, 5, 6, /* 20 2036, 2037, 2010, 2011 */
|
||||||
|
0, 2, 3, 4 /* 24 2012, 2013, 2014, 2015 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Let's assume people are going to be looking for dates in the future.
|
||||||
|
Let's provide some cheats so you can skip ahead.
|
||||||
|
This has a 4x speed boost when near 2008.
|
||||||
|
*/
|
||||||
|
/* Number of days since epoch on Jan 1st, 2008 GMT */
|
||||||
|
#define CHEAT_DAYS (1199145600 / 24 / 60 / 60)
|
||||||
|
#define CHEAT_YEARS 108
|
||||||
|
|
||||||
|
#define IS_LEAP(n) ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && (((n) + 1900) % 100))) != 0)
|
||||||
|
#define WRAP(a,b,m) ((a) = ((a) < 0 ) ? ((b)--, (a) + (m)) : (a))
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_LOCALTIME
|
||||||
|
# define SHOULD_USE_SYSTEM_LOCALTIME(a) ( \
|
||||||
|
(a) <= SYSTEM_LOCALTIME_MAX && \
|
||||||
|
(a) >= SYSTEM_LOCALTIME_MIN \
|
||||||
|
)
|
||||||
|
#else
|
||||||
|
# define SHOULD_USE_SYSTEM_LOCALTIME(a) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_GMTIME
|
||||||
|
# define SHOULD_USE_SYSTEM_GMTIME(a) ( \
|
||||||
|
(a) <= SYSTEM_GMTIME_MAX && \
|
||||||
|
(a) >= SYSTEM_GMTIME_MIN \
|
||||||
|
)
|
||||||
|
#else
|
||||||
|
# define SHOULD_USE_SYSTEM_GMTIME(a) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Multi varadic macros are a C99 thing, alas */
|
||||||
|
#ifdef TIME_64_DEBUG
|
||||||
|
# define TIME64_TRACE(format) (fprintf(stderr, format))
|
||||||
|
# define TIME64_TRACE1(format, var1) (fprintf(stderr, format, var1))
|
||||||
|
# define TIME64_TRACE2(format, var1, var2) (fprintf(stderr, format, var1, var2))
|
||||||
|
# define TIME64_TRACE3(format, var1, var2, var3) (fprintf(stderr, format, var1, var2, var3))
|
||||||
|
#else
|
||||||
|
# define TIME64_TRACE(format) ((void)0)
|
||||||
|
# define TIME64_TRACE1(format, var1) ((void)0)
|
||||||
|
# define TIME64_TRACE2(format, var1, var2) ((void)0)
|
||||||
|
# define TIME64_TRACE3(format, var1, var2, var3) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int is_exception_century(Year year)
|
||||||
|
{
|
||||||
|
int is_exception = ((year % 100 == 0) && !(year % 400 == 0));
|
||||||
|
TIME64_TRACE1("# is_exception_century: %s\n", is_exception ? "yes" : "no");
|
||||||
|
|
||||||
|
return(is_exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Compare two dates.
|
||||||
|
The result is like cmp.
|
||||||
|
Ignores things like gmtoffset and dst
|
||||||
|
*/
|
||||||
|
int cmp_date( const struct TM* left, const struct tm* right ) {
|
||||||
|
if( left->tm_year > right->tm_year )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_year < right->tm_year )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( left->tm_mon > right->tm_mon )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_mon < right->tm_mon )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( left->tm_mday > right->tm_mday )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_mday < right->tm_mday )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( left->tm_hour > right->tm_hour )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_hour < right->tm_hour )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( left->tm_min > right->tm_min )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_min < right->tm_min )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if( left->tm_sec > right->tm_sec )
|
||||||
|
return 1;
|
||||||
|
else if( left->tm_sec < right->tm_sec )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if a date is safely inside a range.
|
||||||
|
The intention is to check if its a few days inside.
|
||||||
|
*/
|
||||||
|
int date_in_safe_range( const struct TM* date, const struct tm* min, const struct tm* max ) {
|
||||||
|
if( cmp_date(date, min) == -1 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( cmp_date(date, max) == 1 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* timegm() is not in the C or POSIX spec, but it is such a useful
|
||||||
|
extension I would be remiss in leaving it out. Also I need it
|
||||||
|
for localtime64()
|
||||||
|
*/
|
||||||
|
Time64_T timegm64(const struct TM *date) {
|
||||||
|
Time64_T days = 0;
|
||||||
|
Time64_T seconds = 0;
|
||||||
|
Year year;
|
||||||
|
Year orig_year = (Year)date->tm_year;
|
||||||
|
int cycles = 0;
|
||||||
|
|
||||||
|
if( orig_year > 100 ) {
|
||||||
|
cycles = (int)((orig_year - 100) / 400);
|
||||||
|
orig_year -= cycles * 400;
|
||||||
|
days += (Time64_T)cycles * days_in_gregorian_cycle;
|
||||||
|
}
|
||||||
|
else if( orig_year < -300 ) {
|
||||||
|
cycles = (int)((orig_year - 100) / 400);
|
||||||
|
orig_year -= cycles * 400;
|
||||||
|
days += (Time64_T)cycles * days_in_gregorian_cycle;
|
||||||
|
}
|
||||||
|
TIME64_TRACE3("# timegm/ cycles: %d, days: %lld, orig_year: %lld\n", cycles, days, orig_year);
|
||||||
|
|
||||||
|
if( orig_year > 70 ) {
|
||||||
|
year = 70;
|
||||||
|
while( year < orig_year ) {
|
||||||
|
days += length_of_year[IS_LEAP(year)];
|
||||||
|
year++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( orig_year < 70 ) {
|
||||||
|
year = 69;
|
||||||
|
do {
|
||||||
|
days -= length_of_year[IS_LEAP(year)];
|
||||||
|
year--;
|
||||||
|
} while( year >= orig_year );
|
||||||
|
}
|
||||||
|
|
||||||
|
days += julian_days_by_month[IS_LEAP(orig_year)][date->tm_mon];
|
||||||
|
days += date->tm_mday - 1;
|
||||||
|
|
||||||
|
seconds = days * 60 * 60 * 24;
|
||||||
|
|
||||||
|
seconds += date->tm_hour * 60 * 60;
|
||||||
|
seconds += date->tm_min * 60;
|
||||||
|
seconds += date->tm_sec;
|
||||||
|
|
||||||
|
return(seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static int check_tm(struct TM *tm)
|
||||||
|
{
|
||||||
|
/* Don't forget leap seconds */
|
||||||
|
assert(tm->tm_sec >= 0);
|
||||||
|
assert(tm->tm_sec <= 61);
|
||||||
|
|
||||||
|
assert(tm->tm_min >= 0);
|
||||||
|
assert(tm->tm_min <= 59);
|
||||||
|
|
||||||
|
assert(tm->tm_hour >= 0);
|
||||||
|
assert(tm->tm_hour <= 23);
|
||||||
|
|
||||||
|
assert(tm->tm_mday >= 1);
|
||||||
|
assert(tm->tm_mday <= days_in_month[IS_LEAP(tm->tm_year)][tm->tm_mon]);
|
||||||
|
|
||||||
|
assert(tm->tm_mon >= 0);
|
||||||
|
assert(tm->tm_mon <= 11);
|
||||||
|
|
||||||
|
assert(tm->tm_wday >= 0);
|
||||||
|
assert(tm->tm_wday <= 6);
|
||||||
|
|
||||||
|
assert(tm->tm_yday >= 0);
|
||||||
|
assert(tm->tm_yday <= length_of_year[IS_LEAP(tm->tm_year)]);
|
||||||
|
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
assert(tm->tm_gmtoff >= -24 * 60 * 60);
|
||||||
|
assert(tm->tm_gmtoff <= 24 * 60 * 60);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The exceptional centuries without leap years cause the cycle to
|
||||||
|
shift by 16
|
||||||
|
*/
|
||||||
|
static Year cycle_offset(Year year)
|
||||||
|
{
|
||||||
|
const Year start_year = 2000;
|
||||||
|
Year year_diff = year - start_year;
|
||||||
|
Year exceptions;
|
||||||
|
|
||||||
|
if( year > start_year )
|
||||||
|
year_diff--;
|
||||||
|
|
||||||
|
exceptions = year_diff / 100;
|
||||||
|
exceptions -= year_diff / 400;
|
||||||
|
|
||||||
|
TIME64_TRACE3("# year: %lld, exceptions: %lld, year_diff: %lld\n",
|
||||||
|
year, exceptions, year_diff);
|
||||||
|
|
||||||
|
return exceptions * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For a given year after 2038, pick the latest possible matching
|
||||||
|
year in the 28 year calendar cycle.
|
||||||
|
|
||||||
|
A matching year...
|
||||||
|
1) Starts on the same day of the week.
|
||||||
|
2) Has the same leap year status.
|
||||||
|
|
||||||
|
This is so the calendars match up.
|
||||||
|
|
||||||
|
Also the previous year must match. When doing Jan 1st you might
|
||||||
|
wind up on Dec 31st the previous year when doing a -UTC time zone.
|
||||||
|
|
||||||
|
Finally, the next year must have the same start day of week. This
|
||||||
|
is for Dec 31st with a +UTC time zone.
|
||||||
|
It doesn't need the same leap year status since we only care about
|
||||||
|
January 1st.
|
||||||
|
*/
|
||||||
|
static int safe_year(const Year year)
|
||||||
|
{
|
||||||
|
int safe_year = 0;
|
||||||
|
Year year_cycle;
|
||||||
|
|
||||||
|
if( year >= MIN_SAFE_YEAR && year <= MAX_SAFE_YEAR ) {
|
||||||
|
return (int)year;
|
||||||
|
}
|
||||||
|
|
||||||
|
year_cycle = year + cycle_offset(year);
|
||||||
|
|
||||||
|
/* safe_years_low is off from safe_years_high by 8 years */
|
||||||
|
if( year < MIN_SAFE_YEAR )
|
||||||
|
year_cycle -= 8;
|
||||||
|
|
||||||
|
/* Change non-leap xx00 years to an equivalent */
|
||||||
|
if( is_exception_century(year) )
|
||||||
|
year_cycle += 11;
|
||||||
|
|
||||||
|
/* Also xx01 years, since the previous year will be wrong */
|
||||||
|
if( is_exception_century(year - 1) )
|
||||||
|
year_cycle += 17;
|
||||||
|
|
||||||
|
year_cycle %= SOLAR_CYCLE_LENGTH;
|
||||||
|
if( year_cycle < 0 )
|
||||||
|
year_cycle = SOLAR_CYCLE_LENGTH + year_cycle;
|
||||||
|
|
||||||
|
assert( year_cycle >= 0 );
|
||||||
|
assert( year_cycle < SOLAR_CYCLE_LENGTH );
|
||||||
|
if( year < MIN_SAFE_YEAR )
|
||||||
|
safe_year = safe_years_low[year_cycle];
|
||||||
|
else if( year > MAX_SAFE_YEAR )
|
||||||
|
safe_year = safe_years_high[year_cycle];
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
TIME64_TRACE3("# year: %lld, year_cycle: %lld, safe_year: %d\n",
|
||||||
|
year, year_cycle, safe_year);
|
||||||
|
|
||||||
|
assert(safe_year <= MAX_SAFE_YEAR && safe_year >= MIN_SAFE_YEAR);
|
||||||
|
|
||||||
|
return safe_year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void copy_tm_to_TM64(const struct tm *src, struct TM *dest) {
|
||||||
|
if( src == NULL ) {
|
||||||
|
memset(dest, 0, sizeof(*dest));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# ifdef USE_TM64
|
||||||
|
dest->tm_sec = src->tm_sec;
|
||||||
|
dest->tm_min = src->tm_min;
|
||||||
|
dest->tm_hour = src->tm_hour;
|
||||||
|
dest->tm_mday = src->tm_mday;
|
||||||
|
dest->tm_mon = src->tm_mon;
|
||||||
|
dest->tm_year = (Year)src->tm_year;
|
||||||
|
dest->tm_wday = src->tm_wday;
|
||||||
|
dest->tm_yday = src->tm_yday;
|
||||||
|
dest->tm_isdst = src->tm_isdst;
|
||||||
|
|
||||||
|
# ifdef HAS_TM_TM_GMTOFF
|
||||||
|
dest->tm_gmtoff = src->tm_gmtoff;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAS_TM_TM_ZONE
|
||||||
|
dest->tm_zone = src->tm_zone;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# else
|
||||||
|
/* They're the same type */
|
||||||
|
memcpy(dest, src, sizeof(*dest));
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void copy_TM64_to_tm(const struct TM *src, struct tm *dest) {
|
||||||
|
if( src == NULL ) {
|
||||||
|
memset(dest, 0, sizeof(*dest));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# ifdef USE_TM64
|
||||||
|
dest->tm_sec = src->tm_sec;
|
||||||
|
dest->tm_min = src->tm_min;
|
||||||
|
dest->tm_hour = src->tm_hour;
|
||||||
|
dest->tm_mday = src->tm_mday;
|
||||||
|
dest->tm_mon = src->tm_mon;
|
||||||
|
dest->tm_year = (int)src->tm_year;
|
||||||
|
dest->tm_wday = src->tm_wday;
|
||||||
|
dest->tm_yday = src->tm_yday;
|
||||||
|
dest->tm_isdst = src->tm_isdst;
|
||||||
|
|
||||||
|
# ifdef HAS_TM_TM_GMTOFF
|
||||||
|
dest->tm_gmtoff = src->tm_gmtoff;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAS_TM_TM_ZONE
|
||||||
|
dest->tm_zone = src->tm_zone;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# else
|
||||||
|
/* They're the same type */
|
||||||
|
memcpy(dest, src, sizeof(*dest));
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Simulate localtime_r() to the best of our ability */
|
||||||
|
struct tm * fake_localtime_r(const time_t *time, struct tm *result) {
|
||||||
|
const struct tm *static_result = localtime(time);
|
||||||
|
|
||||||
|
assert(result != NULL);
|
||||||
|
|
||||||
|
if( static_result == NULL ) {
|
||||||
|
memset(result, 0, sizeof(*result));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(result, static_result, sizeof(*result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Simulate gmtime_r() to the best of our ability */
|
||||||
|
struct tm * fake_gmtime_r(const time_t *time, struct tm *result) {
|
||||||
|
const struct tm *static_result = gmtime(time);
|
||||||
|
|
||||||
|
assert(result != NULL);
|
||||||
|
|
||||||
|
if( static_result == NULL ) {
|
||||||
|
memset(result, 0, sizeof(*result));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(result, static_result, sizeof(*result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Time64_T seconds_between_years(Year left_year, Year right_year) {
|
||||||
|
int increment = (left_year > right_year) ? 1 : -1;
|
||||||
|
Time64_T seconds = 0;
|
||||||
|
int cycles;
|
||||||
|
|
||||||
|
if( left_year > 2400 ) {
|
||||||
|
cycles = (int)((left_year - 2400) / 400);
|
||||||
|
left_year -= cycles * 400;
|
||||||
|
seconds += cycles * seconds_in_gregorian_cycle;
|
||||||
|
}
|
||||||
|
else if( left_year < 1600 ) {
|
||||||
|
cycles = (int)((left_year - 1600) / 400);
|
||||||
|
left_year += cycles * 400;
|
||||||
|
seconds += cycles * seconds_in_gregorian_cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( left_year != right_year ) {
|
||||||
|
seconds += length_of_year[IS_LEAP(right_year - 1900)] * 60 * 60 * 24;
|
||||||
|
right_year += increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return seconds * increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Time64_T mktime64(const struct TM *input_date) {
|
||||||
|
struct tm safe_date;
|
||||||
|
struct TM date;
|
||||||
|
Time64_T time;
|
||||||
|
Year year = input_date->tm_year + 1900;
|
||||||
|
|
||||||
|
if( date_in_safe_range(input_date, &SYSTEM_MKTIME_MIN, &SYSTEM_MKTIME_MAX) )
|
||||||
|
{
|
||||||
|
copy_TM64_to_tm(input_date, &safe_date);
|
||||||
|
return (Time64_T)mktime(&safe_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Have to make the year safe in date else it won't fit in safe_date */
|
||||||
|
date = *input_date;
|
||||||
|
date.tm_year = safe_year(year) - 1900;
|
||||||
|
copy_TM64_to_tm(&date, &safe_date);
|
||||||
|
|
||||||
|
time = (Time64_T)mktime(&safe_date);
|
||||||
|
|
||||||
|
time += seconds_between_years(year, (Year)(safe_date.tm_year + 1900));
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Because I think mktime() is a crappy name */
|
||||||
|
Time64_T timelocal64(const struct TM *date) {
|
||||||
|
return mktime64(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct TM *gmtime64_r (const Time64_T *in_time, struct TM *p)
|
||||||
|
{
|
||||||
|
int v_tm_sec, v_tm_min, v_tm_hour, v_tm_mon, v_tm_wday;
|
||||||
|
Time64_T v_tm_tday;
|
||||||
|
int leap;
|
||||||
|
Time64_T m;
|
||||||
|
Time64_T time = *in_time;
|
||||||
|
Year year = 70;
|
||||||
|
int cycles = 0;
|
||||||
|
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
/* Use the system gmtime() if time_t is small enough */
|
||||||
|
if( SHOULD_USE_SYSTEM_GMTIME(*in_time) ) {
|
||||||
|
time_t safe_time = (time_t)*in_time;
|
||||||
|
struct tm safe_date;
|
||||||
|
GMTIME_R(&safe_time, &safe_date);
|
||||||
|
|
||||||
|
copy_tm_to_TM64(&safe_date, p);
|
||||||
|
assert(check_tm(p));
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
p->tm_gmtoff = 0;
|
||||||
|
#endif
|
||||||
|
p->tm_isdst = 0;
|
||||||
|
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
p->tm_zone = "UTC";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v_tm_sec = (int)(time % 60);
|
||||||
|
time /= 60;
|
||||||
|
v_tm_min = (int)(time % 60);
|
||||||
|
time /= 60;
|
||||||
|
v_tm_hour = (int)(time % 24);
|
||||||
|
time /= 24;
|
||||||
|
v_tm_tday = time;
|
||||||
|
|
||||||
|
WRAP (v_tm_sec, v_tm_min, 60);
|
||||||
|
WRAP (v_tm_min, v_tm_hour, 60);
|
||||||
|
WRAP (v_tm_hour, v_tm_tday, 24);
|
||||||
|
|
||||||
|
v_tm_wday = (int)((v_tm_tday + 4) % 7);
|
||||||
|
if (v_tm_wday < 0)
|
||||||
|
v_tm_wday += 7;
|
||||||
|
m = v_tm_tday;
|
||||||
|
|
||||||
|
if (m >= CHEAT_DAYS) {
|
||||||
|
year = CHEAT_YEARS;
|
||||||
|
m -= CHEAT_DAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m >= 0) {
|
||||||
|
/* Gregorian cycles, this is huge optimization for distant times */
|
||||||
|
cycles = (int)(m / (Time64_T) days_in_gregorian_cycle);
|
||||||
|
if( cycles ) {
|
||||||
|
m -= (cycles * (Time64_T) days_in_gregorian_cycle);
|
||||||
|
year += (cycles * years_in_gregorian_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Years */
|
||||||
|
leap = IS_LEAP (year);
|
||||||
|
while (m >= (Time64_T) length_of_year[leap]) {
|
||||||
|
m -= (Time64_T) length_of_year[leap];
|
||||||
|
year++;
|
||||||
|
leap = IS_LEAP (year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Months */
|
||||||
|
v_tm_mon = 0;
|
||||||
|
while (m >= (Time64_T) days_in_month[leap][v_tm_mon]) {
|
||||||
|
m -= (Time64_T) days_in_month[leap][v_tm_mon];
|
||||||
|
v_tm_mon++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
year--;
|
||||||
|
|
||||||
|
/* Gregorian cycles */
|
||||||
|
cycles = (int)((m / (Time64_T) days_in_gregorian_cycle) + 1);
|
||||||
|
if( cycles ) {
|
||||||
|
m -= (cycles * (Time64_T) days_in_gregorian_cycle);
|
||||||
|
year += (cycles * years_in_gregorian_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Years */
|
||||||
|
leap = IS_LEAP (year);
|
||||||
|
while (m < (Time64_T) -length_of_year[leap]) {
|
||||||
|
m += (Time64_T) length_of_year[leap];
|
||||||
|
year--;
|
||||||
|
leap = IS_LEAP (year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Months */
|
||||||
|
v_tm_mon = 11;
|
||||||
|
while (m < (Time64_T) -days_in_month[leap][v_tm_mon]) {
|
||||||
|
m += (Time64_T) days_in_month[leap][v_tm_mon];
|
||||||
|
v_tm_mon--;
|
||||||
|
}
|
||||||
|
m += (Time64_T) days_in_month[leap][v_tm_mon];
|
||||||
|
}
|
||||||
|
|
||||||
|
p->tm_year = (int)year;
|
||||||
|
if( p->tm_year != year ) {
|
||||||
|
#ifdef EOVERFLOW
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point m is less than a year so casting to an int is safe */
|
||||||
|
p->tm_mday = (int) m + 1;
|
||||||
|
p->tm_yday = julian_days_by_month[leap][v_tm_mon] + (int)m;
|
||||||
|
p->tm_sec = v_tm_sec;
|
||||||
|
p->tm_min = v_tm_min;
|
||||||
|
p->tm_hour = v_tm_hour;
|
||||||
|
p->tm_mon = v_tm_mon;
|
||||||
|
p->tm_wday = v_tm_wday;
|
||||||
|
|
||||||
|
assert(check_tm(p));
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct TM *localtime64_r (const Time64_T *time, struct TM *local_tm)
|
||||||
|
{
|
||||||
|
time_t safe_time;
|
||||||
|
struct tm safe_date;
|
||||||
|
struct TM gm_tm;
|
||||||
|
Year orig_year;
|
||||||
|
int month_diff;
|
||||||
|
|
||||||
|
assert(local_tm != NULL);
|
||||||
|
|
||||||
|
/* Use the system localtime() if time_t is small enough */
|
||||||
|
if( SHOULD_USE_SYSTEM_LOCALTIME(*time) ) {
|
||||||
|
safe_time = (time_t)*time;
|
||||||
|
|
||||||
|
TIME64_TRACE1("Using system localtime for %lld\n", *time);
|
||||||
|
|
||||||
|
LOCALTIME_R(&safe_time, &safe_date);
|
||||||
|
|
||||||
|
copy_tm_to_TM64(&safe_date, local_tm);
|
||||||
|
assert(check_tm(local_tm));
|
||||||
|
|
||||||
|
return local_tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( gmtime64_r(time, &gm_tm) == NULL ) {
|
||||||
|
TIME64_TRACE1("gmtime64_r returned null for %lld\n", *time);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
orig_year = gm_tm.tm_year;
|
||||||
|
|
||||||
|
if (gm_tm.tm_year > (2037 - 1900) ||
|
||||||
|
gm_tm.tm_year < (1970 - 1900)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TIME64_TRACE1("Mapping tm_year %lld to safe_year\n", (Year)gm_tm.tm_year);
|
||||||
|
gm_tm.tm_year = safe_year((Year)(gm_tm.tm_year + 1900)) - 1900;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_time = (time_t)timegm64(&gm_tm);
|
||||||
|
if( LOCALTIME_R(&safe_time, &safe_date) == NULL ) {
|
||||||
|
TIME64_TRACE1("localtime_r(%d) returned NULL\n", (int)safe_time);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_tm_to_TM64(&safe_date, local_tm);
|
||||||
|
|
||||||
|
local_tm->tm_year = (int)orig_year;
|
||||||
|
if( local_tm->tm_year != orig_year ) {
|
||||||
|
TIME64_TRACE2("tm_year overflow: tm_year %lld, orig_year %lld\n",
|
||||||
|
(Year)local_tm->tm_year, (Year)orig_year);
|
||||||
|
|
||||||
|
#ifdef EOVERFLOW
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
month_diff = local_tm->tm_mon - gm_tm.tm_mon;
|
||||||
|
|
||||||
|
/* When localtime is Dec 31st previous year and
|
||||||
|
gmtime is Jan 1st next year.
|
||||||
|
*/
|
||||||
|
if( month_diff == 11 ) {
|
||||||
|
local_tm->tm_year--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When localtime is Jan 1st, next year and
|
||||||
|
gmtime is Dec 31st, previous year.
|
||||||
|
*/
|
||||||
|
if( month_diff == -11 ) {
|
||||||
|
local_tm->tm_year++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GMT is Jan 1st, xx01 year, but localtime is still Dec 31st
|
||||||
|
in a non-leap xx00. There is one point in the cycle
|
||||||
|
we can't account for which the safe xx00 year is a leap
|
||||||
|
year. So we need to correct for Dec 31st comming out as
|
||||||
|
the 366th day of the year.
|
||||||
|
*/
|
||||||
|
if( !IS_LEAP(local_tm->tm_year) && local_tm->tm_yday == 365 )
|
||||||
|
local_tm->tm_yday--;
|
||||||
|
|
||||||
|
assert(check_tm(local_tm));
|
||||||
|
|
||||||
|
return local_tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int valid_tm_wday( const struct TM* date ) {
|
||||||
|
if( 0 <= date->tm_wday && date->tm_wday <= 6 )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int valid_tm_mon( const struct TM* date ) {
|
||||||
|
if( 0 <= date->tm_mon && date->tm_mon <= 11 )
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Non-thread safe versions of the above */
|
||||||
|
struct TM *localtime64(const Time64_T *time) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_tzset();
|
||||||
|
#else
|
||||||
|
tzset();
|
||||||
|
#endif
|
||||||
|
return localtime64_r(time, &Static_Return_Date);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TM *gmtime64(const Time64_T *time) {
|
||||||
|
return gmtime64_r(time, &Static_Return_Date);
|
||||||
|
}
|
||||||
67
asyncio_mongo/_bson/time64.h
Normal file
67
asyncio_mongo/_bson/time64.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#ifndef TIME64_H
|
||||||
|
# define TIME64_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include "time64_config.h"
|
||||||
|
|
||||||
|
/* Set our custom types */
|
||||||
|
typedef INT_64_T Int64;
|
||||||
|
typedef Int64 Time64_T;
|
||||||
|
typedef Int64 Year;
|
||||||
|
|
||||||
|
|
||||||
|
/* A copy of the tm struct but with a 64 bit year */
|
||||||
|
struct TM64 {
|
||||||
|
int tm_sec;
|
||||||
|
int tm_min;
|
||||||
|
int tm_hour;
|
||||||
|
int tm_mday;
|
||||||
|
int tm_mon;
|
||||||
|
Year tm_year;
|
||||||
|
int tm_wday;
|
||||||
|
int tm_yday;
|
||||||
|
int tm_isdst;
|
||||||
|
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
long tm_gmtoff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
char *tm_zone;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Decide which tm struct to use */
|
||||||
|
#ifdef USE_TM64
|
||||||
|
#define TM TM64
|
||||||
|
#else
|
||||||
|
#define TM tm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Declare public functions */
|
||||||
|
struct TM *gmtime64_r (const Time64_T *, struct TM *);
|
||||||
|
struct TM *localtime64_r (const Time64_T *, struct TM *);
|
||||||
|
struct TM *gmtime64 (const Time64_T *);
|
||||||
|
struct TM *localtime64 (const Time64_T *);
|
||||||
|
|
||||||
|
Time64_T timegm64 (const struct TM *);
|
||||||
|
Time64_T mktime64 (const struct TM *);
|
||||||
|
Time64_T timelocal64 (const struct TM *);
|
||||||
|
|
||||||
|
|
||||||
|
/* Not everyone has gm/localtime_r(), provide a replacement */
|
||||||
|
#ifdef HAS_LOCALTIME_R
|
||||||
|
# define LOCALTIME_R(clock, result) localtime_r(clock, result)
|
||||||
|
#else
|
||||||
|
# define LOCALTIME_R(clock, result) fake_localtime_r(clock, result)
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_GMTIME_R
|
||||||
|
# define GMTIME_R(clock, result) gmtime_r(clock, result)
|
||||||
|
#else
|
||||||
|
# define GMTIME_R(clock, result) fake_gmtime_r(clock, result)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
78
asyncio_mongo/_bson/time64_config.h
Normal file
78
asyncio_mongo/_bson/time64_config.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/* Configuration
|
||||||
|
-------------
|
||||||
|
Define as appropriate for your system.
|
||||||
|
Sensible defaults provided.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TIME64_CONFIG_H
|
||||||
|
# define TIME64_CONFIG_H
|
||||||
|
|
||||||
|
/* Debugging
|
||||||
|
TIME_64_DEBUG
|
||||||
|
Define if you want debugging messages
|
||||||
|
*/
|
||||||
|
/* #define TIME_64_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
/* INT_64_T
|
||||||
|
A 64 bit integer type to use to store time and others.
|
||||||
|
Must be defined.
|
||||||
|
*/
|
||||||
|
#define INT_64_T long long
|
||||||
|
|
||||||
|
|
||||||
|
/* USE_TM64
|
||||||
|
Should we use a 64 bit safe replacement for tm? This will
|
||||||
|
let you go past year 2 billion but the struct will be incompatible
|
||||||
|
with tm. Conversion functions will be provided.
|
||||||
|
*/
|
||||||
|
/* #define USE_TM64 */
|
||||||
|
|
||||||
|
|
||||||
|
/* Availability of system functions.
|
||||||
|
|
||||||
|
HAS_GMTIME_R
|
||||||
|
Define if your system has gmtime_r()
|
||||||
|
|
||||||
|
HAS_LOCALTIME_R
|
||||||
|
Define if your system has localtime_r()
|
||||||
|
|
||||||
|
HAS_TIMEGM
|
||||||
|
Define if your system has timegm(), a GNU extension.
|
||||||
|
*/
|
||||||
|
#if !defined(WIN32) && !defined(_MSC_VER)
|
||||||
|
#define HAS_GMTIME_R
|
||||||
|
#define HAS_LOCALTIME_R
|
||||||
|
#endif
|
||||||
|
/* #define HAS_TIMEGM */
|
||||||
|
|
||||||
|
|
||||||
|
/* Details of non-standard tm struct elements.
|
||||||
|
|
||||||
|
HAS_TM_TM_GMTOFF
|
||||||
|
True if your tm struct has a "tm_gmtoff" element.
|
||||||
|
A BSD extension.
|
||||||
|
|
||||||
|
HAS_TM_TM_ZONE
|
||||||
|
True if your tm struct has a "tm_zone" element.
|
||||||
|
A BSD extension.
|
||||||
|
*/
|
||||||
|
/* #define HAS_TM_TM_GMTOFF */
|
||||||
|
/* #define HAS_TM_TM_ZONE */
|
||||||
|
|
||||||
|
|
||||||
|
/* USE_SYSTEM_LOCALTIME
|
||||||
|
USE_SYSTEM_GMTIME
|
||||||
|
USE_SYSTEM_MKTIME
|
||||||
|
USE_SYSTEM_TIMEGM
|
||||||
|
Should we use the system functions if the time is inside their range?
|
||||||
|
Your system localtime() is probably more accurate, but our gmtime() is
|
||||||
|
fast and safe.
|
||||||
|
*/
|
||||||
|
#define USE_SYSTEM_LOCALTIME
|
||||||
|
/* #define USE_SYSTEM_GMTIME */
|
||||||
|
#define USE_SYSTEM_MKTIME
|
||||||
|
/* #define USE_SYSTEM_TIMEGM */
|
||||||
|
|
||||||
|
#endif /* TIME64_CONFIG_H */
|
||||||
95
asyncio_mongo/_bson/time64_limits.h
Normal file
95
asyncio_mongo/_bson/time64_limits.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
Maximum and minimum inputs your system's respective time functions
|
||||||
|
can correctly handle. time64.h will use your system functions if
|
||||||
|
the input falls inside these ranges and corresponding USE_SYSTEM_*
|
||||||
|
constant is defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIME64_LIMITS_H
|
||||||
|
#define TIME64_LIMITS_H
|
||||||
|
|
||||||
|
/* Max/min for localtime() */
|
||||||
|
#define SYSTEM_LOCALTIME_MAX 2147483647
|
||||||
|
#define SYSTEM_LOCALTIME_MIN -2147483647-1
|
||||||
|
|
||||||
|
/* Max/min for gmtime() */
|
||||||
|
#define SYSTEM_GMTIME_MAX 2147483647
|
||||||
|
#define SYSTEM_GMTIME_MIN -2147483647-1
|
||||||
|
|
||||||
|
/* Max/min for mktime() */
|
||||||
|
static const struct tm SYSTEM_MKTIME_MAX = {
|
||||||
|
7,
|
||||||
|
14,
|
||||||
|
19,
|
||||||
|
18,
|
||||||
|
0,
|
||||||
|
138,
|
||||||
|
1,
|
||||||
|
17,
|
||||||
|
0
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
,-28800
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
,"PST"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct tm SYSTEM_MKTIME_MIN = {
|
||||||
|
52,
|
||||||
|
45,
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
11,
|
||||||
|
1,
|
||||||
|
5,
|
||||||
|
346,
|
||||||
|
0
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
,-28800
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
,"PST"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Max/min for timegm() */
|
||||||
|
#ifdef HAS_TIMEGM
|
||||||
|
static const struct tm SYSTEM_TIMEGM_MAX = {
|
||||||
|
7,
|
||||||
|
14,
|
||||||
|
3,
|
||||||
|
19,
|
||||||
|
0,
|
||||||
|
138,
|
||||||
|
2,
|
||||||
|
18,
|
||||||
|
0
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
,0
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
,"UTC"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct tm SYSTEM_TIMEGM_MIN = {
|
||||||
|
52,
|
||||||
|
45,
|
||||||
|
20,
|
||||||
|
13,
|
||||||
|
11,
|
||||||
|
1,
|
||||||
|
5,
|
||||||
|
346,
|
||||||
|
0
|
||||||
|
#ifdef HAS_TM_TM_GMTOFF
|
||||||
|
,0
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_TM_TM_ZONE
|
||||||
|
,"UTC"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif /* HAS_TIMEGM */
|
||||||
|
|
||||||
|
#endif /* TIME64_LIMITS_H */
|
||||||
Binary file not shown.
1265
asyncio_mongo/_pymongo/_cmessagemodule.c
Normal file
1265
asyncio_mongo/_pymongo/_cmessagemodule.c
Normal file
File diff suppressed because it is too large
Load Diff
26
setup.py
26
setup.py
@@ -12,11 +12,16 @@ from distutils.errors import CCompilerError
|
|||||||
from distutils.errors import DistutilsPlatformError, DistutilsExecError
|
from distutils.errors import DistutilsPlatformError, DistutilsExecError
|
||||||
from distutils.core import Extension
|
from distutils.core import Extension
|
||||||
|
|
||||||
requirements = ["asyncio"]
|
|
||||||
|
requirements = []
|
||||||
try:
|
try:
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
except ImportError:
|
except ImportError:
|
||||||
requirements.append("elementtree")
|
requirements.append("elementtree")
|
||||||
|
try:
|
||||||
|
import asyncio
|
||||||
|
except ImportError:
|
||||||
|
requirements.append("asyncio")
|
||||||
|
|
||||||
|
|
||||||
if sys.platform == 'win32' and sys.version_info > (2, 6):
|
if sys.platform == 'win32' and sys.version_info > (2, 6):
|
||||||
@@ -69,11 +74,16 @@ although they do result in significant speed improvements.
|
|||||||
c_ext = Feature(
|
c_ext = Feature(
|
||||||
"optional C extension",
|
"optional C extension",
|
||||||
standard=True,
|
standard=True,
|
||||||
ext_modules=[Extension('txmongo._pymongo._cbson',
|
ext_modules=[Extension('asyncio_mongo._bson._cbson',
|
||||||
include_dirs=['txmongo/_pymongo'],
|
include_dirs=['asyncio_mongo/_bson'],
|
||||||
sources=['txmongo/_pymongo/_cbsonmodule.c',
|
sources=['asyncio_mongo/_bson/_cbsonmodule.c',
|
||||||
'txmongo/_pymongo/time_helpers.c',
|
'asyncio_mongo/_bson/time64.c',
|
||||||
'txmongo/_pymongo/encoding_helpers.c'])])
|
'asyncio_mongo/_bson/buffer.c',
|
||||||
|
'asyncio_mongo/_bson/encoding_helpers.c']),
|
||||||
|
Extension('asyncio_mongo._pymongo._cmessage',
|
||||||
|
include_dirs=['bson'],
|
||||||
|
sources=['asyncio_mongo._pymongo/_cmessagemodule.c',
|
||||||
|
'asyncio_mongo/_bson/buffer.c'])])
|
||||||
|
|
||||||
if "--no_ext" in sys.argv:
|
if "--no_ext" in sys.argv:
|
||||||
sys.argv = [x for x in sys.argv if x != "--no_ext"]
|
sys.argv = [x for x in sys.argv if x != "--no_ext"]
|
||||||
@@ -83,13 +93,13 @@ else:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="asyncio-mongo",
|
name="asyncio-mongo",
|
||||||
version="0.1.0",
|
version="0.1-dev",
|
||||||
description="Asynchronous Python 3.3+ driver for MongoDB <http://www.mongodb.org>",
|
description="Asynchronous Python 3.3+ driver for MongoDB <http://www.mongodb.org>",
|
||||||
author="Alexandre Fiori, Don Brown",
|
author="Alexandre Fiori, Don Brown",
|
||||||
author_email="mrdon@twdata.org",
|
author_email="mrdon@twdata.org",
|
||||||
url="https://bitbucket.org/mrdon/asyncio-mongo",
|
url="https://bitbucket.org/mrdon/asyncio-mongo",
|
||||||
keywords=["mongo", "mongodb", "pymongo", "gridfs", "asyncio_mongo", "asyncio"],
|
keywords=["mongo", "mongodb", "pymongo", "gridfs", "asyncio_mongo", "asyncio"],
|
||||||
packages=["asyncio_mongo", "asyncio_mongo._pymongo", "asyncio_mongo._gridfs", "asyncio_mongo._bson"],
|
packages=["asyncio_mongo", "asyncio_mongo._pymongo", "asyncio_mongo._bson"],
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
features=features,
|
features=features,
|
||||||
license="Apache License, Version 2.0",
|
license="Apache License, Version 2.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user