[OPEN-ILS-DEV] PATCH: osrf_json_object.c (storing numbers as character strings)

Scott McKellar mck9 at swbell.net
Mon Dec 17 00:34:36 EST 2007


These patches are a first attempt at storing numerical values as
character strings, rather than doubles, in jsonObjects.

However they not ready for prime time, so please don't apply them to 
the main trunk.  First, I have done only the most rudimentary testing
at this point.  Secondly, the validation of character strings as 
numeric doesn't really work properly yet; it's just a stopgap until I 
can finish the real function.

Note that I have NOT done anything yet with the parser, so there 
should be no visible change in behavior, unless of course I have 
introduced bugs.

The purpose of these patches is to serve as a basis for 
experimentation and discussion.

-----------------

First let me mention something which is unrelated to the storage of
numbers but is obscured by those changes.

The original JSON_INIT_CLEAR macro freed the string of a JSON_STRING
only if the object was changing into a non-string.  If it was still
going to be a JSON_STRING, we still freed the string, but only after
calling the macro.  I changed the macro to free the string of a 
JSON_STRING unconditionally, and removed the other free.

Now, of course, I also free the string if the object is a JSON_NUMBER.

------------------

1. I store a numeric string using the same character pointer that we 
use for JSON_STRING strings.  The alternative would be to use one
string for numerics and a separate pointer for non-numerics, but I
don't see any compelling reason to do it that way.

2. I adopted the convention that a NULL pointer is equivalent to
zero.

3. In jsonNewNumberObject() I use a new doubleToString function to
translate the parameter (a double) into a character string.  Yes, I
know about the DOUBLE_TO_STRING macro, but I don't like it.  The
macro always makes two calls to snprintf(), once to find out how big
a buffer to allocate and once for real.  doubleToString only calls it
once, except in the rare case where the we need more than the
preallocated buffer of 64 bytes.

4. In jsonObjectFree() I added a line to free the string for a
JSON_NUMBER.

5. add_json_to_buffer() got simpler.  Since the number is already
in a character string, I don't have to format it into a character
string before appending it to the growing_buffer.

6. Originally jsonObjectGetString() returned NULL for anything but a
JSON_STRING.  I extended it to return non-NULL for a JSON_NUMBER as
well.  This change in semantics may or may not be welcome.  I don't
know if any existing code relies on getting a NULL for a non-string
object.  If so, we can easily revert to the original semantics.

7. jsonObjectGetNumber now uses strtod() to translate the string
into a double.

8. I created a new jsonObjectSetNumberString function to supplement
the existing jsonObjectSetNumber function.  Instead of accepting a
double as the numeric value, it accepts a string, which it expects
to encode a number.

At this point we need to decide what to do if the character string
we receive is not numeric.  I have adopted the simplest possible
policy: If the string is not numeric, I store a NULL pointer, which
is treated elsewhere as the equivalent of a zero.

Other possibilities: return an error code, issue error messages, 
coredump, or whatever suits your fancy.  We can discuss the options.

9. I plan to implement a function similar to the existing
jsonNewNumberObject(), accepting the numerical value as a string 
instead of a double.  The same issue arises: what do we do with a
non-numeric string?  Whatever we decide to do, we should do it
consistently.

10. jsonObjectSetNumber uses doubleToString() to format its
double argument into a character string.

11. In jsonObjectClone, I use a two-step procedure to clone a
JSON_NUMBER.  I first create a JSON_STRING using the numeric string
from the object to be cloned; then I change the object type to 
JSON_NUMBER.  It should be possible to do it with a single step,
but I haven't written the appropriate function yet (see item 9 above).

12. jsonObjectToSimpleString() got simpler, because I don't have to
translate from a double to a string.

13. The new isStringNumeric function is a bit of a cheat at this
point.  I simply call strtod() and let it do the dirty work.

This is a temporary stopgap.  It is not a correct solution because
strtod() accepts things as numeric that we don't want to treat as
numeric: hexadecimal, NANs, and infinities.  I am working on a better
solution that will march through the string looking for a valid
character sequence, but it's not done yet.

-----------------

I expect to send at least one more new improved version of 
osrf_json_object.c, if only to fix isStringNumeric().  I'm not sure
whether I should send it as a patch based on the current trunk version
or based on the patch I'm sending now.  Or maybe I should send the
whole thing rather than a patch.

Scott McKellar
http://home.swbell.net/mck9/ct/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: osrf_json_h_8.patch
Type: text/x-patch
Size: 500 bytes
Desc: 4245941045-osrf_json_h_8.patch
Url : http://list.georgialibraries.org/pipermail/open-ils-dev/attachments/20071216/29216102/osrf_json_h_8.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: osrf_json_object_c_5.patch
Type: text/x-patch
Size: 6626 bytes
Desc: 3626387582-osrf_json_object_c_5.patch
Url : http://list.georgialibraries.org/pipermail/open-ils-dev/attachments/20071216/29216102/osrf_json_object_c_5.bin


More information about the Open-ils-dev mailing list