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.

+3


source to share


1 answer


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 used GenericStringRef

    .
  • 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 using std::string

    , you can enable it. This should make it easier for you to work with std::string

    .
+7


source







All Articles