Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

When dealing with PyLong objects, pull them out as long long's and us…

…e yajl_gen_number()

On 32-bit machines, a PyLong_AsLong() call on a 64-bit number will fail,
to remedy this we pull out the `long long` and use that to generate a buffer
to pass into yajl_gen_number() which will handle it appropriately

http://github.com/rtyler/py-yajl/issues#issue/16

Change-Id: Iec800f6e765e14041d7a264e3fdecdbb15cc986d
  • Loading branch information...
commit 1c276f4366746c973b0e92061e528dda87403f13 1 parent 215f62f
@rtyler authored
Showing with 22 additions and 3 deletions.
  1. +22 −3 encoder.c
View
25 encoder.c
@@ -41,7 +41,7 @@
static const char *hexdigit = "0123456789abcdef";
/* Located in yajl_hacks.c */
-extern yajl_gen_status yajl_gen_raw_string(yajl_gen g,
+extern yajl_gen_status yajl_gen_raw_string(yajl_gen g,
const unsigned char * str, unsigned int len);
static yajl_gen_status ProcessObject(_YajlEncoder *self, PyObject *object)
@@ -160,11 +160,30 @@ static yajl_gen_status ProcessObject(_YajlEncoder *self, PyObject *object)
}
#ifndef IS_PYTHON3
if (PyInt_Check(object)) {
- return yajl_gen_integer(handle, PyInt_AsLong(object));
+ long number = PyInt_AsLong(object);

why long for Python 3 and long long if not? (just curious, still learning how python works)

oops, other way around

@rtyler Owner
rtyler added a note

It's not that one supports long long and the other doesn't, it's that "PyInt_Check()" is undefined in Python 3.

The change in the PyLong_Check block is to support larger numbers on 32-bit platforms, since long alone isn't large enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ if ( (number == -1) && (PyErr_Occurred()) ) {
+ return yajl_gen_in_error_state;
+ }
+ return yajl_gen_integer(handle, number);
}
#endif
if (PyLong_Check(object)) {
- return yajl_gen_integer(handle, PyLong_AsLong(object));
+ long long number = PyLong_AsLongLong(object);
+ char *buffer = NULL;
+
+ if ( (number == -1) && (PyErr_Occurred()) ) {
+ return yajl_gen_in_error_state;;
+ }
+
+ /*
+ * Nifty trick for getting the buffer length of a long long, going
+ * to convert this long long into a buffer to be handled by
+ * yajl_gen_number()
+ */
+ unsigned int length = (unsigned int)(snprintf(NULL, 0, "%lld", number)) + 1;
+ buffer = (char *)(malloc(length));
+ snprintf(buffer, length, "%lld", number);
+ return yajl_gen_number(handle, buffer, length - 1);
}
if (PyFloat_Check(object)) {
return yajl_gen_double(handle, PyFloat_AsDouble(object));
Please sign in to comment.
Something went wrong with that request. Please try again.