From f4c5b15cc6cf972695bb2281714f5b13b299fbd3 Mon Sep 17 00:00:00 2001
From: Naoki INADA <inada-n@klab.jp>
Date: Thu, 17 Dec 2009 11:13:47 +0900
Subject: [PATCH] Add `use_tuple` option that returns tuple for array object to
 Unpacker.

---
 python/msgpack/_msgpack.pyx | 10 +++++++++-
 python/msgpack/unpack.h     | 14 ++++++++++++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/python/msgpack/_msgpack.pyx b/python/msgpack/_msgpack.pyx
index dcabc0f9..b20ad7b9 100644
--- a/python/msgpack/_msgpack.pyx
+++ b/python/msgpack/_msgpack.pyx
@@ -151,7 +151,11 @@ def packb(object o):
 packs = packb
 
 cdef extern from "unpack.h":
+    ctypedef struct msgpack_user:
+        int use_tuple
+
     ctypedef struct template_context:
+        msgpack_user user
         PyObject* obj
         size_t count
         unsigned int ct
@@ -170,6 +174,7 @@ def unpackb(object packed_bytes):
     cdef size_t off = 0
     cdef int ret
     template_init(&ctx)
+    ctx.user.use_tuple = 0
     ret = template_execute(&ctx, p, len(packed_bytes), &off)
     if ret == 1:
         return template_data(&ctx)
@@ -225,6 +230,7 @@ cdef class Unpacker(object):
     cdef object file_like
     cdef int read_size
     cdef object waiting_bytes
+    cdef int use_tuple
 
     def __cinit__(self):
         self.buf = NULL
@@ -233,9 +239,10 @@ cdef class Unpacker(object):
         if self.buf:
             free(self.buf);
 
-    def __init__(self, file_like=None, int read_size=0):
+    def __init__(self, file_like=None, int read_size=0, use_tuple=0):
         if read_size == 0:
             read_size = 1024*1024
+        self.use_tuple = use_tuple
         self.file_like = file_like
         self.read_size = read_size
         self.waiting_bytes = []
@@ -244,6 +251,7 @@ cdef class Unpacker(object):
         self.buf_head = 0
         self.buf_tail = 0
         template_init(&self.ctx)
+        self.ctx.user.use_tuple = use_tuple
 
     def feed(self, next_bytes):
         if not isinstance(next_bytes, str):
diff --git a/python/msgpack/unpack.h b/python/msgpack/unpack.h
index 40058d08..0bf2568d 100644
--- a/python/msgpack/unpack.h
+++ b/python/msgpack/unpack.h
@@ -20,6 +20,7 @@
 #include "unpack_define.h"
 
 typedef struct unpack_user {
+    int use_tuple;
 } unpack_user;
 
 
@@ -135,7 +136,8 @@ 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)
 {
-    PyObject *p = PyList_New(n);
+    PyObject *p = u->use_tuple ? PyTuple_New(n) : PyList_New(n);
+
     if (!p)
         return -1;
     *o = p;
@@ -143,7 +145,15 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac
 }
 
 static inline int template_callback_array_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object o)
-{ PyList_SET_ITEM(*c, current, o); return 0; }
+{
+    if (u->use_tuple) {
+        PyTuple_SET_ITEM(*c, current, o);
+    }
+    else {
+        PyList_SET_ITEM(*c, current, o);
+    }
+    return 0;
+}
 
 static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o)
 {