To all those that are familiar with rapidjson i have the following issue:
I have a certain function that accepts as parameter a date and if that date exists in the json file the method does some operations and if not some other operations.
Generally it looks like this: (not actual code more like pseudo)
Function:
void updateData(string date) {
//
//code to turn date from string to const char* (tested)
//
if (v.HasMember(date)) { //v is a value
Value d;
d=v[date];
//
//code that involves getting data from d (d is object) using HasMember
//
} else {
//generic code that has nothing to do with json
}
JSON file:
{
"main": {
"v": {
"2014-10-02" : {
//some fields
},
"2014-10-03" : {
//some fields
}
}
}
}
So the first time that i call updateData for date "2014-10-02" it runs correctly(executes the if part).
The problem is when i call updateData for another date (like "2014-10-03" that is supposed to work well) it always executes the wrong part(else part) and even when i switch back to the first date it still executes the else part. (while popping many assertions (mostly isString())).
So is HasMember really the problem here, in the sense that it is maybe altering the object?
And are there any alternative ways to search for a member, other than that?
Any tip is appreciated...
Its hard to tell without the actual code, but I think problem might be that you are treating "v" as a Value instead of an Object. "v" isn't a value, its the name of the object. So what you have is a nested object. In order to do this I think you would have to used MemberIterators and iterate through the child objects in the v object.
rapidjson has a pretty good example on how to use iterators.
there is also this question here, which has a pretty good answer on how to use nested objects
Retrieving a nested object inside a JSON string using rapidjson
Related
I own a Go library, gofileseq, for which I would like to try and made a C/C++ binding.
It is pretty straightforward to be able to export functions that use simple types (ints, strings, ...). It is even easy enough to export data from custom Go types to C by defining a C struct and translating the Go type to it, to be used in the exported functions, since you are allocating C memory to do it. But with the go 1.5 cgo rules I am finding it difficult to figure out how to export functionality from a more complex struct that stores state.
Example of a struct from gofileseq that I would like to export somehow to a C++ binding:
// package fileseq
//
type FrameSet struct {
frange string
rangePtr *ranges.InclusiveRanges
}
func NewFrameSet(frange string) (*FrameSet, error) {
// bunch of processing to set up internal state
}
func (s *FrameSet) Len() int {
return s.rangePtr.Len()
}
// package ranges
//
type InclusiveRanges struct {
blocks []*InclusiveRange
}
type InclusiveRange struct {
start int
end int
step int
cachedEnd int
isEndCached bool
cachedLen int
isLenCached bool
}
As you can see, the FrameSet type that I want to expose contains a slice of pointers to an underlying type, each of which stores state.
Ideally, I would love to be able to store a void* on a C++ class, and make it just a simple proxy for calling back into exported Go functions with the void*. But the cgo rules disallow C storing a Go pointer longer than the function call. And I am failing to see how I could use an approach of defining C++ classes that could be allocated and used to operate with my Go library.
Is it possible to wrap complex types for exposure to C/C++?
Is there a pattern that would allow a C++ client to create a Go FrameSet?
Edit
One idea I can think of would be to let C++ create objects in Go that get stored on the Go side in a static map[int]*FrameSet and then return the int id to C++. Then all the C++ operations make requests into Go with the id. Does that sound like a valid solution?
Update
For now, I am proceeding with testing a solution that uses global maps and unique ids to store objects. C++ would request a new object to be created and only get back an opaque id. Then they can call all of the methods exported as functions, using that id, including requesting for it to be destroyed when done.
If there is a better approach than this, I would love to see an answer. Once I get a fully working prototype, I will add my own answer.
Update #2
I've written a blog post about the final solution that I ended up using: http://justinfx.com/2016/05/14/cpp-bindings-for-go/
The way I ended up solving this, for lack of a better solution, was to use private global maps on the Go side (ref). These maps would associate instances of the Go objects with a random uint64 id, and the id would be returned to C++ as an "opaque handle".
type frameSetMap struct {
lock *sync.RWMutex
m map[FrameSetId]*frameSetRef
rand idMaker
}
//...
func (m *frameSetMap) Add(fset fileseq.FrameSet) FrameSetId {
// fmt.Printf("frameset Add %v as %v\n", fset.String(), id)
m.lock.Lock()
id := FrameSetId(m.rand.Uint64())
m.m[id] = &frameSetRef{fset, 1}
m.lock.Unlock()
return id
}
Then I use reference counting to determine when C++ no longer needs the object, and remove it from the map:
// Go
func (m *frameSetMap) Incref(id FrameSetId) {
m.lock.RLock()
ref, ok := m.m[id]
m.lock.RUnlock()
if !ok {
return
}
atomic.AddUint32(&ref.refs, 1)
// fmt.Printf("Incref %v to %d\n", ref, refs)
}
func (m *frameSetMap) Decref(id FrameSetId) {
m.lock.RLock()
ref, ok := m.m[id]
m.lock.RUnlock()
if !ok {
return
}
refs := atomic.AddUint32(&ref.refs, ^uint32(0))
// fmt.Printf("Decref %v to %d\n", ref, refs)
if refs != 0 {
return
}
m.lock.Lock()
if atomic.LoadUint32(&ref.refs) == 0 {
// fmt.Printf("Deleting %v\n", ref)
delete(m.m, id)
}
m.lock.Unlock()
}
//C++
FileSequence::~FileSequence() {
if (m_valid) {
// std::cout << "FileSequence destroy " << m_id << std::endl;
m_valid = false;
internal::FileSequence_Decref(m_id);
m_id = 0;
m_fsetId = 0;
}
}
And all C++ interactions with the exported Go library communicate via the opaque handle:
// C++
size_t FileSequence::length() const {
return internal::FileSequence_Len(m_id);
}
Unfortunately it does mean that in a multhreaded C++ environment, all threads would go through a mutex to the map. But it is only a write lock when objects are created and destroyed, and for all method calls on an object it is a read lock.
In my code I have an if-else block condition like this:
public String method (Info info) {
if (info.isSomeBooleanCondition) {
return "someString";
}
else if (info.isSomeOtherCondition) {
return "someOtherString";
}
else if (info.anotherCondition) {
return "anotherStringAgain";
}
else if (lastCondition) {
return "string ...";
}
else return "lastButNotLeastString";
}
Each conditional branch returns a String.
Since if-else statements are difficult to read, test and maintain, how can I replace?
I was thinking to use Chain Of Responsability Pattern, is it right in this case?
Is there any other elegant way that I can do that?
I am left to assume that your code does not exist in the Info class as it is passed in an referenced for all but that last condition. My first instinct would be to make String OtherClass.method(Info) into String Info.method() and have it return the appropriate string.
Next, I would take a look at the conditions. Are they really conditions or can they be mapped to a table. Whenever I see code performing a lookup, such as this, I tend to fall back on attempting to fit into a dictionary or map so I can perform a lookup for the value.
If you are left with conditions that must be checked then I would begin thinking about lambdas, delegates or custom interface. A series of if..then across the same type could easily be represented. Next, you would collect them and execute accordingly. IMO, this would make the if..then bunch much clearer. It is more code by is secondary at this point.
interface IInfoCheck
{
bool TryCheck(Info info, out string);
}
public OtherClass()
{
// Setup checks
CheckerCollection.add(new IInfoCheck{
public String check(out result) {
// check code
}
});
}
public String method(Info info) {
foreach (IInfoCheck ic in CheckerCollection)
{
String result = null;
if (ic.TryCheck(out result))
{
return result;
}
}
}
The problem statement does not fit into an ideal chain of responsibility scenario because it is either/or kind or conditions which look 'chained' but is actually 'not'. Reason - one processes all the chain-links in the chain of responsibility pattern irrespective of what happened in the previous links, i.e. no chain-links are skipped(although you can configure which chain links to process and which not - but still the execution of a chain-link is not dependent on the outcome of a previous chain-link). However, in this if-else-if* scenario - once an if statement condition matches, the further conditions are not evaluated.
I have thought of an alternative design which achieves the above without if-else, but it is lengthier but at the same time more flexible.
Lets say we have a FunctionalInterface IfElseReplacer which takes 'info' as input and gives 'String' output.
public Interface IfElseReplacer(){
public String executeCondition(Info);
}
Then the above conditions can be re-phrased as lambda expressions would look like -
"(Info info) -> info.someCondition ? someString"
"(Info info) -> info.anotherCondition ? someOtherString"
and so on...
Then we need a processConditons method to process these Lambdas- it could be a default method in ifElseReplacer -
default String processConditions(List<IfElseReplacer> ifElseReplacerList, Info info){
String strToReturn="lastButNotLeastString";
for(IfElseReplacer ifElseRep:ifElseReplacerList){
strToReturn=ifElseRep.executeCondition(info);
if(!"lastButNotLeastString".equals(strToReturn)){
break;//if strToReturn's value changes i.e. executeCondition returns a String valueother than "lastButNotLeastString" then exit the for loop
}
return strToReturn;
}
What remains now is to (I am skipping the code for this - please let me know if you need it then will write this also) -
From wherever the if-else conditions need to be checked there -
Create an array of lambda expressions as explained above assigning them to IfElseReplacer interfaces while adding them to a list of type IfElseReplacer.
Pass this list to the default method processConditions() along with an instance of Info.
Default method would return the String value which we would be same as the result of if-else-if* block given in the problem statement.
I'd simply factor out the returns:
return
info.isSomeBooleanCondition ? "someString" :
info.isSomeOtherCondition ? "someOtherString" :
info.anotherCondition ? "anotherStringAgain" :
lastCondition ? "string ..." :
"lastButNotLeastString"
;
From the limited information about the problem, and the code given, it looks like this a case of type-switching. The default solution would be to use a inheritance for that:
class Info {
public abstract String method();
};
class BooleanCondition extends Info {
public String method() {
return "something";
};
class SomeOther extends Info {
public String getString() {
return "somethingElse";
};
Patterns which are interesting in this case are Decorator, Strategy and Template Method. Chain of Responsibility has another focus. Each element in the chain implement logic to process some commands. When chained, an object forwards the command if it cannot process it. This implements a loosly coupled structure to process commands where no central dispatch is needed.
If computing the string on the conditions is an operation, and from the name of the class I am guessing that it is probably an expression tree, you should look at the Visitor pattern.
I have been struggling with this problem for a few hours now and I've searched for every term that made sense to me. I might even have already read through a relevant answer but didn't recognize it as such because I'm a little confused by pointers.
So, I have a struct that is part of an object which is part of a chain of objects that is "anchored" (if you can call it that) in another object, which is itself part of a chain which is "anchored" in an anchor object initialized in main.
struct values
{
double val, ues;
}
class small
{
public:
values vals;
}
class big
{
public:
small *small_anchor;
}
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
int main()
{
values *main_values=NULL;//This is supposed to be pointing to the "vals" struct contained inside the "small" object.
big *big_anchor;
big_anchor = new big;
big_anchor->small_anchor = new small;
big_anchor->small_anchor->vals.val=10;
big_anchor->small_anchor->vals.ues=5;
main_values = getPointerToStruct(&big_anchor);//now main_values should be pointing to the "vals" struct
//I want to manipulate the value INSIDE the object itself
main_values.val++;
}
I have tried every combination of &, * and no prefix I could come up with, but nothing would give the result I was hoping for. "Closest" I got was copying "vals" (from inside the object) into "main_values" so that I could manipulate the values there, which isn't of any use to me, as I want to manipulate the SOURCE of the variables.
Also please note that I left out the process of scrolling down the chains to get to the object I was trying to reach and that "return_vals" seems arbitrary, but it happens that there are two possible candidates that could be the struct my program is looking for and the "return_vals" contains the best candidate found so far and is overwritten when a better one is found, or returned when the routine ends.
You wrote
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
where I think you wanted
values *getPointerToStruct(big *con)
{
values *return_vals = 0;
if(con->small_anchor->vals.val==10)
return_vals=&con->small_anchor->vals;
return (return_vals);
}
But the . in main_values.val++; is wrong anyway. You need to be consistent about whether you wanted to work with a values* or a values&. You could make all this work with a values& if you like, but then main_values should be a values& and not declared until you are ready to initialize it. return_vals would not be practical as a values& because of the stated requirement that the full code gives it a tentative address that is conditionally modified later. But even with return_vals as a values* you could still return a values& if that is what you preferred.
I'm making Json format data editor with Qt treeview and Qt Json support.
I wanna pass QJsonObject or QJsonArray reference parameter to function.
This works:
void makeJsonData(QJsonObject &obj) {
obj.insert("key", 1234);
}
//call makeJsonData()
QJsonObject jobj;
makeJsonData(jobj);
int keysize = jobj.keys().size(); //1, OK.
But not with this:
//QJsonValue, because it can handle both QJsonObject and QJsonArray
void makeJsonData(QJsonValue &obj) {
obj.toObject().insert("key", 1234); //obj is QJsonObject
}
//call makeJsonData()
QJsonObject jobj;
makeJsonData(QJsonValue::fromVariant(jobj)); //fromVariant() to cast QJsonObject to QJsonValue
int keysize = jobj.keys().size(); //0, Fail.
It looks like QJsonValue::toObject() just copies parameter..
How can I use reference of both QJsonObject and QJsonArray with one parameter type?
There are a couple ways I see to solve your problem:
Option 1 (as mentioned in my comment)
A dynamic cast can be used like so:
bool makeJsonData(void* obj) {
QJsonObject* asObj = dynamic_cast<QJsonObject*>(obj);
QJsonArray* asArray = dynamic_cast<QJsonArray*>(obj);
if (asObj) {
//do what you would if it were an object
}
else if (asArray) {
//do what you would if it were an array
}
else {
//cast fail. Returning false to tell the caller that they passed bad data
//an alternate (probably better) would be to throw an exception
return false;
}
}
Option 2
I honestly feel that this business with void* is the wrong way to do it. Doing void* stuff is almost always a code smell (it removes compile-time checks that save us from stepping on their own feet) and in this case I think that the way you are doing this needs work. Also, dynamic_cast requires RTTI which may not always be turned on (compiler support, performance issues, etc).
I took a look at the Qt headers on my machine and as far as I can tell, QJsonObject and QJsonArray don't really inherit from anything, so going down the route of changing the void* to a base type in order to keep a semblance of type checking won't quite work.
What I would do would be this:
Make two separate methods. One for handling arrays and one for handling objects. They have different methods and different things you can do, so this makes sense to me. You could even keep the same name so that they are overloaded.
Have another method with your common stuff in it. I assume that your function is trying to add some data to either the array or object that is passed. Make a method that creates the data (i.e. QJsonObject createJsonData()) and call it inside both of your methods mentioned above.
The idea is to keep code repetition down while still preserving type checking. The time you spend making the one extra method to handle both cases could be far less than the time you will spend debugging code after accidentally passing in something to a void* pointer that you never meant to pass.
Option 3
Alternately, you could use QJsonValue, change the return type of the function to QJsonValue, and make it return the new object without modifying the original. Further, the QJsonValue class has those fun isArray/isObject methods that you could use to do something like mentioned earlier. An example:
QJsonValue makeJsonData(const QJsonValue& val) {
if (val.isObject()) {
QJsonObject obj = val.toObject();
//do your stuff, modifying obj as you please (perhaps calling another method so that this can have less repetition
return QJsonValue(obj);
}
else if (val.isArray()) {
QJsonArray arr = val.toArray();
//do your stuff, modifying arr as you please (perhaps calling another method so that this can have less repetition
return QJsonValue(arr);
}
else {
throw "Invalid Value Type";
}
}
I honestly prefer this pattern, but I know there are reasons for going the way you have mentioned such as avoiding gratuitous memory allocations.
You may need to add this:
#include <QJsonArray>
I am currently using Qt5.0 with the core QJson library to handle some data for the program I am developing.
To set the scene for this question I will provide you with some JSON data that illustrates my problem:
{
"CLOCKS": [
{
"ID": "clk",
"MAX": 2e+08,
"MIN": 1e+07,
"VALUE": "no_clock"
},
{
"ID": "memclk",
"MAX": 2e+08,
"MIN": 1e+07,
"VALUE": "memclk"
}
]
}
Here we have a parent QJsonObject containing a single key 'CLOCKS'. The value for this key is a QJsonArray of QJsonObjects that contain a number of key/value pairs that contain my data.
If I wanted to retrieve the QJsonObject with id 'clk' I am currently using code like this:
// imagine m_data is my parent QJsonObject
QJsonArray clocks = m_data["CLOCKS"].toArray();
foreach (const QJsonValue & value, clocks) {
QJsonObject obj = value.toObject();
if (obj["ID"].toString() == "clk") {
return obj;
}
}
This works fine and the library has been great so far. However, I have started running into issues recently when I want to obtain a QJsonObject reference for modification instead of a copy.
So my question is, given the sample data provided how do I obtain a QJsonObject reference in order to modify the key/value pairs in the desired clock data object. The problem manifests itself, IMO due to the fact that you can obtain QJsonValueRefs, which are references to the value entries... but to actually access the data inside this (if the value is another array/object) you must convert using the toArray(), toObject() functions etc. This functions only return copies and not references creating a barrier to iterating down the object hierarchy with references.
The only way I have come up with so far to get around this is to create a copy of the entire "CLOCKS" QJsonArray, find the object I want then delete it and reinsert it with the changed data... and finally assign the entire array back to the "CLOCKS" key in the parent object. This seems cumbersome enough to me to me that I feel like I am doing something wrong and there must be a better way.
To support this here is what my code looks like so far... just to change the "VALUE" for one of the clock QJsonObjects:
QJsonArray resets = m_data.value(TAG_RESETS).toArray();
// get a copy of the QJsonObject
QJsonObject obj;
foreach (const QJsonValue & value, resets) {
QJsonObject o = value.toObject();
if (o.value(TAG_ID).toString() == id) {
obj = o;
break;
}
}
// modify the object
obj[TAG_VALUE] = "NEW VALUE";
// erase the old instance of the object
for (auto it = resets.begin(); it != resets.end(); ++it) {
QJsonObject obj = (*it).toObject();
if (obj.value(TAG_ID).toString() == id) {
resets.erase(it);
// assign the array copy which has the object deleted
m_data[TAG_RESETS] = resets;
break;
}
}
// add the modified QJsonObject
resets.append(obj);
// replace the original array with the array containing our modified object
m_data[TAG_RESETS] = resets;
I know this could be shortened a little bit but it still seems like there must be a better way to change a single value in a QJson object hierarchy without going to all this effort!!!
After wasting three hours of my life I can confirm that as of today this is still impossible with Qt 5.4. You can modify JSON objects, but not nested JSON objects.
The problem is that the code such as:
json["aa"].toObject()["bb"] = 123;
essentially means the following:
QJsonObject temp = json["aa"].toObject();
temp["bb"] = 123;
and since temp is not a reference but object (and toObject() doesn't return a reference), the assignment is compiled but then discarded.
Essentially it breaks down to the fact that it is impossible to obtain the reference to an object you just created, meaning you cannot create them from left to right, i.e. aa["bb"] -> aa["bb"]["cc"] etc - you cannot obtain reference to aa["bb"], only a copy of its value.
What IS possible though is to recreate the JSON with a new value added, as described here: https://forum.qt.io/topic/25096/modify-nested-qjsonvalue/4 - note that this keeps recreating the object each time it is called, and is essentially memory usage disaster, but this is all Qt currently allows.
According to information from Qt developer who actually wrote QJson in Qt5 -
What's currently included in Qt is a 'read-only' implementation to provide parsing facilities. He has an intention to extend design with 'references' support in future, but it's not yet done.
I have had a similar problem for a couple of days and I have managed to find a workaround which works for me and I thought I should share it here.
You can navigate to the object whose key-value you wish to update. Then use the "remove" method to delete the key-value pair and then use the "insert" method to insert it again with the new value.
This might ruin the order of key-value pairs in your object but since you will anyways access by a key, it should not be a problem.
The in-place changing of values is not supported as I found out the hard way :)