Esempio n. 1
0
int svrapp::client_ack(param_list * pl){
	
	log_out(log_debug, "client_ack::json (%s)\n", pl->content);	
	
	uint cnt_id = 0;
	char cnt_serial[128] = {0};
	if(parse_serial(pl->serial, cnt_id, cnt_serial, sizeof(cnt_serial)) < 0){
		log_out(log_error, "client_ack::json invalid serial %s\n", pl->serial);
		return -1;
	}
	
	
	std::map<uint, app_connection*>::iterator it =  m_cntmap.find(cnt_id);
	if (it == m_cntmap.end()){
		log_out(log_error, "client_ack::client(%u) is off\n", cnt_id);
		return -1;
	}
	
	cJSON * jserror  = cJSON_GetObjectItem(pl->json, "error");
	cJSON * jsreason = cJSON_GetObjectItem(pl->json, "reason");
	if(!jserror || !jsreason){
		log_out(log_error, "client_ack::no error item\n");
		return -1;
	}

	cJSON_DeleteItemFromObject(pl->jsdata, "device_id");
	cJSON_DeleteItemFromObject(pl->jsdata, "company_id");
	char * out = cJSON_PrintUnformatted(pl->jsdata);
	
	post_ack(it->second, pl->cmd, cnt_serial, 
		jserror->valueint, jsreason->valuestring, out);
	
	return 0;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
int svrapp::client_ack(param_list * pl){
	
	log_out(log_debug, "client_ack::json (%s)\n", pl->content);	
	
	uint realplay_id = 0;
	char cnt_serial[128] = {0};
	if(parse_serial(pl->serial, realplay_id, cnt_serial, sizeof(cnt_serial)) < 0){
		log_out(log_error, "client_ack::json invalid serial %s\n", pl->serial);
		return -1;
	}
	

	std::map<uint, app_connection*>::iterator it =  m_cntmap.find(realplay_id);
	if (it == m_cntmap.end()){
		log_out(log_error, "client_ack::client(%u) is off\n", realplay_id);
		return -1;
	}
	
	cJSON * jserror  = cJSON_GetObjectItem(pl->json, "error");
	cJSON * jsreason = cJSON_GetObjectItem(pl->json, "reason");
	if(!jserror || !jsreason){
		log_out(log_error, "client_ack::no error item\n");
		return -1;
	}
	
	if(strcmp(pl->cmd, start_realplay_ack) == 0){
		start_realplay_ackx(realplay_id, jserror->valueint, it->second);
	}
	else if(strcmp(pl->cmd, stop_realplay_ack) == 0){
		stop_realplay_ackx(realplay_id, jserror->valueint, it->second);
	}
	
	cJSON_DeleteItemFromObject(pl->jsdata, "device_id");
	cJSON_DeleteItemFromObject(pl->jsdata, "company_id");
	char * out = cJSON_PrintUnformatted(pl->jsdata);
	
	realplay_info * rpif = (realplay_info*)it->second->get_context();
	
	if(rpif){
		rpif->post_ack(pl->cmd, cnt_serial, 
			jserror->valueint, jsreason->valuestring, out);
	}
		
	free(out);
	
	return 0;
}
Esempio n. 4
0
void JSONElement::removeProperty(const wxString& name)
{
    // delete child property
    if(!_json) {
        return;
    }
    cJSON_DeleteItemFromObject(_json, name.mb_str(wxConvUTF8).data());
}
Esempio n. 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;
}
void App42Response::buildJsonDocument(cJSON *json, JSONDocument *jsonDocumnet)
{
    
    cJSON *docIdJson = Util::getJSONChild("_id", json);
    if (docIdJson!=NULL)
    {
        
        jsonDocumnet->setDocId(Util::getJSONString("$oid", docIdJson));
        cJSON_DeleteItemFromObject(json, "_id");
    }
    
    cJSON *ownerJson = Util::getJSONChild("_$owner", json);
    if (ownerJson!=NULL)
    {
        
        jsonDocumnet->setOwner(Util::getJSONString("owner", ownerJson));
        cJSON_DeleteItemFromObject(json,"_$owner");
    }
    
    string createdAt = Util::getJSONString("_$createdAt", json);
    if (createdAt.c_str()!=NULL)
    {
        jsonDocumnet->setCreatedAt(createdAt);
        cJSON_DeleteItemFromObject(json, "_$createdAt");
    }
    
    string updatedAt = Util::getJSONString("_$updatedAt", json);
    if (updatedAt.c_str()!=NULL)
    {
        jsonDocumnet->setUpdatedAt(updatedAt);
        cJSON_DeleteItemFromObject(json, "_$updatedAt");
    }
    
    string event = Util::getJSONString("_$event", json);
    if (event.c_str()!=NULL)
    {
        jsonDocumnet->setEvent(event);
        cJSON_DeleteItemFromObject(json, "_$event");
    }
    char *doc = cJSON_PrintUnformatted(json);
    jsonDocumnet->setJsonDoc(doc);
    free(doc);
    
}
Esempio n. 7
0
int stream_write_block(StreamWriter *sp, StreamBlock *blk, STREAM_CHECKSUM check)
/*=============================================================================*/
{
  blk->error = 0 ;
  if (blk->type == '#') blk->error = STREAM_ERROR_HASHRESERVED ;
  else {
    int n ;
    char *json ;
    char lenbuf[32] ;

    md5_state_t md5, *md5p ;
    if (sp->checksum || check) {
      md5p = &md5 ;
      md5_init(md5p) ;
      }
    else md5p = NULL ;

    if (blk->header) {
      cJSON_DeleteItemFromObject(blk->header, "length") ;
      cJSON_AddNumberToObject(blk->header, "length", blk->length) ;
      json = cJSON_PrintUnformatted(blk->header) ;
      }
    else {
      json = calloc(32, 1) ;
      sprintf(json, "{\"length\":%d}", blk->length) ;
      }
    stream_write_data(sp->file, "#", 1, md5p) ;
    stream_write_data(sp->file, &blk->type, 1, md5p) ;
    sprintf(lenbuf, "%d", (int)strlen(json)) ;
    stream_write_data(sp->file, lenbuf, strlen(lenbuf), md5p) ;
    stream_write_data(sp->file, json, strlen(json), md5p) ;
    stream_write_data(sp->file, "\n", 1, md5p) ;
    free(json) ;
    n = 0 ;
    while (n < blk->length) {
      int w = min(blk->length - n, STREAM_BUFFER_SIZE) ;
      w = stream_write_data(sp->file, blk->content + n, w, md5p) ;
      if (w < 0) {
        blk->error = STREAM_ERROR_WRITEOF ;
        break ;
        }
      n += w ;
      }
    write(sp->file, "##", 2) ;
    if (md5p) {
      md5_byte_t digest[16] ;
      char hexdigest[33] ;
      int i ;
      md5_finish(md5p, digest) ;
      for (i = 0 ;  i < 16 ;  ++i) sprintf(hexdigest + 2*i, "%02x", digest[i]) ;
      write(sp->file, hexdigest, 32) ;
      }
    write(sp->file, "\n", 1) ;
    }
  return blk->error ;
  }
Esempio n. 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;
}
Esempio n. 9
0
char *remove_secret(cJSON **argjsonp,char *parmstxt)
{
    long len;
    cJSON_DeleteItemFromObject(*argjsonp,"secret");
    if ( parmstxt != 0 )
        free(parmstxt);
    parmstxt = cJSON_Print(*argjsonp);
    len = strlen(parmstxt);
    stripwhite_ns(parmstxt,len);
    return(parmstxt);
}
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);
}
Esempio n. 11
0
void ram_parse_MGWpingstr(struct mgw777 *mgw,char *sender,char *pingstr)
{
    void save_MGW_status(char *NXTaddr,char *jsonstr);
    char name[512],coinstr[MAX_JSON_FIELD],*jsonstr = 0;
    struct MGWstate S;
    int32_t gatewayid;
    cJSON *json,*array;
    if ( (array= cJSON_Parse(pingstr)) != 0 && is_cJSON_Array(array) != 0 )
    {
        json = cJSON_GetArrayItem(array,0);
        if ( mgw == 0 )
        {
            copy_cJSON(coinstr,cJSON_GetObjectItem(json,"coin"));
            if ( coinstr[0] != 0 )
                mgw = get_MGW_info(coinstr);
        }
        if ( Debuglevel > 2 || (mgw != 0 && mgw->remotemode != 0) )
            printf("[%s] parse.(%s)\n",coinstr,pingstr);
        if ( mgw != 0 )
        {
            cJSON_DeleteItemFromObject(json,"ipaddr");
            if ( (gatewayid= (int32_t)get_API_int(cJSON_GetObjectItem(json,"gatewayid"),-1)) >= 0 && gatewayid < mgw->numgateways )
            {
                if ( strcmp(mgw->special_NXTaddrs[gatewayid],sender) == 0 )
                    ram_parse_MGWstate(&mgw->otherS[gatewayid],json,mgw->coinstr,sender);
                else printf("ram_parse_MGWpingstr: got wrong address.(%s) for gatewayid.%d expected.(%s)\n",sender,gatewayid,mgw->special_NXTaddrs[gatewayid]);
            }
            else
            {
                //printf("call parse.(%s)\n",cJSON_Print(json));
                ram_parse_MGWstate(&S,json,mgw->coinstr,sender);
                ram_update_remotesrc(mgw,&S);
            }
            jsonstr = cJSON_Print(json);
            if ( gatewayid >= 0 && gatewayid < 3 && strcmp(mgw->mgwstrs[gatewayid],jsonstr) != 0 )
            {
                safecopy(mgw->mgwstrs[gatewayid],jsonstr,sizeof(mgw->mgwstrs[gatewayid]));
                //sprintf(name,"%s.%s",mgw->coinstr,Server_ipaddrs[gatewayid]);
                sprintf(name,"%s.%d",mgw->coinstr,gatewayid);
                //printf("name is (%s) + (%s) -> (%s)\n",mgw->coinstr,Server_ipaddrs[gatewayid],name);
                save_MGW_status(name,jsonstr);
            }
        }
        if ( jsonstr != 0 )
            free(jsonstr);
        free_json(array);
    }
    //printf("parsed\n");
}
Esempio n. 12
0
char *rm_item(char *old,char *id)
{
	cJSON *root;
	char *out;
	if(old!=NULL)
		root=cJSON_Parse(old);
	else
		root=cJSON_CreateObject();	
	cJSON *data;
	data=cJSON_GetObjectItem(root,id);
	if(data)
	{
		cJSON_DeleteItemFromObject(root, id);
	}
	out=cJSON_PrintUnformatted(root);	
	cJSON_Delete(root);
	if(old)
		free(old);
	return out;
}
Esempio n. 13
0
void ICACHE_FLASH_ATTR config_set(serverConnData *conn, uint8_t argc, char *argv[]){
    bool err = false;
    cJSON * config = NULL;
    cJSON * lastchild = NULL;
    char *stmp = NULL;

    DBG_MSG("config_set argc: %d\r\n", argc);
    if (argc == 0)
        espbuffsentprintf(conn, "Usage: set <key> [value]\r\nUse help for more details\r\n");
    else if (argc == 1) {
        // Delete config
        DBG_MSG("Delete config %s\r\n", argv[1]);
        config = get_parent_by_key(jconfig_root, argv[1], &stmp);
        if (config != NULL) lastchild = cJSON_GetObjectItem(config, stmp);
        DBG_MSG("config: %p, stmp: %p\r\n", config, stmp);
        if (config == NULL) {
            espbuffsentprintf(conn, "Could not found parent config with key [%s].\r\n", argv[1]);
        }else if(lastchild == NULL) {
            espbuffsentprintf(conn, "Could not found lastchild config with key [%s].\r\n", argv[1]);
        } else {
            char *tmp;
            DBG_MSG("Delete %s from %s.\r\n", lastchild->string, config->string);
            cJSON_DeleteItemFromObject(config, lastchild->string);
            tmp = cJSON_PrintUnformatted(config);
            espbuffsentstring(conn, "Deleted. Now content is:\r\n");
            espbuffsentstring(conn, tmp);
            os_free(tmp);
        }
    } else {
        // Update config value
        char value[255];
        uint8_t i;
        uint32_t idx = 0;

        os_bzero(value, sizeof(value));
        for (i=2; i<=argc; ++i) {
            DBG_MSG("argv[%d] = %s.\r\n", i, argv[i]);
            os_sprintf(value + idx, "%s ", argv[i]);
            idx += os_strlen(argv[i]) + 1;
        }
        value[idx - 1] = 0;
        DBG_MSG("Update config %s to %s.\r\n", argv[1], value);
        config = get_parent_by_key(jconfig_root, argv[1], &stmp);
        DBG_MSG("config: %p, stmp: %p\r\n", config, stmp);
        if (config == NULL) {
            espbuffsentprintf(conn, "Could not found parent config with key [%s].\r\n", argv[1]);
        }else if (stmp == NULL) {
            espbuffsentprintf(conn, "Could not found last config with key [%s].\r\n", argv[1]);
        } else {
            char *tmp;
            int i;
            cJSON *newchild = NULL;

            DBG_MSG("stmp: %s, valuetype: %c.\r\n", stmp, value[0]);
            lastchild = cJSON_GetObjectItem(config, stmp);
            DBG_MSG("lastchild: %p.\r\n", lastchild);
            switch (value[0]) {
                case 'i':
                if (os_strlen(value) < 2) {
                    espbuffsentstring(conn, "value is invalid format: i10\r\n");
                    break;
                }
                i = atoi(&value[1]);
                newchild = cJSON_CreateNumber(i);
                break;
                case 's':
                if (os_strlen(value) < 2) {
                    espbuffsentstring(conn, "value is invalid format: slamp\r\n");
                    break;
                }
                newchild = cJSON_CreateString(&value[1]);
                DBG_MSG("Create item: %s -> %p.\r\n", &value[1], newchild);
                break;
                default:
                    espbuffsentstring(conn, "value is invalid format\r\n");
                    newchild = NULL;
                break;
            }

            if (newchild != NULL) {
                if (lastchild != NULL) {
                    cJSON_ReplaceItemInObject(config, lastchild->string, newchild);
                } else {
                    DBG_MSG("Add config %s to %s.\r\n", stmp, config->string);
                    cJSON_AddItemToObject(config, stmp, newchild);
                }
                tmp = cJSON_PrintUnformatted(config);
                espbuffsentstring(conn, "Updated. Now content is:\r\n");
                espbuffsentstring(conn, tmp);
                os_free(tmp);
            }
        }
    }
    if (err)
        espbuffsentstring(conn, MSG_ERROR);
    else
        espbuffsentstring(conn, MSG_OK);
}
Esempio n. 14
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;
}
Esempio n. 15
0
/*
{
	"serial":"",
	"cmd":"start_realpaly_req",
	"data":{
		"token":"",
		"channel":0,
		"sub_channel":0,
	}
}*/
int svrapp::start_realplay_reqx(param_list * pl){

	realplay_info * rpif = (realplay_info*)pl->n->get_context();
	if(!rpif){
		post_ack(pl->n, pl->ack_cmd, pl->serial, ERROR_NO_SUPPORT, "try again");
		log_out(log_error, "start_realplay_reqx::unknow error\n");
		return -1;
	}
	
	if(rpif->is_playing()){
		rpif->post_ack(pl->ack_cmd, pl->serial, ERROR_NO_SUPPORT, "is playing");
		log_out(log_error, "start_realplay_reqx::is playing\n");
		return -1;
	}
	
	stream_key  * stmkey = rpif->get_stream_key();
	uint64 key64 = rpif->get_key64();
	
	//find dev
	std::map<uint, app_connection*>::iterator it = m_devmap.find(stmkey->device_id);
	if(it == m_devmap.end()){
		log_out(log_error, "start_realpaly_req::device(%u) off line\n", stmkey->device_id);
		rpif->post_ack(pl->ack_cmd, pl->serial, ERROR_DEV_OFFLINE, "device is offline");
		return -1;
	}
	
	std::map<uint, app_connection*>::iterator it1 = m_cntmap.find(rpif->get_id());
	if(it1 == m_cntmap.end() ){
		m_cntmap[rpif->get_id()] = pl->n;
	}

	//判断是否已经在播放
	std::map<uint64, stream_info*>::iterator it0 = m_realplaymap.find(key64);
	if(it0 != m_realplaymap.end()){
		stream_info * stmif = it0->second;
		stmif->add(rpif->get_id(), pl->n);
		
		rpif->reset_resource();
		rpif->set_playing();
		rpif->post_ack(pl->ack_cmd, pl->serial, ERROR_OK, "ok");
		log_out(log_debug, "start_realpaly_req::appid(%d) stream(%llX) already playing, clients(%u)\n",
		get_appid(), key64, stmif->client_number());		
		return 0;
	}
	else{
		stream_info * stmif = new stream_info(stm_type, stmkey);
		m_realplaymap[key64] = stmif;
		stmif->add(rpif->get_id(), pl->n);
	}

	rpif->reset_resource();
	rpif->set_playing();
	
	///add realplay server
	char serverAddr[64] = {0};
	sprintf(serverAddr, "%s:%d",g_sdr->self_ipaddr.ip, g_sdr->self_ipaddr.port);
	cJSON_AddStringToObject(pl->jsdata, "server", serverAddr);
	cJSON_AddStringToObject(pl->jsdata, "transport_protocol", "tcp");
	
	//generate token
	char token[128] = {0};
	sprintf(token, "%08X%04X%04X", stmkey->device_id, stmkey->chn, stmkey->sub_chn);
	cJSON_DeleteItemFromObject(pl->jsdata, "token");
	cJSON_AddStringToObject(pl->jsdata, "token", token);
	
	
	//send request to mgr
	char new_serial[128] = {0};
	create_serial(rpif->get_id(), pl->serial, new_serial, sizeof(new_serial));
	char * out = cJSON_PrintUnformatted(pl->jsdata);
	log_out(log_debug, "start_realpaly_req::appid(%d) %s\n",get_appid(),  out);
		
	app_connection * dn = it->second;
	post_req(dn, pl->cmd, out, new_serial);
	free(out);
	return 0;
}
Esempio n. 16
0
void jdelete(cJSON *json,char *field)
{
    if ( jobj(json,field) != 0 )
        cJSON_DeleteItemFromObject(json,field);
}
Esempio n. 17
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,*addr,*retstr = 0; struct destbuf echostr;
    retbuf[0] = 0;
    plugin->allowremote = 1;
    //fprintf(stderr,"<<<<<<<<<<<< INSIDE PLUGIN! process %s (%s)\n",plugin->name,jsonstr);
    if ( initflag > 0 )
    {
        // configure settings
        strcpy(retbuf,"{\"result\":\"echodemo init\"}");
    }
    else
    {
        resultstr = cJSON_str(cJSON_GetObjectItem(json,"result"));
        methodstr = cJSON_str(cJSON_GetObjectItem(json,"method"));
        copy_cJSON(&echostr,cJSON_GetObjectItem(json,"echostr"));
        retbuf[0] = 0;
        if ( resultstr != 0 && strcmp(resultstr,"registered") == 0 )
        {
            plugin->registered = 1;
            strcpy(retbuf,"{\"result\":\"activated\"}");
            return((int32_t)strlen(retbuf));
        }
        if ( plugin_result(retbuf,json,tag) > 0 )
            return((int32_t)strlen(retbuf));
        if ( methodstr == 0 || methodstr[0] == 0 )
        {
            printf("(%s) has not method\n",jsonstr);
            return(0);
        }
        else if ( strcmp(methodstr,"echo") == 0 )
        {
            sprintf(retbuf,"{\"result\":\"%s\"}",echostr.buf);
        }
        else if ( strcmp(methodstr,"passthru") == 0 )
        {
            if ( jstr(json,"destplugin") != 0 )
            {
                cJSON_DeleteItemFromObject(json,"plugin");
                jaddstr(json,"plugin",jstr(json,"destplugin"));
                cJSON_DeleteItemFromObject(json,"destplugin");
            }
            if ( jstr(json,"destmethod") != 0 )
            {
                cJSON_DeleteItemFromObject(json,"method");
                jaddstr(json,"method",jstr(json,"destmethod"));
                cJSON_DeleteItemFromObject(json,"destmethod");
            }
            jaddstr(json,"pluginrequest","SuperNET");
            retstr = jprint(json,0);
            //printf("passhru.(%s)\n",retstr);
        }
        else if ( strcmp(methodstr,"RS") == 0 )
        {
            int32_t is_decimalstr(char *str);
            uint64_t RS_decode(char *rs);
            int32_t RS_encode(char *,uint64_t id);
            char rsaddr[64]; uint64_t nxt64bits = 0;
            if ( (addr= cJSON_str(cJSON_GetObjectItem(json,"addr"))) != 0 )
            {
                rsaddr[0] = 0;
                if ( strlen(addr) > 4 )
                {
                    if ( strncmp(addr,"NXT-",4) == 0 )
                    {
                        nxt64bits = RS_decode(addr);
                        sprintf(retbuf,"{\"result\":\"success\",\"accountRS\":\"%s\",\"account\":\"%llu\"}",addr,(long long)nxt64bits);
                    }
                    else if ( is_decimalstr(addr) != 0 )
                    {
                        nxt64bits = calc_nxt64bits(addr), RS_encode(rsaddr,nxt64bits);
                        sprintf(retbuf,"{\"result\":\"success\",\"account\":\"%llu\",\"accountRS\":\"%s\"}",(long long)nxt64bits,rsaddr);
                    }
                }
                else sprintf(retbuf,"{\"error\":\"illegal addr field\",\"addr\":\"%s\"}",addr);
            }
            else sprintf(retbuf,"{\"error\":\"no addr field\"}");
        }
    }
    return(plugin_copyretstr(retbuf,maxlen,retstr));
}
Esempio n. 18
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;
}
Esempio n. 19
0
void App42Response::buildJsonDocument(cJSON *json, JSONDocument *jsonDocumnet)
{
    
    cJSON *docIdJson = Util::getJSONChild("_id", json);
    if (docIdJson!=NULL)
    {
        
        jsonDocumnet->setDocId(Util::getJSONString("$oid", docIdJson));
        cJSON_DeleteItemFromObject(json, "_id");
    }
    
    cJSON *ownerJson = Util::getJSONChild("_$owner", json);
    if (ownerJson!=NULL)
    {
        jsonDocumnet->setOwner(Util::getJSONString("owner", ownerJson));
        cJSON_DeleteItemFromObject(json,"_$owner");
    }
    
    string createdAt = Util::getJSONString("_$createdAt", json);
    if (createdAt.c_str()!=NULL)
    {
        jsonDocumnet->setCreatedAt(createdAt);
        cJSON_DeleteItemFromObject(json, "_$createdAt");
    }
    
    string updatedAt = Util::getJSONString("_$updatedAt", json);
    if (updatedAt.c_str()!=NULL)
    {
        jsonDocumnet->setUpdatedAt(updatedAt);
        cJSON_DeleteItemFromObject(json, "_$updatedAt");
    }
    
    string event = Util::getJSONString("_$event", json);
    if (event.c_str()!=NULL)
    {
        jsonDocumnet->setEvent(event);
        cJSON_DeleteItemFromObject(json, "_$event");
    }
    
    cJSON *App42ACLJson = Util::getJSONChild("_$App42ACL", json);
    if (App42ACLJson!=NULL)
    {
        cJSON* child = App42ACLJson;
        if(child->type == cJSON_Array)
        {
            child = child->child;
        }
        while(child != NULL && child->type == cJSON_Object)
        {
            string name = Util::getJSONKeyString(child);
            string value = Util::getJSONString(name, child);
            App42ACL *acl = new App42ACL();
            acl->setUserName(name);
            acl->setPermission(value);
            jsonDocumnet->pushToApp42ACLList(acl);
            child = child->next;
        }
        cJSON_DeleteItemFromObject(json, "_$App42ACL");
    }
    
    char *doc = cJSON_PrintUnformatted(json);
    //printf("\nJsonDoc=%s",doc);
    jsonDocumnet->setJsonDoc(doc);
    printf("\nJsonDoc=%s\n",jsonDocumnet->getJsonDoc().c_str());

    free(doc);
    
}
Esempio n. 20
0
int main(int argc, char *argv[])
{
    pid_t pid = getpid();
    int str_end,hash_beg,i = 0, sm, lo, rs, dr, hash_len;
    char dir[200],report[1000],mdString[40]= {0}, *parcel, tmp[100], *from_str, *from_str_tmp, *hash_et, *help_ptr, *arglist_sm[100], *arglist_lo[100], *arglist_rs[100], *arglist_dr[100];
    unsigned char *hash_cand = malloc(50*sizeof(char));
    t_elements parsed_elements;
    sprintf(dir,"%s%d_log.log",LOG_DIR,pid);
    FILE *log = fopen(dir,"w");
    if(log == NULL) exit(-4);
    from_str_tmp = malloc(sizeof(char)*100000);
    sprintf(tmp, "/tmp/%d/", pid);
    mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    chdir(tmp);
    fprintf(log, "PID: %d, dir changed\nthats what we got:\n", pid);
    do
    {
        from_str_tmp[i] = getc(stdin);
        fputc(from_str_tmp[i],log);
        if(from_str_tmp[i] == '-' && from_str_tmp[i-1] == '-')
        {
            str_end=i-1;
            hash_beg=i+1;
            from_str_tmp[str_end]=0;
        }
    }
    while(from_str_tmp[i++] != EOF);
    hash_et = from_str_tmp + sizeof(char)*hash_beg;
    hash_et[40]=0;
    from_str_tmp += 8*sizeof(char);
    from_str = curl_decode(from_str_tmp);
    help_ptr = from_str;
    from_str_tmp = decode(from_str); /*base64 conversion*/
    fprintf(log,"\nAfter url_decode:%s",from_str);
    //\r\n
    from_str=from_str_tmp;
    fprintf(log,"\nhashed string:%s\n",help_ptr);
    HMAC(EVP_sha1(),SALT, strlen(SALT), (unsigned char*)help_ptr, strlen(help_ptr),hash_cand,(unsigned int*)&hash_len);
    for(i = 0; i < 20; i++)
        sprintf(&mdString[i*2], "%02x",hash_cand[i]);
    //FIXME leaks everywhere
    if(strcmp(mdString,hash_et)==0)
    {
        fprintf(log,"\nhash correct\n");
        fprintf(log,"decoded string: %s\n", from_str);
        printf("Content-Type: text/plain;charset=us-ascii\n\n");
    }
    else
    {
        fprintf(log, "%s\n%s\n hash incorrect\n",mdString,hash_et);
        printf("Content-Type: text/html\nStatus: 422 Bad Request\n\n");
        free(hash_cand);
        free(from_str);
        fclose(log);
        exit(-1);
    }
    /*we have now string to parse*/
    cJSON *root = cJSON_Parse(from_str);
    if (!root)
    {
        fprintf(log,"Error before: [%s]\n", cJSON_GetErrorPtr());
    }
    fprintf(log,"exec part\n");
    parse_into_elements(&parsed_elements, root, log);
    fflush(NULL);
    lo = make_arglist_for_login(arglist_lo, parsed_elements);
    fork_exec_with_inp_redir(arglist_lo, 1, "whatever");
    sm = make_arglist_for_submit_and_run(arglist_sm, parsed_elements, arglist_lo[4]);
    fork_exec_with_inp_redir(arglist_sm, 1, "num.txt");
    rs = make_arglist_for_run_status(arglist_rs, parsed_elements, arglist_lo[4]);
    int rep_num;
    if((rep_num=wait_for_report(5, arglist_rs, parsed_elements.status))==-1)
    {
        strcpy(parsed_elements.status,"error");
        strcpy(report,"ejudge marking error");
    }
    else
    {
        int flag=0,some;
        some = submit_checked(parsed_elements.status, ejudge_common);
        if(strcmp(parsed_elements.status,"OK")==0)
        {
            strcpy(parsed_elements.status,"ok");
            flag=1;
        }
        else if(submit_checked(parsed_elements.status, ejudge_error)!=-1)
        {
            strcpy(parsed_elements.status,"error");
            strcpy(report,ejudge_detailed[some]);
            if(some == 1) flag = 2; /*let report be when compilation error*/
        }
        else
        {
            strcpy(parsed_elements.status, "fail");
            flag=1;
        }
        if(flag)
        {
            dr = make_arglist_for_dump_report(arglist_dr, parsed_elements, arglist_lo[4]); //BACKTRACE part
            fork_exec_with_inp_redir(arglist_dr, 1, "return_report.xml");
            /*xml parse part*/
            if(flag==1){
                ezxml_t trace = ezxml_parse_file("return_report.xml");
                const char * points = ezxml_attr(trace, "score");
                const char * tp = ezxml_attr(trace, "tests-passed");
                const char * to = ezxml_attr(trace, "run-tests");
                sprintf(report, "%s. Your score is = %s, %s/%s tests passed",ejudge_detailed[some], points , tp, to);
                ezxml_free(trace);
                /* parse part end */
                /* BTW ezxml lib used so you have possibility to add smth to report */
            }
            else if(flag==2)
            {
                char *iftmp;
                iftmp = read_string("return_report.xml");
                strcat(report, iftmp);
                free(iftmp);
            }

        }
    }
    fprintf(log, "exec part end\n");
    cJSON_AddStringToObject(root, "trace", report);
    cJSON_AddStringToObject(root, "status", parsed_elements.status);
    cJSON_DeleteItemFromObject(root,"programming_language");
    cJSON_DeleteItemFromObject(root,"file_name");
    cJSON_DeleteItemFromObject(root,"file_content");
    parcel = cJSON_Print(root);
    fprintf(log,"output:%s\n",parcel);
    free(from_str);
    from_str=encode(parcel);
    fprintf(log,"encoded output:%s\n", from_str);
    parcel=curl_encode(from_str);
    fprintf(log,"curl_encoded output:%s\n", parcel);
    HMAC(EVP_sha1(),SALT, strlen(SALT), (unsigned char*)from_str, strlen(from_str),hash_cand,(unsigned int*)&hash_len);
    for(i = 0; i < 20; i++)
        sprintf(&mdString[i*2], "%02x", (unsigned int)hash_cand[i]);
    fprintf(log,"hash HMAC:%s\n", mdString);
    sprintf(from_str,"session=%s--%s",parcel,mdString);
    fprintf(log,"final output:%s\n", from_str);
    /*ready to send backparcel*/
    sendJSON(parsed_elements.url, from_str);
    sendJSON("http://ejudge.100ege.ru/cgi-bin/a.out", from_str); //FIXME: for logging purposes
    //printf("%s",from_str);
    /*now clean part*/
    fprintf(log,"\n%s\n",from_str);
    str_vector_free(arglist_lo, lo);
    str_vector_free(arglist_rs, rs);
    str_vector_free(arglist_sm, sm);
    free(root);
    free(from_str);
    free(parcel);
    fclose(log);
    chdir("/tmp/");
    execl("/bin/rm", "/bin/rm", "-rf", tmp, NULL);
    return 0;
}
Esempio n. 21
0
void stream_process_data(StreamReader *sp)
//========================================
{
  sp->block.error = 0 ;

  while (!sp->block.error && sp->state != STREAM_STATE_BLOCK) {

    if (sp->datalen <= 0) return ;   // Need more data

    switch (sp->state) {
      case STREAM_STATE_RESET: {            // Looking for a block
        char *next = memchr(sp->datapos, '#', sp->datalen) ;
        if (next) {
          sp->datalen -= (next - sp->datapos + 1) ;
          sp->datapos = next + 1 ;
          md5_init(&sp->md5) ;
          md5_append(&sp->md5, (const md5_byte_t *)"#", 1) ;
          stream_free_buffers(sp) ;
          sp->state = STREAM_STATE_TYPE ;
          }
        else sp->datalen = 0 ;
        break ;
        }

      case STREAM_STATE_TYPE: {            // Getting block type 
        sp->block.type = *sp->datapos ;
        sp->datapos += 1 ;
        sp->datalen -= 1 ;
        if (sp->block.type != '#') {
          md5_append(&sp->md5, (const md5_byte_t *)&sp->block.type, 1) ;
          sp->block.number += 1 ;
          sp->expected = 0 ;
          sp->state = STREAM_STATE_HDRLEN ;
          }
        else sp->block.error = STREAM_ERROR_UNEXPECTED_TRAILER ;
        break ;
        }

      case STREAM_STATE_HDRLEN: {            // Getting header length
        while (sp->datalen > 0 && isdigit(*sp->datapos)) {
          sp->expected = 10*sp->expected + (*sp->datapos - '0') ;
          md5_append(&sp->md5, (const md5_byte_t *)sp->datapos, 1) ;
          sp->datapos += 1 ;
          sp->datalen -= 1 ;
          }
        if (sp->datalen > 0) {
          sp->jsonhdr = calloc(sp->expected + 1, 1) ;
          sp->state = STREAM_STATE_HEADER ;
          }
        break ;
        }

      case STREAM_STATE_HEADER: {            // Getting header JSON
        while (sp->datalen > 0 && sp->expected > 0) {
          int delta = min(sp->expected, sp->datalen) ;
          strncat(sp->jsonhdr, sp->datapos, delta) ;
          md5_append(&sp->md5, (const md5_byte_t *)sp->datapos, delta) ;
          sp->datapos += delta ;
          sp->datalen -= delta ;
          sp->expected -= delta ;
          }
        if (sp->expected == 0) {
          if (*sp->jsonhdr) sp->block.header = cJSON_Parse(sp->jsonhdr) ;
          sp->state = STREAM_STATE_HDREND ;
          }
        break ;
        }

      case STREAM_STATE_HDREND: {            // Checking header LF
        if (*sp->datapos == '\n') {
          sp->datapos += 1 ;
          sp->datalen -= 1 ;
          md5_append(&sp->md5, (const md5_byte_t *)"\n", 1) ;
          sp->block.length = 0 ;
          if (sp->block.header) {
            cJSON *lenp = cJSON_GetObjectItem(sp->block.header, "length") ;
            if (lenp && lenp->type == cJSON_Number) sp->block.length = lenp->valueint ;
            cJSON_DeleteItemFromObject(sp->block.header, "length") ;
            }
          sp->block.content = calloc(sp->block.length+1, 1) ;
          sp->storepos = sp->block.content ;
          sp->expected = sp->block.length ;
          sp->state = STREAM_STATE_CONTENT ;
          }
        else sp->block.error = STREAM_ERROR_MISSING_HEADER_LF ;
        break ;
        }

      case STREAM_STATE_CONTENT: {            // Getting content
        while (sp->datalen > 0 && sp->expected > 0) {
          int delta = min(sp->expected, sp->datalen) ;
          memcpy(sp->storepos, sp->datapos, delta) ;
          md5_append(&sp->md5, (const md5_byte_t *)sp->datapos, delta) ;
          sp->storepos += delta ;
          sp->datapos += delta ;
          sp->datalen -= delta ;
          sp->expected -= delta ;
          }
        if (sp->expected == 0) {
          sp->expected = 2 ;
          sp->state = STREAM_STATE_TRAILER ;
          }
        break ;
        }

      case STREAM_STATE_TRAILER: {             // Getting trailer
        if (*sp->datapos == '#') {
          sp->datapos += 1 ;
          sp->datalen -= 1 ;
          sp->expected -= 1 ;
          if (sp->expected == 0) sp->state = STREAM_STATE_CHECKSUM ;
          }
        else sp->block.error = STREAM_ERROR_MISSING_TRAILER ;
        break ;
        }

      case STREAM_STATE_CHECKSUM: {            // Checking for checksum
        if (*sp->datapos != '\n' && sp->checksum != STREAM_CHECKSUM_NONE) {
          sp->storepos = sp->checktext ;
          sp->expected = 32 ;
          sp->state = STREAM_STATE_CHECKDATA ;
          }
        else sp->state = STREAM_STATE_BLOCKEND ;
        sp->checktext[0] = '\0' ;
        break ;
        }

      case STREAM_STATE_CHECKDATA: {           // Getting checksum
        while (sp->datalen > 0 && sp->expected > 0 && isxdigit(*sp->datapos)) {
          *sp->storepos++ = *sp->datapos++ ;
          sp->datalen -= 1 ;
          sp->expected -= 1 ;
          }
        if (sp->datalen > 0) sp->state = STREAM_STATE_BLOCKEND ;
        break ;
        }

      case STREAM_STATE_BLOCKEND: {            // Checking for final LF
        if (sp->checksum == STREAM_CHECKSUM_STRICT
         || sp->checksum == STREAM_CHECKSUM_CHECK && sp->checktext[0]) {
          md5_byte_t digest[16] ;
          char hexdigest[33] ;
          int i ;
          md5_finish(&sp->md5, digest) ;
          for (i = 0 ;  i < 16 ;  ++i) sprintf(hexdigest + 2*i, "%02x", digest[i]) ;
          if (strcmp(sp->checktext, hexdigest) != 0) sp->block.error = STREAM_ERROR_INVALID_CHECKSUM ;
          }
        if (sp->block.error == 0) {
          if (*sp->datapos == '\n') {
            sp->datapos += 1 ;
            sp->datalen -= 1 ;
            }
          else sp->block.error = STREAM_ERROR_MISSING_TRAILER_LF ;
          }
        sp->state = STREAM_STATE_BLOCK ;    // All done, exit loop
        break ;
        }
      }
    }
  }