summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2020-06-18 21:39:30 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2020-06-20 21:25:11 +0200
commitcb95276e6e6bf12a1c06d5c252551e55c788fcb2 (patch)
tree9e54d9ddbd03f02f508af48ce8dce02d5c83a277 /tools
parent292d9519bd368db69920cf0f8b94e0e51c3d14a1 (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.cxx38
-rw-r--r--tools/source/misc/json_writer.cxx117
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: */