summaryrefslogtreecommitdiff
path: root/msgpack
diff options
context:
space:
mode:
Diffstat (limited to 'msgpack')
-rw-r--r--msgpack/_packer.pyx22
-rw-r--r--msgpack/_unpacker.pyx42
-rw-r--r--msgpack/fallback.py4
-rw-r--r--msgpack/pack.h34
-rw-r--r--msgpack/unpack.h6
-rw-r--r--msgpack/unpack_template.h14
6 files changed, 57 insertions, 65 deletions
diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx
index fcd20a7..0a6513c 100644
--- a/msgpack/_packer.pyx
+++ b/msgpack/_packer.pyx
@@ -135,13 +135,21 @@ cdef class Packer(object):
ret = msgpack_pack_false(&self.pk)
elif PyLong_Check(o):
# PyInt_Check(long) is True for Python 3.
- # Sow we should test long before int.
- if o > 0:
- ullval = o
- ret = msgpack_pack_unsigned_long_long(&self.pk, ullval)
- else:
- llval = o
- ret = msgpack_pack_long_long(&self.pk, llval)
+ # So we should test long before int.
+ try:
+ if o > 0:
+ ullval = o
+ ret = msgpack_pack_unsigned_long_long(&self.pk, ullval)
+ else:
+ llval = o
+ ret = msgpack_pack_long_long(&self.pk, llval)
+ except OverflowError as oe:
+ if not default_used and self._default is not None:
+ o = self._default(o)
+ default_used = True
+ continue
+ else:
+ raise
elif PyInt_Check(o):
longval = o
ret = msgpack_pack_long(&self.pk, longval)
diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx
index b98957e..1aefc64 100644
--- a/msgpack/_unpacker.pyx
+++ b/msgpack/_unpacker.pyx
@@ -37,16 +37,17 @@ cdef extern from "unpack.h":
ctypedef struct unpack_context:
msgpack_user user
PyObject* obj
- size_t count
+ Py_ssize_t count
ctypedef int (*execute_fn)(unpack_context* ctx, const char* data,
- size_t len, size_t* off) except? -1
+ Py_ssize_t len, Py_ssize_t* off) except? -1
execute_fn unpack_construct
execute_fn unpack_skip
execute_fn read_array_header
execute_fn read_map_header
void unpack_init(unpack_context* ctx)
object unpack_data(unpack_context* ctx)
+ void unpack_clear(unpack_context* ctx)
cdef inline init_ctx(unpack_context *ctx,
object object_hook, object object_pairs_hook,
@@ -112,7 +113,7 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
See :class:`Unpacker` for options.
"""
cdef unpack_context ctx
- cdef size_t off = 0
+ cdef Py_ssize_t off = 0
cdef int ret
cdef char* buf
@@ -141,14 +142,18 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
if off < buf_len:
raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off))
return obj
- else:
- raise UnpackValueError("Unpack failed: error = %d" % (ret,))
+ unpack_clear(&ctx)
+ raise UnpackValueError("Unpack failed: error = %d" % (ret,))
def unpack(object stream, object object_hook=None, object list_hook=None,
bint use_list=1, encoding=None, unicode_errors="strict",
- object_pairs_hook=None, ext_hook=ExtType
- ):
+ object_pairs_hook=None, ext_hook=ExtType,
+ Py_ssize_t max_str_len=2147483647, # 2**32-1
+ Py_ssize_t max_bin_len=2147483647,
+ Py_ssize_t max_array_len=2147483647,
+ Py_ssize_t max_map_len=2147483647,
+ Py_ssize_t max_ext_len=2147483647):
"""
Unpack an object from `stream`.
@@ -158,7 +163,12 @@ def unpack(object stream, object object_hook=None, object list_hook=None,
"""
return unpackb(stream.read(), use_list=use_list,
object_hook=object_hook, object_pairs_hook=object_pairs_hook, list_hook=list_hook,
- encoding=encoding, unicode_errors=unicode_errors, ext_hook=ext_hook
+ encoding=encoding, unicode_errors=unicode_errors, ext_hook=ext_hook,
+ max_str_len=max_str_len,
+ max_bin_len=max_bin_len,
+ max_array_len=max_array_len,
+ max_map_len=max_map_len,
+ max_ext_len=max_ext_len,
)
@@ -233,14 +243,14 @@ cdef class Unpacker(object):
"""
cdef unpack_context ctx
cdef char* buf
- cdef size_t buf_size, buf_head, buf_tail
+ cdef Py_ssize_t buf_size, buf_head, buf_tail
cdef object file_like
cdef object file_like_read
cdef Py_ssize_t read_size
# To maintain refcnt.
cdef object object_hook, object_pairs_hook, list_hook, ext_hook
cdef object encoding, unicode_errors
- cdef size_t max_buffer_size
+ cdef Py_ssize_t max_buffer_size
def __cinit__(self):
self.buf = NULL
@@ -325,10 +335,10 @@ cdef class Unpacker(object):
cdef:
char* buf = self.buf
char* new_buf
- size_t head = self.buf_head
- size_t tail = self.buf_tail
- size_t buf_size = self.buf_size
- size_t new_size
+ Py_ssize_t head = self.buf_head
+ Py_ssize_t tail = self.buf_tail
+ Py_ssize_t buf_size = self.buf_size
+ Py_ssize_t new_size
if tail + _buf_len > buf_size:
if ((tail - head) + _buf_len) <= buf_size:
@@ -374,7 +384,7 @@ cdef class Unpacker(object):
cdef object _unpack(self, execute_fn execute, object write_bytes, bint iter=0):
cdef int ret
cdef object obj
- cdef size_t prev_head
+ cdef Py_ssize_t prev_head
if self.buf_head >= self.buf_tail and self.file_like is not None:
self.read_from_file()
@@ -408,7 +418,7 @@ cdef class Unpacker(object):
def read_bytes(self, Py_ssize_t nbytes):
"""Read a specified number of raw bytes from the stream"""
- cdef size_t nread
+ cdef Py_ssize_t nread
nread = min(self.buf_tail - self.buf_head, nbytes)
ret = PyBytes_FromStringAndSize(self.buf + self.buf_head, nread)
self.buf_head += nread
diff --git a/msgpack/fallback.py b/msgpack/fallback.py
index 5b5085e..f682611 100644
--- a/msgpack/fallback.py
+++ b/msgpack/fallback.py
@@ -655,6 +655,10 @@ class Packer(object):
return self._buffer.write(struct.pack(">BQ", 0xcf, obj))
if -0x8000000000000000 <= obj < -0x80000000:
return self._buffer.write(struct.pack(">Bq", 0xd3, obj))
+ if not default_used and self._default is not None:
+ obj = self._default(obj)
+ default_used = True
+ continue
raise PackValueError("Integer value out of range")
if self._use_bin_type and isinstance(obj, bytes):
n = len(obj)
diff --git a/msgpack/pack.h b/msgpack/pack.h
index 971065c..a75bdb0 100644
--- a/msgpack/pack.h
+++ b/msgpack/pack.h
@@ -39,40 +39,6 @@ typedef struct msgpack_packer {
typedef struct Packer Packer;
-static inline int msgpack_pack_int(msgpack_packer* pk, int d);
-static inline int msgpack_pack_long(msgpack_packer* pk, long d);
-static inline int msgpack_pack_long_long(msgpack_packer* pk, long long d);
-static inline int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d);
-static inline int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d);
-static inline int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d);
-//static inline int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d);
-
-static inline int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d);
-static inline int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d);
-static inline int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d);
-static inline int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d);
-static inline int msgpack_pack_int8(msgpack_packer* pk, int8_t d);
-static inline int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
-static inline int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
-static inline int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
-
-static inline int msgpack_pack_float(msgpack_packer* pk, float d);
-static inline int msgpack_pack_double(msgpack_packer* pk, double d);
-
-static inline int msgpack_pack_nil(msgpack_packer* pk);
-static inline int msgpack_pack_true(msgpack_packer* pk);
-static inline int msgpack_pack_false(msgpack_packer* pk);
-
-static inline int msgpack_pack_array(msgpack_packer* pk, unsigned int n);
-
-static inline int msgpack_pack_map(msgpack_packer* pk, unsigned int n);
-
-static inline int msgpack_pack_raw(msgpack_packer* pk, size_t l);
-static inline int msgpack_pack_bin(msgpack_packer* pk, size_t l);
-static inline int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l);
-
-static inline int msgpack_pack_ext(msgpack_packer* pk, char typecode, size_t l);
-
static inline int msgpack_pack_write(msgpack_packer* pk, const char *data, size_t l)
{
char* buf = pk->buf;
diff --git a/msgpack/unpack.h b/msgpack/unpack.h
index 5deb7cd..92f4f11 100644
--- a/msgpack/unpack.h
+++ b/msgpack/unpack.h
@@ -33,7 +33,7 @@ typedef struct unpack_user {
typedef PyObject* msgpack_unpack_object;
struct unpack_context;
typedef struct unpack_context unpack_context;
-typedef int (*execute_fn)(unpack_context *ctx, const char* data, size_t len, size_t* off);
+typedef int (*execute_fn)(unpack_context *ctx, const char* data, Py_ssize_t len, Py_ssize_t* off);
static inline msgpack_unpack_object unpack_callback_root(unpack_user* u)
{
@@ -69,7 +69,7 @@ static inline int unpack_callback_uint64(unpack_user* u, uint64_t d, msgpack_unp
if (d > LONG_MAX) {
p = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)d);
} else {
- p = PyInt_FromSize_t((size_t)d);
+ p = PyInt_FromLong((long)d);
}
if (!p)
return -1;
@@ -100,7 +100,7 @@ static inline int unpack_callback_int64(unpack_user* u, int64_t d, msgpack_unpac
{
PyObject *p;
if (d > LONG_MAX || d < LONG_MIN) {
- p = PyLong_FromLongLong((unsigned PY_LONG_LONG)d);
+ p = PyLong_FromLongLong((PY_LONG_LONG)d);
} else {
p = PyInt_FromLong((long)d);
}
diff --git a/msgpack/unpack_template.h b/msgpack/unpack_template.h
index d34eced..e1e08fe 100644
--- a/msgpack/unpack_template.h
+++ b/msgpack/unpack_template.h
@@ -24,8 +24,8 @@
typedef struct unpack_stack {
PyObject* obj;
- size_t size;
- size_t count;
+ Py_ssize_t size;
+ Py_ssize_t count;
unsigned int ct;
PyObject* map_key;
} unpack_stack;
@@ -70,9 +70,13 @@ static inline PyObject* unpack_data(unpack_context* ctx)
return (ctx)->stack[0].obj;
}
+static inline void unpack_clear(unpack_context *ctx)
+{
+ Py_CLEAR(ctx->stack[0].obj);
+}
template <bool construct>
-static inline int unpack_execute(unpack_context* ctx, const char* data, size_t len, size_t* off)
+static inline int unpack_execute(unpack_context* ctx, const char* data, Py_ssize_t len, Py_ssize_t* off)
{
assert(len >= *off);
@@ -89,7 +93,7 @@ static inline int unpack_execute(unpack_context* ctx, const char* data, size_t l
*/
unpack_user* user = &ctx->user;
- PyObject* obj;
+ PyObject* obj = NULL;
unpack_stack* c = NULL;
int ret;
@@ -409,7 +413,7 @@ _end:
#undef start_container
template <unsigned int fixed_offset, unsigned int var_offset>
-static inline int unpack_container_header(unpack_context* ctx, const char* data, size_t len, size_t* off)
+static inline int unpack_container_header(unpack_context* ctx, const char* data, Py_ssize_t len, Py_ssize_t* off)
{
assert(len >= *off);
uint32_t size;