Bug 1774329 - JSONWriter() can be single-line from the top, removing the final newline - r=florian

Differential Revision: https://phabricator.services.mozilla.com/D152602
This commit is contained in:
Gerald Squelart 2022-07-28 12:41:54 +00:00
parent 9cb83c13c2
commit a05b4ea2c2
2 changed files with 55 additions and 10 deletions

View File

@ -245,8 +245,7 @@ class JSONWriter {
static constexpr Span<const char> scSpaceString = MakeStringSpan(" ");
static constexpr Span<const char> scTopObjectBeginString =
MakeStringSpan("{");
static constexpr Span<const char> scTopObjectEndString =
MakeStringSpan("}\n");
static constexpr Span<const char> scTopObjectEndString = MakeStringSpan("}");
static constexpr Span<const char> scTrueString = MakeStringSpan("true");
const UniquePtr<JSONWriteFunc> mWriter;
@ -303,13 +302,13 @@ class JSONWriter {
mNeedComma[mDepth] = true;
}
void NewVectorEntries() {
void NewVectorEntries(bool aNeedNewLines) {
// If these tiny allocations OOM we might as well just crash because we
// must be in serious memory trouble.
MOZ_RELEASE_ASSERT(mNeedComma.resizeUninitialized(mDepth + 1));
MOZ_RELEASE_ASSERT(mNeedNewlines.resizeUninitialized(mDepth + 1));
mNeedComma[mDepth] = false;
mNeedNewlines[mDepth] = true;
mNeedNewlines[mDepth] = aNeedNewLines;
}
void StartCollection(const Span<const char>& aMaybePropertyName,
@ -322,9 +321,7 @@ class JSONWriter {
mWriter->Write(aStartChar);
mNeedComma[mDepth] = true;
mDepth++;
NewVectorEntries();
mNeedNewlines[mDepth] =
mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle;
NewVectorEntries(mNeedNewlines[mDepth - 1] && aStyle == MultiLineStyle);
}
// Adds the whitespace and closing char necessary to end a collection.
@ -341,9 +338,10 @@ class JSONWriter {
}
public:
explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter)
explicit JSONWriter(UniquePtr<JSONWriteFunc> aWriter,
CollectionStyle aStyle = MultiLineStyle)
: mWriter(std::move(aWriter)), mNeedComma(), mNeedNewlines(), mDepth(0) {
NewVectorEntries();
NewVectorEntries(aStyle == MultiLineStyle);
}
// Returns the JSONWriteFunc passed in at creation, for temporary use. The
@ -362,7 +360,12 @@ class JSONWriter {
}
// Prints: } and final newline.
void End() { EndCollection(scTopObjectEndString); }
void End() {
EndCollection(scTopObjectEndString);
if (mNeedNewlines[mDepth]) {
mWriter->Write(scNewLineString);
}
}
// Prints: "<aName>": null
void NullProperty(const Span<const char>& aName) {

View File

@ -432,6 +432,47 @@ void TestOneLineObject() {
Check(w.WriteFunc(), expected);
}
void TestOneLineJson() {
const char* expected =
"\
{\"i\": 1, \"array\": [null, [{}], {\"o\": {}}, \"s\"], \"d\": 3.33}\
";
JSONWriter w(MakeUnique<StringWriteFunc>(), JSONWriter::SingleLineStyle);
w.Start(w.MultiLineStyle); // style overridden from above
w.IntProperty("i", 1);
w.StartArrayProperty("array");
{
w.NullElement();
w.StartArrayElement(w.MultiLineStyle); // style overridden from above
{
w.StartObjectElement();
w.EndObject();
}
w.EndArray();
w.StartObjectElement();
{
w.StartObjectProperty("o");
w.EndObject();
}
w.EndObject();
w.StringElement("s");
}
w.EndArray();
w.DoubleProperty("d", 3.33);
w.End(); // No newline in this case.
Check(w.WriteFunc(), expected);
}
void TestStringEscaping() {
// This test uses hexadecimal character escapes because UTF8 literals cause
// problems for some compilers (see bug 1069726).
@ -605,6 +646,7 @@ int main(void) {
TestBasicProperties();
TestBasicElements();
TestOneLineObject();
TestOneLineJson();
TestStringEscaping();
TestDeepNesting();
TestEscapedPropertyNames();