Jansson string handling

480 views
Skip to first unread message

Vish

unread,
Jul 18, 2014, 5:58:10 AM7/18/14
to jansso...@googlegroups.com

I am having difficulty handling strings and arrays in jansson.

unsigned char number[10]; // contains a hex array using upto 6 bytes

Now I did

json_object_set_new(foo,"bar",json_string(number));

This results in an empty json object.

I have also tried this

number[6]='\0';

followed by

json_object_set_new(foo,"bar",json_string(number));

yet the result is same. I can not undestand why.


Graeme Smecher

unread,
Jul 18, 2014, 11:53:27 AM7/18/14
to jansso...@googlegroups.com
Hi Vish,

First, I don't think your problems are specifically related to Jansson's
string handling. You will probably get better and faster help by writing
similar code in a more general forum (for example, stackexchange), and
without using jansson functions.

Now, I'm trying to figure out your example code. Can you describe the
output you're expecting to see?

Comments in-line.

On Fri, 2014-07-18 at 02:58 -0700, Vish wrote:
> I am having difficulty handling strings and arrays in jansson.
>
>
> unsigned char number[10]; // contains a hex array using upto 6 bytes

What do you mean by "hex array"? If you're using up to 6 bytes, why is
your array of length 10? (What number should it be? Hint: probably not
6!)

>
> Now I did
>
> json_object_set_new(foo,"bar",json_string(number));
>
> This results in an empty json object.

Your string (number) is uninitialized, so its contents are
unpredictable. You should not expect your code to behave reliably unless
"number" contains a valid C string.

>
> I have also tried this
>
> number[6]='\0';
>
> followed by
>
> json_object_set_new(foo,"bar",json_string(number));
>
> yet the result is same. I can not undestand why.

Likewise, it's hard to say from the code you've posted. Since "number"
is uninitialized, it's unlikely to make sense as a string. In this
context, setting number[6] is unlikely to change much.

Can you post a complete example, including initialization of the object
"foo" and dumping the resulting JSON object? It should only be a few
lines longer than the code you already posted, and will let us converge
on a good starting point for you to build on.

best,
Graeme



Vish

unread,
Jul 22, 2014, 3:10:39 AM7/22/14
to jansso...@googlegroups.com
Here is the format in which data will be processed[
[
    {
        "name": "abcd",
        "value": "abcdefghijkl"
      },
    {
        "name":"efgh",
       "value" : "xyzsqwertyui"
    },
    ...
]

This is the data structure

struct data 
{
   unsigned char name[2];
   unsigned char value[6];
   struct data*next;
};

The name and value contains hex strings which will be decoded in the server using hex2bin php function (wanted to minimise data transfer between server and client)
In the main function an object of this structure will be looped over to gather data and it will be called into json_object_set 

Here is the code,

main()
{
       json_t *root =json_object();
       // var is the structure object
       while(var->next!=NULL)
      {
             json_t *temp=json_object();
             json_object_set(temp,"name",json_string(var->name));
//here json_string returns null
             json_object_set(temp,"value",json_string(var->value));
//here json_string returns null
               ..........
               .........
               ..........
       }

I dont know why json_string is failing.

the number variable used in the first post was some trial and error done on my part.

We are forced to use hex since there will be bulk packet transfers so we want to minimise data size of each packet as much as we can and there are many more variables in struct data.

Thanks

Petri Lehtinen

unread,
Jul 23, 2014, 3:36:03 AM7/23/14
to jansso...@googlegroups.com
Vish wrote:
> This is the data structure
>
> struct data
> {
> unsigned char name[2];
> unsigned char value[6];
> struct data*next;
> };
>

(snip)

> Here is the code,
>
> main()
> {
> json_t *root =json_object();
> // var is the structure object
> while(var->next!=NULL)
> {
> json_t *temp=json_object();
> json_object_set(temp,"name",json_string(var->name));
> //here json_string returns null
> json_object_set(temp,"value",json_string(var->value));
> //here json_string returns null
> ..........
> .........
> ..........
> }
>
> I dont know why json_string is failing.
>
> the number variable used in the first post was some trial and error done on my

Are the name and value strings null terminated? If not, Jansson will
try to read past their end (overflow) and probably encounters an
invalid UTF-8 code unit, and thus fails with an error.

If you're using latest Jansson from git, you can circumvent this by
using json_stringn() which takes a length and thus doesn't require
input strings to be null terminated.

Petri

Graeme Smecher

unread,
Jul 25, 2014, 1:12:04 AM7/25/14
to jansso...@googlegroups.com
Hi Vish,

I've pasted a complete example at the end of this e-mail that works for
me. (It doesn't include any error checking!)

First off, I'm still not sure your structures are appropriately sized --
your example strings require 5 bytes for "name" and 13 bytes for
"example", and they're too long for the structure defined in your code.
For this data, you need at least:

struct data {
char name[5];
char value[13];
struct data*next;
};

Please make sure you understand why the numbers are 5 and 13, not 4 and
12! String overruns are the kind of thing that can break code that
otherwise looks just fine. If you can't guarantee your strings will fit
in the structure, use pointers instead of fixed-length buffers. (Again,
this is a C question, not a jansson question, so you're better off
asking for help on stackoverflow.com or elsewhere.)

Also, note that "root" is actually an array, not an object, in your JSON
code. That means you should use json_array() and related functions to
construct it.

Also, your code used "json_object_set" to construct "temp". You should
look into Jansson's reference-counting mechanism and make sure you
aren't leaking references (and therefore leaking memory). The code below
uses json_object_set_new() instead. Valgrind is a great tool for
tracking and catching memory leaks.

Finally, you can simplify the contents of your loop by using json_pack()
instead of json_object methods. I'll leave this as an exercise to you.

best,
Graeme

---

#include <jansson.h>
#include <stdio.h>

struct data {
const char name[2];
const char value[6];
struct data *next;
} test_data[] = {
{
.name = "a",
.value = "bcdef",
.next = test_data+1,
}, {
.name = "b",
.value = "cdefg",
.next = NULL,
},
};

int main(void)
{
struct data *var;
json_t *root = json_array();
char *out;

for(var=test_data; var; var=var->next) {
json_t *temp=json_object();
json_object_set_new(temp,"name",json_string(var->name));
json_object_set_new(temp,"value",json_string(var->value));
json_array_append_new(root, temp);
}

out = json_dumps(root, JSON_INDENT(1));
json_decref(root);
puts(out);
free(out);
return(0);
> --
> --
> Jansson users mailing list
> jansso...@googlegroups.com
> http://groups.google.com/group/jansson-users
> ---
> You received this message because you are subscribed to the Google
> Groups "Jansson users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to jansson-user...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Vish

unread,
Aug 26, 2014, 3:32:41 AM8/26/14
to jansso...@googlegroups.com
Update,

Since Jansson was not working,I finally coded up a custom JSON creator in C.

Thank you Petri and Graeme for your time.
Reply all
Reply to author
Forward
0 new messages