@@ -13,6 +13,7 @@ cdef extern from "Python.h":
13
13
int PyMemoryView_Check(object obj)
14
14
int PyByteArray_Check(object obj)
15
15
int PyByteArray_CheckExact(object obj)
16
+ char * PyUnicode_AsUTF8AndSize(object obj, Py_ssize_t * l) except NULL
16
17
17
18
18
19
cdef extern from " pack.h" :
@@ -37,6 +38,7 @@ cdef extern from "pack.h":
37
38
int msgpack_pack_bin(msgpack_packer* pk, size_t l)
38
39
int msgpack_pack_raw_body(msgpack_packer* pk, char * body, size_t l)
39
40
int msgpack_pack_ext(msgpack_packer* pk, char typecode, size_t l)
41
+ int msgpack_pack_unicode(msgpack_packer* pk, object o, long long limit)
40
42
41
43
cdef int DEFAULT_RECURSE_LIMIT= 511
42
44
cdef long long ITEM_LIMIT = (2 ** 32 )- 1
@@ -126,8 +128,12 @@ cdef class Packer(object):
126
128
raise TypeError (" default must be a callable." )
127
129
self ._default = default
128
130
if encoding is None :
129
- self .encoding = ' utf_8'
130
- self .unicode_errors = NULL
131
+ if unicode_errors is None :
132
+ self .encoding = NULL
133
+ self .unicode_errors = NULL
134
+ else :
135
+ self .encoding = " utf_8"
136
+ self .unicode_errors = unicode_errors
131
137
else :
132
138
if isinstance (encoding, unicode ):
133
139
self ._bencoding = encoding.encode(' ascii' )
@@ -140,6 +146,8 @@ cdef class Packer(object):
140
146
self ._berrors = unicode_errors
141
147
if self ._berrors is not None :
142
148
self .unicode_errors = PyBytes_AsString(self ._berrors)
149
+ else :
150
+ self .unicode_errors = NULL
143
151
144
152
def __dealloc__ (self ):
145
153
PyMem_Free(self .pk.buf)
@@ -206,17 +214,19 @@ cdef class Packer(object):
206
214
if ret == 0 :
207
215
ret = msgpack_pack_raw_body(& self .pk, rawval, L)
208
216
elif PyUnicode_CheckExact(o) if strict_types else PyUnicode_Check(o):
209
- if not self .encoding:
210
- raise TypeError (" Can't encode unicode string: no encoding is specified" )
211
- # TODO: Use faster API for UTF-8
212
- o = PyUnicode_AsEncodedString(o, self .encoding, self .unicode_errors)
213
- L = len (o)
214
- if L > ITEM_LIMIT:
215
- raise PackValueError(" unicode string is too large" )
216
- rawval = o
217
- ret = msgpack_pack_raw(& self .pk, L)
218
- if ret == 0 :
219
- ret = msgpack_pack_raw_body(& self .pk, rawval, L)
217
+ if self .encoding == NULL :
218
+ ret = msgpack_pack_unicode(& self .pk, o, ITEM_LIMIT);
219
+ if ret == - 2 :
220
+ raise PackValueError(" unicode string is too large" )
221
+ else :
222
+ o = PyUnicode_AsEncodedString(o, self .encoding, self .unicode_errors)
223
+ L = len (o)
224
+ if L > ITEM_LIMIT:
225
+ raise PackValueError(" unicode string is too large" )
226
+ ret = msgpack_pack_raw(& self .pk, L)
227
+ if ret == 0 :
228
+ rawval = o
229
+ ret = msgpack_pack_raw_body(& self .pk, rawval, L)
220
230
elif PyDict_CheckExact(o):
221
231
d = < dict > o
222
232
L = len (d)
0 commit comments