diff options
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | msgpack/_msgpack.pyx | 2 | ||||
-rw-r--r-- | msgpack/unpack.h | 79 | ||||
-rw-r--r-- | setup.py | 3 |
4 files changed, 72 insertions, 14 deletions
@@ -1,4 +1,4 @@ -msgpack.c +msgpack.cpp setup.py msgpack/pack.h msgpack/unpack.h diff --git a/msgpack/_msgpack.pyx b/msgpack/_msgpack.pyx index 7c07cde..cbdcfc5 100644 --- a/msgpack/_msgpack.pyx +++ b/msgpack/_msgpack.pyx @@ -118,7 +118,7 @@ cdef class Packer: intval = o msgpack_pack_long_long(&self.pk, intval) elif isinstance(o, float): - fval = 9 + fval = o msgpack_pack_double(&self.pk, fval) elif isinstance(o, str): rawval = o diff --git a/msgpack/unpack.h b/msgpack/unpack.h index e51557f..694e816 100644 --- a/msgpack/unpack.h +++ b/msgpack/unpack.h @@ -15,10 +15,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include <map> +#include <string> + +#define MSGPACK_MAX_STACK_SIZE (1024) #include "msgpack/unpack_define.h" -typedef struct { - int reserved; +using namespace std; + +typedef struct unpack_user { + struct array_stack_type{unsigned int size, last;}; + array_stack_type array_stack[MSGPACK_MAX_STACK_SIZE]; + int array_current; + + map<string, PyObject*> str_cache; + + ~unpack_user() { + map<string, PyObject*>::iterator it, itend; + itend = str_cache.end(); + for (it = str_cache.begin(); it != itend; ++it) { + Py_DECREF(it->second); + } + } } unpack_user; @@ -40,7 +59,10 @@ struct template_context; typedef struct template_context template_context; static inline msgpack_unpack_object template_callback_root(unpack_user* u) -{ return NULL; } +{ + u->array_current = -1; + return NULL; +} static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o) { *o = PyInt_FromLong((long)d); return 0; } @@ -50,8 +72,8 @@ static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_u static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o) { - if (d >= 0x80000000UL) { - *o = PyLong_FromUnsignedLongLong((unsigned long long)d); + if (d > LONG_MAX) { + *o = PyLong_FromUnsignedLong((unsigned long)d); } else { *o = PyInt_FromLong((long)d); } @@ -90,14 +112,32 @@ static inline int template_callback_false(unpack_user* u, msgpack_unpack_object* static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o) { - /* TODO: use PyList_New(n). */ - *o = PyList_New(0); + if (n > 0) { + int cur = ++u->array_current; + u->array_stack[cur].size = n; + u->array_stack[cur].last = 0; + *o = PyList_New(n); + } + else { + *o = PyList_New(0); + } return 0; } static inline int template_callback_array_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object o) { - PyList_Append(*c, o); + int cur = u->array_current; + int n = u->array_stack[cur].size; + int last = u->array_stack[cur].last; + + PyList_SetItem(*c, last, o); + last++; + if (last >= n) { + u->array_current--; + } + else { + u->array_stack[cur].last = last; + } return 0; } @@ -110,13 +150,30 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_ static inline int template_callback_map_item(unpack_user* u, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v) { PyDict_SetItem(*c, k, v); - return 0; + Py_DECREF(k); + Py_DECREF(v); + return 0; } static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) { - *o = PyString_FromStringAndSize(p, l); - return 0; + if (l < 16) { + string s(p, l); + map<string,PyObject*>::iterator it = u->str_cache.find(s); + if (it != u->str_cache.end()) { + *o = it->second; + Py_INCREF(*o); + } + else { + *o = PyString_FromStringAndSize(p, l); + Py_INCREF(*o); + u->str_cache[s] = *o; + } + } + else { + *o = PyString_FromStringAndSize(p, l); + } + return 0; } #include "msgpack/unpack_template.h" @@ -2,11 +2,12 @@ from distutils.core import setup, Extension from Cython.Distutils import build_ext import os -version = '0.0.1' +version = '0.0.1dev' PACKAGE_ROOT = os.getcwdu() INCLUDE_PATH = os.path.join(PACKAGE_ROOT, 'include') msgpack_mod = Extension('msgpack._msgpack', + language="c++", sources=['msgpack/_msgpack.pyx'], include_dirs=[INCLUDE_PATH]) |