Search code examples
cjsoncjson

I don't understand how to use cJSON to parse a JSON file into a struct


I have a fairly simple struct Message which contains two fields of type Envelope.

struct Envelope
{
    char* Payload; //Byte array of message data
    char* Signature; //Byte array for signature of endorser
};

struct Message
{
    char* configSeq; //Byte array config sequence
    Envelope* configMsg;
    Envelope* normalMsg;
};

Everything boils down to a byte array (represented as char* since C has no byte type)

I just want to use cJSON to read in a JSON file and deserialize it into a Message object. I have read the entire documentation on the cJSON github page but it doesn't say how to do this. Here is an example of what I want to do:

char* message = checkForMessage();
if (message) //If a message exists
{
    //Must parse as JSON
    cJSON* json = cJSON_Parse(message);
    Message* msg = //have json convert to Message type
    checkMessage<<<1, 1>>>(msg, time(0));
}

I've tried using the cJSON functions with object in their name but all those do is modify/return a cJSON*. I need to get it from a cJSON into a different struct.

Thanks for any help.


Solution

  • Use the valuestring member of the cJSON object to get string values, then just copy them into

    cJSON *str;
    str = cJSON_GetObjectItemCaseSensitive(json, "configSeq");
    msg.configSeq = strdup(str.valuestring);
    
    msg.configMsg = malloc(sizeof(*msg.configMsg));
    cJSON *configMsg = cJSON_GetObjectItemCaseSensitive(json, "configMsg");
    str = cJSON_GetObjectItemCaseSensitive(configMsg, "Payload");
    msg.configMsg->Payload = strdup(str.valuestring);
    str = cJSON_GetObjectItemCaseSensitive(configMsg, "Signature");
    msg.configMsg->Signature = strdup(str.valuestring);
    
    msg.normalMsg = malloc(sizeof(*msg.normalMsg));
    cJSON *normalMsg = cJSON_GetObjectItemCaseSensitive(json, "normalMsg");
    str = cJSON_GetObjectItemCaseSensitive(normaMsg, "Payload");
    msg.normalMsg->Payload = strdup(str.valuestring);
    str = cJSON_GetObjectItemCaseSensitive(normalMsg, "Signature");
    msg.normalMsg->Signature = strdup(str.valuestring);
    
    cJSON_Delete(json);
    

    The above code assumes that the message JSON looks something like this:

    {
      "configSeq": "String",
      "configMsg": {
        "Payload": "String",
        "Signature": "String"
      },
      "normalMsg": {
        "Payload": "String",
        "Signature": "String"
      }
    }