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; }
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; }
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; }
/*------------------------------------------------------------------- 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; }
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; }
/*------------------------------------------------------------------- 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); }
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)); }
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); }
/*------------------------------------------------------------------- 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; }
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); }
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); }
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)); }
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; }
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; }
cJSON *jduplicate(cJSON *json) { return(cJSON_Duplicate(json,1)); }
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(<ree, 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(<ree); 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(<ree, 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(<ree, (uint64_t*)hists, hist_distsize, hist_covgsize); } if(clean) { ltree_clean(<ree, cutoff); } // Accumulate statistics ltree_get_stats(<ree, &tree_stats); num_links = tree_stats.num_links - init_num_links; init_num_links = tree_stats.num_links; if(list) { ltree_write_list(<ree, &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(<ree, 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(<ree, &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(<ree); size_buf_dealloc(&countbuf); size_buf_dealloc(&jposbuf); strbuf_dealloc(&kmerbuf); strbuf_dealloc(&juncsbuf); strbuf_dealloc(&seqbuf); strbuf_dealloc(&outbuf); return EXIT_SUCCESS; }
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; }
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; }
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; }