Commit eb90b3b1 authored by Gerald Squelart's avatar Gerald Squelart
Browse files

Bug 1784812 - JSONWriter may optionally not own its writer - r=canaltinova

mWriter is now a reference, and the ownership is optional through a separate
member variable that could stay null.
User can now choose to keep the JSONWriteFunc on their stack, which saves a
heap allocation, and makes it easier to access the concrete JSONWriteFunc
implementation directly (instead of through WriteFunc()).

Differential Revision: https://phabricator.services.mozilla.com/D154617
parent 24798f28
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -623,12 +623,8 @@ static bool PrepPing(const PingThreadContext& aContext, const std::wstring& aId,
}

static bool DoSendPing(const PingThreadContext& aContext) {
  auto writeFunc = mozilla::MakeUnique<TempFileWriter>();
  if (!(*writeFunc)) {
    return false;
  }

  mozilla::JSONWriter json(std::move(writeFunc));
  TempFileWriter tempFile;
  mozilla::JSONWriter json(tempFile);

  UUID uuid;
  if (::UuidCreate(&uuid) != RPC_S_OK) {
@@ -650,7 +646,6 @@ static bool DoSendPing(const PingThreadContext& aContext) {
  }

  // Obtain the name of the temp file that we have written
  TempFileWriter& tempFile = static_cast<TempFileWriter&>(json.WriteFunc());
  const std::wstring& fileName = tempFile.GetFileName();

  // Using the path to our executable binary, construct the path to
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ class ReportJSONWriter final : public JSONWriter {
                    const Span<const char>& aJSON) {
    Separator();
    PropertyNameAndColon(aProperty);
    mWriter->Write(aJSON);
    mWriter.Write(aJSON);
  }
};

+31 −20
Original line number Diff line number Diff line
@@ -250,14 +250,15 @@ class JSONWriter {
  static constexpr Span<const char> scTopObjectEndString = MakeStringSpan("}");
  static constexpr Span<const char> scTrueString = MakeStringSpan("true");

  const UniquePtr<JSONWriteFunc> mWriter;
  JSONWriteFunc& mWriter;
  const UniquePtr<JSONWriteFunc> mMaybeOwnedWriter;
  Vector<bool, 8> mNeedComma;     // do we need a comma at depth N?
  Vector<bool, 8> mNeedNewlines;  // do we need newlines at depth N?
  size_t mDepth;                  // the current nesting depth

  void Indent() {
    for (size_t i = 0; i < mDepth; i++) {
      mWriter->Write(scSpaceString);
      mWriter.Write(scSpaceString);
    }
  }

@@ -266,22 +267,22 @@ class JSONWriter {
  // before.
  void Separator() {
    if (mNeedComma[mDepth]) {
      mWriter->Write(scCommaString);
      mWriter.Write(scCommaString);
    }
    if (mDepth > 0 && mNeedNewlines[mDepth]) {
      mWriter->Write(scNewLineString);
      mWriter.Write(scNewLineString);
      Indent();
    } else if (mNeedComma[mDepth] && mNeedNewlines[0]) {
      mWriter->Write(scSpaceString);
      mWriter.Write(scSpaceString);
    }
  }

  void PropertyNameAndColon(const Span<const char>& aName) {
    mWriter->Write(scPropertyBeginString);
    mWriter->Write(EscapedString(aName).SpanRef());
    mWriter->Write(scPropertyEndString);
    mWriter.Write(scPropertyBeginString);
    mWriter.Write(EscapedString(aName).SpanRef());
    mWriter.Write(scPropertyEndString);
    if (mNeedNewlines[0]) {
      mWriter->Write(scSpaceString);
      mWriter.Write(scSpaceString);
    }
  }

@@ -291,7 +292,7 @@ class JSONWriter {
    if (!aMaybePropertyName.empty()) {
      PropertyNameAndColon(aMaybePropertyName);
    }
    mWriter->Write(aStringValue);
    mWriter.Write(aStringValue);
    mNeedComma[mDepth] = true;
  }

@@ -301,9 +302,9 @@ class JSONWriter {
    if (!aMaybePropertyName.empty()) {
      PropertyNameAndColon(aMaybePropertyName);
    }
    mWriter->Write(scQuoteString);
    mWriter->Write(aStringValue);
    mWriter->Write(scQuoteString);
    mWriter.Write(scQuoteString);
    mWriter.Write(aStringValue);
    mWriter.Write(scQuoteString);
    mNeedComma[mDepth] = true;
  }

@@ -323,7 +324,7 @@ class JSONWriter {
    if (!aMaybePropertyName.empty()) {
      PropertyNameAndColon(aMaybePropertyName);
    }
    mWriter->Write(aStartChar);
    mWriter.Write(aStartChar);
    mNeedComma[mDepth] = true;
    mDepth++;
    NewVectorEntries(mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle);
@@ -333,28 +334,38 @@ class JSONWriter {
  void EndCollection(const Span<const char>& aEndChar) {
    MOZ_ASSERT(mDepth > 0);
    if (mNeedNewlines[mDepth]) {
      mWriter->Write(scNewLineString);
      mWriter.Write(scNewLineString);
      mDepth--;
      Indent();
    } else {
      mDepth--;
    }
    mWriter->Write(aEndChar);
    mWriter.Write(aEndChar);
  }

 public:
  explicit JSONWriter(JSONWriteFunc& aWriter,
                      CollectionStyle aStyle = MultiLineStyle)
      : mWriter(aWriter), mNeedComma(), mNeedNewlines(), mDepth(0) {
    NewVectorEntries(aStyle == MultiLineStyle);
  }

  explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter,
                      CollectionStyle aStyle = MultiLineStyle)
      : mWriter(std::move(aWriter)), mNeedComma(), mNeedNewlines(), mDepth(0) {
      : mWriter(*aWriter),
        mMaybeOwnedWriter(std::move(aWriter)),
        mNeedComma(),
        mNeedNewlines(),
        mDepth(0) {
    MOZ_RELEASE_ASSERT(
        mWriter,
        mMaybeOwnedWriter,
        "JSONWriter must be given a non-null UniquePtr<JSONWriteFunc>");
    NewVectorEntries(aStyle == MultiLineStyle);
  }

  // Returns the JSONWriteFunc passed in at creation, for temporary use. The
  // JSONWriter object still owns the JSONWriteFunc.
  JSONWriteFunc& WriteFunc() const { return *mWriter.get(); }
  JSONWriteFunc& WriteFunc() const { return mWriter; }

  // For all the following functions, the "Prints:" comment indicates what the
  // basic output looks like. However, it doesn't indicate the whitespace and
@@ -371,7 +382,7 @@ class JSONWriter {
  void End() {
    EndCollection(scTopObjectEndString);
    if (mNeedNewlines[mDepth]) {
      mWriter->Write(scNewLineString);
      mWriter.Write(scNewLineString);
    }
  }

+2 −1
Original line number Diff line number Diff line
@@ -439,7 +439,8 @@ void TestOneLineJson() {
{\"i\":1,\"array\":[null,[{}],{\"o\":{}},\"s\"],\"d\":3.33}\
";

  JSONWriter w(MakeUnique<StringWriteFunc>(), JSONWriter::SingleLineStyle);
  StringWriteFunc func;
  JSONWriter w(func, JSONWriter::SingleLineStyle);

  w.Start(w.MultiLineStyle);  // style overridden from above

+2 −1
Original line number Diff line number Diff line
@@ -3028,7 +3028,8 @@ static void locked_profiler_save_profile_to_file(PSLockRef aLock,
  std::ofstream stream;
  stream.open(aFilename);
  if (stream.is_open()) {
    SpliceableJSONWriter w(MakeUnique<OStreamJSONWriteFunc>(stream));
    OStreamJSONWriteFunc jw(stream);
    SpliceableJSONWriter w(jw);
    w.Start();
    {
      locked_profiler_stream_json_for_this_process(aLock, w, /* sinceTime */ 0,
Loading