diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2020-06-18 21:39:30 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-06-20 21:25:11 +0200 |
commit | cb95276e6e6bf12a1c06d5c252551e55c788fcb2 (patch) | |
tree | 9e54d9ddbd03f02f508af48ce8dce02d5c83a277 /tools | |
parent | 292d9519bd368db69920cf0f8b94e0e51c3d14a1 (diff) |
use JsonWriter for the rest of ITiledRenderable
and fix bug in buffer reallacotion where mPos pointing
at the beginning of the new buffer instead of at the
correct index inside it.
Change-Id: Ie1ffaa176f6165e2cec85c93adc945312eff38e4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96650
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qa/cppunit/test_json_writer.cxx | 38 | ||||
-rw-r--r-- | tools/source/misc/json_writer.cxx | 117 |
2 files changed, 139 insertions, 16 deletions
diff --git a/tools/qa/cppunit/test_json_writer.cxx b/tools/qa/cppunit/test_json_writer.cxx index e27afc95f712..6a2cc7813574 100644 --- a/tools/qa/cppunit/test_json_writer.cxx +++ b/tools/qa/cppunit/test_json_writer.cxx @@ -30,12 +30,19 @@ public: virtual void setUp() override {} void test1(); + void test2(); CPPUNIT_TEST_SUITE(JsonWriterTest); CPPUNIT_TEST(test1); + CPPUNIT_TEST(test2); CPPUNIT_TEST_SUITE_END(); }; +struct Free +{ + void operator()(void* p) const { std::free(p); } +}; + void JsonWriterTest::test1() { tools::JsonWriter aJson; @@ -48,10 +55,6 @@ void JsonWriterTest::test1() aJson.put("int", 12); } - struct Free - { - void operator()(void* p) const { std::free(p); } - }; std::unique_ptr<char, Free> result(aJson.extractData()); CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"oustring\": \"val1\", \"ostring\": \"val2\", " @@ -59,6 +62,33 @@ void JsonWriterTest::test1() std::string(result.get())); } +void JsonWriterTest::test2() +{ + tools::JsonWriter aJson; + + { + auto testNode = aJson.startNode("node"); + aJson.put("field1", OUString("val1")); + aJson.put("field2", OUString("val2")); + { + auto testNode2 = aJson.startNode("node"); + aJson.put("field3", OUString("val3")); + { + auto testNode3 = aJson.startNode("node"); + aJson.put("field4", OUString("val4")); + aJson.put("field5", OUString("val5")); + } + } + } + + std::unique_ptr<char, Free> result(aJson.extractData()); + + CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"field1\": \"val1\", \"field2\": \"val2\", " + "\"node\": { \"field3\": \"val3\", \"node\": { \"field4\": " + "\"val4\", \"field5\": \"val5\"}}}}"), + std::string(result.get())); +} + CPPUNIT_TEST_SUITE_REGISTRATION(JsonWriterTest); } diff --git a/tools/source/misc/json_writer.cxx b/tools/source/misc/json_writer.cxx index 8a57e2ac337f..251c44c0246f 100644 --- a/tools/source/misc/json_writer.cxx +++ b/tools/source/misc/json_writer.cxx @@ -10,6 +10,7 @@ #include <tools/json_writer.hxx> #include <stdio.h> #include <cstring> +#include <rtl/strbuf.hxx> namespace tools { @@ -22,6 +23,7 @@ JsonWriter::JsonWriter() , mpBuffer(static_cast<char*>(malloc(mSpaceAllocated))) , mStartNodeCount(0) , mPos(mpBuffer) + , mbFirstFieldInNode(true) { *mPos = '{'; ++mPos; @@ -38,7 +40,10 @@ JsonWriter::~JsonWriter() ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName) { auto len = strlen(pNodeName); - ensureSpace(len + 4); + ensureSpace(len + 6); + + addCommaBeforeField(); + *mPos = '"'; ++mPos; memcpy(mPos, pNodeName, len); @@ -57,15 +62,70 @@ void JsonWriter::endNode() ensureSpace(1); *mPos = '}'; ++mPos; + mbFirstFieldInNode = false; } -void JsonWriter::put(const char* pPropName, const OUString& rPropVal) +ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName) +{ + auto len = strlen(pNodeName); + ensureSpace(len + 6); + + addCommaBeforeField(); + + *mPos = '"'; + ++mPos; + memcpy(mPos, pNodeName, len); + mPos += len; + strncpy(mPos, "\": [ ", 5); + mPos += 5; + mStartNodeCount++; + mbFirstFieldInNode = true; + return ScopedJsonWriterArray(*this); +} + +void JsonWriter::endArray() +{ + assert(mStartNodeCount && "mismatched StartNode/EndNode somewhere"); + --mStartNodeCount; + ensureSpace(1); + *mPos = ']'; + ++mPos; + mbFirstFieldInNode = false; +} + +ScopedJsonWriterStruct JsonWriter::startStruct() { + ensureSpace(6); + addCommaBeforeField(); + *mPos = '{'; + ++mPos; + *mPos = ' '; + ++mPos; + mStartNodeCount++; + mbFirstFieldInNode = true; + return ScopedJsonWriterStruct(*this); +} + +void JsonWriter::endStruct() +{ + assert(mStartNodeCount && "mismatched StartNode/EndNode somewhere"); + --mStartNodeCount; + ensureSpace(1); + *mPos = '}'; + ++mPos; + mbFirstFieldInNode = false; +} + +void JsonWriter::put(const char* pPropName, const OUString& rPropVal) +{ auto nPropNameLength = strlen(pPropName); auto nWorstCasePropValLength = rPropVal.getLength() * 2; - ensureSpace(nPropNameLength + nWorstCasePropValLength + 6); + ensureSpace(nPropNameLength + nWorstCasePropValLength + 8); + + addCommaBeforeField(); + *mPos = '"'; ++mPos; memcpy(mPos, pPropName, nPropNameLength); @@ -120,11 +180,12 @@ void JsonWriter::put(const char* pPropName, const OUString& rPropVal) void JsonWriter::put(const char* pPropName, const OString& rPropVal) { - addCommaBeforeField(); - auto nPropNameLength = strlen(pPropName); auto nWorstCasePropValLength = rPropVal.getLength(); - ensureSpace(nPropNameLength + nWorstCasePropValLength + 6); + ensureSpace(nPropNameLength + nWorstCasePropValLength + 8); + + addCommaBeforeField(); + *mPos = '"'; ++mPos; memcpy(mPos, pPropName, nPropNameLength); @@ -163,12 +224,13 @@ void JsonWriter::put(const char* pPropName, const OString& rPropVal) void JsonWriter::put(const char* pPropName, const char* pPropVal) { - addCommaBeforeField(); - auto nPropNameLength = strlen(pPropName); auto nPropValLength = strlen(pPropVal); auto nWorstCasePropValLength = nPropValLength * 2; - ensureSpace(nPropNameLength + nWorstCasePropValLength + 6); + ensureSpace(nPropNameLength + nWorstCasePropValLength + 8); + + addCommaBeforeField(); + *mPos = '"'; ++mPos; memcpy(mPos, pPropName, nPropNameLength); @@ -210,11 +272,12 @@ void JsonWriter::put(const char* pPropName, const char* pPropVal) void JsonWriter::put(const char* pPropName, int nPropVal) { - addCommaBeforeField(); - auto nPropNameLength = strlen(pPropName); auto nWorstCasePropValLength = 32; - ensureSpace(nPropNameLength + nWorstCasePropValLength + 6); + ensureSpace(nPropNameLength + nWorstCasePropValLength + 8); + + addCommaBeforeField(); + *mPos = '"'; ++mPos; memcpy(mPos, pPropName, nPropNameLength); @@ -225,6 +288,16 @@ void JsonWriter::put(const char* pPropName, int nPropVal) mPos += sprintf(mPos, "%d", nPropVal); } +void JsonWriter::putRaw(const rtl::OStringBuffer& rRawBuf) +{ + ensureSpace(rRawBuf.getLength() + 2); + + addCommaBeforeField(); + + memcpy(mPos, rRawBuf.getStr(), rRawBuf.getLength()); + mPos += rRawBuf.getLength(); +} + void JsonWriter::addCommaBeforeField() { if (mbFirstFieldInNode) @@ -238,12 +311,24 @@ void JsonWriter::addCommaBeforeField() } } +void JsonWriter::reallocBuffer(int noMoreBytesRequired) +{ + int currentUsed = mPos - mpBuffer; + auto newSize = std::max<int>(mSpaceAllocated * 2, (currentUsed + noMoreBytesRequired) * 2); + char* pNew = static_cast<char*>(malloc(newSize)); + memcpy(pNew, mpBuffer, currentUsed); + free(mpBuffer); + mpBuffer = pNew; + mPos = mpBuffer + currentUsed; +} + /** Hands ownership of the underlying storage buffer to the caller, * after this no more document modifications may be written. */ char* JsonWriter::extractData() { assert(mStartNodeCount == 0 && "did not close all nodes"); assert(mpBuffer && "data already extracted"); + ensureSpace(2); // add closing brace *mPos = '}'; ++mPos; @@ -255,5 +340,13 @@ char* JsonWriter::extractData() return pRet; } +OString JsonWriter::extractAsOString() +{ + char* pChar = extractData(); + OString ret(pChar); + free(pChar); + return ret; +} + } // namespace tools /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |