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

How to deep copy json_object in C++ ? #301

Closed
daiziyi opened this issue Feb 10, 2017 · 4 comments
Closed

How to deep copy json_object in C++ ? #301

daiziyi opened this issue Feb 10, 2017 · 4 comments

Comments

@daiziyi
Copy link

daiziyi commented Feb 10, 2017

hi, I use 'json-c' in C++ and define json_object* mJson as a member variable of class Response. (Defined the code below)

In member function bool Response::GetJson(json_object **result) , I get json_object * pointer with passing param json_object **result , and then operate json_object *.

But I want to deep copy of json_object * in member functin bool Response::GetJson(json_object *result). I did not found 'releated copy funcion' in json-c api.
How can i do it? Or Is it necessary to deep copy of json_object * ? Thank you!

Here is my code:

/* File: response.h */
/* how to deep copy of json_object* ?  */

#ifndef RESPONSE_H
#define RESPONSE_H

#include <string>
#include <json-c/json.h>

class Response
{
private:
    std::string mStr;
    json_object *mJson;

public:
    Response(std::string str);
    ~Response();
    bool Str2Json();
    bool GetJson(json_object **result);

};

#endif // RESPONSE_H
/* File:response.cpp */
#include "response.h"
#include <iostream>

Response::Response(std::string str)
{
    mStr = str;
    //mJson = json_object_new_object();  /* 'json_tokener_parse_verbose' does not need 'new_object' ?*/
    mJson = NULL;   

}

Response::~Response()
{
    json_object_put(mJson);
    std::cout << "Destruct function: Response Class" << std::endl;
}


bool Response::Str2Json()
{
    bool result = true;
    enum json_tokener_error jerr = json_tokener_success;
    mJson = json_tokener_parse_verbose( mStr.c_str(), &jerr );

    if(  jerr != json_tokener_success ){
        result = false;
    }

    //std::cout << mJson._ref_count << std::endl;  //ERROR
    return result;

}

bool Response::GetJson(json_object **result)
{
    *result = mJson;
}



/*****************TEST*******************/
int main(int argc, char *argv[])
{
    std::string str = "{\"Name\":\"Tom\", \"Age\":18, \"Address\":\"New York City\"}";
    json_object *json;
    //json = json_object_new_object();
    bool result = false;

    Response response(str);
    result = response.Str2Json();
    if( !result ){
        std::cout << "Parse string to json error!" << std::endl;
        return -1;
    }

    response.GetJson(&json);
    std::cout << json_object_get_string(json) << std::endl;
    json = NULL;
    //json_object_put(json);

    return 0;
}
/***************************************/
@hawicz
Copy link
Member

hawicz commented Feb 11, 2017

@hawicz
Copy link
Member

hawicz commented Feb 11, 2017

There is currently no copy function available, but it could be implemented with json_c_visit. A pull request to add this would be welcome.

As a quick, though rather inefficient, hack people have converted their object to a string then re-parsed it to get an independent object.
Note that if you don't actually need the object to be entirely independent (e.g. if you know your use-case is read-only) then you can simple increase the reference count with json_object_get() and return the original object, which will be appropriately freed once all references are released.

@daiziyi
Copy link
Author

daiziyi commented Feb 13, 2017

Thanks to hawicz's detailed answer! And i will implement the Copy Function with your advice and blog. In addition, let me know another web site about ‘json-c’ "https://groups.google.com/forum/#!forum/json-c". Thank you!

@hawicz
Copy link
Member

hawicz commented Jul 9, 2017

@commodo has written a deep copy function that walks the object tree instead of converting to/from a string. It's not yet merged, but I expect that will happen relatively soon once a few issues with that code are addressed, so i'm closing this issue. See PR #328 for future updates.

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

No branches or pull requests

2 participants