Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] I am confused about how to PushBack an object into an existed array. #598

Closed
coderwenhao opened this issue Apr 8, 2016 · 3 comments

Comments

@coderwenhao
Copy link

I have a json just like this: {"version":1.0, "data": {"count": 0, "datalist": []}} . Then I'd like to add some data into the "datalist" array dynamically, but I can't find a real way to do that.
There is a demo I hava writen.

data_json.h:

#ifndef DATA_JSON_H
#define DATA_JSON_H

#include <string>

#include "rapidjson/document.h"

using namespace std;

class DataJson 
{
public:
    DataJson(void);
    ~DataJson(void);

    void CreateJson();
    void AddData(const string & proJson); 
    void GetString(string & str);

private:
    rapidjson::Document     m_document;
};

#endif // DATA_JSON_H

data_json.cpp:


#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include "data_json.h"

DataJson::DataJson(void)
{
}


DataJson::~DataJson(void)
{
}

void DataJson::CreateJson()
{
    m_document.Parse("{\"version\":1.0, \"data\": {\"count\": 0, \"datalist\": []}}");
}

void DataJson::AddData(const string & json)
{
    rapidjson::Document tempDoc;
    tempDoc.Parse(json.c_str());
    if(! tempDoc.IsObject())
    {
        return;
    }
    rapidjson::Document::AllocatorType &allocator = m_document.GetAllocator();
    if(m_document.HasMember("data"))
    {
        rapidjson::Value &dataObject = m_document["data"];
        if(dataObject.IsObject())
        {
            bool addNewData = false;
            if(dataObject.HasMember("datalist"))
            {
                rapidjson::Value &dataList = dataObject["datalist"];
                if(dataList.IsArray())
                {
                    dataList.PushBack(tempDoc.GetObject(), allocator);
                    addNewData = true;
                }
            }
            else
            {
                rapidjson::Value dataArray(rapidjson::kArrayType);
                dataArray.PushBack(tempDoc.GetObject(), allocator);
                dataObject.AddMember("datalist", dataArray, allocator);
                addNewData = true;
            }

            if(addNewData)
            {
                rapidjson::Value::MemberIterator countItr = dataObject.FindMember("count");
                if(countItr != dataObject.MemberEnd())
                {
                    if(countItr->value.IsInt())
                    {
                        countItr->value.SetInt(countItr->value.GetInt() + 1);
                    }
                }
                else
                {
                    rapidjson::Value dataCount(rapidjson::kNumberType);
                    dataCount.SetInt(1);
                    dataObject.AddMember("count", dataCount, allocator);
                }
            }
        }
    }
}

void DataJson::GetString(string & str)
{
    str.clear();
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    m_document.Accept(writer);
    str.append(buffer.GetString());
}

main.cpp:


#include <string>
#include <iostream>
#include "data_json.h"

using namespace std;

int main()
{
    DataJson dataJson;
    dataJson.CreateJson();

    string jsonStr;
    string dataStr;

    dataJson.GetString(jsonStr);
    cout << "Json:" << jsonStr << endl;

    cout << "please input the data json: " <<endl;
    cin >> dataStr;
    while(dataStr != "0")
    {
        dataJson.AddData(dataStr);
        dataJson.GetString(jsonStr);
        cout << "Json:" << jsonStr << endl;

        cout << "please input the data json: " <<endl;
        cin >> dataStr;
    }
    return 0;
}

1b64 tm

What's the error about this demo ?

Thank you !

@miloyip
Copy link
Collaborator

miloyip commented Apr 8, 2016

It is because the tempDoc and the values allocated during parsing is destroyed at the end of AddData().

A simple fix is:

rapidjson::Document tempDoc(*m_document.GetAllocator());

@miloyip miloyip closed this as completed Apr 12, 2016
@michcleary
Copy link

michcleary commented Apr 17, 2017

Do you mean that for tempDoc, you need to use an allocator based off m_document? The above doesn't compile. There isn't a constructor for rapidjson::Document that takes *m_document.GetAllocator()

Then again, that's what this person was doing in the first place....using allocator based off m_document with tempDoc.

@ivantchomgue
Copy link

rapidjson::Document tempDoc(*m_document.GetAllocator()); Here I think
it is more

rapidjson::Document tempDoc(&m_document.GetAllocator());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants