cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
{
    cJSON *patch = 0;
    if (!to)
    {
        /* patch to delete everything */
        return cJSON_CreateNull();
    }
    if ((to->type != cJSON_Object) || !from || (from->type != cJSON_Object))
    {
        return cJSON_Duplicate(to, 1);
    }

    cJSONUtils_SortObject(from);
    cJSONUtils_SortObject(to);

    from = from->child;
    to = to->child;
    patch = cJSON_CreateObject();
    while (from || to)
    {
        int compare = from ? (to ? strcmp(from->string, to->string) : -1) : 1;
        if (compare < 0)
        {
            /* from has a value that to doesn't have -> remove */
            cJSON_AddItemToObject(patch, from->string, cJSON_CreateNull());
            from = from->next;
        }
        else if (compare > 0)
        {
            /* to has a value that from doesn't have -> add to patch */
            cJSON_AddItemToObject(patch, to->string, cJSON_Duplicate(to, 1));
            to = to->next;
        }
        else
        {
            /* object key exists in both objects */
            if (cJSONUtils_Compare(from, to))
            {
                /* not identical --> generate a patch */
                cJSON_AddItemToObject(patch, to->string, cJSONUtils_GenerateMergePatch(from, to));
            }
            /* next key in the object */
            from = from->next;
            to = to->next;
        }
    }
    if (!patch->child)
    {
        cJSON_Delete(patch);
        return 0;
    }

    return patch;
}
cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
{
    if (!patch || (patch->type != cJSON_Object))
    {
        /* scalar value, array or NULL, just duplicate */
        cJSON_Delete(target);
        return cJSON_Duplicate(patch, 1);
    }

    if (!target || (target->type != cJSON_Object))
    {
        cJSON_Delete(target);
        target = cJSON_CreateObject();
    }

    patch = patch->child;
    while (patch)
    {
        if (patch->type == cJSON_NULL)
        {
            /* NULL is the indicator to remove a value, see RFC7396 */
            cJSON_DeleteItemFromObject(target, patch->string);
        }
        else
        {
            cJSON *replaceme = cJSON_DetachItemFromObject(target, patch->string);
            cJSON_AddItemToObject(target, patch->string, cJSONUtils_MergePatch(replaceme, patch));
        }
        patch = patch->next;
    }
    return target;
}
Beispiel #3
0
static void compose_patch(cJSON * const patches, const unsigned char * const operation, const unsigned char * const path, const unsigned char *suffix, const cJSON * const value)
{
    cJSON *patch = cJSON_CreateObject();
    if (patch == NULL)
    {
        return;
    }
    cJSON_AddItemToObject(patch, "op", cJSON_CreateString((const char*)operation));

    if (suffix == NULL)
    {
        cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)path));
    }
    else
    {
        size_t suffix_length = pointer_encoded_length(suffix);
        size_t path_length = strlen((const char*)path);
        unsigned char *full_path = (unsigned char*)cJSON_malloc(path_length + suffix_length + sizeof("/"));

        sprintf((char*)full_path, "%s/", (const char*)path);
        encode_string_as_pointer(full_path + path_length + 1, suffix);

        cJSON_AddItemToObject(patch, "path", cJSON_CreateString((const char*)full_path));
        cJSON_free(full_path);
    }

    if (value != NULL)
    {
        cJSON_AddItemToObject(patch, "value", cJSON_Duplicate(value, 1));
    }
    cJSON_AddItemToArray(patches, patch);
}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
	cJSON *newitem,*cptr,*nptr=0,*newchild;
	/* Bail on bad ptr */
	if (!item) return 0;
	/* Create new item */
	newitem=cJSON_New_Item();
	if (!newitem) return 0;
	/* Copy over all vars */
	newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
	if (item->valuestring)	{newitem->valuestring=cJSON_strdup(item->valuestring);	if (!newitem->valuestring)	{cJSON_Delete(newitem);return 0;}}
	if (item->string)		{newitem->string=cJSON_strdup(item->string);			if (!newitem->string)		{cJSON_Delete(newitem);return 0;}}
	/* If non-recursive, then we're done! */
	if (!recurse) return newitem;
	/* Walk the ->next chain for the child. */
	cptr=item->child;
	while (cptr)
	{
		newchild=cJSON_Duplicate(cptr,1);		/* Duplicate (with recurse) each item in the ->next chain */
		if (!newchild) {cJSON_Delete(newitem);return 0;}
		if (nptr)	{nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}	/* If newitem->child already set, then crosswire ->prev and ->next and move on */
		else		{newitem->child=newchild;nptr=newchild;}					/* Set newitem->child and move to it */
		cptr=cptr->next;
	}
	return newitem;
}
Beispiel #5
0
static cJSON *merge_patch(cJSON *target, const cJSON * const patch, const cJSON_bool case_sensitive)
{
    cJSON *patch_child = NULL;

    if (!cJSON_IsObject(patch))
    {
        /* scalar value, array or NULL, just duplicate */
        cJSON_Delete(target);
        return cJSON_Duplicate(patch, 1);
    }

    if (!cJSON_IsObject(target))
    {
        cJSON_Delete(target);
        target = cJSON_CreateObject();
    }

    patch_child = patch->child;
    while (patch_child != NULL)
    {
        if (cJSON_IsNull(patch_child))
        {
            /* NULL is the indicator to remove a value, see RFC7396 */
            if (case_sensitive)
            {
                cJSON_DeleteItemFromObjectCaseSensitive(target, patch_child->string);
            }
            else
            {
                cJSON_DeleteItemFromObject(target, patch_child->string);
            }
        }
        else
        {
            cJSON *replace_me = NULL;
            cJSON *replacement = NULL;

            if (case_sensitive)
            {
                replace_me = cJSON_DetachItemFromObjectCaseSensitive(target, patch_child->string);
            }
            else
            {
                replace_me = cJSON_DetachItemFromObject(target, patch_child->string);
            }

            replacement = merge_patch(replace_me, patch_child, case_sensitive);
            if (replacement == NULL)
            {
                return NULL;
            }

            cJSON_AddItemToObject(target, patch_child->string, replacement);
        }
        patch_child = patch_child->next;
    }
    return target;
}
Beispiel #6
0
/*-------------------------------------------------------------------
Function: GenerateOutData();
Purpose: 通过比较现有数据跟原有数据,产生要输出的字符串.
Parameters: 
Return: 0 --- successful, -1 --- failed
-------------------------------------------------------------------*/
int CRedWoodDataParse::GenerateOutData(void)
{
    int iRet = 0;

    if (!oldDataJson) 
        return GenerateOutDataFromJson(updatedDataJson);
    else {
        assert(updatedDataJson);

        cJSON* outJson = NULL;
        outJson = cJSON_Duplicate(updatedDataJson, 1);
        if (!outJson)
            return -1;

        cJSON* newJsonFixture = NULL;
        cJSON* oldJsonFixture = NULL;

        newJsonFixture = cJSON_GetObjectItem(outJson, "fixture");
        oldJsonFixture = cJSON_GetObjectItem(oldDataJson, "fixture");

        if (!newJsonFixture || !oldJsonFixture) {
            cJSON_Delete(outJson);
            return -1;
        }        

        int iDataLen = 0;
        iDataLen = cJSON_GetArraySize(newJsonFixture); 

        assert(iDataLen == cJSON_GetArraySize(oldJsonFixture));

        //比较 fixture 节点的 每个子节点,如果相同,则从输出中删除
        for (int i = iDataLen - 1; i >= 0; i--) {
            cJSON* oldJsonTemp = cJSON_GetArrayItem(oldJsonFixture, i);
            cJSON* newJsonTemp = cJSON_GetArrayItem(newJsonFixture, i);

            char* pOldDataTemp = cJSON_Print(oldJsonTemp);
            char* pNewDataTemp = cJSON_Print(newJsonTemp);

            if (strcmp(pOldDataTemp, pNewDataTemp) == 0)
                cJSON_DeleteItemFromArray(newJsonFixture, i);

            free(pOldDataTemp);
            free(pNewDataTemp);
        }

        //改变输出的数据个数
        if (iDataLen != cJSON_GetArraySize(newJsonFixture)) {
            iDataLen = cJSON_GetArraySize(newJsonFixture); 
            cJSON_ReplaceItemInObject(outJson, "data length", cJSON_CreateNumber(iDataLen));
        }

        //生成目标字符串,以便输出
        iRet = GenerateOutDataFromJson(outJson);
        cJSON_Delete(outJson);
    }

    return iRet;
}
Beispiel #7
0
susiaccess_packet_body_t * SAManager_WrapAutoReportPacket(Handler_info const * plugin, void const * const requestData, unsigned int const requestLen, bool bCust)
{
	PJSON ReqInfoJSON = NULL;
	char* pReqInfoPayload = NULL;
	susiaccess_packet_body_t* packet = NULL;

	cJSON* node = NULL;
	cJSON* root = NULL;
	cJSON* pfinfoNode = NULL;
	char* buff = NULL;
	char* data = NULL;
	int length = 0;

	if(plugin == NULL)
		return packet;
	if(plugin->agentInfo == NULL)
		return packet;

	if(requestData)
	{
		data = ConvertMessageToUTF8(requestData);
	}

	root = cJSON_CreateObject();
	pfinfoNode = cJSON_CreateObject();
	//node = cJSON_Parse((const char *)requestData);
	node = cJSON_Parse((const char *)data);
	free(data);
	
	if(pfinfoNode)
	{
		cJSON* chNode = node->child;
		cJSON_AddItemToObject(pfinfoNode, chNode->string, cJSON_Duplicate(chNode, true));	
	}
	cJSON_Delete(node);
	cJSON_AddItemToObject(root, "data", pfinfoNode);
	buff = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);
	length = strlen(buff);
	
	packet = malloc(sizeof(susiaccess_packet_body_t));
	memset(packet, 0, sizeof(susiaccess_packet_body_t));
	packet->content = (char*)malloc(length+1);
	memset(packet->content, 0, length+1);
	memcpy(packet->content, buff, length);

	free(buff);

	strcpy(packet->devId, plugin->agentInfo->devId);
	strcpy(packet->handlerName, "general");  //Special case for auto report.

	packet->requestID = cagent_action_general;

	packet->cmd = general_info_upload_rep;
	//SAManagerLog(g_samanagerlogger, Normal, "Parser_CreateRequestInfo");

	return packet;
}
Beispiel #8
0
/*-------------------------------------------------------------------
Function: UpdateData();
Purpose: Upatate json data from raw json. For user, ParseFromStr 
         should be called before called this function.
Parameters: 
Return: 0 --- successful, -1 --- failed
-------------------------------------------------------------------*/
int CRedWoodDataParse::UpdateData(void)
{
    if (!rawJson)
        return -1;

    //save data gotten last time
    if (updatedDataJson) {
        if (oldDataJson) {
            cJSON_Delete(oldDataJson);
            oldDataJson = NULL;
        }

        oldDataJson = updatedDataJson;
    }
    
    //create new json from raw data
    cJSON* fixtureJson = NULL;    //son 'fuxture' of rawjson
    int iDataCount = 0;
    cJSON* srcJson = NULL;
    cJSON* descJson = NULL;       //as variable to save fixture
    cJSON* srcJsonTemp = NULL;
    cJSON* descJsonTemp = NULL;

    fixtureJson = cJSON_GetObjectItem(rawJson, "fixture");
    if (!fixtureJson)
        return -1;

    iDataCount = cJSON_GetArraySize(fixtureJson); 

    updatedDataJson = cJSON_CreateObject();	
    cJSON_AddStringToObject(updatedDataJson, "version", TRANSER_JSON_VERSION);
    cJSON_AddNumberToObject(updatedDataJson, "data length", iDataCount);
    cJSON_AddNumberToObject(updatedDataJson, "currentTime", 
                            cJSON_GetObjectItem(rawJson, "currentTime")->valueint);

    cJSON_AddItemToObject(updatedDataJson, "fixture",  
        descJson = cJSON_CreateArray());

    //create each sub json
    for (int i = 0; i < iDataCount; i++) {        
        srcJsonTemp = cJSON_GetArrayItem(fixtureJson, i);
        descJsonTemp = cJSON_Duplicate(srcJsonTemp, 1);
        cJSON_AddItemToArray(descJson, descJsonTemp);

        //将要保存目标结点的 sensorStats 节点删除
        cJSON_DeleteItemFromObject(descJsonTemp, "sensorStats");

        //将原有数据的 sensorStats 节点中的数据经转化保存到 目标结点
        AddSensorDataToJson(cJSON_GetObjectItem(srcJsonTemp, "sensorStats"), descJsonTemp);        
    }

    GenerateFullOutDataFromJson(updatedDataJson);

    return 0;
}
void conference_event_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id)
{
	char *domain = NULL, *name = NULL;
	conference_obj_t *conference = NULL;
	cJSON *data, *reply = NULL, *conference_desc = NULL;
	const char *action = NULL;
	char *dup = NULL;

	if ((data = cJSON_GetObjectItem(json, "data"))) {
		action = cJSON_GetObjectCstr(data, "action");
	}

	if (!action) action = "";

	reply = cJSON_Duplicate(json, 1);
	cJSON_DeleteItemFromObject(reply, "data");

	if ((name = strchr(event_channel, '.'))) {
		dup = strdup(name + 1);
		switch_assert(dup);
		name = dup;

		if ((domain = strchr(name, '@'))) {
			*domain++ = '\0';
		}
	}

	if (!strcasecmp(action, "bootstrap")) {
		if (!zstr(name) && (conference = conference_find(name, domain))) {
			conference_desc = conference_cdr_json_render(conference, json);
		} else {
			conference_desc = cJSON_CreateObject();
			json_add_child_string(conference_desc, "conferenceDescription", "FreeSWITCH Conference");
			json_add_child_string(conference_desc, "conferenceState", "inactive");
			json_add_child_array(conference_desc, "users");
			json_add_child_array(conference_desc, "oldUsers");
		}
	} else {
		conference_desc = cJSON_CreateObject();
		json_add_child_string(conference_desc, "error", "Invalid action");
	}

	json_add_child_string(conference_desc, "action", "conferenceDescription");

	cJSON_AddItemToObject(reply, "data", conference_desc);

	switch_safe_free(dup);

	switch_event_channel_broadcast(event_channel, &reply, "mod_conference", conference_globals.event_channel_id);
}
Beispiel #10
0
int32_t PLUGNAME(_process_json)(char *forwarder,char *sender,int32_t valid,struct plugin_info *plugin,uint64_t tag,char *retbuf,int32_t maxlen,char *jsonstr,cJSON *json,int32_t initflag,char *tokenstr)
{
    char *SuperNET_install(char *plugin,char *jsonstr,cJSON *json);
    char *retstr,*resultstr,*methodstr,*destplugin;
    int32_t len;
    retbuf[0] = 0;
    //printf("<<<<<<<<<<<< INSIDE PLUGIN.(%s)! (%s) initflag.%d process %s\n",plugin->name,jsonstr,initflag,plugin->name);
    if ( initflag > 0 )
    {
        SUPERNET.ppid = OS_getppid();
        SUPERNET.argjson = cJSON_Duplicate(json,1);
        SUPERNET.readyflag = 1;
        if ( SUPERNET.UPNP != 0 )
        {
            char portstr[64];
            sprintf(portstr,"%d",SUPERNET.serviceport), upnpredirect(portstr,portstr,"TCP","SuperNET");
            sprintf(portstr,"%d",SUPERNET.port + LB_OFFSET), upnpredirect(portstr,portstr,"TCP","SuperNET");
            sprintf(portstr,"%d",SUPERNET.port + PUBGLOBALS_OFFSET), upnpredirect(portstr,portstr,"TCP","SuperNET");
            sprintf(portstr,"%d",SUPERNET.port + PUBRELAYS_OFFSET), upnpredirect(portstr,portstr,"TCP","SuperNET");
        }
    }
    else
    {
        if ( plugin_result(retbuf,json,tag) > 0 )
            return((int32_t)strlen(retbuf));
        methodstr = cJSON_str(cJSON_GetObjectItem(json,"method"));
        resultstr = cJSON_str(cJSON_GetObjectItem(json,"result"));
        if ( (destplugin= cJSON_str(cJSON_GetObjectItem(json,"name"))) == 0 )
            destplugin = cJSON_str(cJSON_GetObjectItem(json,"path"));
        printf("SUPERNET\n");
        if ( resultstr != 0 && strcmp(resultstr,"registered") == 0 )
        {
            plugin->registered = 1;
            retstr = "return registered";
        }
        else if ( methodstr != 0 && strcmp(methodstr,"install") == 0 && destplugin != 0 && destplugin[0] != 0 )
            retstr = SuperNET_install(destplugin,jsonstr,json);
        else retstr = "return JSON result";
        strcpy(retbuf,retstr);
        len = (int32_t)strlen(retbuf);
        while ( --len > 0 )
            if ( retbuf[len] == '}' )
                break;
        sprintf(retbuf + len,",\"debug\":%d,\"USESSL\":%d,\"MAINNET\":%d,\"DATADIR\":\"%s\",\"NXTAPI\":\"%s\",\"WEBSOCKETD\":\"%s\",\"SUPERNET_PORT\":%d,\"APISLEEP\":%d,\"domain\":\"%s\"}",Debuglevel,SUPERNET.usessl,SUPERNET.ismainnet,SUPERNET.DATADIR,SUPERNET.NXTAPIURL,SUPERNET.WEBSOCKETD,SUPERNET.port,SUPERNET.APISLEEP,SUPERNET.hostname);
    }
    return((int32_t)strlen(retbuf));
}
Beispiel #11
0
static void cJSONUtils_GeneratePatch(cJSON *patches, const char *op, const char *path, const char *suffix, cJSON *val)
{
    cJSON *patch = cJSON_CreateObject();
    cJSON_AddItemToObject(patch, "op", cJSON_CreateString(op));
    if (suffix)
    {
        char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(suffix) + 2);
        cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), suffix);
        cJSON_AddItemToObject(patch, "path", cJSON_CreateString(newpath));
        free(newpath);
    }
    else
    {
        cJSON_AddItemToObject(patch, "path", cJSON_CreateString(path));
    }
    if (val)
    {
        cJSON_AddItemToObject(patch, "value", cJSON_Duplicate(val, 1));
    }
    cJSON_AddItemToArray(patches, patch);
}
Beispiel #12
0
/*-------------------------------------------------------------------
 Function: genFromDevArrayJson(json_devArray)
 Purpose: generate json data from dev list json
 Parameters: json_devArray -- [IN], dev list json in json file
 return: 0 -- success
         -1 -- failed
-------------------------------------------------------------------*/
int CEhJsonReader::genFromDevArrayJson(cJSON* json_devArray)
{
    cJSON* json_dev = NULL;
    cJSON* json_addrArray = NULL;
    cJSON* json_addr = NULL;
    int devCount = 0;
    int addrCount = 0;
    int devPos = 0;
    int addrPos = 0;

    if (!json_devArray)
        return -1;

    if (!m_jsonTransData)
        m_jsonTransData = cJSON_CreateArray();

    devCount = cJSON_GetArraySize(json_devArray);
    for (devPos = 0; devPos < devCount; devPos++) {
        json_dev = cJSON_GetArrayItem(json_devArray, devPos);
        if (!json_dev)
            return -1;

        json_addrArray = cJSON_GetObjectItem(json_dev, JSONADDRESS);
        if (!json_addrArray)
            return -1;

        addrCount = cJSON_GetArraySize(json_addrArray);
        for (addrPos = 0; addrPos < addrCount; addrPos++) {
            json_addr = cJSON_GetArrayItem(json_addrArray, addrPos);

            //copy
            cJSON_AddItemToArray(m_jsonTransData, 
                cJSON_Duplicate(json_addr, 1));
        }
    }

    return 0;
}
Beispiel #13
0
struct coin777 *coin777_create(char *coinstr,cJSON *argjson)
{
    char *serverport,*path=0,*conf=0; struct destbuf tmp;
    struct coin777 *coin = calloc(1,sizeof(*coin));
    if ( coinstr == 0 || coinstr[0] == 0 )
    {
        printf("null coinstr?\n");
        //getchar();
        return(0);
    }
    safecopy(coin->name,coinstr,sizeof(coin->name));
    coin->jvin = -1;
    if ( argjson == 0 || strcmp(coinstr,"NXT") == 0 )
    {
        coin->usep2sh = 1;
        coin->minconfirms = (strcmp("BTC",coinstr) == 0) ? 3 : 10;
        coin->estblocktime = (strcmp("BTC",coinstr) == 0) ? 600 : 120;
        coin->mgw.use_addmultisig = (strcmp("BTC",coinstr) != 0);
    }
    else
    {
        coin->minoutput = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"minoutput"));
        coin->minconfirms = get_API_int(cJSON_GetObjectItem(argjson,"minconfirms"),(strcmp("BTC",coinstr) == 0) ? 3 : 10);
        coin->estblocktime = get_API_int(cJSON_GetObjectItem(argjson,"estblocktime"),(strcmp("BTC",coinstr) == 0) ? 600 : 120);
        coin->jsonstr = cJSON_Print(argjson);
        coin->argjson = cJSON_Duplicate(argjson,1);
        if ( (serverport= cJSON_str(cJSON_GetObjectItem(argjson,"rpc"))) != 0 )
            safecopy(coin->serverport,serverport,sizeof(coin->serverport));
        path = cJSON_str(cJSON_GetObjectItem(argjson,"path"));
        conf = cJSON_str(cJSON_GetObjectItem(argjson,"conf"));

        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"assetid")), safecopy(coin->mgw.assetidstr,tmp.buf,sizeof(coin->mgw.assetidstr));
        if ( (coin->mgw.assetidbits= calc_nxt64bits(coin->mgw.assetidstr)) == 0 )
            coin->mgw.assetidbits = is_MGWcoin(coinstr);
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"issuer")), safecopy(coin->mgw.issuer,tmp.buf,sizeof(coin->mgw.issuer));;
        coin->mgw.issuerbits = conv_acctstr(coin->mgw.issuer);
        printf(">>>>>>>>>>>> a issuer.%s %llu assetid.%llu minoutput.%llu\n",coin->mgw.issuer,(long long)coin->mgw.issuerbits,(long long)coin->mgw.assetidbits,(long long)coin->minoutput);
        //uint32_t set_assetname(uint64_t *multp,char *name,uint64_t assetbits);
        if ( coin->mgw.assetidbits != 0 )
            _set_assetname(&coin->mgw.ap_mult,coin->mgw.assetname,0,coin->mgw.assetidbits);
        printf("assetname.(%s) mult.%llu\n",coin->mgw.assetname,coin->mgw.ap_mult);
        strcpy(coin->mgw.coinstr,coinstr);
        if ( (coin->mgw.special= cJSON_GetObjectItem(argjson,"special")) == 0 )
            coin->mgw.special = cJSON_GetObjectItem(COINS.argjson,"special");
        if ( coin->mgw.special != 0 )
        {
            coin->mgw.special = NXT_convjson(coin->mgw.special);
            printf("CONVERTED.(%s)\n",cJSON_Print(coin->mgw.special));
        }
        coin->mgw.limbo = cJSON_GetObjectItem(argjson,"limbo");
        coin->mgw.dust = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"dust"));
        coin->mgw.txfee = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"txfee_satoshis"));
        if ( coin->mgw.txfee == 0 )
            coin->mgw.txfee = (uint64_t)(SATOSHIDEN * get_API_float(cJSON_GetObjectItem(argjson,"txfee")));
        coin->mgw.NXTfee_equiv = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"NXTfee_equiv_satoshis"));
        if ( coin->mgw.NXTfee_equiv == 0 )
            coin->mgw.NXTfee_equiv = (uint64_t)(SATOSHIDEN * get_API_float(cJSON_GetObjectItem(argjson,"NXTfee_equiv")));
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"opreturnmarker")), safecopy(coin->mgw.opreturnmarker,tmp.buf,sizeof(coin->mgw.opreturnmarker));
        printf("OPRETURN.(%s)\n",coin->mgw.opreturnmarker);
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"marker2")), safecopy(coin->mgw.marker2,tmp.buf,sizeof(coin->mgw.marker2));
        coin->mgw.redeemheight = get_API_int(cJSON_GetObjectItem(argjson,"redeemheight"),430000);
        coin->mgw.use_addmultisig = get_API_int(cJSON_GetObjectItem(argjson,"useaddmultisig"),(strcmp("BTC",coinstr) != 0));
        coin->mgw.do_opreturn = get_API_int(cJSON_GetObjectItem(argjson,"do_opreturn"),(strcmp("BTC",coinstr) == 0));
        coin->mgw.oldtx_format = get_API_int(cJSON_GetObjectItem(argjson,"oldtx_format"),(strcmp("BTC",coinstr) == 0));
        coin->mgw.firstunspentind = get_API_int(cJSON_GetObjectItem(argjson,"firstunspent"),(strcmp("BTCD",coinstr) == 0) ? 2500000 : 0);
        if ( (coin->mgw.NXTconvrate = get_API_float(cJSON_GetObjectItem(argjson,"NXTconvrate"))) == 0 )
        {
            if ( coin->mgw.NXTfee_equiv != 0 && coin->mgw.txfee != 0 )
                coin->mgw.NXTconvrate = ((double)coin->mgw.NXTfee_equiv / coin->mgw.txfee);
        }
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"marker")), safecopy(coin->mgw.marker,tmp.buf,sizeof(coin->mgw.marker));
        printf("OPRETURN.(%s)\n",coin->mgw.opreturnmarker);
        coin->addrtype = get_API_int(jobj(argjson,"addrtype"),0);
        coin->p2shtype = get_API_int(jobj(argjson,"p2shtype"),0);
        coin->usep2sh = get_API_int(jobj(argjson,"usep2sh"),1);
    }
    if ( coin->mgw.txfee == 0 )
        coin->mgw.txfee = 10000;
    if ( strcmp(coin->name,"BTC") == 0 )
    {
        coin->addrtype = 0, coin->p2shtype = 5;
        if ( coin->donationaddress[0] == 0 )
        {
            strcpy(coin->donationaddress,"177MRHRjAxCZc7Sr5NViqHRivDu1sNwkHZ");
            sprintf(coin->donationscript,"76a91443044b8d5dc8f3758dbc83374c596e96d25ead4f88ac");
        }
    }
    else if ( strcmp(coin->name,"LTC") == 0 )
        coin->addrtype = 48, coin->p2shtype = 5, coin->minconfirms = 1, coin->mgw.txfee = 100000, coin->usep2sh = 0;
    else if ( strcmp(coin->name,"BTCD") == 0 )
        coin->addrtype = 60, coin->p2shtype = 85, coin->mgw.txfee = 1000000;//, strcpy(coin->donationaddress,"RDRWMSrDdoUcfZRBWUz7KZQSxPS9bZRerM");
    else if ( strcmp(coin->name,"DOGE") == 0 )
        coin->addrtype = 30, coin->p2shtype = 35;
    else if ( strcmp(coin->name,"VRC") == 0 )
        coin->addrtype = 70, coin->p2shtype = 85;
    else if ( strcmp(coin->name,"OPAL") == 0 )
        coin->addrtype = 115, coin->p2shtype = 28;
    else if ( strcmp(coin->name,"BITS") == 0 )
        coin->addrtype = 25, coin->p2shtype = 8;
    printf("coin777_create %s: (%s) %llu mult.%llu NXTconvrate %.8f minconfirms.%d issuer.(%s) %llu opreturn.%d oldformat.%d\n",coin->mgw.coinstr,coin->mgw.assetidstr,(long long)coin->mgw.assetidbits,(long long)coin->mgw.ap_mult,coin->mgw.NXTconvrate,coin->minconfirms,coin->mgw.issuer,(long long)coin->mgw.issuerbits,coin->mgw.do_opreturn,coin->mgw.oldtx_format);
    if ( strcmp(coin->name,"NXT") != 0 )
    {
        extract_userpass(coin->serverport,coin->userpass,coinstr,SUPERNET.userhome,path,conf);
        set_atomickeys(coin);
        printf("COIN.%s serverport.(%s) userpass.(%s) %s/%s %s/%s\n",coin->name,coin->serverport,coin->userpass,coin->atomicrecv,coin->atomicrecvpubkey,coin->atomicsend,coin->atomicsendpubkey);
    }
    COINS.LIST = realloc(COINS.LIST,(COINS.num+1) * sizeof(*coin));
    COINS.LIST[COINS.num] = coin, COINS.num++;
    //ensure_packedptrs(coin);
    return(coin);
}
Beispiel #14
0
struct coin777 *coin777_create(char *coinstr,cJSON *argjson)
{
    char *serverport,*path=0,*conf=0; struct destbuf tmp;
    struct coin777 *coin = calloc(1,sizeof(*coin));
    safecopy(coin->name,coinstr,sizeof(coin->name));
    if ( argjson == 0 )
    {
        coin->minconfirms = (strcmp("BTC",coinstr) == 0) ? 3 : 10;
        coin->estblocktime = (strcmp("BTC",coinstr) == 0) ? 600 : 120;
    }
    else
    {
        coin->minoutput = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"minoutput"));
        coin->minconfirms = get_API_int(cJSON_GetObjectItem(argjson,"minconfirms"),(strcmp("BTC",coinstr) == 0) ? 3 : 10);
        coin->estblocktime = get_API_int(cJSON_GetObjectItem(argjson,"estblocktime"),(strcmp("BTC",coinstr) == 0) ? 600 : 120);
        coin->jsonstr = cJSON_Print(argjson);
        coin->argjson = cJSON_Duplicate(argjson,1);
        if ( (serverport= cJSON_str(cJSON_GetObjectItem(argjson,"rpc"))) != 0 )
            safecopy(coin->serverport,serverport,sizeof(coin->serverport));
        path = cJSON_str(cJSON_GetObjectItem(argjson,"path"));
        conf = cJSON_str(cJSON_GetObjectItem(argjson,"conf"));

        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"assetid")), safecopy(coin->mgw.assetidstr,tmp.buf,sizeof(coin->mgw.assetidstr));
        coin->mgw.assetidbits = calc_nxt64bits(coin->mgw.assetidstr);
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"issuer")), safecopy(coin->mgw.issuer,tmp.buf,sizeof(coin->mgw.issuer));;
        coin->mgw.issuerbits = conv_acctstr(coin->mgw.issuer);
        printf(">>>>>>>>>>>> a issuer.%s %llu assetid.%llu minoutput.%llu\n",coin->mgw.issuer,(long long)coin->mgw.issuerbits,(long long)coin->mgw.assetidbits,(long long)coin->minoutput);
        //uint32_t set_assetname(uint64_t *multp,char *name,uint64_t assetbits);
        _set_assetname(&coin->mgw.ap_mult,coin->mgw.assetname,0,coin->mgw.assetidbits);
        printf("assetname.(%s) mult.%llu\n",coin->mgw.assetname,coin->mgw.ap_mult);
        strcpy(coin->mgw.coinstr,coinstr);
        if ( (coin->mgw.special= cJSON_GetObjectItem(argjson,"special")) == 0 )
            coin->mgw.special = cJSON_GetObjectItem(COINS.argjson,"special");
        if ( coin->mgw.special != 0 )
            coin->mgw.special = NXT_convjson(coin->mgw.special);
        printf("CONVERTED.(%s)\n",cJSON_Print(coin->mgw.special));
        coin->mgw.limbo = cJSON_GetObjectItem(argjson,"limbo");
        coin->mgw.dust = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"dust"));
        coin->mgw.txfee = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"txfee_satoshis"));
        if ( coin->mgw.txfee == 0 )
            coin->mgw.txfee = (uint64_t)(SATOSHIDEN * get_API_float(cJSON_GetObjectItem(argjson,"txfee")));
        if ( coin->mgw.txfee == 0 )
            coin->mgw.txfee = 10000;
        coin->mgw.NXTfee_equiv = get_API_nxt64bits(cJSON_GetObjectItem(argjson,"NXTfee_equiv_satoshis"));
        if ( coin->mgw.NXTfee_equiv == 0 )
            coin->mgw.NXTfee_equiv = (uint64_t)(SATOSHIDEN * get_API_float(cJSON_GetObjectItem(argjson,"NXTfee_equiv")));
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"opreturnmarker")), safecopy(coin->mgw.opreturnmarker,tmp.buf,sizeof(coin->mgw.opreturnmarker));
        printf("OPRETURN.(%s)\n",coin->mgw.opreturnmarker);
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"marker2")), safecopy(coin->mgw.marker2,tmp.buf,sizeof(coin->mgw.marker2));
        coin->mgw.redeemheight = get_API_int(cJSON_GetObjectItem(argjson,"redeemheight"),430000);
        coin->mgw.use_addmultisig = get_API_int(cJSON_GetObjectItem(argjson,"useaddmultisig"),(strcmp("BTC",coinstr) != 0));
        coin->mgw.do_opreturn = get_API_int(cJSON_GetObjectItem(argjson,"do_opreturn"),(strcmp("BTC",coinstr) == 0));
        coin->mgw.oldtx_format = get_API_int(cJSON_GetObjectItem(argjson,"oldtx_format"),(strcmp("BTC",coinstr) == 0));
        coin->mgw.firstunspentind = get_API_int(cJSON_GetObjectItem(argjson,"firstunspent"),(strcmp("BTCD",coinstr) == 0) ? 2500000 : 0);
        if ( (coin->mgw.NXTconvrate = get_API_float(cJSON_GetObjectItem(argjson,"NXTconvrate"))) == 0 )
        {
            if ( coin->mgw.NXTfee_equiv != 0 && coin->mgw.txfee != 0 )
                coin->mgw.NXTconvrate = ((double)coin->mgw.NXTfee_equiv / coin->mgw.txfee);
        }
        copy_cJSON(&tmp,cJSON_GetObjectItem(argjson,"marker")), safecopy(coin->mgw.marker,tmp.buf,sizeof(coin->mgw.marker));
        printf("OPRETURN.(%s)\n",coin->mgw.opreturnmarker);
    }
    printf("coin777_create %s: (%s) %llu mult.%llu NXTconvrate %.8f minconfirms.%d issuer.(%s) %llu opreturn.%d oldformat.%d\n",coin->mgw.coinstr,coin->mgw.assetidstr,(long long)coin->mgw.assetidbits,(long long)coin->mgw.ap_mult,coin->mgw.NXTconvrate,coin->minconfirms,coin->mgw.issuer,(long long)coin->mgw.issuerbits,coin->mgw.do_opreturn,coin->mgw.oldtx_format);
    extract_userpass(coin->serverport,coin->userpass,coinstr,SUPERNET.userhome,path,conf);
    printf("COIN.%s serverport.(%s) userpass.(%s)\n",coin->name,coin->serverport,coin->userpass);
    COINS.LIST = realloc(COINS.LIST,(COINS.num+1) * sizeof(*coin));
    COINS.LIST[COINS.num] = coin, COINS.num++;
    //ensure_packedptrs(coin);
    return(coin);
}
Beispiel #15
0
int32_t PLUGNAME(_process_json)(char *forwarder,char *sender,int32_t valid,struct plugin_info *plugin,uint64_t tag,char *retbuf,int32_t maxlen,char *jsonstr,cJSON *json,int32_t initflag,char *tokenstr)
{
    char *resultstr,*methodstr,zerobuf[1],*coinstr,*str = 0; cJSON *array,*item; int32_t i,n,j = 0; struct coin777 *coin; struct destbuf tmp;
    retbuf[0] = 0;
    if ( initflag > 0 )
    {
        if ( json != 0 )
        {
            COINS.argjson = cJSON_Duplicate(json,1);
            COINS.slicei = get_API_int(cJSON_GetObjectItem(json,"slice"),0);
            if ( (array= cJSON_GetObjectItem(json,"coins")) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
            {
                for (i=j=0; i<n; i++)
                {
                    item = cJSON_GetArrayItem(array,i);
                    coinstr = cJSON_str(cJSON_GetObjectItem(item,"name"));
                    if ( coinstr != 0 && coinstr[0] != 0 && (coin= coin777_find(coinstr,0)) == 0 )
                    {
                        printf("CALL coin777_create.(%s) (%s)\n",coinstr,cJSON_Print(item));
                        coin777_create(coinstr,item);
                    }
                }
            }
        } else strcpy(retbuf,"{\"result\":\"no JSON for init\"}");
        COINS.readyflag = 1;
        plugin->allowremote = 1;
        //plugin->sleepmillis = 1;
    }
    else
    {
        if ( plugin_result(retbuf,json,tag) > 0 )
            return((int32_t)strlen(retbuf));
        resultstr = cJSON_str(cJSON_GetObjectItem(json,"result"));
        methodstr = cJSON_str(cJSON_GetObjectItem(json,"method"));
        coinstr = cJSON_str(cJSON_GetObjectItem(json,"coin"));
        if ( methodstr == 0 || methodstr[0] == 0 )
        {
            printf("(%s) has not method\n",jsonstr);
            return(0);
        }
        //printf("COINS.(%s) for (%s) (%s)\n",methodstr,coinstr!=0?coinstr:"",jsonstr);
        if ( resultstr != 0 && strcmp(resultstr,"registered") == 0 )
        {
            plugin->registered = 1;
            strcpy(retbuf,"{\"result\":\"activated\"}");
        }
        else
        {
            zerobuf[0] = 0;
            str = 0;
            //printf("INSIDE COINS.(%s) methods.%ld\n",jsonstr,sizeof(coins_methods)/sizeof(*coins_methods));
            copy_cJSON(&tmp,cJSON_GetObjectItem(json,"NXT")), safecopy(sender,tmp.buf,32);
            if ( coinstr == 0 )
                coinstr = zerobuf;
            else coin = coin777_find(coinstr,1);
#ifdef INSIDE_MGW
            if ( strcmp(methodstr,"acctpubkeys") == 0 )
            {
                if ( SUPERNET.gatewayid >= 0 )
                {
                    if ( coinstr[0] == 0 )
                        strcpy(retbuf,"{\"result\":\"need to specify coin\"}");
                    else if ( (coin= coin777_find(coinstr,1)) != 0 )
                    {
                        int32_t MGW_publish_acctpubkeys(char *coinstr,char *str);
                        char *get_msig_pubkeys(char *coinstr,char *serverport,char *userpass);
                        if ( (str= get_msig_pubkeys(coin->name,coin->serverport,coin->userpass)) != 0 )
                        {
                            MGW_publish_acctpubkeys(coin->name,str);
                            strcpy(retbuf,"{\"result\":\"published and processed acctpubkeys\"}");
                            free(str), str= 0;
                        } else sprintf(retbuf,"{\"error\":\"no get_msig_pubkeys result\",\"method\":\"%s\"}",methodstr);
                    } else sprintf(retbuf,"{\"error\":\"no coin777\",\"method\":\"%s\"}",methodstr);
                } else sprintf(retbuf,"{\"error\":\"gateway only method\",\"method\":\"%s\"}",methodstr);
            }
            else if ( strcmp(methodstr,"gotmsigaddr") == 0 )
            {
                if ( SUPERNET.gatewayid < 0 )
                    printf("GOTMSIG.(%s)\n",jsonstr);
            }
            else
#endif
                sprintf(retbuf,"{\"error\":\"unsupported method\",\"method\":\"%s\"}",methodstr);
        }
    }
    //printf("<<<<<<<<<<<< INSIDE PLUGIN.(%s) initflag.%d process %s slice.%d\n",SUPERNET.myNXTaddr,initflag,plugin->name,COINS.slicei);
    return(plugin_copyretstr(retbuf,maxlen,str));
}
Beispiel #16
0
int SAParser_ParseRecvMessage(void* data, int datalen, susiaccess_packet_body_t * pkt)
{
	/*{"susiCommData":{"commCmd":251,"catalogID":4,"requestID":10}}*/

	cJSON* root = NULL;
	cJSON* body = NULL;
	cJSON* target = NULL;
	cJSON* content = NULL;

	if(!data) return false;

	if(!pkt) return false;

	memset(pkt, 0 , sizeof(susiaccess_packet_body_t));

	root = cJSON_Parse(data);
	if(!root) return false;

	body = cJSON_GetObjectItem(root, BASICINFO_BODY_STRUCT);
	if(!body)
	{
		cJSON_Delete(root);
		return false;
	}

	target = body->child;
	while (target)
	{
		if(!strcmp(target->string, BASICINFO_CMDTYPE))
			pkt->cmd = target->valueint;
		else if(!strcmp(target->string, BASICINFO_REQID))
			pkt->requestID = target->valueint;
		else if(!strcmp(target->string, BASICINFO_AGENTID))
			strcpy(pkt->devId, target->valuestring);
		else if(!strcmp(target->string, BASICINFO_HANDLERNAME))
			strcpy(pkt->handlerName, target->valuestring);
		else if(!strcmp(target->string, BASICINFO_CATALOG))
		{
			//pkt->catalogID = target->valueint;
		}
		else
		{
			if(!content)
				content = cJSON_CreateObject();

			cJSON_AddItemToObject(content, target->string, cJSON_Duplicate(target,true));
		}
		target = target->next;
	}

	if(content)
	{
		char* strcontent = cJSON_PrintUnformatted(content);
		cJSON_Delete(content);
		pkt->content = _strdup(strcontent);
		free(strcontent);
	}

	cJSON_Delete(root);
	return true;
}
Beispiel #17
0
int main(int argc, char **argv)
{
    void portable_OS_init();
    CGI_varlist *varlist; const char *name; char namebuf[512],postbuf[65536],*remoteaddr,*str=0,*retstr,*delim,*url = 0;
    int i,j,iter,localaccess=0,doneflag=0,portflag = 0; cJSON *json; long offset; CGI_value  *value; struct destbuf urlbuf;
    portable_OS_init();
    setenv("CONTENT_TYPE", "application/x-www-form-urlencoded", 1);
    json = cJSON_CreateObject();
    if ( (remoteaddr= getenv("REMOTE_ADDR")) == 0 || strncmp("127.0.0.1",remoteaddr,strlen("127.0.0.1")) == 0 )
        remoteaddr = 0,localaccess = 1;
    else cJSON_AddItemToObject(json,"remoteaddr",cJSON_CreateString(remoteaddr));
    for (i=j=0; argv[0][i]!=0; i++)
        if ( argv[0][i] == '/' || argv[0][i] == '\\' )
            j = i+1;
    strcpy(namebuf,&argv[0][j]);
    offset = strlen(namebuf) - 4;
    if ( offset > 0 && strcmp(".exe",namebuf + offset) == 0 )
        namebuf[offset] = 0;
    if ( offset > 0 && strcmp(".cgi",namebuf + offset) == 0 )
        namebuf[offset] = 0;
    if ( strcmp(namebuf,"init") == 0 || strcmp(namebuf,"") == 0 || strcmp(namebuf,"index.cgi") == 0 )
    {
        // "http://178.63.60.131/init/?requestType=status&coin=VRC"
        //"http://78.47.115.250:7777/public?plugin=relay&method=busdata&servicename=MGW&serviceNXT=8119557380101451968&destplugin=MGW&submethod=status&coin=BTC"
        if ( strcmp(namebuf,"api") != 0 )
            cJSON_AddItemToObject(json,"agent",cJSON_CreateString(namebuf));
        cJSON_AddItemToObject(json,"plugin",cJSON_CreateString("relay"));
        cJSON_AddItemToObject(json,"method",cJSON_CreateString("busdata"));
        cJSON_AddItemToObject(json,"servicename",cJSON_CreateString("MGW"));
        cJSON_AddItemToObject(json,"serviceNXT",cJSON_CreateString("8119557380101451968"));
        cJSON_AddItemToObject(json,"destplugin",cJSON_CreateString("MGW"));
        if ( jstr(json,"requestType") != 0 )
            cJSON_AddItemToObject(json,"submethod",cJSON_CreateString(jstr(json,"requestType")));
    }
    if ( strcmp("nxt",namebuf) == 0 )
    {
        if ( setnxturl(&urlbuf) != 0 )
            url = urlbuf.buf;
        else url = "http://127.0.0.1:7876/nxt";
    }
    else if ( strcmp("nxts",namebuf) == 0 )
        url = "https://127.0.0.1:7876/nxt";
    else if ( strcmp("port",namebuf) == 0 )
        url = "http://127.0.0.1", portflag = 1;
    else if ( strcmp("ports",namebuf) == 0 )
        url = "https://127.0.0.1", portflag = 1;
    fprintf(stderr,"namebuf.(%s)\n",namebuf);
    if ( url != 0 )
         postbuf[0] = 0, delim = "";
    for (iter=0; iter<3; iter++)
    {
        if ( (varlist= ((iter==0) ? CGI_get_post(0,0) : ((iter==1) ? CGI_get_query(0) : CGI_get_cookie(0)))) != 0 )
        {
            for (name=CGI_first_name(varlist); name!=0&&doneflag==0; name=CGI_next_name(varlist))
            {
                value = CGI_lookup_all(varlist,0);
                for (i=0; value[i]!=0; i++)
                {
                fprintf(stderr,"iter.%d %s [%d] = %s\r\n",iter,name,i,value[i]);
                    if ( i == 0 )
                    {
                        if ( url == 0 )
                        {
                            if ( strcmp(name,"stringified") == 0 || strcmp(namebuf,"stringified") == 0 )
                            {
                                char *unstringify(char *str);
                                cJSON *obj;
                                if ( (obj= cJSON_Parse(name)) == 0 )
                                {
                                    str = malloc(strlen(value[i])+1);
                                    strcpy(str,value[i]);
                                    unstringify(str);
                                    printf("unstringify (%s) -> (%s)\n",value[i],str);
                                    obj= cJSON_Parse(str);
                                }
                                if ( obj != 0 )
                                {
                                    //unstringified ((null)) -> ({"stringified":{"method":"orderbook","baseid":"12071612744977229797","relid":"5527630","maxdepth":"1"},"agent":"InstantDEX"})
                                    free_json(json);
                                    if ( jobj(obj,"stringified") != 0 )
                                        json = cJSON_Duplicate(jobj(obj,"stringified"),1), free_json(obj);
                                    else json = obj;
                                    cJSON_AddItemToObject(json,"agent",cJSON_CreateString("InstantDEX"));
                                    if ( remoteaddr != 0 && remoteaddr[0] != 0 )
                                        cJSON_AddItemToObject(json,"remoteaddr",cJSON_CreateString(remoteaddr));
                                    fprintf(stderr,"unstringified (%s) -> (%s)\n",str!=0?str:"",jprint(json,0));
                                    if ( str != 0 )
                                        free(str);
                                    doneflag = 1;
                                    break;
                                }
                            }
                            cJSON_AddItemToObject(json,name,cJSON_CreateString(value[i]));
                        }
                        else
                        {
                            if ( portflag != 0 && strncmp(name,"port",strlen("port")) == 0 )
                                sprintf(urlbuf.buf,"%s:%s",url,value[i]), url = urlbuf.buf, portflag = 0;
                            else sprintf(postbuf + strlen(postbuf),"%s%s=%s",delim,name,value[i]), delim = "&";
                        }
                    }
                }
            }
        }
        CGI_free_varlist(varlist);
    }
    if ( localaccess == 0 )
        fputs("Access-Control-Allow-Origin: *\r\n",stdout);
    else fputs("Access-Control-Allow-Origin: null\r\n",stdout);
    fputs("Access-Control-Allow-Credentials: true\r\n",stdout);
    fputs("Access-Control-Allow-Headers: Authorization, Content-Type\r\n",stdout);
    fputs("Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n",stdout);
    fputs("Cache-Control: no-cache, no-store, must-revalidate\r\n",stdout);
    fputs("Content-type: text/plain\r\n",stdout);
    if ( url != 0 )
    {
fprintf(stderr,"url.(%s) (%s)\n",url,postbuf);
        if ( (retstr= issue_POST(url,postbuf)) != 0 )
        {
            //fprintf(stderr,"%s",retstr);
            printf("Content-Length: %ld\r\n\r\n",strlen(retstr)+2);
            printf("%s\r\n",retstr);
            free(retstr);
        } else printf("{\"error\":\"null return from issue_NXTPOST\"}\r\n");
    }
    else
    {
        if ( jobj(json,"agent") == 0 && strcmp(namebuf,"api") != 0 )
            cJSON_AddItemToObject(json,"agent",cJSON_CreateString(namebuf));
        fprintf(stderr,"PROCESS.(%s)\n",jprint(json,0));
        process_json(json,remoteaddr,localaccess);
    }
    free_json(json);
    return 0;
}
Beispiel #18
0
cJSON *jduplicate(cJSON *json) { return(cJSON_Duplicate(json,1)); }
Beispiel #19
0
int ctx_links(int argc, char **argv)
{
  size_t limit = 0;
  const char *link_out_path = NULL, *csv_out_path = NULL, *plot_out_path = NULL;
  const char *thresh_path = NULL, *hist_path = NULL;

  size_t hist_distsize = 0, hist_covgsize = 0;
  size_t cutoff = 0;
  bool clean = false;

  // Arg parsing
  char cmd[100];
  char shortopts[300];
  cmd_long_opts_to_short(longopts, shortopts, sizeof(shortopts));
  int c;

  while((c = getopt_long_only(argc, argv, shortopts, longopts, NULL)) != -1) {
    cmd_get_longopt_str(longopts, c, cmd, sizeof(cmd));
    switch(c) {
      case 0: /* flag set */ break;
      case 'h': cmd_print_usage(NULL); break;
      case 'o': cmd_check(!link_out_path, cmd); link_out_path = optarg; break;
      case 'f': cmd_check(!futil_get_force(), cmd); futil_set_force(true); break;
      case 'l': cmd_check(!csv_out_path, cmd); csv_out_path = optarg; break;
      case 'c': cmd_check(!cutoff, cmd); cutoff = cmd_size(cmd, optarg); clean = true; break;
      case 'L': cmd_check(!limit, cmd); limit = cmd_size(cmd, optarg); break;
      case 'P': cmd_check(!plot_out_path, cmd); plot_out_path = optarg; break;
      case 'T': cmd_check(!thresh_path, cmd); thresh_path = optarg; break;
      case 'H': cmd_check(!hist_path, cmd); hist_path = optarg; break;
      case 'C': cmd_check(!hist_covgsize, cmd); hist_covgsize = cmd_size(cmd, optarg); break;
      case 'D': cmd_check(!hist_distsize, cmd); hist_distsize = cmd_size(cmd, optarg); break;
      case ':': /* BADARG */
      case '?': /* BADCH getopt_long has already printed error */
        // cmd_print_usage(NULL);
        die("`"CMD" links -h` for help. Bad option: %s", argv[optind-1]);
      default: ctx_assert2(0, "shouldn't reach here: %c", c);
    }
  }

  if(hist_distsize && !hist_path) cmd_print_usage("--max-dist without --covg-hist");
  if(hist_covgsize && !hist_path) cmd_print_usage("--max-covg without --covg-hist");

  // Defaults
  if(!hist_distsize) hist_distsize = DEFAULT_MAX_DIST;
  if(!hist_covgsize) hist_covgsize = DEFAULT_MAX_COVG;

  if(optind + 1 != argc) cmd_print_usage("Wrong number of arguments");
  const char *ctp_path = argv[optind];

  bool list = (csv_out_path != NULL);
  bool plot = (plot_out_path != NULL);
  bool save = (link_out_path != NULL);
  bool hist_covg = (thresh_path != NULL || hist_path != NULL);

  size_t plot_kmer_idx = (limit == 0 ? 0 : limit - 1);

  if(clean && !save)
    cmd_print_usage("Need to give --out <out.ctp.gz> with --clean");

  if(!save && !list && !plot && !hist_covg)
    cmd_print_usage("Please specify one of --plot, --list or --clean");

  if(link_out_path && hist_covg && strcmp(link_out_path,"-") == 0)
    cmd_print_usage("Outputing both cleaning threshold (-T) and links (-o) to STDOUT!");

  // Open input file
  FILE *list_fh = NULL, *plot_fh = NULL, *link_tmp_fh = NULL;
  FILE *thresh_fh = NULL, *hist_fh = NULL;
  gzFile link_gz = NULL;

  // Check file don't exist or that we can overwrite
  // Will ignore if path is null
  bool err = false;
  err |= futil_check_outfile(csv_out_path);
  err |= futil_check_outfile(plot_out_path);
  err |= futil_check_outfile(link_out_path);
  err |= futil_check_outfile(thresh_path);
  err |= futil_check_outfile(hist_path);
  if(err) die("Use -f,--force to overwrite files");

  StrBuf link_tmp_path;
  strbuf_alloc(&link_tmp_path, 1024);

  GPathReader ctpin;
  memset(&ctpin, 0, sizeof(ctpin));
  gpath_reader_open(&ctpin, ctp_path);

  size_t ncols = file_filter_into_ncols(&ctpin.fltr);
  size_t kmer_size = gpath_reader_get_kmer_size(&ctpin);
  cJSON *newhdr = cJSON_Duplicate(ctpin.json, 1);

  if(ncols != 1) die("Can only clean a single colour at a time. Sorry.");

  uint64_t (*hists)[hist_covgsize] = NULL;

  if(hist_covg) {
    hists = ctx_calloc(hist_distsize, sizeof(hists[0]));
  }

  if(hist_path && (hist_fh = futil_fopen_create(hist_path, "w")) == NULL)
      die("Cannot open file: %s", hist_path);

  if(thresh_path && (thresh_fh = futil_fopen_create(thresh_path, "w")) == NULL)
      die("Cannot open file: %s", thresh_path);

  if(limit)
    status("Limiting to the first %zu kmers", limit);

  if(clean)
  {
    timestamp();
    message(" Cleaning coverage below %zu", cutoff);
    message("\n");
  }

  if(save)
  {
    // Check we can find the fields we need
    cJSON *links_json  = json_hdr_get(newhdr, "paths", cJSON_Object, link_out_path);
    cJSON *nkmers_json = json_hdr_get(links_json, "num_kmers_with_paths", cJSON_Number, link_out_path);
    cJSON *nlinks_json = json_hdr_get(links_json, "num_paths",            cJSON_Number, link_out_path);
    cJSON *nbytes_json = json_hdr_get(links_json, "path_bytes",           cJSON_Number, link_out_path);
    if(!nkmers_json || !nlinks_json || !nbytes_json)
      die("Cannot find required header entries");

    // Create a random temporary file
    link_tmp_fh = create_tmp_file(&link_tmp_path, link_out_path);

    status("Saving output to: %s", link_out_path);
    status("Temporary output: %s", link_tmp_path.b);

    // Open output file
    if((link_gz = futil_gzopen_create(link_out_path, "w")) == NULL)
      die("Cannot open output link file: %s", link_out_path);

    // Need to open output file first so we can get absolute path
    // Update the header to include this command
    json_hdr_add_curr_cmd(newhdr, link_out_path);
  }

  if(list)
  {
    status("Listing to %s", csv_out_path);
    if((list_fh = futil_fopen_create(csv_out_path, "w")) == NULL)
      die("Cannot open output CSV file %s", csv_out_path);

    // Print csv header
    fprintf(list_fh, "SeqLen,Covg\n");
  }

  if(plot)
  {
    status("Plotting kmer %zu to %s", plot_kmer_idx, plot_out_path);
    if((plot_fh = futil_fopen_create(plot_out_path, "w")) == NULL)
      die("Cannot open output .dot file %s", plot_out_path);
  }

  SizeBuffer countbuf, jposbuf;
  size_buf_alloc(&countbuf, 16);
  size_buf_alloc(&jposbuf, 1024);

  StrBuf kmerbuf, juncsbuf, seqbuf, outbuf;
  strbuf_alloc(&kmerbuf, 1024);
  strbuf_alloc(&juncsbuf, 1024);
  strbuf_alloc(&seqbuf, 1024);
  strbuf_alloc(&outbuf, 1024);

  bool link_fw;
  size_t njuncs;
  size_t knum, nlinks, num_links_exp = 0;

  LinkTree ltree;
  ltree_alloc(&ltree, kmer_size);

  LinkTreeStats tree_stats;
  memset(&tree_stats, 0, sizeof(tree_stats));
  size_t init_num_links = 0, num_links = 0;

  for(knum = 0; !limit || knum < limit; knum++)
  {
    ltree_reset(&ltree);
    if(!gpath_reader_read_kmer(&ctpin, &kmerbuf, &num_links_exp)) break;
    ctx_assert2(kmerbuf.end == kmer_size, "Kmer incorrect length %zu != %zu",
                kmerbuf.end, kmer_size);
    // status("kmer: %s", kmerbuf.b);

    for(nlinks = 0;
        gpath_reader_read_link(&ctpin, &link_fw, &njuncs,
                               &countbuf, &juncsbuf,
                               &seqbuf, &jposbuf);
        nlinks++)
    {
      ltree_add(&ltree, link_fw, countbuf.b[0], jposbuf.b,
                juncsbuf.b, seqbuf.b);
    }

    if(nlinks != num_links_exp)
      warn("Links count mismatch %zu != %zu", nlinks, num_links_exp);

    if(hist_covg)
    {
      ltree_update_covg_hists(&ltree, (uint64_t*)hists,
                              hist_distsize, hist_covgsize);
    }
    if(clean)
    {
      ltree_clean(&ltree, cutoff);
    }

    // Accumulate statistics
    ltree_get_stats(&ltree, &tree_stats);
    num_links = tree_stats.num_links - init_num_links;
    init_num_links = tree_stats.num_links;

    if(list)
    {
      ltree_write_list(&ltree, &outbuf);
      if(fwrite(outbuf.b, 1, outbuf.end, list_fh) != outbuf.end)
        die("Cannot write CSV file to: %s", csv_out_path);
      strbuf_reset(&outbuf);
    }
    if(save && num_links)
    {
      ltree_write_ctp(&ltree, kmerbuf.b, num_links, &outbuf);
      if(fwrite(outbuf.b, 1, outbuf.end, link_tmp_fh) != outbuf.end)
        die("Cannot write ctp file to: %s", link_tmp_path.b);
      strbuf_reset(&outbuf);
    }
    if(plot && knum == plot_kmer_idx)
    {
      status("Plotting tree...");
      ltree_write_dot(&ltree, &outbuf);
      if(fwrite(outbuf.b, 1, outbuf.end, plot_fh) != outbuf.end)
        die("Cannot write plot DOT file to: %s", plot_out_path);
      strbuf_reset(&outbuf);
    }
  }

  gpath_reader_close(&ctpin);

  cJSON *links_json = json_hdr_get(newhdr, "paths", cJSON_Object, link_out_path);
  cJSON *nkmers_json = json_hdr_get(links_json, "num_kmers_with_paths", cJSON_Number, link_out_path);
  cJSON *nlinks_json = json_hdr_get(links_json, "num_paths",            cJSON_Number, link_out_path);
  cJSON *nbytes_json = json_hdr_get(links_json, "path_bytes",           cJSON_Number, link_out_path);

  status("Number of kmers with links %li -> %zu", nkmers_json->valueint, tree_stats.num_trees_with_links);
  status("Number of links %li -> %zu", nlinks_json->valueint, tree_stats.num_links);
  status("Number of bytes %li -> %zu", nbytes_json->valueint, tree_stats.num_link_bytes);

  if(save)
  {
    // Update JSON
    nkmers_json->valuedouble = nkmers_json->valueint = tree_stats.num_trees_with_links;
    nlinks_json->valuedouble = nlinks_json->valueint = tree_stats.num_links;
    nbytes_json->valuedouble = nbytes_json->valueint = tree_stats.num_link_bytes;

    char *json_str = cJSON_Print(newhdr);
    if(gzputs(link_gz, json_str) != (int)strlen(json_str))
      die("Cannot write ctp file to: %s", link_out_path);
    free(json_str);

    gzputs(link_gz, "\n\n");
    gzputs(link_gz, ctp_explanation_comment);
    gzputs(link_gz, "\n");

    fseek(link_tmp_fh, 0, SEEK_SET);
    char *tmp = ctx_malloc(4*ONE_MEGABYTE);
    size_t s;
    while((s = fread(tmp, 1, 4*ONE_MEGABYTE, link_tmp_fh)) > 0) {
      if(gzwrite(link_gz, tmp, s) != (int)s)
        die("Cannot write to output: %s", link_out_path);
    }
    ctx_free(tmp);

    gzclose(link_gz);
    fclose(link_tmp_fh);
  }

  // Write histogram to file
  if(hist_fh)
  {
    size_t i, j;
    fprintf(hist_fh, "  ");
    for(j = 1; j < hist_covgsize; j++) fprintf(hist_fh, ",covg.%02zu", j);
    fprintf(hist_fh, "\n");
    for(i = 1; i < hist_distsize; i++) {
      fprintf(hist_fh, "dist.%02zu", i);
      for(j = 1; j < hist_covgsize; j++) {
        fprintf(hist_fh, ",%"PRIu64, hists[i][j]);
      }
      fprintf(hist_fh, "\n");
    }
  }

  if(thresh_fh)
  {
    // Use median of first five cutoffs
    print_suggest_cutoff(6, hist_covgsize, hists, thresh_fh);
  }

  if(hist_fh && hist_fh != stdout) fclose(hist_fh);

  if(list)
  {
    fclose(list_fh);
  }

  if(plot)
  {
    fclose(plot_fh);
  }

  ctx_free(hists);
  cJSON_Delete(newhdr);
  strbuf_dealloc(&link_tmp_path);
  ltree_dealloc(&ltree);
  size_buf_dealloc(&countbuf);
  size_buf_dealloc(&jposbuf);
  strbuf_dealloc(&kmerbuf);
  strbuf_dealloc(&juncsbuf);
  strbuf_dealloc(&seqbuf);
  strbuf_dealloc(&outbuf);

  return EXIT_SUCCESS;
}
Beispiel #20
0
static cJSON *generate_merge_patch(cJSON * const from, cJSON * const to, const cJSON_bool case_sensitive)
{
    cJSON *from_child = NULL;
    cJSON *to_child = NULL;
    cJSON *patch = NULL;
    if (to == NULL)
    {
        /* patch to delete everything */
        return cJSON_CreateNull();
    }
    if (!cJSON_IsObject(to) || !cJSON_IsObject(from))
    {
        return cJSON_Duplicate(to, 1);
    }

    sort_object(from, case_sensitive);
    sort_object(to, case_sensitive);

    from_child = from->child;
    to_child = to->child;
    patch = cJSON_CreateObject();
    while (from_child || to_child)
    {
        int diff;
        if (from_child != NULL)
        {
            if (to_child != NULL)
            {
                diff = strcmp(from_child->string, to_child->string);
            }
            else
            {
                diff = -1;
            }
        }
        else
        {
            diff = 1;
        }

        if (diff < 0)
        {
            /* from has a value that to doesn't have -> remove */
            cJSON_AddItemToObject(patch, from_child->string, cJSON_CreateNull());

            from_child = from_child->next;
        }
        else if (diff > 0)
        {
            /* to has a value that from doesn't have -> add to patch */
            cJSON_AddItemToObject(patch, to_child->string, cJSON_Duplicate(to_child, 1));

            to_child = to_child->next;
        }
        else
        {
            /* object key exists in both objects */
            if (!compare_json(from_child, to_child, case_sensitive))
            {
                /* not identical --> generate a patch */
                cJSON_AddItemToObject(patch, to_child->string, cJSONUtils_GenerateMergePatch(from_child, to_child));
            }

            /* next key in the object */
            from_child = from_child->next;
            to_child = to_child->next;
        }
    }
    if (patch->child == NULL)
    {
        /* no patch generated */
        cJSON_Delete(patch);
        return NULL;
    }

    return patch;
}
Beispiel #21
0
static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_sensitive)
{
    cJSON *path = NULL;
    cJSON *value = NULL;
    cJSON *parent = NULL;
    enum patch_operation opcode = INVALID;
    unsigned char *parent_pointer = NULL;
    unsigned char *child_pointer = NULL;
    int status = 0;

    path = get_object_item(patch, "path", case_sensitive);
    if (!cJSON_IsString(path))
    {
        /* malformed patch. */
        status = 2;
        goto cleanup;
    }

    opcode = decode_patch_operation(patch, case_sensitive);
    if (opcode == INVALID)
    {
        status = 3;
        goto cleanup;
    }
    else if (opcode == TEST)
    {
        /* compare value: {...} with the given path */
        status = !compare_json(get_item_from_pointer(object, path->valuestring, case_sensitive), get_object_item(patch, "value", case_sensitive), case_sensitive);
        goto cleanup;
    }

    /* special case for replacing the root */
    if (path->valuestring[0] == '\0')
    {
        if (opcode == REMOVE)
        {
            static const cJSON invalid = { NULL, NULL, NULL, cJSON_Invalid, NULL, 0, 0, NULL};

            overwrite_item(object, invalid);

            status = 0;
            goto cleanup;
        }

        if ((opcode == REPLACE) || (opcode == ADD))
        {
            value = get_object_item(patch, "value", case_sensitive);
            if (value == NULL)
            {
                /* missing "value" for add/replace. */
                status = 7;
                goto cleanup;
            }

            value = cJSON_Duplicate(value, 1);
            if (value == NULL)
            {
                /* out of memory for add/replace. */
                status = 8;
                goto cleanup;
            }

            overwrite_item(object, *value);

            /* delete the duplicated value */
            cJSON_free(value);
            value = NULL;

            /* the string "value" isn't needed */
            if (object->string != NULL)
            {
                cJSON_free(object->string);
                object->string = NULL;
            }

            status = 0;
            goto cleanup;
        }
    }

    if ((opcode == REMOVE) || (opcode == REPLACE))
    {
        /* Get rid of old. */
        cJSON *old_item = detach_path(object, (unsigned char*)path->valuestring, case_sensitive);
        if (old_item == NULL)
        {
            status = 13;
            goto cleanup;
        }
        cJSON_Delete(old_item);
        if (opcode == REMOVE)
        {
            /* For Remove, this job is done. */
            status = 0;
            goto cleanup;
        }
    }

    /* Copy/Move uses "from". */
    if ((opcode == MOVE) || (opcode == COPY))
    {
        cJSON *from = get_object_item(patch, "from", case_sensitive);
        if (from == NULL)
        {
            /* missing "from" for copy/move. */
            status = 4;
            goto cleanup;
        }

        if (opcode == MOVE)
        {
            value = detach_path(object, (unsigned char*)from->valuestring, case_sensitive);
        }
        if (opcode == COPY)
        {
            value = get_item_from_pointer(object, from->valuestring, case_sensitive);
        }
        if (value == NULL)
        {
            /* missing "from" for copy/move. */
            status = 5;
            goto cleanup;
        }
        if (opcode == COPY)
        {
            value = cJSON_Duplicate(value, 1);
        }
        if (value == NULL)
        {
            /* out of memory for copy/move. */
            status = 6;
            goto cleanup;
        }
    }
    else /* Add/Replace uses "value". */
    {
        value = get_object_item(patch, "value", case_sensitive);
        if (value == NULL)
        {
            /* missing "value" for add/replace. */
            status = 7;
            goto cleanup;
        }
        value = cJSON_Duplicate(value, 1);
        if (value == NULL)
        {
            /* out of memory for add/replace. */
            status = 8;
            goto cleanup;
        }
    }

    /* Now, just add "value" to "path". */

    /* split pointer in parent and child */
    parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring);
    child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/');
    if (child_pointer != NULL)
    {
        child_pointer[0] = '\0';
        child_pointer++;
    }
    parent = get_item_from_pointer(object, (char*)parent_pointer, case_sensitive);
    decode_pointer_inplace(child_pointer);

    /* add, remove, replace, move, copy, test. */
    if ((parent == NULL) || (child_pointer == NULL))
    {
        /* Couldn't find object to add to. */
        status = 9;
        goto cleanup;
    }
    else if (cJSON_IsArray(parent))
    {
        if (strcmp((char*)child_pointer, "-") == 0)
        {
            cJSON_AddItemToArray(parent, value);
            value = NULL;
        }
        else
        {
            size_t index = 0;
            if (!decode_array_index_from_pointer(child_pointer, &index))
            {
                status = 11;
                goto cleanup;
            }

            if (!insert_item_in_array(parent, index, value))
            {
                status = 10;
                goto cleanup;
            }
            value = NULL;
        }
    }
    else if (cJSON_IsObject(parent))
    {
        cJSON_DeleteItemFromObject(parent, (char*)child_pointer);
        cJSON_AddItemToObject(parent, (char*)child_pointer, value);
        value = NULL;
    }

cleanup:
    if (value != NULL)
    {
        cJSON_Delete(value);
    }
    if (parent_pointer != NULL)
    {
        cJSON_free(parent_pointer);
    }

    return status;
}
Beispiel #22
0
static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
{
    cJSON *op = 0;
    cJSON *path = 0;
    cJSON *value = 0;
    cJSON *parent = 0;
    int opcode = 0;
    char *parentptr = 0;
    char *childptr = 0;

    op = cJSON_GetObjectItem(patch, "op");
    path = cJSON_GetObjectItem(patch, "path");
    if (!op || !path)
    {
        /* malformed patch. */
        return 2;
    }

    /* decode operation */
    if (!strcmp(op->valuestring, "add"))
    {
        opcode = 0;
    }
    else if (!strcmp(op->valuestring, "remove"))
    {
        opcode = 1;
    }
    else if (!strcmp(op->valuestring, "replace"))
    {
        opcode = 2;
    }
    else if (!strcmp(op->valuestring, "move"))
    {
        opcode = 3;
    }
    else if (!strcmp(op->valuestring, "copy"))
    {
        opcode = 4;
    }
    else if (!strcmp(op->valuestring, "test"))
    {
        /* compare value: {...} with the given path */
        return cJSONUtils_Compare(cJSONUtils_GetPointer(object, path->valuestring), cJSON_GetObjectItem(patch, "value"));
    }
    else
    {
        /* unknown opcode. */
        return 3;
    }

    /* Remove/Replace */
    if ((opcode == 1) || (opcode == 2))
    {
        /* Get rid of old. */
        cJSON_Delete(cJSONUtils_PatchDetach(object, path->valuestring));
        if (opcode == 1)
        {
            /* For Remove, this is job done. */
            return 0;
        }
    }

    /* Copy/Move uses "from". */
    if ((opcode == 3) || (opcode == 4))
    {
        cJSON *from = cJSON_GetObjectItem(patch, "from");
        if (!from)
        {
            /* missing "from" for copy/move. */
            return 4;
        }

        if (opcode == 3)
        {
            /* move */
            value = cJSONUtils_PatchDetach(object, from->valuestring);
        }
        if (opcode == 4)
        {
            /* copy */
            value = cJSONUtils_GetPointer(object, from->valuestring);
        }
        if (!value)
        {
            /* missing "from" for copy/move. */
            return 5;
        }
        if (opcode == 4)
        {
            value = cJSON_Duplicate(value, 1);
        }
        if (!value)
        {
            /* out of memory for copy/move. */
            return 6;
        }
    }
    else /* Add/Replace uses "value". */
    {
        value = cJSON_GetObjectItem(patch, "value");
        if (!value)
        {
            /* missing "value" for add/replace. */
            return 7;
        }
        value = cJSON_Duplicate(value, 1);
        if (!value)
        {
            /* out of memory for add/replace. */
            return 8;
        }
    }

    /* Now, just add "value" to "path". */

    /* split pointer in parent and child */
    parentptr = cJSONUtils_strdup(path->valuestring);
    childptr = strrchr(parentptr, '/');
    if (childptr)
    {
        *childptr++ = '\0';
    }
    parent = cJSONUtils_GetPointer(object, parentptr);
    cJSONUtils_InplaceDecodePointerString(childptr);

    /* add, remove, replace, move, copy, test. */
    if (!parent)
    {
        /* Couldn't find object to add to. */
        free(parentptr);
        cJSON_Delete(value);
        return 9;
    }
    else if (parent->type == cJSON_Array)
    {
        if (!strcmp(childptr, "-"))
        {
            cJSON_AddItemToArray(parent, value);
        }
        else
        {
            cJSON_InsertItemInArray(parent, atoi(childptr), value);
        }
    }
    else if (parent->type == cJSON_Object)
    {
        cJSON_DeleteItemFromObject(parent, childptr);
        cJSON_AddItemToObject(parent, childptr, value);
    }
    else
    {
        cJSON_Delete(value);
    }
    free(parentptr);

    return 0;
}