| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * MessagePack for Python unpacking routine | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2009 Naoki INADA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *    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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-06-16 01:56:04 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-26 15:19:59 +09:00
										 |  |  | #define MSGPACK_EMBED_STACK_SIZE  (1024)
 | 
					
						
							| 
									
										
										
										
											2009-06-24 01:38:48 +09:00
										 |  |  | #include "unpack_define.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-28 21:24:16 +09:00
										 |  |  | typedef struct unpack_user { | 
					
						
							| 
									
										
										
										
											2018-01-11 17:02:41 +09:00
										 |  |  |     bool use_list; | 
					
						
							| 
									
										
										
										
											2018-01-12 19:22:36 +09:00
										 |  |  |     bool raw; | 
					
						
							| 
									
										
										
										
											2012-09-23 19:37:28 +10:00
										 |  |  |     bool has_pairs_hook; | 
					
						
							| 
									
										
										
										
											2018-11-29 22:29:38 +09:00
										 |  |  |     bool strict_map_key; | 
					
						
							| 
									
										
										
										
											2018-01-11 17:02:41 +09:00
										 |  |  |     PyObject *object_hook; | 
					
						
							| 
									
										
										
										
											2010-10-26 02:09:52 +09:00
										 |  |  |     PyObject *list_hook; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:28:32 +09:00
										 |  |  |     PyObject *ext_hook; | 
					
						
							| 
									
										
										
										
											2019-12-05 18:29:15 +09:00
										 |  |  |     PyObject *timestamp_t; | 
					
						
							| 
									
										
										
										
											2011-04-15 17:36:17 +03:00
										 |  |  |     const char *unicode_errors; | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     Py_ssize_t max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len; | 
					
						
							| 
									
										
										
										
											2009-06-28 21:24:16 +09:00
										 |  |  | } unpack_user; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | typedef PyObject* msgpack_unpack_object; | 
					
						
							|  |  |  | struct unpack_context; | 
					
						
							|  |  |  | typedef struct unpack_context unpack_context; | 
					
						
							| 
									
										
										
										
											2015-11-07 16:30:18 +09:00
										 |  |  | typedef int (*execute_fn)(unpack_context *ctx, const char* data, Py_ssize_t len, Py_ssize_t* off); | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline msgpack_unpack_object unpack_callback_root(unpack_user* u) | 
					
						
							| 
									
										
										
										
											2009-06-17 13:45:08 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_uint16(unpack_user* u, uint16_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *p = PyInt_FromLong((long)d); | 
					
						
							|  |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  |     return unpack_callback_uint16(u, d, o); | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-31 02:29:05 +09:00
										 |  |  |     PyObject *p = PyInt_FromSize_t((size_t)d); | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_uint64(unpack_user* u, uint64_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-16 12:41:02 +09:00
										 |  |  |     PyObject *p; | 
					
						
							|  |  |  |     if (d > LONG_MAX) { | 
					
						
							| 
									
										
										
										
											2013-06-03 13:49:44 +09:00
										 |  |  |         p = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)d); | 
					
						
							| 
									
										
										
										
											2013-05-16 12:41:02 +09:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2015-11-09 01:50:40 +09:00
										 |  |  |         p = PyInt_FromLong((long)d); | 
					
						
							| 
									
										
										
										
											2013-05-16 12:41:02 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_int32(unpack_user* u, int32_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *p = PyInt_FromLong(d); | 
					
						
							|  |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_int16(unpack_user* u, int16_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  |     return unpack_callback_int32(u, d, o); | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_int8(unpack_user* u, int8_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  |     return unpack_callback_int32(u, d, o); | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_int64(unpack_user* u, int64_t d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-16 12:41:02 +09:00
										 |  |  |     PyObject *p; | 
					
						
							|  |  |  |     if (d > LONG_MAX || d < LONG_MIN) { | 
					
						
							| 
									
										
										
										
											2015-11-09 01:50:40 +09:00
										 |  |  |         p = PyLong_FromLongLong((PY_LONG_LONG)d); | 
					
						
							| 
									
										
										
										
											2013-05-16 12:41:02 +09:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         p = PyInt_FromLong((long)d); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_double(unpack_user* u, double d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *p = PyFloat_FromDouble(d); | 
					
						
							|  |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_float(unpack_user* u, float d, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  |     return unpack_callback_double(u, d, o); | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_nil(unpack_user* u, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-08 04:33:47 +09:00
										 |  |  | { Py_INCREF(Py_None); *o = Py_None; return 0; } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_true(unpack_user* u, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-08 04:33:47 +09:00
										 |  |  | { Py_INCREF(Py_True); *o = Py_True; return 0; } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_false(unpack_user* u, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-08 04:33:47 +09:00
										 |  |  | { Py_INCREF(Py_False); *o = Py_False; return 0; } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     if (n > u->max_array_len) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%u exceeds max_array_len(%zd)", n, u->max_array_len); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-12-17 15:19:18 +09:00
										 |  |  |     PyObject *p = u->use_list ? PyList_New(n) : PyTuple_New(n); | 
					
						
							| 
									
										
										
										
											2009-12-17 11:13:47 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-24 01:13:39 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_array_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object o) | 
					
						
							| 
									
										
										
										
											2009-12-17 11:13:47 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-17 15:19:18 +09:00
										 |  |  |     if (u->use_list) | 
					
						
							| 
									
										
										
										
											2009-12-17 11:13:47 +09:00
										 |  |  |         PyList_SET_ITEM(*c, current, o); | 
					
						
							| 
									
										
										
										
											2009-12-17 15:19:18 +09:00
										 |  |  |     else | 
					
						
							|  |  |  |         PyTuple_SET_ITEM(*c, current, o); | 
					
						
							| 
									
										
										
										
											2009-12-17 11:13:47 +09:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_array_end(unpack_user* u, msgpack_unpack_object* c) | 
					
						
							| 
									
										
										
										
											2010-10-26 02:09:52 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     if (u->list_hook) { | 
					
						
							| 
									
										
										
										
											2013-10-21 00:29:05 +09:00
										 |  |  |         PyObject *new_c = PyObject_CallFunctionObjArgs(u->list_hook, *c, NULL); | 
					
						
							| 
									
										
										
										
											2012-10-12 13:19:53 +03:00
										 |  |  |         if (!new_c) | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2012-02-28 15:36:58 +01:00
										 |  |  |         Py_DECREF(*c); | 
					
						
							|  |  |  |         *c = new_c; | 
					
						
							| 
									
										
										
										
											2010-10-26 02:09:52 +09:00
										 |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     if (n > u->max_map_len) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%u exceeds max_map_len(%zd)", n, u->max_map_len); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-09-23 19:37:28 +10:00
										 |  |  |     PyObject *p; | 
					
						
							|  |  |  |     if (u->has_pairs_hook) { | 
					
						
							|  |  |  |         p = PyList_New(n); // Or use tuple?
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         p = PyDict_New(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     if (!p) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = p; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_map_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v) | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-29 22:29:38 +09:00
										 |  |  |     if (u->strict_map_key && !PyUnicode_CheckExact(k) && !PyBytes_CheckExact(k)) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%.100s is not allowed for map key", Py_TYPE(k)->tp_name); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-03 21:18:17 +09:00
										 |  |  |     if (PyUnicode_CheckExact(k)) { | 
					
						
							|  |  |  |         PyUnicode_InternInPlace(&k); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-09-23 19:37:28 +10:00
										 |  |  |     if (u->has_pairs_hook) { | 
					
						
							|  |  |  |         msgpack_unpack_object item = PyTuple_Pack(2, k, v); | 
					
						
							|  |  |  |         if (!item) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         Py_DECREF(k); | 
					
						
							|  |  |  |         Py_DECREF(v); | 
					
						
							|  |  |  |         PyList_SET_ITEM(*c, current, item); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (PyDict_SetItem(*c, k, v) == 0) { | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |         Py_DECREF(k); | 
					
						
							|  |  |  |         Py_DECREF(v); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_map_end(unpack_user* u, msgpack_unpack_object* c) | 
					
						
							| 
									
										
										
										
											2010-10-26 01:26:06 +09:00
										 |  |  | { | 
					
						
							|  |  |  |     if (u->object_hook) { | 
					
						
							| 
									
										
										
										
											2013-10-21 00:29:05 +09:00
										 |  |  |         PyObject *new_c = PyObject_CallFunctionObjArgs(u->object_hook, *c, NULL); | 
					
						
							| 
									
										
										
										
											2012-10-12 12:32:32 +03:00
										 |  |  |         if (!new_c) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 15:36:58 +01:00
										 |  |  |         Py_DECREF(*c); | 
					
						
							|  |  |  |         *c = new_c; | 
					
						
							| 
									
										
										
										
											2010-10-26 01:26:06 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-26 02:09:52 +09:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2010-10-26 01:26:06 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-27 21:12:20 +09:00
										 |  |  | static inline int unpack_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     if (l > u->max_str_len) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%u exceeds max_str_len(%zd)", l, u->max_str_len); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-24 04:25:05 +09:00
										 |  |  |     PyObject *py; | 
					
						
							| 
									
										
										
										
											2018-01-11 17:02:41 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-03 21:13:05 +09:00
										 |  |  |     if (u->raw) { | 
					
						
							| 
									
										
										
										
											2011-04-15 17:36:17 +03:00
										 |  |  |         py = PyBytes_FromStringAndSize(p, l); | 
					
						
							| 
									
										
										
										
											2018-01-11 17:02:41 +09:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2018-02-05 02:19:48 +09:00
										 |  |  |         py = PyUnicode_DecodeUTF8(p, l, u->unicode_errors); | 
					
						
							| 
									
										
										
										
											2011-04-15 17:36:17 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-24 14:58:02 +09:00
										 |  |  |     if (!py) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = py; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:38 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 08:35:08 +09:00
										 |  |  | static inline int unpack_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     if (l > u->max_bin_len) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%u exceeds max_bin_len(%zd)", l, u->max_bin_len); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 08:35:08 +09:00
										 |  |  |     PyObject *py = PyBytes_FromStringAndSize(p, l); | 
					
						
							|  |  |  |     if (!py) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = py; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-05 18:29:15 +09:00
										 |  |  | typedef struct msgpack_timestamp { | 
					
						
							|  |  |  |     int64_t tv_sec; | 
					
						
							|  |  |  |     uint32_t tv_nsec; | 
					
						
							|  |  |  | } msgpack_timestamp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Unpack ext buffer to a timestamp. Pulled from msgpack-c timestamp.h. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int unpack_timestamp(const char* buf, unsigned int buflen, msgpack_timestamp* ts) { | 
					
						
							|  |  |  |     switch (buflen) { | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |         ts->tv_nsec = 0; | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             uint32_t v = _msgpack_load32(uint32_t, buf); | 
					
						
							|  |  |  |             ts->tv_sec = (int64_t)v; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     case 8: { | 
					
						
							|  |  |  |         uint64_t value =_msgpack_load64(uint64_t, buf); | 
					
						
							|  |  |  |         ts->tv_nsec = (uint32_t)(value >> 34); | 
					
						
							|  |  |  |         ts->tv_sec = value & 0x00000003ffffffffLL; | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case 12: | 
					
						
							|  |  |  |         ts->tv_nsec = _msgpack_load32(uint32_t, buf); | 
					
						
							|  |  |  |         ts->tv_sec = _msgpack_load64(int64_t, buf + 4); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 17:27:16 +02:00
										 |  |  | static inline int unpack_callback_ext(unpack_user* u, const char* base, const char* pos, | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |                                       unsigned int length, msgpack_unpack_object* o) | 
					
						
							| 
									
										
										
										
											2013-10-19 17:27:16 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject *py; | 
					
						
							|  |  |  |     int8_t typecode = (int8_t)*pos++; | 
					
						
							| 
									
										
										
										
											2013-10-20 20:28:32 +09:00
										 |  |  |     if (!u->ext_hook) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_AssertionError, "u->ext_hook cannot be NULL"); | 
					
						
							| 
									
										
										
										
											2013-10-19 17:27:16 +02:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-06-23 22:46:08 +09:00
										 |  |  |     if (length-1 > u->max_ext_len) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "%u exceeds max_ext_len(%zd)", length, u->max_ext_len); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // length also includes the typecode, so the actual data is length-1
 | 
					
						
							| 
									
										
										
										
											2019-12-05 18:29:15 +09:00
										 |  |  |     if (typecode == -1) { | 
					
						
							|  |  |  |         msgpack_timestamp ts; | 
					
						
							|  |  |  |         if (unpack_timestamp(pos, length-1, &ts) == 0) { | 
					
						
							|  |  |  |             py = PyObject_CallFunction(u->timestamp_t, "(Lk)", ts.tv_sec, ts.tv_nsec); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             py = NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         py = PyObject_CallFunction(u->ext_hook, "(iy#)", (int)typecode, pos, (Py_ssize_t)length-1); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-10-19 17:27:16 +02:00
										 |  |  |     if (!py) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     *o = py; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-24 01:38:48 +09:00
										 |  |  | #include "unpack_template.h"
 |