include/tools/json_writer.hxx     |   31 +++---
 tools/source/misc/json_writer.cxx |  183 +++++++++-----------------------------
 2 files changed, 65 insertions(+), 149 deletions(-)

New commits:
commit e8e244d93c02f4d5b58b9a29dd7fc0d69316888a
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Mon Apr 3 11:21:54 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 3 15:25:23 2023 +0200

    Simplify JsonWriter a bit
    
    Change-Id: I0ca4a0fcf4f19bc26ae931bae0b2ee53db47f12c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149951
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx
index 700e82b9a2c6..d0c057bc63bc 100644
--- a/include/tools/json_writer.hxx
+++ b/include/tools/json_writer.hxx
@@ -47,25 +47,28 @@ public:
     JsonWriter();
     ~JsonWriter();
 
-    [[nodiscard]] ScopedJsonWriterNode startNode(const char*);
-    [[nodiscard]] ScopedJsonWriterArray startArray(const char*);
+    [[nodiscard]] ScopedJsonWriterNode startNode(std::string_view);
+    [[nodiscard]] ScopedJsonWriterArray startArray(std::string_view);
     [[nodiscard]] ScopedJsonWriterStruct startStruct();
 
-    void put(const char* pPropName, const OUString& rPropValue);
+    void put(std::string_view pPropName, const OUString& rPropValue);
     // Assumes utf-8 property value encoding
-    void put(const char* pPropName, std::string_view rPropValue);
-    void put(const char* pPropName, const char* pPropVal)
+    void put(std::string_view pPropName, std::string_view rPropValue);
+    void put(std::string_view pPropName, const char* pPropVal)
     {
         put(pPropName, std::string_view(pPropVal));
     }
+    template <size_t N> void put(std::string_view pPropName, const char 
(&pPropVal)[N])
+    {
+        put(pPropName, std::string_view(pPropVal, N));
+    }
 
-    void put(const char* pPropName, sal_uInt16 nPropVal) { put(pPropName, 
sal_Int64(nPropVal)); }
-    void put(const char* pPropName, sal_Int16 nPropVal) { put(pPropName, 
sal_Int64(nPropVal)); }
-    void put(const char* pPropName, sal_Int32 nPropVal) { put(pPropName, 
sal_Int64(nPropVal)); }
-    void put(const char* pPropName, sal_uInt32 nPropVal) { put(pPropName, 
sal_Int64(nPropVal)); }
-    void put(const char* pPropName, sal_Int64);
-    void put(const char* pPropName, bool);
-    void put(const char* pPropName, double);
+    template <typename N, std::enable_if_t<std::is_arithmetic_v<N>, int> = 0>
+    void put(std::string_view pPropName, N n)
+    {
+        putLiteral(pPropName, OString::number(n));
+    }
+    void put(std::string_view pPropName, bool);
 
     void putSimpleValue(const OUString& rPropValue);
 
@@ -79,7 +82,7 @@ public:
     std::string extractAsStdString();
 
     /** returns true if the current JSON data matches the string */
-    bool isDataEquals(const std::string&) const;
+    bool isDataEquals(std::string_view) const;
 
 private:
     void endNode();
@@ -89,6 +92,8 @@ private:
     void writeEscapedOUString(const OUString& rPropVal);
     std::pair<char*, int> extractDataImpl();
     void ensureSpace(int noMoreBytesRequired);
+    void ensureSpaceAndWriteNameColon(std::string_view name, int valSize);
+    void putLiteral(std::string_view propName, std::string_view propValue);
 
     // overflow validation in debug mode
     static constexpr unsigned char JSON_WRITER_DEBUG_MARKER = 0xde;
diff --git a/tools/source/misc/json_writer.cxx 
b/tools/source/misc/json_writer.cxx
index 3d78f82e08e6..c5e92385904b 100644
--- a/tools/source/misc/json_writer.cxx
+++ b/tools/source/misc/json_writer.cxx
@@ -39,24 +39,13 @@ JsonWriter::~JsonWriter()
     free(mpBuffer);
 }
 
-ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName)
+ScopedJsonWriterNode JsonWriter::startNode(std::string_view pNodeName)
 {
-    auto len = strlen(pNodeName);
-    ensureSpace(len + 8);
+    putLiteral(pNodeName, "{ ");
 
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pNodeName, len);
-    mPos += len;
-    memcpy(mPos, "\": { ", 5);
-    mPos += 5;
     mStartNodeCount++;
     mbFirstFieldInNode = true;
 
-    validate();
-
     return ScopedJsonWriterNode(*this);
 }
 
@@ -72,24 +61,13 @@ void JsonWriter::endNode()
     validate();
 }
 
-ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName)
+ScopedJsonWriterArray JsonWriter::startArray(std::string_view pNodeName)
 {
-    auto len = strlen(pNodeName);
-    ensureSpace(len + 8);
+    putLiteral(pNodeName, "[ ");
 
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pNodeName, len);
-    mPos += len;
-    memcpy(mPos, "\": [ ", 5);
-    mPos += 5;
     mStartNodeCount++;
     mbFirstFieldInNode = true;
 
-    validate();
-
     return ScopedJsonWriterArray(*this);
 }
 
@@ -187,6 +165,9 @@ static bool writeEscapedSequence(sal_uInt32 ch, char*& pos)
 
 void JsonWriter::writeEscapedOUString(const OUString& rPropVal)
 {
+    *mPos = '"';
+    ++mPos;
+
     // Convert from UTF-16 to UTF-8 and perform escaping
     sal_Int32 i = 0;
     while (i < rPropVal.getLength())
@@ -228,50 +209,30 @@ void JsonWriter::writeEscapedOUString(const OUString& 
rPropVal)
         }
     }
 
+    *mPos = '"';
+    ++mPos;
+
     validate();
 }
 
-void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
+void JsonWriter::put(std::string_view pPropName, const OUString& rPropVal)
 {
-    auto nPropNameLength = strlen(pPropName);
-    // But values can be any UTF-8,
+    // Values can be any UTF-8,
     // if the string only contains of 0x2028, it will be expanded 6 times (see 
writeEscapedSequence)
-    auto nWorstCasePropValLength = rPropVal.getLength() * 6;
-    ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
-
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pPropName, nPropNameLength);
-    mPos += nPropNameLength;
-    memcpy(mPos, "\": \"", 4);
-    mPos += 4;
+    auto nWorstCasePropValLength = rPropVal.getLength() * 6 + 2;
+    ensureSpaceAndWriteNameColon(pPropName, nWorstCasePropValLength);
 
     writeEscapedOUString(rPropVal);
-
-    *mPos = '"';
-    ++mPos;
-
-    validate();
 }
 
-void JsonWriter::put(const char* pPropName, std::string_view rPropVal)
+void JsonWriter::put(std::string_view pPropName, std::string_view rPropVal)
 {
-    // we assume property names are ascii
-    auto nPropNameLength = strlen(pPropName);
-    // escaping can double the length
-    auto nWorstCasePropValLength = rPropVal.size() * 2;
-    ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
-
-    addCommaBeforeField();
+    // escaping can double the length, plus quotes
+    auto nWorstCasePropValLength = rPropVal.size() * 2 + 2;
+    ensureSpaceAndWriteNameColon(pPropName, nWorstCasePropValLength);
 
     *mPos = '"';
     ++mPos;
-    memcpy(mPos, pPropName, nPropNameLength);
-    mPos += nPropNameLength;
-    memcpy(mPos, "\": \"", 4);
-    mPos += 4;
 
     // copy and perform escaping
     for (size_t i = 0; i < rPropVal.size(); ++i)
@@ -311,92 +272,19 @@ void JsonWriter::put(const char* pPropName, 
std::string_view rPropVal)
     validate();
 }
 
-void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal)
-{
-    auto nPropNameLength = strlen(pPropName);
-    auto nWorstCasePropValLength = 32;
-    ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
-
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pPropName, nPropNameLength);
-    mPos += nPropNameLength;
-    memcpy(mPos, "\": ", 3);
-    mPos += 3;
-
-    // clang-format off
-    SAL_WNODEPRECATED_DECLARATIONS_PUSH // sprintf (macOS 13 SDK)
-    mPos += sprintf(mPos, "%" SAL_PRIdINT64, nPropVal);
-    SAL_WNODEPRECATED_DECLARATIONS_POP
-    // clang-format on
-
-    validate();
-}
-
-void JsonWriter::put(const char* pPropName, double fPropVal)
-{
-    OString sPropVal = rtl::math::doubleToString(fPropVal, 
rtl_math_StringFormat_F, 12, '.');
-    auto nPropNameLength = strlen(pPropName);
-    ensureSpace(nPropNameLength + sPropVal.getLength() + 8);
-
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pPropName, nPropNameLength);
-    mPos += nPropNameLength;
-    memcpy(mPos, "\": ", 3);
-    mPos += 3;
-
-    memcpy(mPos, sPropVal.getStr(), sPropVal.getLength());
-    mPos += sPropVal.getLength();
-
-    validate();
-}
-
-void JsonWriter::put(const char* pPropName, bool nPropVal)
+void JsonWriter::put(std::string_view pPropName, bool nPropVal)
 {
-    auto nPropNameLength = strlen(pPropName);
-    ensureSpace(nPropNameLength + 5 + 8);
-
-    addCommaBeforeField();
-
-    *mPos = '"';
-    ++mPos;
-    memcpy(mPos, pPropName, nPropNameLength);
-    mPos += nPropNameLength;
-    memcpy(mPos, "\": ", 3);
-    mPos += 3;
-
-    const char* pVal;
-    if (nPropVal)
-        pVal = "true";
-    else
-        pVal = "false";
-    memcpy(mPos, pVal, strlen(pVal));
-    mPos += strlen(pVal);
-
-    validate();
+    putLiteral(pPropName, nPropVal ? std::string_view("true") : 
std::string_view("false"));
 }
 
 void JsonWriter::putSimpleValue(const OUString& rPropVal)
 {
-    auto nWorstCasePropValLength = rPropVal.getLength() * 3;
+    auto nWorstCasePropValLength = rPropVal.getLength() * 6;
     ensureSpace(nWorstCasePropValLength + 4);
 
     addCommaBeforeField();
 
-    *mPos = '"';
-    ++mPos;
-
     writeEscapedOUString(rPropVal);
-
-    *mPos = '"';
-    ++mPos;
-
-    validate();
 }
 
 void JsonWriter::putRaw(std::string_view rRawBuf)
@@ -439,6 +327,30 @@ void JsonWriter::ensureSpace(int noMoreBytesRequired)
     }
 }
 
+void JsonWriter::ensureSpaceAndWriteNameColon(std::string_view name, int 
valSize)
+{
+    // we assume property names are ascii
+    ensureSpace(name.size() + valSize + 6);
+
+    addCommaBeforeField();
+
+    *mPos = '"';
+    ++mPos;
+    memcpy(mPos, name.data(), name.size());
+    mPos += name.size();
+    memcpy(mPos, "\": ", 3);
+    mPos += 3;
+}
+
+void JsonWriter::putLiteral(std::string_view propName, std::string_view 
propValue)
+{
+    ensureSpaceAndWriteNameColon(propName, propValue.size());
+    memcpy(mPos, propValue.data(), propValue.size());
+    mPos += propValue.size();
+
+    validate();
+}
+
 /** Hands ownership of the underlying storage buffer to the caller,
   * after this no more document modifications may be written. */
 std::pair<char*, int> JsonWriter::extractDataImpl()
@@ -472,10 +384,9 @@ std::string JsonWriter::extractAsStdString()
     return ret;
 }
 
-bool JsonWriter::isDataEquals(const std::string& s) const
+bool JsonWriter::isDataEquals(std::string_view s) const
 {
-    return s.length() == static_cast<size_t>(mPos - mpBuffer)
-           && memcmp(s.data(), mpBuffer, s.length()) == 0;
+    return std::string_view(mpBuffer, static_cast<size_t>(mPos - mpBuffer)) == 
s;
 }
 
 } // namespace tools

Reply via email to