Is there a way to use quickjson efficiently with std :: string?
I am trying to work with fastjson.
I want to generate a string and add it to some rapidjson::Value
that is an object.
I used std :: string when working with qjson, but in the case of quickjson, it seems out of place. I don't want to generate a string and then copy it, end of object lifecycle before object ( rapidjson::Value
) lifetime (so generated_string.c_str()
not the case). There may be \ 0 in json, so char*
a null terminated string is not a solution either.
So, should I write my own string type? Or use something like
auto create_string_object() -> rapidjson::GenericStringRef<char>
{
size_t len;
char* result;
// generate char* result with length len
const char* return_value = result;
return rapidjson::StringRef(return_value,len);
}
auto create_object_object(rapidjson::Document::AllocatorType &allocator) -> rapidjson::Value
{
// ...
rapidjson::Value result(rapidjson::kObjectType);
rapidjson::Value tmp; // tmp = create_string_object() will not compile
tmp = create_string_object();
result.AddMember("key", tmp, allocator);
// ...
}
Or are there other ways to work with strings? This seems difficult to me. We cannot move the string in rapidjson::Value
because of the different structures inside Value
, we cannot set the pointer inside Value
to c_str()
because the string will be destroyed before Value
. Even with GenericStringRef<char>
I have to rewrite almost all of the string work.
By the way, why RAPIDJSON_HAS_STDSTRING
is 0 by default? Some problems with work? I see that I can copy the string to rapidjson::Value
and copy the pointer if I know the string's lifetime will end before the lifetime value.
UPD: Now I see that quickjson only frees the copied lines:
//! Destructor.
/*! Need to destruct elements of array, members of object, or copy-string.
*/
~GenericValue() {
if (Allocator::kNeedFree) { // Shortcut by Allocator trait
switch(flags_) {
case kArrayFlag:
for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
v->~GenericValue();
Allocator::Free(data_.a.elements);
break;
case kObjectFlag:
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
m->~Member();
Allocator::Free(data_.o.members);
break;
case kCopyStringFlag:
Allocator::Free(const_cast<Ch*>(data_.s.str));
break;
default:
break; // Do nothing for other types.
}
}
}
So, as the answer said, using GenericStringRef
in a way like in my code is a bad idea because then I have to manage the memory myself.
source to share
I don't quite understand the question. But I'm trying to clear up a few things here.
-
GenericStringRef
used to prevent copying of lines. It should only be used if the string's lifetime is known to be sufficient. For a dynamically generated string, generally shouldn't be usedGenericStringRef
. - The setting is
RAPIDJSON_HAS_STDSTRING=1
fine. It is not enabled by default because support for it is added after an early release. And I don't want the RapidJSON header to include<string>
unless the user needs it. Since you are usingstd::string
, you can enable it. This should make it easier for you to work withstd::string
.
source to share