desktop/source/lib/init.cxx       |   58 +++++++++++---------------------------
 include/tools/json_writer.hxx     |    2 +
 tools/source/misc/json_writer.cxx |   26 +++++++++++++++++
 vcl/jsdialog/jsdialogbuilder.cxx  |    3 -
 4 files changed, 46 insertions(+), 43 deletions(-)

New commits:
commit 178b15672b0e8b7f3a0ea1d6b2d46739b3c87f0e
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Fri May 19 13:45:22 2023 +0200
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Tue May 23 09:10:16 2023 +0200

    jsdialog: lazy json generation when closing tab in dialog
    
    After profiling Writer -> Format -> Character dialog
    I found that full dialog update happens while creating
    the dialog as some of the tabs are destroyed.
    
    Instead of instant JSON generation we should
    add the message to the queue and send it in idle time.
    Problem is that we are closing the tab and it's builder
    so we will not be able to do it later.
    
    So using jsdialog::SendFullUpdate trigger update in parent
    dialog which shares the same WINDOW_ID.
    
    This behaviour can be tested in Highlight tab when switching
    between "Color" and "None". As previous solution was introduced
    for it in:
    
    commit 41a1a2f04301dc22b156b4e11767859e40473897
    jsdialog: don't close dialog on tab page destroy
    
    Change-Id: I916250cf08d87c1109dc2db6dbbc1fbff7f48c07
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152008
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>

diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 359368f2a702..6944cc817af7 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -677,8 +677,7 @@ JSInstanceBuilder::~JSInstanceBuilder()
     // tab page closed -> refresh parent window
     if (m_bIsNestedBuilder && m_sTypeOfJSON == "dialog")
     {
-        sendFullUpdate(true);
-        flush();
+        jsdialog::SendFullUpdate(std::to_string(m_nWindowId), "__DIALOG__");
     }
 
     if (m_sTypeOfJSON == "popup")
commit 9a8c2106aede982007e15bdb1d0f2764a5610dde
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Thu May 18 15:00:38 2023 +0200
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Tue May 23 09:07:48 2023 +0200

    linking: api: use JsonWriter
    
    Change-Id: If5bf1897f1aef8db1672789cbee14b90cb96dc08
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151959
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 7da7aaad7444..1472bbeb6747 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -411,7 +411,7 @@ std::vector<beans::PropertyValue> 
desktop::jsonToPropertyValuesVector(const char
     return aArguments;
 }
 
-static bool extractLinks(const uno::Reference< container::XNameAccess >& 
xLinks, bool subcontent, OUStringBuffer& jsonText)
+static void extractLinks(const uno::Reference< container::XNameAccess >& 
xLinks, bool subcontent, tools::JsonWriter& aJson)
 {
     const uno::Sequence< OUString > aNames( xLinks->getElementNames() );
 
@@ -452,47 +452,27 @@ static bool extractLinks(const uno::Reference< 
container::XNameAccess >& xLinks,
 
                 if (subcontent)
                 {
-                    jsonText.append("\"");
-                    jsonText.append(aStrDisplayname);
-                    jsonText.append("\": \"");
-                    jsonText.append(aLink);
-                    jsonText.append("\"");
-                    if (i < nLinks-1)
-                    {
-                        jsonText.append(", ");
-                    }
+                    aJson.put(aStrDisplayname, aLink);
                 }
                 else
                 {
                     uno::Reference< lang::XServiceInfo > xSI( xTarget, 
uno::UNO_QUERY );
                     bIsTarget = xSI->supportsService( aProp_LinkTarget );
-                    if (i != 0)
-                    {
-                        if (!bIsTarget)
-                            jsonText.append("}");
-                        if (i < nLinks)
-                        {
-                            jsonText.append(", ");
-                        }
-                    }
-                    jsonText.append("\"");
-                    jsonText.append(aStrDisplayname);
-                    jsonText.append("\": ");
 
                     if (bIsTarget)
                     {
-                        jsonText.append("\"");
-                        jsonText.append(aLink);
-                        jsonText.append("\"");
+                        aJson.put(aStrDisplayname, aLink);
                         continue;
                     }
-                    jsonText.append("{");
-                }
+                    else
+                    {
+                        std::unique_ptr<char[], o3tl::free_delete> 
pName(convertOUString(aStrDisplayname));
+                        auto aNode = aJson.startNode(pName.get());
 
-                uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, 
uno::UNO_QUERY );
-                if( xLTS.is() )
-                {
-                    extractLinks(xLTS->getLinks(), true, jsonText);
+                        uno::Reference< document::XLinkTargetSupplier > xLTS( 
xTarget, uno::UNO_QUERY );
+                        if( xLTS.is() )
+                            extractLinks(xLTS->getLinks(), true, aJson);
+                    }
                 }
             }
             catch(...)
@@ -501,7 +481,6 @@ static bool extractLinks(const uno::Reference< 
container::XNameAccess >& xLinks,
             }
         }
     }
-    return bIsTarget;
 }
 
 static void unoAnyToJson(tools::JsonWriter& rJson, const char * pNodeName, 
const uno::Any& anyItem)
@@ -3144,15 +3123,12 @@ static char* lo_extractRequest(LibreOfficeKit* 
/*pThis*/, const char* pFilePath)
 
                 if( xLTS.is() )
                 {
-                    OUStringBuffer jsonText;
-                    jsonText.append("{ \"Targets\": { ");
-                    bool lastParentheses = extractLinks(xLTS->getLinks(), 
false, jsonText);
-                    jsonText.append("} }");
-                    if (!lastParentheses)
-                        jsonText.append(" }");
-
-                    OUString res(jsonText.makeStringAndClear());
-                    return convertOUString(res);
+                    tools::JsonWriter aJson;
+                    {
+                        auto aNode = aJson.startNode("Targets");
+                        extractLinks(xLTS->getLinks(), false, aJson);
+                    }
+                    return aJson.extractData();
                 }
                 xComp->dispose();
             }
diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx
index 700e82b9a2c6..b8b47ddb2ef8 100644
--- a/include/tools/json_writer.hxx
+++ b/include/tools/json_writer.hxx
@@ -51,6 +51,8 @@ public:
     [[nodiscard]] ScopedJsonWriterArray startArray(const char*);
     [[nodiscard]] ScopedJsonWriterStruct startStruct();
 
+    void put(const OUString& pPropName, const OUString& rPropValue);
+
     void put(const char* pPropName, const OUString& rPropValue);
     // Assumes utf-8 property value encoding
     void put(const char* pPropName, std::string_view rPropValue);
diff --git a/tools/source/misc/json_writer.cxx 
b/tools/source/misc/json_writer.cxx
index aea89a15d421..5bc718608d6a 100644
--- a/tools/source/misc/json_writer.cxx
+++ b/tools/source/misc/json_writer.cxx
@@ -231,6 +231,32 @@ void JsonWriter::writeEscapedOUString(const OUString& 
rPropVal)
     validate();
 }
 
+void JsonWriter::put(const OUString& pPropName, const OUString& rPropVal)
+{
+    auto nPropNameLength = pPropName.getLength();
+    // But 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;
+
+    writeEscapedOUString(pPropName);
+
+    memcpy(mPos, "\": \"", 4);
+    mPos += 4;
+
+    writeEscapedOUString(rPropVal);
+
+    *mPos = '"';
+    ++mPos;
+
+    validate();
+}
+
 void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
 {
     auto nPropNameLength = strlen(pPropName);

Reply via email to