2

Advance Thanks for the help.

I have a requirement to create array of json records of 10KB each. I am using rapidjson::writer and rapidjson::stringbuffer. I am getting Assertion error (at writer.h #488, !hasRoot_ error) for the below mentioned code piece:

rapidjson::StringBuffer s;
rapidjson::Writerrapidjson::StringBuffer writer(s);
writer.StartArray();

for (auto itr =myMap.begin(); itr != myMap.end(); itr++) {
writer.StartObject();
writer.Key(itr->first.c_str());
writer.String(itr->second.c_str());
writer.EndObject();
if (cond_matches) {
writer.EndArray();
Process( s.GetString() );
s.Clear();
writer.Reset(s); //(Without Resetting writer, next line seems to cause Assertion error.)
writer.StartArray(); //start another array of records
}
}

Error that I am getting:

../include/rapidjson/writer.h:488: void rapidjson::Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::Prefix(rapidjson::Type) [with OutputStream = rapidjson::GenericStringBuffer<rapidjson::UTF8<> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0]: Assertion `!hasRoot_' failed.

What am I doing wrong here? Any workaround for this use case? Thanks.

Expectation is that the entire entries in **myMap ** map should be converted to series of 10KB json records.

Edited: After adding writer.Reset(s) post s.clear() seems to have resolved the issue (As Peter suggested). One additional question: Is this code piece is bug free with respect to the way in which RapidJson Writer & Buffer is being used & JSON is being created?

Hegde
  • 21
  • 2
  • 1
    I don't think you can have two json array objects on the top-level. That's just not a valid json document. "[ ], [ ]" is not valid json, but packing it into another object or array should work i.e. "{ 'key1': [ ] , "key2": [ ] }" or "[ [ ] , [ ] ]" – PeterT Jun 21 '23 at 09:39
  • Thanks for the reply. Agree with you on valid JSON structure, but I am clearing the buffer on which previous record was written. My expectation is that when I write second array, I am writing it on an empty buffer which should be valid – Hegde Jun 21 '23 at 10:56
  • 2
    that may be, but the state is tracked inside the writer, not the stringbuffer from what I can tell. So maybe you should also call `writer.Reset(s);` after clearing the stringbuffer – PeterT Jun 21 '23 at 11:44
  • Thanks @PeterT. Resetting writer seems to have addressed the issue. One additional question: Can this solution/approach be better than what I have written here by still using rapidjson? – Hegde Jun 22 '23 at 05:41
  • I don't really know what you mean by better? There's stuff you could optimize if this function is limiting your runtime, but if it's not an issue I wouldn't make it more complicated. If i.e. the "Process" function takes some time you could put that into its own thread and have a couple stringbuffers that you queue for processing. So do the json conversion in one thread and "processing" the result in another thread. But if you want to optimize you should always profile first to make sure you need it. – PeterT Jun 22 '23 at 06:12
  • Oh, also if you have bad performance, the first thing to do would be to compile with optimizations enabled. You hit an assertion, so it seems like you're compiling in debug mode right now. – PeterT Jun 22 '23 at 06:14
  • Sorry word better was very generic & subjective. By "better", Is this code piece is bug free with respect to the way in which RapidJson Writer & Buffer is being used & JSON is being created? Additionally, Thanks for your insight into making "Process" function to run in other thread, but currently time optimization is not a priority & as you said it will become more complicated to spawn another thread for "Process" – Hegde Jun 23 '23 at 04:10

0 Answers0