fix leaks when using tools::JsonWriter

Specifically in sd/source/core/annotations/Annotation.cxx

We seem to end up fixing leaks here often.
The current tools::JsonWriter API is just very hard to use correctly.

So rather return an OString, which is cheap to copy,
and push that down into the LOK code.

AFAIK that seems to end up requiring less code and less adhoc copying
of data (specifically the queueing code in init.cxx was creating
copies when converting to std::string).

Ideally, we could have some special API to avoid the new strdup()
calls in init.cxx, but not sure how to prevent other people
from accidentally using that.

Change-Id: Ia33437c1bfd9cc2d54dfb99914d1b72db20335f2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149963
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2023-04-05 17:02:46 +02:00
committed by Noel Grandin
parent e4042da6e6
commit e57d5daaea
36 changed files with 176 additions and 199 deletions
+14 -14
View File
@@ -86,7 +86,7 @@ namespace desktop {
return m_aRectangle.IsEmpty();
}
static RectangleAndPart Create(const std::string& rPayload);
static RectangleAndPart Create(const OString& rPayload);
/// Makes sure a rectangle is valid (apparently some code does not like negative coordinates for example).
static tools::Rectangle SanitizedRectangle(tools::Long nLeft, tools::Long nTop, tools::Long nWidth, tools::Long nHeight);
static tools::Rectangle SanitizedRectangle(const tools::Rectangle& rect);
@@ -100,7 +100,7 @@ namespace desktop {
virtual ~CallbackFlushHandler() override;
virtual void Invoke() override;
// TODO This should be dropped and the binary libreOfficeKitViewCallback() variants should be called?
void queue(const int type, const char* data);
void queue(const int type, const OString& data);
/// Disables callbacks on this handler. Must match with identical count
/// of enableCallbacks. Used during painting and changing views.
@@ -117,8 +117,8 @@ namespace desktop {
void setViewId( int viewId ) { m_viewId = viewId; }
// SfxLockCallbackInterface
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) override;
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) override;
virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode) override;
virtual void libreOfficeKitViewUpdatedCallback(int nType) override;
virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) override;
@@ -128,13 +128,13 @@ namespace desktop {
private:
struct CallbackData
{
CallbackData(const char* payload)
: PayloadString(payload ? payload : "(nil)")
CallbackData(OString payload)
: PayloadString(payload)
{
}
CallbackData(const char* payload, int viewId)
: PayloadString(payload ? payload : "(nil)")
CallbackData(OString payload, int viewId)
: PayloadString(payload)
, PayloadObject(viewId)
{
}
@@ -149,7 +149,7 @@ namespace desktop {
{ // PayloadString will be done on demand
}
const std::string& getPayload() const;
const OString& getPayload() const;
/// Update a RectangleAndPart object and update PayloadString if necessary.
void updateRectangleAndPart(const RectangleAndPart& rRectAndPart);
/// Return the parsed RectangleAndPart instance.
@@ -165,7 +165,7 @@ namespace desktop {
bool isEmpty() const
{
return PayloadString.empty() && PayloadObject.which() == 0;
return PayloadString.isEmpty() && PayloadObject.which() == 0;
}
void clear()
{
@@ -180,7 +180,7 @@ namespace desktop {
bool isCached() const { return PayloadObject.which() != 0; }
private:
mutable std::string PayloadString;
mutable OString PayloadString;
/// The parsed payload cache. Update validate() when changing this.
mutable boost::variant<boost::blank, RectangleAndPart, boost::property_tree::ptree, int> PayloadObject;
@@ -204,9 +204,9 @@ namespace desktop {
so we split the queue in 2 to make the scanning cache friendly. */
queue_type1 m_queue1;
queue_type2 m_queue2;
std::map<int, std::string> m_states;
std::unordered_map<std::string, std::string> m_lastStateChange;
std::unordered_map<int, std::unordered_map<int, std::string>> m_viewStates;
std::map<int, OString> m_states;
std::unordered_map<OString, OString> m_lastStateChange;
std::unordered_map<int, std::unordered_map<int, OString>> m_viewStates;
// For some types only the last message matters (see isUpdatedType()) or only the last message
// per each viewId value matters (see isUpdatedTypePerViewId()), so instead of using push model
+3 -3
View File
@@ -2578,7 +2578,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
tools::JsonWriter aJson;
addParameter(aJson, "Text", "string", "Comment");
addParameter(aJson, "Author", "string", "LOK User1");
aCommandArgs = aJson.extractAsOString();
aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", aCommandArgs.getStr(), false);
@@ -2593,7 +2593,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
tools::JsonWriter aJson;
addParameter(aJson, "Id", "string", OString::number(nCommentId1));
addParameter(aJson, "Text", "string", "Edited comment");
aCommandArgs = aJson.extractAsOString();
aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:EditAnnotation", aCommandArgs.getStr(), false);
@@ -2607,7 +2607,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
{
tools::JsonWriter aJson;
addParameter(aJson, "Id", "string", OString::number(nCommentId1));
aCommandArgs = aJson.extractAsOString();
aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:DeleteAnnotation", aCommandArgs.getStr(), false);
Scheduler::ProcessEventsToIdle();
+49 -49
View File
@@ -517,29 +517,29 @@ static void unoAnyToJson(tools::JsonWriter& rJson, const char * pNodeName, const
}
}
static int lcl_getViewId(const std::string& payload);
static int lcl_getViewId(std::string_view payload);
namespace desktop {
RectangleAndPart RectangleAndPart::Create(const std::string& rPayload)
RectangleAndPart RectangleAndPart::Create(const OString& rPayload)
{
RectangleAndPart aRet;
if (rPayload.compare(0, 5, "EMPTY") == 0) // payload starts with "EMPTY"
if (rPayload.startsWith("EMPTY")) // payload starts with "EMPTY"
{
aRet.m_aRectangle = tools::Rectangle(0, 0, SfxLokHelper::MaxTwips, SfxLokHelper::MaxTwips);
if (comphelper::LibreOfficeKit::isPartInInvalidation())
{
int nSeparatorPos = rPayload.find(',', 6);
int nSeparatorPos = rPayload.indexOf(',', 6);
bool bHasMode = nSeparatorPos > 0;
if (bHasMode)
{
aRet.m_nPart = std::stol(rPayload.substr(6, nSeparatorPos - 6));
assert(rPayload.length() > o3tl::make_unsigned(nSeparatorPos));
aRet.m_nMode = std::stol(rPayload.substr(nSeparatorPos + 1));
aRet.m_nPart = o3tl::toInt32(rPayload.subView(6, nSeparatorPos - 6));
assert(rPayload.getLength() > nSeparatorPos);
aRet.m_nMode = o3tl::toInt32(rPayload.subView(nSeparatorPos + 1));
}
else
{
aRet.m_nPart = std::stol(rPayload.substr(6));
aRet.m_nPart = o3tl::toInt32(rPayload.subView(6));
aRet.m_nMode = 0;
}
}
@@ -548,8 +548,8 @@ RectangleAndPart RectangleAndPart::Create(const std::string& rPayload)
}
// Read '<left>, <top>, <width>, <height>[, <part>, <mode>]'. C++ streams are simpler but slower.
const char* pos = rPayload.c_str();
const char* end = rPayload.c_str() + rPayload.size();
const char* pos = rPayload.getStr();
const char* end = rPayload.getStr() + rPayload.getLength();
tools::Long nLeft = rtl_str_toInt64_WithLength(pos, 10, end - pos);
while( *pos != ',' )
++pos;
@@ -622,9 +622,9 @@ tools::Rectangle RectangleAndPart::SanitizedRectangle(const tools::Rectangle& re
return SanitizedRectangle(rect.Left(), rect.Top(), rect.getOpenWidth(), rect.getOpenHeight());
}
const std::string& CallbackFlushHandler::CallbackData::getPayload() const
const OString& CallbackFlushHandler::CallbackData::getPayload() const
{
if(PayloadString.empty())
if(PayloadString.isEmpty())
{
// Do to-string conversion on demand, as many calls will get dropped without
// needing the string.
@@ -667,7 +667,7 @@ void CallbackFlushHandler::CallbackData::setJson(const boost::property_tree::ptr
std::stringstream aJSONStream;
constexpr bool bPretty = false; // Don't waste time and bloat logs.
boost::property_tree::write_json(aJSONStream, rTree, bPretty);
PayloadString = boost::trim_copy(aJSONStream.str());
PayloadString = OString(o3tl::trim(aJSONStream.str()));
PayloadObject = rTree;
}
@@ -706,7 +706,7 @@ bool CallbackFlushHandler::CallbackData::validate() const
std::stringstream aJSONStream;
boost::property_tree::write_json(aJSONStream, getJson(), false);
const std::string aExpected = boost::trim_copy(aJSONStream.str());
return aExpected == getPayload();
return getPayload() == std::string_view(aExpected);
}
// View id.
@@ -764,7 +764,7 @@ static bool isUpdatedTypePerViewId(int type)
}
}
static int lcl_getViewId(const std::string& payload)
static int lcl_getViewId(std::string_view payload)
{
// this is a cheap way how to get the viewId from a JSON message; proper
// parsing is terribly expensive, and we just need the viewId here
@@ -783,7 +783,7 @@ static int lcl_getViewId(const std::string& payload)
}
if (numberPos < payload.length() && payload[numberPos] >= '0' && payload[numberPos] <= '9')
return strtol(payload.substr(numberPos).c_str(), nullptr, 10);
return o3tl::toInt32(payload.substr(numberPos));
return 0;
}
@@ -1597,13 +1597,13 @@ void CallbackFlushHandler::resetUpdatedTypePerViewId( int nType, int nViewId )
}
}
void CallbackFlushHandler::libreOfficeKitViewCallback(int nType, const char* pPayload)
void CallbackFlushHandler::libreOfficeKitViewCallback(int nType, const OString& pPayload)
{
CallbackData callbackData(pPayload);
queue(nType, callbackData);
}
void CallbackFlushHandler::libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId)
void CallbackFlushHandler::libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId)
{
CallbackData callbackData(pPayload, nViewId);
queue(nType, callbackData);
@@ -1654,7 +1654,7 @@ void CallbackFlushHandler::libreOfficeKitViewAddPendingInvalidateTiles()
startTimer();
}
void CallbackFlushHandler::queue(const int type, const char* data)
void CallbackFlushHandler::queue(const int type, const OString& data)
{
CallbackData callbackData(data);
queue(type, callbackData);
@@ -1709,9 +1709,9 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// Suppress invalid payloads.
if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
aCallbackData.getPayload().find(", 0, 0, ") != std::string::npos &&
aCallbackData.getPayload().find("\"hyperlink\":\"\"") == std::string::npos &&
aCallbackData.getPayload().find("\"hyperlink\": {}") == std::string::npos)
aCallbackData.getPayload().indexOf(", 0, 0, ") != -1 &&
aCallbackData.getPayload().indexOf("\"hyperlink\":\"\"") == -1 &&
aCallbackData.getPayload().indexOf("\"hyperlink\": {}") == -1)
{
// The cursor position is often the relative coordinates of the widget
// issuing it, instead of the absolute one that we expect.
@@ -1843,8 +1843,8 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// deleting the duplicate of visible cursor message can cause hyperlink popup not to show up on second/or more click on the same place.
// If the hyperlink is not empty we can bypass that to show the popup
const bool hyperLinkException = type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
aCallbackData.getPayload().find("\"hyperlink\":\"\"") == std::string::npos &&
aCallbackData.getPayload().find("\"hyperlink\": {}") == std::string::npos;
aCallbackData.getPayload().indexOf("\"hyperlink\":\"\"") == -1 &&
aCallbackData.getPayload().indexOf("\"hyperlink\": {}") == -1;
if(!hyperLinkException)
{
const int nViewId = aCallbackData.getViewId();
@@ -1866,16 +1866,16 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
case LOK_CALLBACK_STATE_CHANGED:
{
// Compare the state name=value and overwrite earlier entries with same name.
const auto pos = aCallbackData.getPayload().find('=');
if (pos != std::string::npos)
const auto pos = aCallbackData.getPayload().indexOf('=');
if (pos != -1)
{
const std::string name = aCallbackData.getPayload().substr(0, pos + 1);
const std::string_view name = aCallbackData.getPayload().subView(0, pos + 1);
// This is needed because otherwise it creates some problems when
// a save occurs while a cell is still edited in Calc.
if (name != ".uno:ModifiedStatus=")
{
removeAll(type, [&name] (const CallbackData& elemData) {
return (elemData.getPayload().compare(0, name.size(), name) == 0);
return elemData.getPayload().startsWith(name);
}
);
}
@@ -1893,7 +1893,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// remove only selection ranges and 'EMPTY' messages
// always send 'INPLACE' and 'INPLACE EXIT' messages
removeAll(type, [] (const CallbackData& elemData)
{ return (elemData.getPayload().find("INPLACE") == std::string::npos); });
{ return (elemData.getPayload().indexOf("INPLACE") == -1); });
}
break;
}
@@ -2055,9 +2055,9 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
bool CallbackFlushHandler::processWindowEvent(int type, CallbackData& aCallbackData)
{
const std::string& payload = aCallbackData.getPayload();
const OString& payload = aCallbackData.getPayload();
boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
boost::property_tree::ptree& aTree = aCallbackData.setJson(payload.getStr());
const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
const std::string aAction = aTree.get<std::string>("action", "");
if (aAction == "invalidate")
@@ -2299,7 +2299,7 @@ void CallbackFlushHandler::enqueueUpdatedType( int type, const SfxViewShell* vie
std::optional<OString> payload = viewShell->getLOKPayload( type, viewId );
if(!payload)
return; // No actual payload to send.
CallbackData callbackData(payload->getStr(), viewId);
CallbackData callbackData(*payload, viewId);
m_queue1.emplace_back(type);
m_queue2.emplace_back(callbackData);
SAL_INFO("lok", "Queued updated [" << type << "]: [" << callbackData.getPayload()
@@ -2341,13 +2341,13 @@ void CallbackFlushHandler::Invoke()
// common code-path for events on this view:
if (viewId == -1)
{
size_t idx;
sal_Int32 idx;
// key-value pairs
if (type == LOK_CALLBACK_STATE_CHANGED &&
(idx = payload.find('=')) != std::string::npos)
(idx = payload.indexOf('=')) != -1)
{
std::string key = payload.substr(0, idx);
std::string value = payload.substr(idx+1);
OString key = payload.copy(0, idx);
OString value = payload.copy(idx+1);
const auto stateIt = m_lastStateChange.find(key);
if (stateIt != m_lastStateChange.end())
{
@@ -2409,7 +2409,7 @@ void CallbackFlushHandler::Invoke()
}
}
m_pCallback(type, payload.c_str(), m_pData);
m_pCallback(type, payload.getStr(), m_pData);
}
m_queue1.clear();
@@ -4357,7 +4357,7 @@ static char* getPostIts(LibreOfficeKitDocument* pThis)
}
tools::JsonWriter aJsonWriter;
pDoc->getPostIts(aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
/// Returns the JSON representation of the positions of all the comments in the document
@@ -4372,7 +4372,7 @@ static char* getPostItsPos(LibreOfficeKitDocument* pThis)
}
tools::JsonWriter aJsonWriter;
pDoc->getPostItsPos(aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
static char* getRulerState(LibreOfficeKitDocument* pThis)
@@ -4386,7 +4386,7 @@ static char* getRulerState(LibreOfficeKitDocument* pThis)
}
tools::JsonWriter aJsonWriter;
pDoc->getRulerState(aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode)
@@ -4635,7 +4635,7 @@ public:
}
unoAnyToJson(aJson, "result", rEvent.Result);
mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
virtual void SAL_CALL disposing(const css::lang::EventObject&) override {}
@@ -4829,7 +4829,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
tools::JsonWriter aJson;
aJson.put("commandName", pCommand);
aJson.put("success", bResult);
pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
return;
}
@@ -4867,7 +4867,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
aJson.put("type", "string");
aJson.put("value", "unmodified");
}
pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
return;
}
}
@@ -6049,7 +6049,7 @@ static char* getTrackedChanges(LibreOfficeKitDocument* pThis)
pDoc->getTrackedChanges(aJson);
}
return aJson.extractData();
return strdup(aJson.finishAndGetAsOString().getStr());
}
@@ -6064,7 +6064,7 @@ static char* getTrackedChangeAuthors(LibreOfficeKitDocument* pThis)
}
tools::JsonWriter aJsonWriter;
pDoc->getTrackedChangeAuthors(aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand)
@@ -6170,7 +6170,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
tools::JsonWriter aJsonWriter;
pDoc->getRowColumnHeaders(aRectangle, aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
else if (o3tl::starts_with(aCommand, aSheetGeometryData))
{
@@ -6236,7 +6236,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
// Ignore command's deprecated parameters.
tools::JsonWriter aJsonWriter;
pDoc->getCellCursor(aJsonWriter);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
else if (o3tl::starts_with(aCommand, aFontSubset))
{
@@ -6246,7 +6246,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
{
tools::JsonWriter aJsonWriter;
pDoc->getCommandValues(aJsonWriter, aCommand);
return aJsonWriter.extractData();
return strdup(aJsonWriter.finishAndGetAsOString().getStr());
}
else
{
@@ -7011,7 +7011,7 @@ static char* lo_getFilterTypes(LibreOfficeKit* pThis)
}
}
return aJson.extractData();
return strdup(aJson.finishAndGetAsOString().getStr());
}
static void lo_setOptionalFeatures(LibreOfficeKit* pThis, unsigned long long const features)
+2 -2
View File
@@ -120,9 +120,9 @@ void LOKInteractionHandler::postError(css::task::InteractionClassification class
std::size_t nView = SfxViewShell::Current() ? SfxLokHelper::getView() : 0;
if (m_pLOKDocument && m_pLOKDocument->mpCallbackFlushHandlers.count(nView))
m_pLOKDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_ERROR, aJson.extractAsOString().getStr());
m_pLOKDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_ERROR, aJson.finishAndGetAsOString());
else if (m_pLOKit->mpCallback)
m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aJson.extractAsOString().getStr(), m_pLOKit->mpCallbackData);
m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aJson.finishAndGetAsOString().getStr(), m_pLOKit->mpCallbackData);
}
namespace {
+2 -2
View File
@@ -369,8 +369,8 @@ public:
class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI OutlinerViewShell
{
public:
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const = 0;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) const = 0;
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) const = 0;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) const = 0;
virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode) const = 0;
virtual void libreOfficeKitViewUpdatedCallback(int nType) const = 0;
virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) const = 0;
+4 -2
View File
@@ -13,6 +13,7 @@
namespace rtl
{
class OString;
class OStringBuffer;
}
namespace tools
@@ -32,9 +33,10 @@ class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI SfxLokCallbackInterface
public:
virtual ~SfxLokCallbackInterface() {}
// LibreOfficeKitCallback equivalent.
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) = 0;
virtual void libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload) = 0;
// Callback that explicitly provides view id (which is also included in the payload).
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId)
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const rtl::OString& pPayload,
int nViewId)
= 0;
// LOK_CALLBACK_INVALIDATE_TILES
// nPart is either part, -1 for all-parts, or INT_MIN if
+2 -2
View File
@@ -370,8 +370,8 @@ public:
/// dump view state for diagnostics
void dumpLibreOfficeKitViewState(rtl::OStringBuffer &rState);
/// Invokes the registered callback, if there are any.
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) const override;
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) const override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) const override;
virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode) const override;
virtual void libreOfficeKitViewUpdatedCallback(int nType) const override;
virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) const override;
+2 -2
View File
@@ -31,8 +31,8 @@ public:
void clear();
/// Set the view id of the associated SfxViewShell.
void setLOKViewId(int viewId) { m_viewId = viewId; }
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload,
virtual void libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload) override;
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const rtl::OString& pPayload,
int nViewId) override;
virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart,
int nMode) override;
+5 -6
View File
@@ -42,6 +42,7 @@ class TOOLS_DLLPUBLIC JsonWriter
int mSpaceAllocated;
int mStartNodeCount;
bool mbFirstFieldInNode;
bool mbClosed; // cannot add to it anymore
public:
JsonWriter();
@@ -75,11 +76,9 @@ public:
/// This assumes that this data belongs at this point in the stream, and is valid, and properly encoded
void putRaw(std::string_view);
/** Hands ownership of the underlying storage buffer to the caller,
* after this no more document modifications may be written. */
char* extractData() { return extractDataImpl().first; }
OString extractAsOString();
std::string extractAsStdString();
/** Closes the tags, and returns data.
* After this no more document modifications may be written. */
OString finishAndGetAsOString();
/** returns true if the current JSON data matches the string */
bool isDataEquals(std::string_view) const;
@@ -90,7 +89,7 @@ private:
void endStruct();
void addCommaBeforeField();
void writeEscapedOUString(const OUString& rPropVal);
std::pair<char*, int> extractDataImpl();
void closeDocument();
void ensureSpace(int noMoreBytesRequired);
void ensureSpaceAndWriteNameColon(std::string_view name, int valSize);
void putLiteral(std::string_view propName, std::string_view propValue);
+1 -1
View File
@@ -38,7 +38,7 @@ public:
const OUString& rAction,
const std::vector<LOKPayloadItem>& rPayload = std::vector<LOKPayloadItem>()) const = 0;
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const = 0;
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) const = 0;
/// Emits a LOK_CALLBACK_INVALIDATE_TILES.
virtual void notifyInvalidation(tools::Rectangle const *) const = 0;
+1 -1
View File
@@ -1364,7 +1364,7 @@ public:
virtual void notifyWindow(vcl::LOKWindowId nLOKWindowId,
const OUString& rAction,
const std::vector<vcl::LOKPayloadItem>& rPayload = std::vector<vcl::LOKPayloadItem>()) const override;
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) const override;
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) const override;
virtual void notifyInvalidation(tools::Rectangle const *) const override;
+7 -7
View File
@@ -1825,7 +1825,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testGetRowColumnHeadersInvalidation)
aView1.m_aInvalidations.clear();
tools::JsonWriter aJsonWriter1;
pModelObj->getRowColumnHeaders(tools::Rectangle(0, 15, 19650, 5400), aJsonWriter1);
free(aJsonWriter1.extractData());
aJsonWriter1.finishAndGetAsOString();
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(aView1.m_bInvalidateTiles);
CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size());
@@ -1836,7 +1836,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testGetRowColumnHeadersInvalidation)
aView1.m_aInvalidations.clear();
tools::JsonWriter aJsonWriter2;
pModelObj->getRowColumnHeaders(tools::Rectangle(0, 5400, 19650, 9800), aJsonWriter2);
free(aJsonWriter2.extractData());
aJsonWriter2.finishAndGetAsOString();
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(aView1.m_bInvalidateTiles);
CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size());
@@ -1847,7 +1847,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testGetRowColumnHeadersInvalidation)
aView1.m_aInvalidations.clear();
tools::JsonWriter aJsonWriter3;
pModelObj->getRowColumnHeaders(tools::Rectangle(5400, 5400, 25050, 9800), aJsonWriter3);
free(aJsonWriter3.extractData());
aJsonWriter3.finishAndGetAsOString();
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(aView1.m_bInvalidateTiles);
CPPUNIT_ASSERT_EQUAL(size_t(1), aView1.m_aInvalidations.size());
@@ -1921,7 +1921,7 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testRowColumnHeaders)
SfxLokHelper::setView(nView1);
tools::JsonWriter aJsonWriter1;
pModelObj->getRowColumnHeaders(tools::Rectangle(65,723,10410,4695), aJsonWriter1);
OString aHeaders1 = aJsonWriter1.extractAsOString();
OString aHeaders1 = aJsonWriter1.finishAndGetAsOString();
SfxLokHelper::setView(nView2);
// 50% zoom
@@ -1929,20 +1929,20 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testRowColumnHeaders)
pModelObj->setClientZoom(256, 256, 6636, 6636);
tools::JsonWriter aJsonWriter2;
pModelObj->getRowColumnHeaders(tools::Rectangle(65,723,10410,4695), aJsonWriter2);
OString aHeaders2 = aJsonWriter2.extractAsOString();
OString aHeaders2 = aJsonWriter2.finishAndGetAsOString();
// Check vs. view #1
SfxLokHelper::setView(nView1);
tools::JsonWriter aJsonWriter3;
pModelObj->getRowColumnHeaders(tools::Rectangle(65,723,10410,4695), aJsonWriter3);
OString aHeaders1_2 = aJsonWriter3.extractAsOString();
OString aHeaders1_2 = aJsonWriter3.finishAndGetAsOString();
CPPUNIT_ASSERT_EQUAL(aHeaders1, aHeaders1_2);
// Check vs. view #2
SfxLokHelper::setView(nView2);
tools::JsonWriter aJsonWriter4;
pModelObj->getRowColumnHeaders(tools::Rectangle(65,723,10410,4695), aJsonWriter4);
OString aHeaders2_2 = aJsonWriter4.extractAsOString();
OString aHeaders2_2 = aJsonWriter4.finishAndGetAsOString();
CPPUNIT_ASSERT_EQUAL(aHeaders2, aHeaders2_2);
SfxLokHelper::setView(nView1);
+2 -2
View File
@@ -1331,8 +1331,8 @@ void ScUndoPrintRange::DoChange(bool bUndo)
else
pNewRanges->GetPrintRangesInfo(aJsonWriter);
const std::string message = aJsonWriter.extractAsStdString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_PRINT_RANGES, message.c_str());
const OString message = aJsonWriter.finishAndGetAsOString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_PRINT_RANGES, message);
}
pDocShell->PostPaint( ScRange(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab), PaintPartFlags::Grid );
+2 -2
View File
@@ -1136,8 +1136,8 @@ void ScViewFunc::SetPrintRanges( bool bEntireSheet, const OUString* pPrint,
pNewRanges->GetPrintRangesInfo(aJsonWriter);
SfxViewShell* pViewShell = GetViewData().GetViewShell();
const std::string message = aJsonWriter.extractAsStdString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_PRINT_RANGES, message.c_str());
const OString message = aJsonWriter.finishAndGetAsOString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_PRINT_RANGES, message);
}
pDocSh->GetUndoManager()->AddUndoAction(
+6 -6
View File
@@ -340,7 +340,7 @@ const SdPage* getAnnotationPage(const uno::Reference<office::XAnnotation>& xAnno
namespace
{
std::string lcl_LOKGetCommentPayload(CommentNotificationType nType, uno::Reference<office::XAnnotation> const & rxAnnotation)
OString lcl_LOKGetCommentPayload(CommentNotificationType nType, uno::Reference<office::XAnnotation> const & rxAnnotation)
{
::tools::JsonWriter aJsonWriter;
{
@@ -368,7 +368,7 @@ std::string lcl_LOKGetCommentPayload(CommentNotificationType nType, uno::Referen
aJsonWriter.put("rectangle", sRectangle.getStr());
}
}
return aJsonWriter.extractData();
return aJsonWriter.finishAndGetAsOString();
}
} // anonymous ns
@@ -378,8 +378,8 @@ void LOKCommentNotify(CommentNotificationType nType, const SfxViewShell* pViewSh
if (!comphelper::LibreOfficeKit::isActive() || comphelper::LibreOfficeKit::isTiledAnnotations())
return ;
std::string aPayload = lcl_LOKGetCommentPayload(nType, rxAnnotation);
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str());
OString aPayload = lcl_LOKGetCommentPayload(nType, rxAnnotation);
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload);
}
void LOKCommentNotifyAll(CommentNotificationType nType, uno::Reference<office::XAnnotation> const & rxAnnotation)
@@ -388,12 +388,12 @@ void LOKCommentNotifyAll(CommentNotificationType nType, uno::Reference<office::X
if (!comphelper::LibreOfficeKit::isActive() || comphelper::LibreOfficeKit::isTiledAnnotations())
return ;
std::string aPayload = lcl_LOKGetCommentPayload(nType, rxAnnotation);
OString aPayload = lcl_LOKGetCommentPayload(nType, rxAnnotation);
const SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
{
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload);
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
}
+1 -1
View File
@@ -542,7 +542,7 @@ void SfxDispatchController_Impl::dispatch( const css::util::URL& aURL,
aTree.put("message", "Blocked feature");
aTree.put("viewID", SfxViewShell::Current()->GetViewShellId().get());
SfxViewShell::Current()->libreOfficeKitViewCallback(LOK_COMMAND_BLOCKED, aTree.extractData());
SfxViewShell::Current()->libreOfficeKitViewCallback(LOK_COMMAND_BLOCKED, aTree.finishAndGetAsOString());
return;
}
+2 -4
View File
@@ -1233,8 +1233,7 @@ void SidebarController::RequestCloseDeck()
aJsonWriter.put("type", "dockingwindow");
aJsonWriter.put("text", mpParentWindow->GetText());
aJsonWriter.put("enabled", false);
const std::string message = aJsonWriter.extractAsStdString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, aJsonWriter.finishAndGetAsOString());
}
else if (pViewShell)
{
@@ -1242,8 +1241,7 @@ void SidebarController::RequestCloseDeck()
aJsonWriter.put("id", mpParentWindow->get_id());
aJsonWriter.put("action", "close");
aJsonWriter.put("jsontype", "sidebar");
const std::string message = aJsonWriter.extractAsStdString();
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, aJsonWriter.finishAndGetAsOString());
}
}
+2 -2
View File
@@ -1484,7 +1484,7 @@ void SfxViewShell::libreOfficeKitViewInvalidateTilesCallback(const tools::Rectan
"SfxViewShell::libreOfficeKitViewInvalidateTilesCallback no callback set!");
}
void SfxViewShell::libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) const
void SfxViewShell::libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) const
{
if (ignoreLibreOfficeKitViewCallback(nType, pImpl.get()))
return;
@@ -1497,7 +1497,7 @@ void SfxViewShell::libreOfficeKitViewCallbackWithViewId(int nType, const char* p
<< lokCallbackTypeToString(nType) << ": [" << pPayload << ']');
}
void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const
void SfxViewShell::libreOfficeKitViewCallback(int nType, const OString& pPayload) const
{
if (ignoreLibreOfficeKitViewCallback(nType, pImpl.get()))
return;
@@ -1756,7 +1756,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testRedlineColors)
// Assert that info about exactly one author is returned.
tools::JsonWriter aJsonWriter;
pXTextDocument->getTrackedChangeAuthors(aJsonWriter);
std::stringstream aStream(aJsonWriter.extractAsOString().getStr());
std::stringstream aStream(aJsonWriter.finishAndGetAsOString().getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree.get_child("authors").size());
+2 -3
View File
@@ -1215,9 +1215,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testImageComment)
// rendering and on the desktop.
tools::JsonWriter aJsonWriter;
pTextDoc->getPostIts(aJsonWriter);
char* pChar = aJsonWriter.extractData();
std::stringstream aStream(pChar);
free(pChar);
OString pChar = aJsonWriter.finishAndGetAsOString();
std::stringstream aStream(pChar.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("comments"))
+2 -3
View File
@@ -1481,9 +1481,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf65535)
tools::JsonWriter aJsonWriter;
pTextDoc->getPostIts(aJsonWriter);
char* pChar = aJsonWriter.extractData();
std::stringstream aStream(pChar);
free(pChar);
OString pChar = aJsonWriter.finishAndGetAsOString();
std::stringstream aStream(pChar.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
OString sCommentText;
+2 -3
View File
@@ -1634,9 +1634,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132603)
tools::JsonWriter aJsonWriter;
pTextDoc->getPostIts(aJsonWriter);
char* pChar = aJsonWriter.extractData();
std::stringstream aStream(pChar);
free(pChar);
OString pChar = aJsonWriter.finishAndGetAsOString();
std::stringstream aStream(pChar.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("comments"))
+16 -16
View File
@@ -234,8 +234,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetTextFormFields)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we find the 2 items and ignore the bibliography:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -267,8 +267,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetDocumentProperties)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we find the 2 properties and ignore the other one:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -308,8 +308,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetBookmarks)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we get the 2 references but not the bibliography:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -345,8 +345,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetFields)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we get the 1 refmark:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -400,8 +400,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetTextFormField)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we find the inserted fieldmark:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -432,8 +432,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetSections)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Make sure we find our just inserted section:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Without the accompanying fix in place, this test would have failed with:
@@ -464,8 +464,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetBookmark)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we find the inserted bookmark:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
boost::property_tree::ptree aBookmark = aTree.get_child("bookmark");
@@ -498,8 +498,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetField)
pXTextDocument->getCommandValues(aJsonWriter, aCommand);
// Then make sure we find the inserted refmark:
std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
std::stringstream aStream(pJSON.get());
OString pJSON(aJsonWriter.finishAndGetAsOString());
std::stringstream aStream(pJSON.getStr());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
boost::property_tree::ptree aBookmark = aTree.get_child("setRef");
+2 -2
View File
@@ -438,7 +438,7 @@ namespace sw::mark
aJson.put("DeleteBookmark", fieldCommand);
}
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
void Bookmark::InitDoc(SwDoc& io_rDoc,
@@ -603,7 +603,7 @@ namespace sw::mark
aJson.put("DeleteTextFormField", fieldCommand);
}
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
void TextFieldmark::InitDoc(SwDoc& io_rDoc,
+1 -2
View File
@@ -2157,9 +2157,8 @@ void SwCursorShell::sendLOKCursorUpdates()
}
}
char* pChar = aJsonWriter.extractData();
OString pChar = aJsonWriter.finishAndGetAsOString();
GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TABLE_SELECTED, pChar);
free(pChar);
}
void SwCursorShell::RefreshBlockCursor()
+4 -4
View File
@@ -725,8 +725,8 @@ void SwSelPaintRects::HighlightContentControl()
aJson.put("alias", pContentControl->GetAlias());
}
std::unique_ptr<char, o3tl::free_delete> pJson(aJson.extractData());
GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL, pJson.get());
OString pJson(aJson.finishAndGetAsOString());
GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL, pJson);
}
if (m_pContentControlOverlay)
{
@@ -819,8 +819,8 @@ void SwSelPaintRects::HighlightContentControl()
{
tools::JsonWriter aJson;
aJson.put("action", "hide");
std::unique_ptr<char, o3tl::free_delete> pJson(aJson.extractData());
GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL, pJson.get());
OString pJson(aJson.finishAndGetAsOString());
GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL, pJson);
}
m_pContentControlOverlay.reset();
+1 -1
View File
@@ -2451,7 +2451,7 @@ void SwNodes::RemoveNode( SwNodeOffset nDelPos, SwNodeOffset nSz, bool bDel )
aJson.put("DeleteSection", fieldCommand);
}
SfxViewShell::Current()->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
SfxViewShell::Current()->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
}
+1 -1
View File
@@ -138,7 +138,7 @@ SwTextRefMark::~SwTextRefMark()
aJson.put("DeleteField", fieldCommand);
}
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
const sal_Int32* SwTextRefMark::GetEnd() const
+1 -2
View File
@@ -284,10 +284,9 @@ void SwCommentRuler::NotifyKit()
tools::JsonWriter aJsonWriter;
CreateJsonNotification(aJsonWriter);
char* pJsonData = aJsonWriter.extractData();
OString pJsonData = aJsonWriter.finishAndGetAsOString();
mpViewShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_RULER_UPDATE,
pJsonData);
free(pJsonData);
}
void SwCommentRuler::Update()
+2 -2
View File
@@ -108,9 +108,9 @@ bool SwWrtShell::GotoContentControl(const SwFormatContentControl& rContentContro
{
tools::JsonWriter aJson;
aJson.put("action", "change-picture");
std::unique_ptr<char, o3tl::free_delete> pJson(aJson.extractData());
OString pJson(aJson.finishAndGetAsOString());
GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CONTENT_CONTROL,
pJson.get());
pJson);
}
else
{
+5 -4
View File
@@ -47,15 +47,16 @@ inline void TestLokCallbackWrapper::callCallback(int nType, const char* pPayload
startTimer();
}
void TestLokCallbackWrapper::libreOfficeKitViewCallback(int nType, const char* pPayload)
void TestLokCallbackWrapper::libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload)
{
callCallback(nType, pPayload, NO_VIEWID);
callCallback(nType, pPayload.getStr(), NO_VIEWID);
}
void TestLokCallbackWrapper::libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload,
void TestLokCallbackWrapper::libreOfficeKitViewCallbackWithViewId(int nType,
const rtl::OString& pPayload,
int nViewId)
{
callCallback(nType, pPayload, nViewId);
callCallback(nType, pPayload.getStr(), nViewId);
}
void TestLokCallbackWrapper::libreOfficeKitViewInvalidateTilesCallback(
+11 -12
View File
@@ -43,11 +43,11 @@ void JsonWriterTest::test1()
aJson.put("int", static_cast<sal_Int32>(12));
}
std::unique_ptr<char, o3tl::free_delete> result(aJson.extractData());
OString result(aJson.finishAndGetAsOString());
CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"oustring\": \"val1\", "
"\"charptr\": \"val3\", \"int\": 12}}"),
std::string(result.get()));
CPPUNIT_ASSERT_EQUAL(OString("{ \"node\": { \"oustring\": \"val1\", "
"\"charptr\": \"val3\", \"int\": 12}}"),
result);
}
void JsonWriterTest::test2()
@@ -69,12 +69,12 @@ void JsonWriterTest::test2()
}
}
std::unique_ptr<char, o3tl::free_delete> result(aJson.extractData());
OString result(aJson.finishAndGetAsOString());
CPPUNIT_ASSERT_EQUAL(std::string("{ \"node\": { \"field1\": \"val1\", \"field2\": \"val2\", "
"\"node\": { \"field3\": \"val3\", \"node\": { \"field4\": "
"\"val4\", \"field5\": \"val5\"}}}}"),
std::string(result.get()));
CPPUNIT_ASSERT_EQUAL(OString("{ \"node\": { \"field1\": \"val1\", \"field2\": \"val2\", "
"\"node\": { \"field3\": \"val3\", \"node\": { \"field4\": "
"\"val4\", \"field5\": \"val5\"}}}}"),
result);
}
void JsonWriterTest::testArray()
@@ -86,10 +86,9 @@ void JsonWriterTest::testArray()
aJson.putSimpleValue("bar");
}
std::unique_ptr<char, o3tl::free_delete> aResult(aJson.extractData());
OString aResult(aJson.finishAndGetAsOString());
CPPUNIT_ASSERT_EQUAL(std::string("{ \"items\": [ \"foo\", \"bar\"]}"),
std::string(aResult.get()));
CPPUNIT_ASSERT_EQUAL(OString("{ \"items\": [ \"foo\", \"bar\"]}"), aResult);
}
CPPUNIT_TEST_SUITE_REGISTRATION(JsonWriterTest);
+7 -23
View File
@@ -24,6 +24,7 @@ JsonWriter::JsonWriter()
, mSpaceAllocated(DEFAULT_BUFFER_SIZE)
, mStartNodeCount(0)
, mbFirstFieldInNode(true)
, mbClosed(false)
{
*mPos = '{';
++mPos;
@@ -35,7 +36,7 @@ JsonWriter::JsonWriter()
JsonWriter::~JsonWriter()
{
assert(!mpBuffer && "forgot to extract data?");
assert(mbClosed && "forgot to extract data?");
free(mpBuffer);
}
@@ -314,7 +315,7 @@ void JsonWriter::addCommaBeforeField()
void JsonWriter::ensureSpace(int noMoreBytesRequired)
{
assert(mpBuffer && "already extracted data");
assert(!mbClosed && "already extracted data");
int currentUsed = mPos - mpBuffer;
if (currentUsed + noMoreBytesRequired >= mSpaceAllocated)
{
@@ -351,36 +352,19 @@ void JsonWriter::putLiteral(std::string_view propName, std::string_view propValu
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()
OString JsonWriter::finishAndGetAsOString()
{
assert(mStartNodeCount == 0 && "did not close all nodes");
assert(mpBuffer && "data already extracted");
assert(!mbClosed && "data already extracted");
ensureSpace(2);
// add closing brace
*mPos = '}';
++mPos;
// null-terminate
*mPos = 0;
const int sz = mPos - mpBuffer;
mPos = nullptr;
return { std::exchange(mpBuffer, nullptr), sz };
}
mbClosed = true;
OString JsonWriter::extractAsOString()
{
auto[pChar, sz] = extractDataImpl();
OString ret(pChar, sz);
free(pChar);
return ret;
}
std::string JsonWriter::extractAsStdString()
{
auto[pChar, sz] = extractDataImpl();
std::string ret(pChar, sz);
free(pChar);
OString ret(mpBuffer, mPos - mpBuffer);
return ret;
}
+1 -1
View File
@@ -111,7 +111,7 @@ class JSDialogNotifyIdle final : public Idle
// used to generate JSON
VclPtr<vcl::Window> m_aContentWindow;
OUString m_sTypeOfJSON;
std::string m_LastNotificationMessage;
OString m_LastNotificationMessage;
bool m_bForce;
std::deque<JSDialogMessageInfo> m_aMessageQueue;
+7 -8
View File
@@ -71,7 +71,7 @@ void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter)
{
if (!m_aNotifierWindow)
{
free(aJsonWriter.extractData());
aJsonWriter.finishAndGetAsOString();
return;
}
@@ -81,18 +81,17 @@ void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter)
if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage))
{
m_bForce = false;
m_LastNotificationMessage = aJsonWriter.extractAsStdString();
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
m_LastNotificationMessage.c_str());
m_LastNotificationMessage = aJsonWriter.finishAndGetAsOString();
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, m_LastNotificationMessage);
}
else
{
free(aJsonWriter.extractData());
aJsonWriter.finishAndGetAsOString();
}
}
else
{
free(aJsonWriter.extractData());
aJsonWriter.finishAndGetAsOString();
}
}
@@ -1276,8 +1275,8 @@ JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMe
xMessageDialog->DumpAsPropertyTree(aJsonWriter);
aJsonWriter.put("id", xMessageDialog->GetLOKWindowId());
aJsonWriter.put("jsontype", "dialog");
std::unique_ptr<char[], o3tl::free_delete> message(aJsonWriter.extractData());
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.get());
OString message(aJsonWriter.finishAndGetAsOString());
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message);
OUString sWindowId = OUString::number(xMessageDialog->GetLOKWindowId());
InsertWindowToMap(sWindowId);
+3 -3
View File
@@ -324,14 +324,14 @@ void Application::notifyWindow(vcl::LOKWindowId /*nLOKWindowId*/,
SAL_WARN("vcl", "Invoked not implemented method: Application::notifyWindow");
}
void Application::libreOfficeKitViewCallback(int nType, const char* pPayload) const
void Application::libreOfficeKitViewCallback(int nType, const OString& pPayload) const
{
if (!comphelper::LibreOfficeKit::isActive())
return;
if (m_pCallback)
{
m_pCallback(nType, pPayload, m_pCallbackData);
m_pCallback(nType, pPayload.getStr(), m_pCallbackData);
}
}
@@ -1868,7 +1868,7 @@ void dumpState(rtl::OStringBuffer &rState)
pWin->DumpAsPropertyTree(props);
rState.append("\n\tWindow: ");
rState.append(props.extractAsOString());
rState.append(props.finishAndGetAsOString());
pWin = Application::GetNextTopLevelWindow( pWin );
}