Browse Source

JANSSON: Improved support for JSON-Type "Integer", which can in fact be long (or even long long)

Carsten Bock 9 years ago
parent
commit
691e088fe5

+ 17 - 6
modules/jansson/README

@@ -10,7 +10,11 @@ Matthew Williams
 
    <[email protected]>
 
-   Copyright © 2013 Flowroute LLC (flowroute.com)
+Carsten Bock
+
+   <[email protected]>
+
+   Copyright © 2013 Flowroute LLC (flowroute.com)
      __________________________________________________________________
 
    Table of Contents
@@ -87,7 +91,7 @@ Chapter 1. Admin Guide
    3.4. jansson_array_size(key/path, src, dst)
    3.5. jansson_get_field(src, field_name, dst)
 
-3.1. jansson_get(key/path, src, dst)
+3.1.  jansson_get(key/path, src, dst)
 
    Copy the value at the location 'path' from the json object 'src' and
    store it in pvar 'dst'.
@@ -103,6 +107,9 @@ Chapter 1. Admin Guide
    the pvar is not changed. If it had a previous value, that value remains
    unchanged.
 
+   Note: For JSON-Integer values exceeding the C-Integer boundaries, a
+   String representing the number is returned.
+
    Example 1.1. jansson_get usage
 ...
 if(!jansson_get("inner.deep.list[3]", $var(myjson), "$var(n)")) {
@@ -111,7 +118,7 @@ if(!jansson_get("inner.deep.list[3]", $var(myjson), "$var(n)")) {
 xlog("L_INFO", "foo is $var(n)");
 ...
 
-3.2. jansson_set(type, key/path, value, result)
+3.2.  jansson_set(type, key/path, value, result)
 
    Insert 'value' as 'type' at location 'path' into 'result'.
 
@@ -122,6 +129,10 @@ xlog("L_INFO", "foo is $var(n)");
    as 'int', 'str', and 'obj'. 'value' is ignored when type is 'true',
    'false', or 'null'.
 
+   Note: If you want to insert a JSON-Integer value exceeding the
+   C-Integer boundaries (e.g. C-type long), the a the number can be
+   provided as a string.
+
    Example 1.2. jansson_set usage
 ...
 # create a new json object and put a string in it at key "mystr"
@@ -146,7 +157,7 @@ jansson_set("str", "myobj.foo", "baz", "$var(myjson)");
 :3.14159, "myobj":{"foo":"baz"}}'
 ...
 
-3.3. jansson_append(type, key/path, value, result)
+3.3.  jansson_append(type, key/path, value, result)
 
    Like jansson_set but can be used to append to arrays. It can also be
    used to combine two json objects.
@@ -180,7 +191,7 @@ jansson_append('obj', "", '{"a":1, "b":100}', "$var(newobj)");
 # $var(newobj) == '{"a":1,"b":100","c":3}';
 ...
 
-3.4. jansson_array_size(key/path, src, dst)
+3.4.  jansson_array_size(key/path, src, dst)
 
    Puts the size of the array in 'src' at location 'path' into the pvar
    'dst'.
@@ -212,7 +223,7 @@ while($var(count) < $var(appendme_size)) {
 }
 ...
 
-3.5. jansson_get_field(src, field_name, dst)
+3.5.  jansson_get_field(src, field_name, dst)
 
    Copy field 'field_name' from json object 'src' and store it in pvar
    'dst'.

+ 5 - 0
modules/jansson/doc/jansson.xml

@@ -23,6 +23,11 @@
 			<surname>Williams</surname>
 			<email>[email protected]</email>
 	    </editor>
+	    <editor>
+			<firstname>Carsten</firstname>
+			<surname>Bock</surname>
+			<email>[email protected]</email>
+	    </editor>
 	</authorgroup>
 	<copyright>
 	    <year>2013</year>

+ 6 - 0
modules/jansson/doc/jansson_admin.xml

@@ -72,6 +72,9 @@
  	    If the key/path can't be found in the JSON data structure, the pvar is not changed. If it had a previous
 	    value, that value remains unchanged.
         </para>
+        <para>
+            <emphasis>Note:</emphasis> For JSON-Integer values exceeding the C-Integer boundaries, a String representing the number is returned.
+        </para>
         <example>
         <title><function>jansson_get</function> usage</title>
         <programlisting format="linespecific">
@@ -98,6 +101,9 @@ xlog("L_INFO", "foo is $var(n)");
             Valid 'type' parameters are 'integer', 'real', 'string', 'object', 'array', 'true', 'false', and 'null'  as well as
             abbriviated names such as 'int', 'str', and 'obj'. 'value' is ignored when type is 'true', 'false', or 'null'.
         </para>
+        <para>
+            <emphasis>Note:</emphasis> If you want to insert a JSON-Integer value exceeding the C-Integer boundaries (e.g. C-type long), the a the number can be provided as a string.
+        </para>
         <example>
         <title><function>jansson_set</function> usage</title>
         <programlisting format="linespecific">

+ 1 - 1
modules/jansson/jansson_funcs.c

@@ -163,7 +163,7 @@ int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
 
 	}else if(STR_EQ_STATIC(type_s, "integer")
 				|| STR_EQ_STATIC(type_s, "int")) {
-		int i = strtol(value_s.s, &endptr, 10);
+		long long i = strtoll(value_s.s, &endptr, 10);
 		if(*endptr != '\0') {
 			ERR("parsing int failed for \"%s\"\n", value_s.s);
 			goto fail;

+ 16 - 3
modules/jansson/jansson_utils.c

@@ -23,6 +23,7 @@
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <jansson.h>
+#include <limits.h>
 
 #include "../../lvalue.h"
 
@@ -57,9 +58,21 @@ int jansson_to_val(pv_value_t* val, char** freeme, json_t* v) {
 		val->rs.len = strlen(value);
 		val->flags = PV_VAL_STR;
 	}else if(json_is_integer(v)) {
-		int value = json_integer_value(v);
-		val->ri = value;
-		val->flags = PV_TYPE_INT|PV_VAL_INT;
+		long long value = json_integer_value(v);
+		if ((value > INT_MAX) || (value < INT_MIN))  {
+			char* svalue = NULL;
+			if (asprintf(&svalue, "%"JSON_INTEGER_FORMAT, value) < 0) {
+				ERR("asprintf failed\n");
+				return -1;
+			}
+			*freeme = svalue;
+			val->rs.s = svalue;
+			val->rs.len = strlen(svalue);
+			val->flags = PV_VAL_STR;
+		} else {
+			val->ri = (int)value;
+			val->flags = PV_TYPE_INT|PV_VAL_INT;
+		}
 	}else if(json_is_null(v)) {
 		val->flags = PV_VAL_NULL;
 	}else {