summaryrefslogtreecommitdiffstats
path: root/include/tools
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /include/tools
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/tools')
-rw-r--r--include/tools/GenericTypeSerializer.hxx60
-rw-r--r--include/tools/Guid.hxx165
-rw-r--r--include/tools/UnitConversion.hxx122
-rw-r--r--include/tools/XmlWalker.hxx59
-rw-r--r--include/tools/XmlWriter.hxx70
-rw-r--r--include/tools/b3dtrans.hxx217
-rw-r--r--include/tools/bigint.hxx255
-rw-r--r--include/tools/color.hxx523
-rw-r--r--include/tools/config.hxx69
-rw-r--r--include/tools/contnr.hxx29
-rw-r--r--include/tools/cpuid.hxx109
-rw-r--r--include/tools/date.hxx259
-rw-r--r--include/tools/datetime.hxx151
-rw-r--r--include/tools/datetimeutils.hxx26
-rw-r--r--include/tools/debug.hxx62
-rw-r--r--include/tools/degree.hxx60
-rw-r--r--include/tools/duration.hxx104
-rw-r--r--include/tools/extendapplicationenvironment.hxx34
-rw-r--r--include/tools/fileutil.hxx26
-rw-r--r--include/tools/fix16.hxx40
-rw-r--r--include/tools/fldunit.hxx51
-rw-r--r--include/tools/fontenum.hxx457
-rw-r--r--include/tools/fract.hxx122
-rw-r--r--include/tools/gen.hxx925
-rw-r--r--include/tools/globname.hxx77
-rw-r--r--include/tools/helpers.hxx57
-rw-r--r--include/tools/inetmime.hxx240
-rw-r--r--include/tools/inetmsg.hxx187
-rw-r--r--include/tools/inetstrm.hxx64
-rw-r--r--include/tools/json_writer.hxx169
-rw-r--r--include/tools/line.hxx56
-rw-r--r--include/tools/lineend.hxx33
-rw-r--r--include/tools/link.hxx180
-rw-r--r--include/tools/long.hxx39
-rw-r--r--include/tools/mapunit.hxx35
-rw-r--r--include/tools/multisel.hxx169
-rw-r--r--include/tools/pathutils.hxx72
-rw-r--r--include/tools/poly.hxx317
-rw-r--r--include/tools/ref.hxx234
-rw-r--r--include/tools/resary.hxx26
-rw-r--r--include/tools/simd.hxx30
-rw-r--r--include/tools/simdsupport.hxx83
-rw-r--r--include/tools/solar.h119
-rw-r--r--include/tools/stream.hxx685
-rw-r--r--include/tools/svborder.hxx73
-rw-r--r--include/tools/svlibrary.h15
-rw-r--r--include/tools/tenccvt.hxx58
-rw-r--r--include/tools/time.hxx177
-rw-r--r--include/tools/toolsdllapi.h34
-rw-r--r--include/tools/urlobj.hxx1305
-rw-r--r--include/tools/vcompat.hxx65
-rw-r--r--include/tools/weakbase.h159
-rw-r--r--include/tools/weakbase.hxx162
-rw-r--r--include/tools/wldcrd.hxx65
-rw-r--r--include/tools/zcodec.hxx96
55 files changed, 9076 insertions, 0 deletions
diff --git a/include/tools/GenericTypeSerializer.hxx b/include/tools/GenericTypeSerializer.hxx
new file mode 100644
index 0000000000..f67d92c845
--- /dev/null
+++ b/include/tools/GenericTypeSerializer.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_GENERICTYPESERIALIZER_HXX
+#define INCLUDED_TOOLS_GENERICTYPESERIALIZER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/color.hxx>
+#include <tools/gen.hxx>
+#include <tools/stream.hxx>
+#include <tools/fract.hxx>
+
+namespace tools
+{
+class TOOLS_DLLPUBLIC GenericTypeSerializer
+{
+public:
+ SvStream& mrStream;
+
+ GenericTypeSerializer(SvStream& rStream)
+ : mrStream(rStream)
+ {
+ }
+
+ void readColor(Color& rColor);
+ void writeColor(const Color& rColor);
+
+ void readPoint(Point& rPoint);
+ void writePoint(const Point& rPoint);
+
+ void readSize(Size& rSize);
+ void writeSize(const Size& rSize);
+
+ void readRectangle(Rectangle& rRectangle);
+ void writeRectangle(const Rectangle& rRectangle);
+
+ void readFraction(Fraction& rFraction);
+ void writeFraction(Fraction const& rFraction);
+};
+
+} // end namespace tools
+
+#endif // INCLUDED_TOOLS_GENERICTYPESERIALIZER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/Guid.hxx b/include/tools/Guid.hxx
new file mode 100644
index 0000000000..3922a3da9f
--- /dev/null
+++ b/include/tools/Guid.hxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <array>
+#include <rtl/uuid.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <algorithm>
+#include <stdio.h>
+#include <cctype>
+
+namespace tools
+{
+class Guid
+{
+private:
+ typedef std::array<sal_uInt8, 16> GuidArrayType;
+
+ GuidArrayType maGuidArray;
+
+ static sal_uInt8 gethex(char nChar)
+ {
+ if (nChar >= '0' && nChar <= '9')
+ return nChar - '0';
+ else if (nChar >= 'a' && nChar <= 'f')
+ return nChar - 'a' + 10;
+ else if (nChar >= 'A' && nChar <= 'F')
+ return nChar - 'A' + 10;
+ else
+ return 0;
+ }
+
+ static sal_uInt8 covertHexChar(char high, char low)
+ {
+ return (gethex(high) << 4) + gethex(low);
+ }
+
+ void parse(std::string_view rString)
+ {
+ if (rString.size() != 38)
+ return;
+
+ if (rString[0] != '{' || rString[37] != '}' || rString[9] != '-' || rString[14] != '-'
+ || rString[19] != '-' || rString[24] != '-')
+ return;
+
+ for (size_t x = 1; x <= 8; x++)
+ if (!std::isxdigit(rString[x]))
+ return;
+ for (size_t x = 10; x <= 13; x++)
+ if (!std::isxdigit(rString[x]))
+ return;
+ for (size_t x = 15; x <= 18; x++)
+ if (!std::isxdigit(rString[x]))
+ return;
+ for (size_t x = 20; x <= 23; x++)
+ if (!std::isxdigit(rString[x]))
+ return;
+ for (size_t x = 25; x <= 36; x++)
+ if (!std::isxdigit(rString[x]))
+ return;
+
+ maGuidArray[0] = covertHexChar(rString[1], rString[2]);
+ maGuidArray[1] = covertHexChar(rString[3], rString[4]);
+ maGuidArray[2] = covertHexChar(rString[5], rString[6]);
+ maGuidArray[3] = covertHexChar(rString[7], rString[8]);
+
+ maGuidArray[4] = covertHexChar(rString[10], rString[11]);
+ maGuidArray[5] = covertHexChar(rString[12], rString[13]);
+
+ maGuidArray[6] = covertHexChar(rString[15], rString[16]);
+ maGuidArray[7] = covertHexChar(rString[17], rString[18]);
+
+ maGuidArray[8] = covertHexChar(rString[20], rString[21]);
+ maGuidArray[9] = covertHexChar(rString[22], rString[23]);
+
+ maGuidArray[10] = covertHexChar(rString[25], rString[26]);
+ maGuidArray[11] = covertHexChar(rString[27], rString[28]);
+ maGuidArray[12] = covertHexChar(rString[29], rString[30]);
+ maGuidArray[13] = covertHexChar(rString[31], rString[32]);
+ maGuidArray[14] = covertHexChar(rString[33], rString[34]);
+ maGuidArray[15] = covertHexChar(rString[35], rString[36]);
+ }
+
+public:
+ /// GenerateTag is used as a flag for generating the GUID
+ enum GenerateTag
+ {
+ Generate = 0
+ };
+
+ /// Constructor which generates the GUID
+ Guid(enum GenerateTag) { rtl_createUuid(maGuidArray.data(), nullptr, false); }
+
+ /// Default constructor which initializes the values to 0 (empty GUID)
+ Guid() { maGuidArray.fill(0); }
+
+ /// parse the GUID from the string
+ Guid(std::string_view rString)
+ {
+ maGuidArray.fill(0);
+ parse(rString);
+ }
+
+ /// set the GUID from an array
+ Guid(const sal_uInt8 aGuidArray[16])
+ {
+ std::copy(aGuidArray, aGuidArray + 16, maGuidArray.begin());
+ }
+
+ Guid(Guid&&) = delete;
+
+ Guid(Guid const& rOther) { *this = rOther; }
+
+ void operator=(Guid const& rOther) { std::copy(rOther.cbegin(), rOther.cend(), begin()); }
+
+ bool isEmpty() { return *std::max_element(maGuidArray.begin(), maGuidArray.end()) == 0; }
+
+ GuidArrayType::iterator begin() { return maGuidArray.begin(); }
+ GuidArrayType::iterator end() { return maGuidArray.end(); }
+ GuidArrayType::const_iterator cbegin() const { return maGuidArray.cbegin(); }
+ GuidArrayType::const_iterator cend() const { return maGuidArray.cend(); }
+
+ OString getString() const
+ {
+ char sBuffer[40];
+ snprintf(sBuffer, sizeof(sBuffer),
+ "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ maGuidArray[0], maGuidArray[1], maGuidArray[2], maGuidArray[3], maGuidArray[4],
+ maGuidArray[5], maGuidArray[6], maGuidArray[7], maGuidArray[8], maGuidArray[9],
+ maGuidArray[10], maGuidArray[11], maGuidArray[12], maGuidArray[13],
+ maGuidArray[14], maGuidArray[15]);
+
+ return OString(sBuffer);
+ }
+
+ OUString getOUString() { return OStringToOUString(getString(), RTL_TEXTENCODING_ASCII_US); }
+
+ bool operator==(Guid const& rCompare) const
+ {
+ return rtl_compareUuid(maGuidArray.data(), rCompare.maGuidArray.data()) == 0;
+ }
+
+ bool operator!=(Guid const& rCompare) const { return !(*this == rCompare); }
+};
+
+template <typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& rStream,
+ tools::Guid const& rGuid)
+{
+ OString aString = rGuid.getString();
+ rStream << "GUID" << aString.getStr();
+ return rStream;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/UnitConversion.hxx b/include/tools/UnitConversion.hxx
new file mode 100644
index 0000000000..43237e0514
--- /dev/null
+++ b/include/tools/UnitConversion.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <o3tl/unit_conversion.hxx>
+#include <sal/types.h>
+#include <tools/fldunit.hxx>
+#include <tools/fract.hxx>
+#include <tools/mapunit.hxx>
+
+constexpr o3tl::Length FieldToO3tlLength(FieldUnit eU, o3tl::Length ePixelValue = o3tl::Length::px)
+{
+ switch (eU)
+ {
+ case FieldUnit::MM:
+ return o3tl::Length::mm;
+ case FieldUnit::CM:
+ return o3tl::Length::cm;
+ case FieldUnit::M:
+ return o3tl::Length::m;
+ case FieldUnit::KM:
+ return o3tl::Length::km;
+ case FieldUnit::TWIP:
+ return o3tl::Length::twip;
+ case FieldUnit::POINT:
+ return o3tl::Length::pt;
+ case FieldUnit::PICA:
+ return o3tl::Length::pc;
+ case FieldUnit::INCH:
+ return o3tl::Length::in;
+ case FieldUnit::FOOT:
+ return o3tl::Length::ft;
+ case FieldUnit::MILE:
+ return o3tl::Length::mi;
+ case FieldUnit::CHAR:
+ return o3tl::Length::ch;
+ case FieldUnit::LINE:
+ return o3tl::Length::line;
+ case FieldUnit::MM_100TH:
+ return o3tl::Length::mm100;
+ case FieldUnit::PIXEL:
+ return ePixelValue;
+ default:
+ return o3tl::Length::invalid;
+ }
+}
+
+constexpr o3tl::Length MapToO3tlLength(MapUnit eU, o3tl::Length ePixelValue = o3tl::Length::px)
+{
+ switch (eU)
+ {
+ case MapUnit::Map100thMM:
+ return o3tl::Length::mm100;
+ case MapUnit::Map10thMM:
+ return o3tl::Length::mm10;
+ case MapUnit::MapMM:
+ return o3tl::Length::mm;
+ case MapUnit::MapCM:
+ return o3tl::Length::cm;
+ case MapUnit::Map1000thInch:
+ return o3tl::Length::in1000;
+ case MapUnit::Map100thInch:
+ return o3tl::Length::in100;
+ case MapUnit::Map10thInch:
+ return o3tl::Length::in10;
+ case MapUnit::MapInch:
+ return o3tl::Length::in;
+ case MapUnit::MapPoint:
+ return o3tl::Length::pt;
+ case MapUnit::MapTwip:
+ return o3tl::Length::twip;
+ case MapUnit::MapPixel:
+ return ePixelValue;
+ default:
+ return o3tl::Length::invalid;
+ }
+}
+
+inline Fraction conversionFract(o3tl::Length from, o3tl::Length to)
+{
+ const auto & [ mul, div ] = o3tl::getConversionMulDiv(from, to);
+ return { mul, div };
+}
+
+template <typename N> constexpr auto convertTwipToMm100(N n)
+{
+ return o3tl::convert(n, o3tl::Length::twip, o3tl::Length::mm100);
+}
+
+constexpr sal_Int64 sanitiseMm100ToTwip(sal_Int64 n)
+{
+ return o3tl::convertSaturate(n, o3tl::Length::mm100, o3tl::Length::twip);
+}
+
+template <typename N> constexpr auto convertPointToMm100(N n)
+{
+ return o3tl::convert(n, o3tl::Length::pt, o3tl::Length::mm100);
+}
+template <typename N> constexpr auto convertMm100ToPoint(N n)
+{
+ return o3tl::convert(n, o3tl::Length::mm100, o3tl::Length::pt);
+}
+
+// PPT's "master unit" (1/576 inch) <=> mm/100
+template <typename N> constexpr auto convertMasterUnitToMm100(N n)
+{
+ return o3tl::convert(n, o3tl::Length::master, o3tl::Length::mm100);
+}
+template <typename N> constexpr auto convertMm100ToMasterUnit(N n)
+{
+ return o3tl::convert(n, o3tl::Length::mm100, o3tl::Length::master);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/XmlWalker.hxx b/include/tools/XmlWalker.hxx
new file mode 100644
index 0000000000..ba9d18e856
--- /dev/null
+++ b/include/tools/XmlWalker.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_TOOLS_XMLWALKER_HXX
+#define INCLUDED_TOOLS_XMLWALKER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/string.hxx>
+#include <memory>
+
+class SvStream;
+
+namespace tools
+{
+struct XmlWalkerImpl;
+
+/**
+ * XmlWalker main purpose is to make it easier for walking the
+ * parsed XML DOM tree.
+ *
+ * It hides all the libxml2 and C -isms and makes the usage more
+ * comfortable from LO developer point of view.
+ *
+ */
+class TOOLS_DLLPUBLIC XmlWalker final
+{
+private:
+ std::unique_ptr<XmlWalkerImpl> mpImpl;
+
+public:
+ XmlWalker();
+
+ ~XmlWalker();
+
+ bool open(SvStream* pStream);
+
+ OString name();
+ OString namespaceHref();
+ OString namespacePrefix();
+
+ OString content();
+ void children();
+ void parent();
+ void next();
+ bool isValid() const;
+ OString attribute(const OString& sName) const;
+};
+
+} // end tools namespace
+
+#endif // INCLUDED_TOOLS_XMLWRITER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/XmlWriter.hxx b/include/tools/XmlWriter.hxx
new file mode 100644
index 0000000000..400748611b
--- /dev/null
+++ b/include/tools/XmlWriter.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_TOOLS_XMLWRITER_HXX
+#define INCLUDED_TOOLS_XMLWRITER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/string.hxx>
+#include <memory>
+#include <string_view>
+#include <vector>
+
+class SvStream;
+
+namespace tools
+{
+struct XmlWriterImpl;
+
+/**
+ * XmlWriter writes a XML to a SvStream. It uses libxml2 for writing but hides
+ * all the internal libxml2 workings and uses types that are native for LO
+ * development.
+ *
+ * The codepage used for XML is always "utf-8" and the output is indented by
+ * default so it is easier to read.
+ *
+ */
+class TOOLS_DLLPUBLIC XmlWriter final
+{
+private:
+ std::unique_ptr<XmlWriterImpl> mpImpl;
+
+public:
+ XmlWriter(SvStream* pStream);
+
+ ~XmlWriter();
+
+ bool startDocument(sal_Int32 nIndent = 2, bool bWriteXmlHeader = true);
+ void endDocument();
+
+ void startElement(const char* sName);
+ void startElement(const OString& sName);
+ void startElement(const OString& sPrefix, const OString& sName, const OString& sNamespaceUri);
+ void endElement();
+
+ void attribute(const char* sTagName, const OString& aValue);
+ void attribute(const OString& sTagName, const OString& aValue);
+ void attribute(const char* sTagName, std::u16string_view aValue);
+ void attribute(const char* sTagName, sal_Int32 aNumber);
+ void attributeDouble(const char* sTagName, double aNumber);
+ void attributeBase64(const char* sTagName, std::vector<sal_uInt8> const& rValueInBytes);
+ void attributeBase64(const char* sTagName, std::vector<char> const& rValueInBytes);
+
+ void content(const OString& sValue);
+ void content(std::u16string_view sValue);
+
+ void element(const char* sName);
+};
+
+} // end tools namespace
+
+#endif // INCLUDED_TOOLS_XMLWRITER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/b3dtrans.hxx b/include/tools/b3dtrans.hxx
new file mode 100644
index 0000000000..2f6752e084
--- /dev/null
+++ b/include/tools/b3dtrans.hxx
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_B3DTRANS_HXX
+#define INCLUDED_TOOLS_B3DTRANS_HXX
+
+#define ZBUFFER_DEPTH_RANGE (double(256L * 256L * 256L))
+
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <tools/gen.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/vector/b3dvector.hxx>
+#include <tools/toolsdllapi.h>
+
+/// Transformation sets for 3D output
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC B3dTransformationSet
+{
+private:
+ // Object Matrix Object -> World
+ basegfx::B3DHomMatrix maObjectTrans;
+ basegfx::B3DHomMatrix maInvObjectTrans;
+
+ // Orientation Matrix
+ basegfx::B3DHomMatrix maOrientation;
+ basegfx::B3DHomMatrix maInvOrientation;
+
+ // Projection Matrix
+ basegfx::B3DHomMatrix maProjection;
+ basegfx::B3DHomMatrix maInvProjection;
+
+ // Texture Matrices
+ basegfx::B2DHomMatrix maTexture;
+
+ // Parameters for ViewportTransformation
+ basegfx::B3DVector maScale;
+ basegfx::B3DVector maTranslate;
+
+ // ViewPlane DeviceRectangle (user-defined)
+ double mfLeftBound;
+ double mfRightBound;
+ double mfBottomBound;
+ double mfTopBound;
+
+ // Aspect ratio of 3D transformation (Y / X)
+ // default: 1:1 -> 1.0
+ // Disable with value 0.0
+ double mfRatio;
+
+ // Viewport area in logical coordinates
+ tools::Rectangle maViewportRectangle;
+ // Visible area within viewport
+ tools::Rectangle maVisibleRectangle;
+
+ // Actual coordinates as set by CalcViewport
+ // of visible viewport area (logical coordinates)
+ tools::Rectangle maSetBound;
+
+ // Flags
+ bool mbPerspective : 1;
+ bool mbProjectionValid : 1;
+
+public:
+ B3dTransformationSet();
+ virtual ~B3dTransformationSet();
+
+ B3dTransformationSet(B3dTransformationSet const &) = default;
+ B3dTransformationSet(B3dTransformationSet &&) = default;
+ B3dTransformationSet & operator =(B3dTransformationSet const &) = default;
+ B3dTransformationSet & operator =(B3dTransformationSet &&) = default;
+
+ void Reset();
+
+ /** Set the orientation
+
+ @param vVRP the View Reference Point (VRP)
+ @param vVPN the View Plane Normal (VPN)
+ @param vVUP the View Up Plane (VUP)
+ */
+ void SetOrientation(
+ const basegfx::B3DPoint& rVRP = basegfx::B3DPoint(0.0,0.0,1.0),
+ const basegfx::B3DVector& rVPN = basegfx::B3DVector(0.0,0.0,1.0),
+ const basegfx::B3DVector& rVUP = basegfx::B3DVector(0.0,1.0,0.0));
+
+ // Projection
+ void SetProjection(const basegfx::B3DHomMatrix& mProject);
+ const basegfx::B3DHomMatrix& GetProjection();
+
+ // Texture
+
+ // aspect ratio accessors and the defined method of keeping defined aspect ratio
+ double GetRatio() const { return mfRatio; }
+ void SetRatio(double fNew);
+
+ // Parameters of ViewportTransformation
+ void SetDeviceRectangle(double fL=-1.0, double fR=1.0,
+ double fB=-1.0, double fT=1.0);
+ double GetDeviceRectangleWidth() const { return mfRightBound - mfLeftBound; }
+
+ void SetPerspective(bool bNew);
+
+ void SetViewportRectangle(tools::Rectangle const & rRect, tools::Rectangle const & rVisible);
+ void SetViewportRectangle(tools::Rectangle const & rRect) { SetViewportRectangle(rRect, rRect); }
+
+ void CalcViewport();
+
+ // Direct accessors for miscellaneous transformations
+ basegfx::B3DPoint WorldToEyeCoor(const basegfx::B3DPoint& rVec);
+ basegfx::B3DPoint EyeToWorldCoor(const basegfx::B3DPoint& rVec);
+
+ static void Frustum(
+ basegfx::B3DHomMatrix& rTarget,
+ double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.001, double fFar = 1.0);
+ static void Ortho(
+ basegfx::B3DHomMatrix& rTarget,
+ double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.0, double fFar = 1.0);
+ static void Orientation(
+ basegfx::B3DHomMatrix& rTarget,
+ const basegfx::B3DPoint& aVRP = basegfx::B3DPoint(0.0,0.0,1.0),
+ basegfx::B3DVector aVPN = basegfx::B3DVector(0.0,0.0,1.0),
+ basegfx::B3DVector aVUP = basegfx::B3DVector(0.0,1.0,0.0));
+
+protected:
+ void PostSetObjectTrans();
+ void PostSetOrientation();
+ void PostSetProjection();
+
+ virtual void DeviceRectangleChange();
+};
+
+/** Viewport for B3D
+
+ Uses a simplified model, in which a point is described using a View
+ Reference Point (VRP).
+*/
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC B3dViewport : public B3dTransformationSet
+{
+private:
+ basegfx::B3DPoint aVRP; // View Reference Point
+ basegfx::B3DVector aVPN; // View Plane Normal
+ basegfx::B3DVector aVUV; // View Up Vector
+
+public:
+ B3dViewport();
+ virtual ~B3dViewport() override;
+
+ B3dViewport(B3dViewport const &) = default;
+ B3dViewport(B3dViewport &&) = default;
+ B3dViewport & operator =(B3dViewport const &) = default;
+ B3dViewport & operator =(B3dViewport &&) = default;
+
+ void SetVUV(const basegfx::B3DVector& rNewVUV);
+ void SetViewportValues(
+ const basegfx::B3DPoint& rNewVRP,
+ const basegfx::B3DVector& rNewVPN,
+ const basegfx::B3DVector& rNewVUV);
+
+ const basegfx::B3DPoint& GetVRP() const { return aVRP; }
+ const basegfx::B3DVector& GetVPN() const { return aVPN; }
+ const basegfx::B3DVector& GetVUV() const { return aVUV; }
+
+protected:
+ void CalcOrientation();
+};
+
+// B3D camera
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC B3dCamera final : public B3dViewport
+{
+public:
+ B3dCamera(
+ const basegfx::B3DPoint& rPos = basegfx::B3DPoint(0.0, 0.0, 1.0),
+ const basegfx::B3DVector& rLkAt = basegfx::B3DVector(0.0, 0.0, 0.0),
+ double fFocLen = 35.0, double fBnkAng = 0.0);
+ virtual ~B3dCamera() override;
+
+ B3dCamera(B3dCamera const &) = default;
+ B3dCamera(B3dCamera &&) = default;
+ B3dCamera & operator =(B3dCamera const &) = default;
+ B3dCamera & operator =(B3dCamera &&) = default;
+
+private:
+ void CalcNewViewportValues();
+ void CalcFocalLength();
+
+ virtual void DeviceRectangleChange() override;
+
+ basegfx::B3DPoint aPosition;
+ basegfx::B3DVector aLookAt;
+ double fFocalLength;
+ double fBankAngle;
+
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/bigint.hxx b/include/tools/bigint.hxx
new file mode 100644
index 0000000000..f8f57fc45d
--- /dev/null
+++ b/include/tools/bigint.hxx
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_BIGINT_HXX
+#define INCLUDED_TOOLS_BIGINT_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/long.hxx>
+
+#include <cassert>
+#include <string_view>
+
+#define MAX_DIGITS 8
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC BigInt
+{
+private:
+ // we only use one of these two fields at a time
+ union {
+ sal_Int32 nVal;
+ sal_uInt16 nNum[MAX_DIGITS];
+ };
+ sal_uInt8 nLen : 5; // current length, if 0, data is in nVal, otherwise data is in nNum
+ bool bIsNeg : 1; // Is Sign negative?
+
+ TOOLS_DLLPRIVATE void MakeBigInt(BigInt const &);
+ TOOLS_DLLPRIVATE void Normalize();
+ TOOLS_DLLPRIVATE void Mult(BigInt const &, sal_uInt16);
+ TOOLS_DLLPRIVATE void Div(sal_uInt16, sal_uInt16 &);
+ TOOLS_DLLPRIVATE bool IsLess(BigInt const &) const;
+ TOOLS_DLLPRIVATE void AddLong(BigInt &, BigInt &);
+ TOOLS_DLLPRIVATE void SubLong(BigInt &, BigInt &);
+ TOOLS_DLLPRIVATE void MultLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE void DivLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE void ModLong(BigInt const &, BigInt &) const;
+ TOOLS_DLLPRIVATE bool ABS_IsLess(BigInt const &) const;
+
+public:
+ BigInt()
+ : nVal(0)
+ , nLen(0)
+ , bIsNeg(false)
+ {
+ }
+
+ BigInt(sal_Int32 nValue)
+ : nVal(nValue)
+ , nLen(0)
+ , bIsNeg(false)
+ {
+ }
+
+#if SAL_TYPES_SIZEOFLONG == 4
+ BigInt(int nValue)
+ : nVal(nValue)
+ , nLen(0)
+ , bIsNeg(false)
+ {
+ }
+#endif
+
+ BigInt( double nVal );
+ BigInt( sal_uInt32 nVal );
+ BigInt( sal_Int64 nVal );
+ BigInt( const BigInt& rBigInt );
+ BigInt( std::u16string_view rString );
+
+ operator sal_Int16() const;
+ operator sal_uInt16() const;
+ operator sal_Int32() const;
+ operator sal_uInt32() const;
+ operator double() const;
+#if SAL_TYPES_SIZEOFPOINTER == 8
+ operator tools::Long() const;
+#endif
+
+ bool IsNeg() const;
+ bool IsZero() const;
+ bool IsLong() const { return nLen == 0; }
+
+ void Abs();
+
+ BigInt& operator =( const BigInt& rVal );
+ BigInt& operator +=( const BigInt& rVal );
+ BigInt& operator -=( const BigInt& rVal );
+ BigInt& operator *=( const BigInt& rVal );
+ BigInt& operator /=( const BigInt& rVal );
+ BigInt& operator %=( const BigInt& rVal );
+
+ BigInt& operator =( sal_Int32 nValue );
+
+ /* Scale and round value */
+ static tools::Long Scale(tools::Long nVal, tools::Long nMult, tools::Long nDiv);
+
+ friend inline BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator /( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline BigInt operator %( const BigInt& rVal1, const BigInt& rVal2 );
+
+ TOOLS_DLLPUBLIC friend bool operator==( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline bool operator!=( const BigInt& rVal1, const BigInt& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator< ( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline bool operator> ( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline bool operator<=( const BigInt& rVal1, const BigInt& rVal2 );
+ friend inline bool operator>=( const BigInt& rVal1, const BigInt& rVal2 );
+
+ friend class Fraction;
+};
+
+inline BigInt::operator sal_Int16() const
+{
+ if ( nLen == 0 && nVal >= SAL_MIN_INT16 && nVal <= SAL_MAX_INT16 )
+ return static_cast<sal_Int16>(nVal);
+ assert(false && "out of range");
+ return 0;
+}
+
+inline BigInt::operator sal_uInt16() const
+{
+ if ( nLen == 0 && nVal >= 0 && nVal <= SAL_MAX_UINT16 )
+ return static_cast<sal_uInt16>(nVal);
+ assert(false && "out of range");
+ return 0;
+}
+
+inline BigInt::operator sal_Int32() const
+{
+ if (nLen == 0)
+ return nVal;
+ assert(false && "out of range");
+ return 0;
+}
+
+inline BigInt::operator sal_uInt32() const
+{
+ if ( nLen == 0 && nVal >= 0 )
+ return static_cast<sal_uInt32>(nVal);
+ assert(false && "out of range");
+ return 0;
+}
+
+#if SAL_TYPES_SIZEOFPOINTER == 8
+inline BigInt::operator tools::Long() const
+{
+ // Clamp to int32 since long is int32 on Windows.
+ if (nLen == 0)
+ return nVal;
+ assert(false && "out of range");
+ return 0;
+}
+#endif
+
+inline BigInt& BigInt::operator =( sal_Int32 nValue )
+{
+ nLen = 0;
+ nVal = nValue;
+
+ return *this;
+}
+
+inline bool BigInt::IsNeg() const
+{
+ if ( nLen == 0 )
+ return (nVal < 0);
+ else
+ return bIsNeg;
+}
+
+inline bool BigInt::IsZero() const
+{
+ if ( nLen != 0 )
+ return false;
+ else
+ return (nVal == 0);
+}
+
+inline void BigInt::Abs()
+{
+ if ( nLen != 0 )
+ bIsNeg = false;
+ else if ( nVal < 0 )
+ nVal = -nVal;
+}
+
+inline BigInt operator+( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg += rVal2;
+ return aErg;
+}
+
+inline BigInt operator-( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg -= rVal2;
+ return aErg;
+}
+
+inline BigInt operator*( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg *= rVal2;
+ return aErg;
+}
+
+inline BigInt operator/( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg /= rVal2;
+ return aErg;
+}
+
+inline BigInt operator%( const BigInt &rVal1, const BigInt &rVal2 )
+{
+ BigInt aErg( rVal1 );
+ aErg %= rVal2;
+ return aErg;
+}
+
+inline bool operator!=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !(rVal1 == rVal2);
+}
+
+inline bool operator>(const BigInt& rVal1, const BigInt& rVal2) { return rVal2 < rVal1; }
+
+inline bool operator<=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !( rVal1 > rVal2);
+}
+
+inline bool operator>=( const BigInt& rVal1, const BigInt& rVal2 )
+{
+ return !(rVal1 < rVal2);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/color.hxx b/include/tools/color.hxx
new file mode 100644
index 0000000000..8ab3544589
--- /dev/null
+++ b/include/tools/color.hxx
@@ -0,0 +1,523 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_COLOR_HXX
+#define INCLUDED_TOOLS_COLOR_HXX
+
+#include <sal/types.h>
+#include <tools/toolsdllapi.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <config_global.h>
+#include <basegfx/color/bcolor.hxx>
+#include <osl/endian.h>
+
+namespace color
+{
+
+constexpr sal_uInt32 extractRGB(sal_uInt32 nColorNumber)
+{
+ return nColorNumber & 0x00FFFFFF;
+}
+
+constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8 nSrcTrans)
+{
+ return sal_uInt8(((sal_Int32(nDst) - nSrc) * nSrcTrans + ((nSrc << 8) | nDst)) >> 8);
+}
+
+}
+
+/** used to deliberately select the right constructor */
+enum ColorTransparencyTag { ColorTransparency = 0 };
+enum ColorAlphaTag { ColorAlpha = 0 };
+
+// Color
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Color
+{
+ union
+ {
+ sal_uInt32 mValue;
+ struct
+ {
+#ifdef OSL_BIGENDIAN
+ sal_uInt8 T;
+ sal_uInt8 R;
+ sal_uInt8 G;
+ sal_uInt8 B;
+#else
+ sal_uInt8 B;
+ sal_uInt8 G;
+ sal_uInt8 R;
+ sal_uInt8 T;
+#endif
+ };
+ };
+
+public:
+ constexpr Color()
+ : mValue(0) // black
+ {}
+
+#if HAVE_CPP_CONSTEVAL
+ consteval
+#else
+ constexpr
+#endif
+ Color(const sal_uInt32 nColor)
+ : mValue(nColor)
+ {
+ assert(nColor <= 0xffffff && "don't pass transparency to this constructor, use the Color(ColorTransparencyTag,...) or Color(ColorAlphaTag,...) constructor to make it explicit");
+ }
+
+ constexpr Color(enum ColorTransparencyTag, sal_uInt32 nColor)
+ : mValue(nColor)
+ {
+ }
+
+ constexpr Color(enum ColorAlphaTag, sal_uInt32 nColor)
+ : mValue((nColor & 0xffffff) | ((255 - (nColor >> 24)) << 24))
+ {
+ }
+
+ constexpr Color(enum ColorTransparencyTag, sal_uInt8 nTransparency, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
+ : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16) | (sal_uInt32(nTransparency) << 24))
+ {}
+
+ constexpr Color(enum ColorAlphaTag, sal_uInt8 nAlpha, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
+ : Color(ColorTransparency, 255 - nAlpha, nRed, nGreen, nBlue)
+ {}
+
+ constexpr Color(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
+ : Color(ColorTransparency, 0, nRed, nGreen, nBlue)
+ {}
+
+ // constructor to create a tools-Color from ::basegfx::BColor
+ explicit Color(const basegfx::BColor& rBColor)
+ : Color(ColorTransparency, 0,
+ sal_uInt8(std::lround(rBColor.getRed() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getGreen() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getBlue() * 255.0)))
+ {}
+
+ /** Casts the color to corresponding uInt32.
+ * Primarily used when passing Color objects to UNO API
+ * @return corresponding sal_uInt32
+ */
+ constexpr explicit operator sal_uInt32() const
+ {
+ return mValue;
+ }
+
+ /** Casts the color to corresponding iInt32.
+ * If there is no transparency, will be positive.
+ * @return corresponding sal_Int32
+ */
+ constexpr explicit operator sal_Int32() const
+ {
+ return sal_Int32(mValue);
+ }
+
+ /* Basic RGBA operations */
+
+ /** Gets the red value.
+ * @return R
+ */
+ sal_uInt8 GetRed() const
+ {
+ return R;
+ }
+
+ /** Gets the green value.
+ * @return G
+ */
+ sal_uInt8 GetGreen() const
+ {
+ return G;
+ }
+
+ /** Gets the blue value.
+ * @return B
+ */
+ sal_uInt8 GetBlue() const
+ {
+ return B;
+ }
+
+ /** Gets the alpha value.
+ * @return A
+ */
+ sal_uInt8 GetAlpha() const
+ {
+ return 255 - T;
+ }
+
+ /** Is the color transparent?
+ */
+ bool IsTransparent() const
+ {
+ return GetAlpha() != 255;
+ }
+
+ /** Is the color fully transparent i.e. 100% transparency ?
+ */
+ bool IsFullyTransparent() const
+ {
+ return T == 255;
+ }
+
+ /** Sets the red value.
+ * @param nRed
+ */
+ void SetRed(sal_uInt8 nRed)
+ {
+ R = nRed;
+ }
+
+ /** Sets the green value.
+ * @param nGreen
+ */
+ void SetGreen(sal_uInt8 nGreen)
+ {
+ G = nGreen;
+ }
+
+ /** Sets the blue value.
+ * @param nBlue
+ */
+ void SetBlue(sal_uInt8 nBlue)
+ {
+ B = nBlue;
+ }
+
+ /** Sets the alpha value.
+ * @param nAlpha
+ */
+ void SetAlpha(sal_uInt8 nAlpha)
+ {
+ T = 255 - nAlpha;
+ }
+
+ /** Returns the same color but ignoring the transparency value.
+ * @return RGB version
+ */
+ Color GetRGBColor() const
+ {
+ return {R, G, B};
+ }
+
+ /* Comparison and operators */
+
+ /** Check if the color RGB value is equal than rColor.
+ * @param rColor
+ * @return is equal
+ */
+ bool IsRGBEqual( const Color& rColor ) const
+ {
+ return ( mValue & 0x00FFFFFF ) == ( rColor.mValue & 0x00FFFFFF );
+ }
+
+ /** Check if the color value is lower than aCompareColor.
+ * @param aCompareColor
+ * @return is lower
+ */
+ bool operator<(const Color& aCompareColor) const
+ {
+ return mValue < aCompareColor.mValue;
+ }
+
+ /** Check if the color value is greater than aCompareColor.
+ * @param aCompareColor
+ * @return is greater
+ */
+ bool operator>(const Color& aCompareColor) const
+ {
+ return mValue > aCompareColor.mValue;
+ }
+
+ /** Check if the color value is equal than rColor.
+ * @param rColor
+ * @return is equal
+ */
+ bool operator==(const Color& rColor) const
+ {
+ return mValue == rColor.mValue;
+ }
+
+ /** Check if the color value is unequal than rColor.
+ * @param rColor
+ * @return is unequal
+ */
+ bool operator!=(const Color& rColor) const
+ {
+ return mValue != rColor.mValue;
+ }
+
+ /** Gets the color error compared to another.
+ * It describes how different they are.
+ * It takes the abs of differences in parameters.
+ * @param rCompareColor
+ * @return error
+ */
+ sal_uInt16 GetColorError(const Color& rCompareColor) const
+ {
+ return static_cast<sal_uInt16>(
+ abs(static_cast<int>(GetBlue()) - rCompareColor.GetBlue()) +
+ abs(static_cast<int>(GetGreen()) - rCompareColor.GetGreen()) +
+ abs(static_cast<int>(GetRed()) - rCompareColor.GetRed()));
+ }
+
+ /* Light and contrast */
+
+ /** Gets the color luminance. It means perceived brightness.
+ * @return luminance
+ */
+ sal_uInt8 GetLuminance() const
+ {
+ return sal_uInt8((B * 29UL + G * 151UL + R * 76UL) >> 8);
+ }
+
+ /** Increases the color luminance by cLumInc.
+ * @param cLumInc
+ */
+ void IncreaseLuminance(sal_uInt8 cLumInc);
+
+ /** Decreases the color luminance by cLumDec.
+ * @param cLumDec
+ */
+ void DecreaseLuminance(sal_uInt8 cLumDec);
+
+ /** Decreases color contrast with white by cContDec.
+ * @param cContDec
+ */
+ void DecreaseContrast(sal_uInt8 cContDec);
+
+ /** Comparison with luminance thresholds.
+ * @return is dark
+ */
+ bool IsDark() const
+ {
+ // tdf#156182, and band aid for follow-up issues
+ if (mValue == 0x729fcf) // COL_DEFAULT_SHAPE_FILLING
+ return GetLuminance() <= 62;
+ else
+ return GetLuminance() <= 156;
+ }
+
+ /** Comparison with luminance thresholds.
+ * @return is dark
+ */
+ bool IsBright() const
+ {
+ return GetLuminance() >= 245;
+ }
+
+ /* Color filters */
+
+ /**
+ * Apply tint or shade to a color.
+ *
+ * The input value is the percentage (in 100th of percent) of how much the
+ * color changes towards the black (shade) or white (tint). If the value
+ * is positive, the color is tinted, if the value is negative, the color is
+ * shaded.
+ **/
+ void ApplyTintOrShade(sal_Int16 n100thPercent);
+
+ /**
+ * Apply luminance offset and/or modulation.
+ *
+ * The input values are in percentages (in 100th percents). 100% modulation and 0% offset
+ * results in no change.
+ */
+ void ApplyLumModOff(sal_Int16 nMod, sal_Int16 nOff);
+
+ /** Inverts color. 1 and 0 are switched.
+ * Note that the result will be the complementary color.
+ * For example, if you have red, you will get cyan: FF0000 -> 00FFFF.
+ */
+ void Invert()
+ {
+ R = ~R;
+ G = ~G;
+ B = ~B;
+ }
+
+ /** Merges color with rMergeColor.
+ * Allows to get resulting color when superposing another.
+ * @param rMergeColor
+ * @param cTransparency
+ */
+ void Merge(const Color& rMergeColor, sal_uInt8 cTransparency)
+ {
+ R = color::ColorChannelMerge(R, rMergeColor.R, cTransparency);
+ G = color::ColorChannelMerge(G, rMergeColor.G, cTransparency);
+ B = color::ColorChannelMerge(B, rMergeColor.B, cTransparency);
+ }
+
+ /* Change of format */
+
+ /** Color space conversion tools
+ * The range for h/s/b is:
+ * - Hue: 0-360 degree
+ * - Saturation: 0-100%
+ * - Brightness: 0-100%
+ * @param nHue
+ * @param nSaturation
+ * @param nBrightness
+ * @return rgb color
+ */
+ static Color HSBtoRGB(sal_uInt16 nHue, sal_uInt16 nSaturation, sal_uInt16 nBrightness);
+
+ /** Converts a string into a color. Supports:
+ * #RRGGBB
+ * #rrggbb
+ * #RGB
+ * #rgb
+ * RRGGBB
+ * rrggbb
+ * RGB
+ * rgb
+ * If fails returns Color().
+ */
+ static Color STRtoRGB(std::u16string_view colorname);
+
+ /** Color space conversion tools
+ * @param nHue
+ * @param nSaturation
+ * @param nBrightness
+ */
+ void RGBtoHSB(sal_uInt16& nHue, sal_uInt16& nSaturation, sal_uInt16& nBrightness) const;
+
+ /* Return color as RGB hex string: rrggbb
+ * for example "00ff00" for green color
+ * @return hex string
+ */
+ OUString AsRGBHexString() const;
+
+ /* Return color as RGB hex string: RRGGBB
+ * for example "00FF00" for green color
+ * @return hex string
+ */
+ OUString AsRGBHEXString() const;
+
+ /* get ::basegfx::BColor from this color
+ * @return basegfx color
+ */
+ basegfx::BColor getBColor() const
+ {
+ return basegfx::BColor(R / 255.0, G / 255.0, B / 255.0);
+ }
+};
+
+// to reduce the noise when moving these into and out of Any
+inline bool operator >>=( const css::uno::Any & rAny, Color & value )
+{
+ sal_Int32 nTmp = {}; // spurious -Werror=maybe-uninitialized
+ if (!(rAny >>= nTmp))
+ return false;
+ value = Color(ColorTransparency, nTmp);
+ return true;
+}
+
+inline void operator <<=( css::uno::Any & rAny, Color value )
+{
+ rAny <<= sal_Int32(value);
+}
+
+namespace com::sun::star::uno {
+ template<> inline Any::Any(Color const & value): Any(sal_Int32(value)) {}
+}
+
+// Test compile time conversion of Color to sal_uInt32
+
+static_assert (sal_uInt32(Color(ColorTransparency, 0x00, 0x12, 0x34, 0x56)) == 0x00123456);
+static_assert (sal_uInt32(Color(0x12, 0x34, 0x56)) == 0x00123456);
+
+// Color types
+
+inline constexpr ::Color COL_TRANSPARENT ( ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF );
+inline constexpr ::Color COL_AUTO ( ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF );
+// These are used when drawing to the separate alpha channel we use in vcl
+inline constexpr ::Color COL_ALPHA_TRANSPARENT ( 0x00, 0x00, 0x00 );
+inline constexpr ::Color COL_ALPHA_OPAQUE ( 0xff, 0xff, 0xff );
+
+inline constexpr ::Color COL_BLACK ( 0x00, 0x00, 0x00 );
+inline constexpr ::Color COL_BLUE ( 0x00, 0x00, 0x80 );
+inline constexpr ::Color COL_GREEN ( 0x00, 0x80, 0x00 );
+inline constexpr ::Color COL_CYAN ( 0x00, 0x80, 0x80 );
+inline constexpr ::Color COL_RED ( 0x80, 0x00, 0x00 );
+inline constexpr ::Color COL_MAGENTA ( 0x80, 0x00, 0x80 );
+inline constexpr ::Color COL_BROWN ( 0x80, 0x80, 0x00 );
+inline constexpr ::Color COL_GRAY ( 0x80, 0x80, 0x80 );
+inline constexpr ::Color COL_GRAY3 ( 0xCC, 0xCC, 0xCC );
+inline constexpr ::Color COL_GRAY7 ( 0x66, 0x66, 0x66 );
+inline constexpr ::Color COL_LIGHTGRAY ( 0xC0, 0xC0, 0xC0 );
+inline constexpr ::Color COL_LIGHTBLUE ( 0x00, 0x00, 0xFF );
+inline constexpr ::Color COL_LIGHTGREEN ( 0x00, 0xFF, 0x00 );
+inline constexpr ::Color COL_LIGHTCYAN ( 0x00, 0xFF, 0xFF );
+inline constexpr ::Color COL_LIGHTRED ( 0xFF, 0x00, 0x00 );
+inline constexpr ::Color COL_LIGHTMAGENTA ( 0xFF, 0x00, 0xFF );
+inline constexpr ::Color COL_LIGHTGRAYBLUE ( 0xE0, 0xE0, 0xFF );
+inline constexpr ::Color COL_YELLOW ( 0xFF, 0xFF, 0x00 );
+inline constexpr ::Color COL_WHITE ( 0xFF, 0xFF, 0xFF );
+inline constexpr ::Color COL_AUTHOR1_DARK ( 0xC6, 0x92, 0x00 );
+inline constexpr ::Color COL_AUTHOR1_NORMAL ( 0xFF, 0xFF, 0x9E );
+inline constexpr ::Color COL_AUTHOR1_LIGHT ( 0xFF, 0xFF, 0xC3 );
+inline constexpr ::Color COL_AUTHOR2_DARK ( 0x06, 0x46, 0xA2 );
+inline constexpr ::Color COL_AUTHOR2_NORMAL ( 0xD8, 0xE8, 0xFF );
+inline constexpr ::Color COL_AUTHOR2_LIGHT ( 0xE9, 0xF2, 0xFF );
+inline constexpr ::Color COL_AUTHOR3_DARK ( 0x57, 0x9D, 0x1C );
+inline constexpr ::Color COL_AUTHOR3_NORMAL ( 0xDA, 0xF8, 0xC1 );
+inline constexpr ::Color COL_AUTHOR3_LIGHT ( 0xE2, 0xFA, 0xCF );
+inline constexpr ::Color COL_AUTHOR4_DARK ( 0x69, 0x2B, 0x9D );
+inline constexpr ::Color COL_AUTHOR4_NORMAL ( 0xE4, 0xD2, 0xF5 );
+inline constexpr ::Color COL_AUTHOR4_LIGHT ( 0xEF, 0xE4, 0xF8 );
+inline constexpr ::Color COL_AUTHOR5_DARK ( 0xC5, 0x00, 0x0B );
+inline constexpr ::Color COL_AUTHOR5_NORMAL ( 0xFE, 0xCD, 0xD0 );
+inline constexpr ::Color COL_AUTHOR5_LIGHT ( 0xFF, 0xE3, 0xE5 );
+inline constexpr ::Color COL_AUTHOR6_DARK ( 0x00, 0x80, 0x80 );
+inline constexpr ::Color COL_AUTHOR6_NORMAL ( 0xD2, 0xF6, 0xF6 );
+inline constexpr ::Color COL_AUTHOR6_LIGHT ( 0xE6, 0xFA, 0xFA );
+inline constexpr ::Color COL_AUTHOR7_DARK ( 0x8C, 0x84, 0x00 );
+inline constexpr ::Color COL_AUTHOR7_NORMAL ( 0xED, 0xFC, 0xA3 );
+inline constexpr ::Color COL_AUTHOR7_LIGHT ( 0xF2, 0xFE, 0xB5 );
+inline constexpr ::Color COL_AUTHOR8_DARK ( 0x35, 0x55, 0x6B );
+inline constexpr ::Color COL_AUTHOR8_NORMAL ( 0xD3, 0xDE, 0xE8 );
+inline constexpr ::Color COL_AUTHOR8_LIGHT ( 0xE2, 0xEA, 0xF1 );
+inline constexpr ::Color COL_AUTHOR9_DARK ( 0xD1, 0x76, 0x00 );
+inline constexpr ::Color COL_AUTHOR9_NORMAL ( 0xFF, 0xE2, 0xB9 );
+inline constexpr ::Color COL_AUTHOR9_LIGHT ( 0xFF, 0xE7, 0xC7 );
+inline constexpr ::Color COL_AUTHOR_TABLE_INS ( 0xE1, 0xF2, 0xFA );
+inline constexpr ::Color COL_AUTHOR_TABLE_DEL ( 0xFC, 0xE6, 0xF4 );
+
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits>& operator <<(std::basic_ostream<charT, traits>& rStream, const Color& rColor)
+{
+ std::ios_base::fmtflags nOrigFlags = rStream.flags();
+ rStream << "rgba[" << std::hex << std::setfill ('0')
+ << std::setw(2) << static_cast<int>(rColor.GetRed())
+ << std::setw(2) << static_cast<int>(rColor.GetGreen())
+ << std::setw(2) << static_cast<int>(rColor.GetBlue())
+ << std::setw(2) << static_cast<int>(rColor.GetAlpha()) << "]";
+ rStream.setf(nOrigFlags);
+ return rStream;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/config.hxx b/include/tools/config.hxx
new file mode 100644
index 0000000000..3616d087cf
--- /dev/null
+++ b/include/tools/config.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_CONFIG_HXX
+#define INCLUDED_TOOLS_CONFIG_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/ustring.hxx>
+#include <memory>
+
+struct ImplConfigData;
+struct ImplGroupData;
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Config
+{
+private:
+ OUString maFileName;
+ OString maGroupName;
+ std::unique_ptr<ImplConfigData> mpData;
+ ImplGroupData* mpActGroup;
+ sal_uInt32 mnDataUpdateId;
+
+ TOOLS_DLLPRIVATE bool ImplUpdateConfig() const;
+ TOOLS_DLLPRIVATE ImplGroupData* ImplGetGroup() const;
+
+public:
+ Config( const OUString& rFileName );
+ ~Config();
+
+ void SetGroup(const OString& rGroup);
+ const OString& GetGroup() const { return maGroupName; }
+ void DeleteGroup(std::string_view rGroup);
+ OString GetGroupName(sal_uInt16 nGroup) const;
+ sal_uInt16 GetGroupCount() const;
+ bool HasGroup(std::string_view rGroup) const;
+
+ OString ReadKey(const OString& rKey) const;
+ OString ReadKey(const OString& rKey, const OString& rDefault) const;
+ void WriteKey(const OString& rKey, const OString& rValue);
+ void DeleteKey(std::string_view rKey);
+ OString GetKeyName(sal_uInt16 nKey) const;
+ OString ReadKey(sal_uInt16 nKey) const;
+ sal_uInt16 GetKeyCount() const;
+
+ void Flush();
+
+private:
+ Config( const Config& rConfig ) = delete;
+ Config& operator = ( const Config& rConfig ) = delete;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/contnr.hxx b/include/tools/contnr.hxx
new file mode 100644
index 0000000000..090be0dbee
--- /dev/null
+++ b/include/tools/contnr.hxx
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_CONTNR_HXX
+#define INCLUDED_TOOLS_CONTNR_HXX
+
+#include <sal/types.h>
+
+#define TREELIST_APPEND (SAL_MAX_UINT32)
+#define TREELIST_ENTRY_NOTFOUND (SAL_MAX_UINT32)
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/cpuid.hxx b/include/tools/cpuid.hxx
new file mode 100644
index 0000000000..4f309ff11e
--- /dev/null
+++ b/include/tools/cpuid.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <sal/config.h>
+#include <tools/toolsdllapi.h>
+#include <o3tl/typed_flags_set.hxx>
+#include <rtl/ustring.hxx>
+
+/*
+
+Do NOT include this header in source files compiled with CPU-specific code.
+TODO: For the header to be safe that way, it should be free of any templates
+or inline functions, otherwise their possibly emitted copies compiled
+with the CPU-specific instructions might be chosen by the linker as the copy
+to keep.
+
+Also see the note at the top of simdsupport.hxx .
+
+*/
+
+namespace cpuid {
+
+enum class InstructionSetFlags
+{
+ NONE = 0x00,
+ HYPER = 0x01,
+ SSE2 = 0x02,
+ SSSE3 = 0x04,
+ SSE41 = 0x08,
+ SSE42 = 0x10,
+ AVX = 0x20,
+ AVX2 = 0x40,
+ AVX512F = 0x80
+};
+
+} // end cpuid
+
+namespace o3tl {
+ template<> struct typed_flags<cpuid::InstructionSetFlags> : is_typed_flags<cpuid::InstructionSetFlags, 0x0ff> {};
+}
+
+namespace cpuid {
+
+/** Get supported instruction set flags determined at runtime by probing the CPU.
+ */
+TOOLS_DLLPUBLIC InstructionSetFlags getCpuInstructionSetFlags();
+
+/** Check if a certain instruction set is supported by the CPU at runtime.
+ */
+TOOLS_DLLPUBLIC bool isCpuInstructionSetSupported(InstructionSetFlags eInstructions);
+
+/** Returns a string of supported instructions.
+ */
+TOOLS_DLLPUBLIC OUString instructionSetSupportedString();
+
+/** Check if SSE2 is supported by the CPU
+ */
+inline bool hasSSE2()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::SSE2);
+}
+
+/** Check if SSSE3 is supported by the CPU
+ */
+inline bool hasSSSE3()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::SSSE3);
+}
+
+/** Check if AVX is supported by the CPU
+ */
+inline bool hasAVX()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::AVX);
+}
+
+/** Check if AVX2 is supported by the CPU
+ */
+inline bool hasAVX2()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::AVX2);
+}
+
+/** Check if AVX512F is supported by the CPU
+ */
+inline bool hasAVX512F()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::AVX512F);
+}
+
+/** Check if Hyper Threading is supported
+ */
+inline bool hasHyperThreading()
+{
+ return isCpuInstructionSetSupported(InstructionSetFlags::HYPER);
+}
+
+} // end cpuid
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/date.hxx b/include/tools/date.hxx
new file mode 100644
index 0000000000..6179d637e8
--- /dev/null
+++ b/include/tools/date.hxx
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_DATE_HXX
+#define INCLUDED_TOOLS_DATE_HXX
+
+#include <tools/toolsdllapi.h>
+
+#include <ostream>
+
+#include <com/sun/star/util/Date.hpp>
+
+namespace com::sun::star::util { struct DateTime; }
+
+enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
+ SATURDAY, SUNDAY };
+
+/** Represents a date in the proleptic Gregorian calendar.
+
+ Largest representable date is 32767-12-31 = 327671231
+
+ Smallest representable date is -32768-01-01 = -327680101
+
+ Due to possible conversions to css::util::Date, which has a short
+ Year member variable, these limits are fix.
+
+ Year value 0 is unused. The year before year 1 CE is year 1 BCE, which is
+ the traditional proleptic Gregorian calendar.
+
+ This is not how ISO 8601:2000 defines things (but ISO 8601:1998 Draft
+ Revision did), but it enables class Date to be used for writing XML files
+ as XML Schema Part 2 in D.3.2 No Year Zero says
+ "The year "0000" is an illegal year value.", see
+ https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#noYearZero
+ and furthermore the note for 3.2.7 dateTime
+ https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#dateTime
+
+ */
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Date
+{
+private:
+ sal_Int32 mnDate;
+ void setDateFromDMY( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear );
+
+public:
+ enum DateInitSystem
+ {
+ SYSTEM
+ };
+
+ enum DateInitEmpty
+ {
+ EMPTY
+ };
+
+ explicit Date( DateInitEmpty ) : mnDate(0) {}
+ explicit Date( DateInitSystem );
+ explicit Date( sal_Int32 nDate ) : mnDate(nDate) {}
+ Date( const Date& rDate ) : mnDate(rDate.mnDate) {}
+
+ /** nDay and nMonth both must be <100, nYear must be != 0 */
+ Date( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear )
+ { setDateFromDMY(nDay, nMonth, nYear); }
+
+ Date( const css::util::Date& rUDate )
+ {
+ setDateFromDMY(rUDate.Day, rUDate.Month, rUDate.Year);
+ }
+ Date( const css::util::DateTime& _rDateTime );
+
+ bool IsEmpty() const { return mnDate == 0; }
+
+ void SetDate( sal_Int32 nNewDate );
+ sal_Int32 GetDate() const { return mnDate; }
+ /** Type safe access for values that are guaranteed to be unsigned, like Date::SYSTEM. */
+ sal_uInt32 GetDateUnsigned() const { return static_cast<sal_uInt32>(mnDate < 0 ? -mnDate : mnDate); }
+ css::util::Date GetUNODate() const { return css::util::Date(GetDay(), GetMonth(), GetYear()); }
+
+ /** nNewDay must be <100 */
+ void SetDay( sal_uInt16 nNewDay );
+ /** nNewMonth must be <100 */
+ void SetMonth( sal_uInt16 nNewMonth );
+ /** nNewYear must be != 0 */
+ void SetYear( sal_Int16 nNewYear );
+
+ sal_uInt16 GetDay() const
+ {
+ return mnDate < 0 ?
+ static_cast<sal_uInt16>(-mnDate % 100) :
+ static_cast<sal_uInt16>( mnDate % 100);
+ }
+ sal_uInt16 GetMonth() const
+ {
+ return mnDate < 0 ?
+ static_cast<sal_uInt16>((-mnDate / 100) % 100) :
+ static_cast<sal_uInt16>(( mnDate / 100) % 100);
+ }
+ sal_Int16 GetYear() const { return static_cast<sal_Int16>(mnDate / 10000); }
+ /** Type safe access for values that are guaranteed to be unsigned, like Date::SYSTEM. */
+ sal_uInt16 GetYearUnsigned() const { return static_cast<sal_uInt16>((mnDate < 0 ? -mnDate : mnDate) / 10000); }
+ sal_Int16 GetNextYear() const { sal_Int16 nY = GetYear(); return nY == -1 ? 1 : nY + 1; }
+ sal_Int16 GetPrevYear() const { sal_Int16 nY = GetYear(); return nY == 1 ? -1 : nY - 1; }
+
+ /** Add years skipping year 0 and truncating at limits. If the original
+ date was on Feb-29 and the resulting date is not a leap year, the
+ result is adjusted to Feb-28.
+ */
+ void AddYears( sal_Int16 nAddYears );
+
+ /** Add months skipping year 0 and truncating at limits. If the original
+ date was on Feb-29 or day 31 and the resulting date is not a leap year
+ or a month with fewer days, the result is adjusted to Feb-28 or day 30.
+ */
+ void AddMonths( sal_Int32 nAddMonths );
+
+ /** Add days skipping year 0 and truncating at limits.
+ */
+ void AddDays( sal_Int32 nAddDays );
+
+ /** Obtain the day of the week for the date.
+
+ Internally normalizes a copy of values.
+ The result may be unexpected for a non-normalized invalid date like
+ Date(31,11,2000) or a sequence of aDate.SetDay(31); aDate.SetMonth(11);
+ */
+ DayOfWeek GetDayOfWeek() const;
+
+ /** Obtain the day of the year for the date.
+
+ Internally normalizes a copy of values.
+ The result may be unexpected for a non-normalized invalid date like
+ Date(31,11,2000) or a sequence of aDate.SetDay(31); aDate.SetMonth(11);
+ */
+ sal_uInt16 GetDayOfYear() const;
+
+ /** Obtain the week of the year for a date.
+
+ @param nMinimumNumberOfDaysInWeek
+ How many days of a week must reside in the first week of a year.
+
+ Internally normalizes a copy of values.
+ The result may be unexpected for a non-normalized invalid date like
+ Date(31,11,2000) or a sequence of aDate.SetDay(31); aDate.SetMonth(11);
+ */
+ sal_uInt16 GetWeekOfYear( DayOfWeek eStartDay = MONDAY,
+ sal_Int16 nMinimumNumberOfDaysInWeek = 4 ) const;
+
+ /** Obtain the number of days in the month of the year of the date.
+
+ Internally normalizes a copy of values.
+
+ The result may be unexpected for a non-normalized invalid date like
+ Date(31,11,2000) or a sequence of aDate.SetDay(31); aDate.SetMonth(11);
+
+ These would result in 31 as --11-31 rolls over to --12-01 and the
+ number of days in December is returned.
+
+ Instead, to obtain the value for the actual set use the static method
+ Date::GetDaysInMonth( aDate.GetMonth(), aDate.GetYear()) in such cases.
+ */
+ sal_uInt16 GetDaysInMonth() const;
+
+ sal_uInt16 GetDaysInYear() const { return (IsLeapYear()) ? 366 : 365; }
+ bool IsLeapYear() const;
+
+ /** If the represented date is valid (1<=month<=12, 1<=day<=(28,29,30,31)
+ depending on month/year) AND is of the Gregorian calendar (1582-10-15
+ <= date)
+ */
+ bool IsValidAndGregorian() const;
+
+ /** If the represented date is valid (1<=month<=12, 1<=day<=(28,29,30,31)
+ depending on month/year) */
+ bool IsValidDate() const;
+
+ // Returns true, if the date is the end of the month, false otherwise.
+ bool IsEndOfMonth() const;
+
+ /** Normalize date, invalid day or month values are adapted such that they
+ carry over to the next month or/and year, for example 1999-02-32
+ becomes 1999-03-04, 1999-13-01 becomes 2000-01-01, 1999-13-42 becomes
+ 2000-02-11. Truncates at -32768-01-01 or 32767-12-31, 0001-00-x will
+ yield the normalized value of -0001-12-x
+
+ This may be necessary after Date ctors or if the SetDate(), SetDay(),
+ SetMonth(), SetYear() methods set individual non-matching values.
+ Adding/subtracting to/from dates never produces invalid dates.
+ */
+ void Normalize();
+
+ bool IsBetween( const Date& rFrom, const Date& rTo ) const
+ { return ((mnDate >= rFrom.mnDate) &&
+ (mnDate <= rTo.mnDate)); }
+
+ bool operator ==( const Date& rDate ) const
+ { return (mnDate == rDate.mnDate); }
+ bool operator !=( const Date& rDate ) const
+ { return (mnDate != rDate.mnDate); }
+ bool operator >( const Date& rDate ) const
+ { return (mnDate > rDate.mnDate); }
+ bool operator <( const Date& rDate ) const
+ { return (mnDate < rDate.mnDate); }
+ bool operator >=( const Date& rDate ) const
+ { return (mnDate >= rDate.mnDate); }
+ bool operator <=( const Date& rDate ) const
+ { return (mnDate <= rDate.mnDate); }
+
+ Date& operator =( const Date& rDate )
+ { mnDate = rDate.mnDate; return *this; }
+ Date& operator =( const css::util::Date& rUDate )
+ { setDateFromDMY( rUDate.Day, rUDate.Month, rUDate.Year); return *this; }
+ Date& operator ++();
+ Date& operator --();
+
+ TOOLS_DLLPUBLIC friend Date operator +( const Date& rDate, sal_Int32 nDays );
+ TOOLS_DLLPUBLIC friend Date operator -( const Date& rDate, sal_Int32 nDays );
+ TOOLS_DLLPUBLIC friend sal_Int32 operator -( const Date& rDate1, const Date& rDate2 );
+
+ /** Obtain number of days in a month of a year.
+
+ Internally sanitizes nMonth to values 1 <= nMonth <= 12, does not
+ normalize values.
+ */
+ static sal_uInt16 GetDaysInMonth( sal_uInt16 nMonth, sal_Int16 nYear );
+
+ /// Internally normalizes values.
+ static sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear );
+ /// Semantically identical to IsValidDate() member method.
+ static bool IsValidDate( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear );
+ /// Semantically identical to IsEndOfMonth() member method.
+ static bool IsEndOfMonth(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear);
+ /// Semantically identical to Normalize() member method.
+ static bool Normalize( sal_uInt16 & rDay, sal_uInt16 & rMonth, sal_Int16 & rYear );
+
+ private:
+ /// An accelerated form of DateToDays on this date
+ sal_Int32 GetAsNormalizedDays() const;
+};
+
+TOOLS_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const Date& rDate);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/datetime.hxx b/include/tools/datetime.hxx
new file mode 100644
index 0000000000..ddf29896c1
--- /dev/null
+++ b/include/tools/datetime.hxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_DATETIME_HXX
+#define INCLUDED_TOOLS_DATETIME_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+
+#include <iomanip>
+
+namespace tools
+{
+class Duration;
+}
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC DateTime : public Date, public tools::Time
+{
+public:
+ enum DateTimeInitSystem
+ {
+ SYSTEM
+ };
+
+ enum DateTimeInitEmpty
+ {
+ EMPTY
+ };
+
+ explicit DateTime( DateTimeInitEmpty ) : Date( Date::EMPTY ), Time( Time::EMPTY ) {}
+ explicit DateTime( DateTimeInitSystem );
+ DateTime( const DateTime& rDateTime ) :
+ Date( rDateTime ), Time( rDateTime ) {}
+ DateTime( const Date& rDate ) : Date( rDate ), Time(0) {}
+ DateTime( const tools::Time& rTime ) : Date(0), Time( rTime ) {}
+ DateTime( const Date& rDate, const tools::Time& rTime ) :
+ Date( rDate ), Time( rTime ) {}
+ DateTime( const css::util::DateTime& rDateTime );
+
+ css::util::DateTime
+ GetUNODateTime() const
+ { return css::util::DateTime(GetNanoSec(), GetSec(), GetMin(), GetHour(),
+ GetDay(), GetMonth(), GetYear(), false); }
+
+ bool IsBetween( const DateTime& rFrom,
+ const DateTime& rTo ) const;
+
+ bool IsEqualIgnoreNanoSec( const DateTime& rDateTime ) const
+ {
+ if ( Date::operator!=( rDateTime ) )
+ return false;
+ return Time::IsEqualIgnoreNanoSec( rDateTime );
+ }
+
+ bool operator ==( const DateTime& rDateTime ) const
+ { return (Date::operator==( rDateTime ) &&
+ Time::operator==( rDateTime )); }
+ bool operator !=( const DateTime& rDateTime ) const
+ { return (Date::operator!=( rDateTime ) ||
+ Time::operator!=( rDateTime )); }
+ bool operator >( const DateTime& rDateTime ) const;
+ bool operator <( const DateTime& rDateTime ) const;
+ bool operator >=( const DateTime& rDateTime ) const;
+ bool operator <=( const DateTime& rDateTime ) const;
+
+ sal_Int64 GetSecFromDateTime( const Date& rDate ) const;
+
+ void ConvertToUTC() { *this -= Time::GetUTCOffset(); }
+ void ConvertToLocalTime() { *this += Time::GetUTCOffset(); }
+
+ void AddTime( double fTimeInDays );
+ DateTime& operator +=( const tools::Time& rTime );
+ DateTime& operator -=( const tools::Time& rTime );
+ /** Duration can be negative, so adding it will subtract its value. */
+ DateTime& operator +=( const tools::Duration& rDuration );
+private:
+ void NormalizeTimeRemainderAndApply( tools::Time& rTime );
+public:
+
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, sal_Int32 nDays );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, sal_Int32 nDays );
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, double fTimeInDays );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, double fTimeInDays )
+ { return operator+( rDateTime, -fTimeInDays ); }
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, const tools::Time& rTime );
+ TOOLS_DLLPUBLIC friend DateTime operator -( const DateTime& rDateTime, const tools::Time& rTime );
+ /** Use operator-() if a duration is to be remembered or processed. */
+ TOOLS_DLLPUBLIC friend tools::Duration operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 );
+ /** Use Sub() if the floating point "time in days" value is to be
+ processed. This also takes a shortcut for whole days values (equal
+ times), and only for times inflicted values uses an intermediary
+ tools::Duration for conversion. Note that the resulting floating point
+ value nevertheless in many cases is not an exact representation down to
+ nanoseconds. */
+ static double Sub( const DateTime& rDateTime1, const DateTime& rDateTime2 );
+ TOOLS_DLLPUBLIC friend sal_Int64 operator -( const DateTime& rDateTime, const Date& rDate )
+ { return static_cast<const Date&>(rDateTime) - rDate; }
+ /** Duration can be negative, so adding it will subtract its value. */
+ TOOLS_DLLPUBLIC friend DateTime operator +( const DateTime& rDateTime, const tools::Duration& rDuration );
+
+ DateTime& operator =( const DateTime& rDateTime );
+ DateTime& operator =( const css::util::DateTime& rUDateTime );
+
+ void GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper ) const;
+ static DateTime CreateFromWin32FileDateTime( sal_uInt32 rLower, sal_uInt32 rUpper );
+
+ /// Creates DateTime given a unix time, which is the number of seconds
+ /// elapsed since Jan 1st, 1970.
+ static DateTime CreateFromUnixTime( const double fSecondsSinceEpoch );
+};
+
+inline DateTime& DateTime::operator =( const DateTime& rDateTime )
+{
+ Date::operator=( rDateTime );
+ Time::operator=( rDateTime );
+ return *this;
+}
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const DateTime& datetime)
+{
+ return stream << datetime.GetYear() << '-' <<
+ std::setw(2) << std::setfill('0') << datetime.GetMonth() << '-' <<
+ std::setw(2) << std::setfill('0') << datetime.GetDay() << ' ' <<
+ std::setw(2) << std::setfill('0') << datetime.GetHour() << ':' <<
+ std::setw(2) << std::setfill('0') << datetime.GetMin() << ':' <<
+ std::setw(2) << std::setfill('0') << datetime.GetSec() << "." <<
+ std::setw(9) << std::setfill('0') << datetime.GetNanoSec();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/datetimeutils.hxx b/include/tools/datetimeutils.hxx
new file mode 100644
index 0000000000..3df6229cb5
--- /dev/null
+++ b/include/tools/datetimeutils.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_TOOLS_DATETIMEUTILS_HXX
+#define INCLUDED_TOOLS_DATETIMEUTILS_HXX
+
+#include <tools/datetime.hxx>
+
+// This function converts a 'DateTime' object to an 'OString' object
+TOOLS_DLLPUBLIC OString DateTimeToOString(const DateTime& rDateTime);
+
+// This function converts a 'Date' object to an 'OString' object in ISO-8601 representation
+TOOLS_DLLPUBLIC OString DateToOString(const Date& rDate);
+
+// This function converts a 'Date' object to an 'OString' object in DD/MM/YYYY format
+TOOLS_DLLPUBLIC OString DateToDDMMYYYYOString(const Date& rDate);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/debug.hxx b/include/tools/debug.hxx
new file mode 100644
index 0000000000..c72da4d068
--- /dev/null
+++ b/include/tools/debug.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_DEBUG_HXX
+#define INCLUDED_TOOLS_DEBUG_HXX
+
+#include <tools/toolsdllapi.h>
+
+#include <sal/detail/log.h>
+
+/** The facilities provided by this header are deprecated. True assertions
+ (that detect broken program logic) should use standard assert (which aborts
+ if an assertion fails, and is controlled by the standard NDEBUG macro).
+ Logging of warnings (e.g., about malformed input) should use the facilities
+ provided by sal/log.hxx.
+
+ Because the assertion macro (DBG_ASSERT) has been used for
+ true assertions as well as to log warnings, it maps to SAL_WARN instead of
+ standard assert.
+*/
+
+typedef void (*DbgTestSolarMutexProc)();
+
+TOOLS_DLLPUBLIC void DbgSetTestSolarMutex( DbgTestSolarMutexProc pParam );
+TOOLS_DLLPUBLIC void DbgTestSolarMutex();
+
+#ifndef NDEBUG
+// we want the solar mutex checking to be enabled in the assert-enabled builds that the QA people use
+
+#define DBG_TESTSOLARMUTEX() \
+do \
+{ \
+ DbgTestSolarMutex(); \
+} while(false)
+
+#else
+
+#define DBG_TESTSOLARMUTEX() ((void)0)
+
+#endif
+
+#define DBG_ASSERT( sCon, aError ) \
+ SAL_DETAIL_WARN_IF_FORMAT(!(sCon), "legacy.tools", "%s", aError)
+
+
+#endif // INCLUDED_TOOLS_DEBUG_HXX
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/degree.hxx b/include/tools/degree.hxx
new file mode 100644
index 0000000000..560f9b115f
--- /dev/null
+++ b/include/tools/degree.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <basegfx/numeric/ftools.hxx>
+#include <sal/types.h>
+#include <o3tl/strong_int.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <cstdlib>
+#include <math.h>
+#include <numeric>
+
+template <int N> struct FractionTag;
+// 1/Nth fraction of a degree
+template <typename I, int N> using Degree = o3tl::strong_int<I, FractionTag<N>>;
+
+template <typename I, int N> char (&NofDegree(Degree<I, N>))[N]; // helper
+// Nof<DegreeN> gives compile-time constant N, needed in templates
+template <class D> constexpr int Nof = sizeof(NofDegree(std::declval<D>()));
+
+/** tenths of a Degree, normally rotation */
+typedef Degree<sal_Int16, 10> Degree10;
+
+/** custom literal */
+constexpr Degree10 operator""_deg10(unsigned long long n) { return Degree10{ n }; }
+
+/** hundredths of a Degree, normally rotation */
+typedef Degree<sal_Int32, 100> Degree100;
+
+// Android has trouble calling the correct overload of std::abs
+#ifdef ANDROID
+inline Degree100 abs(Degree100 x) { return Degree100(std::abs(static_cast<int>(x.get()))); }
+#else
+inline Degree100 abs(Degree100 x) { return Degree100(std::abs(x.get())); }
+#endif
+
+/** custom literal */
+constexpr Degree100 operator""_deg100(unsigned long long n) { return Degree100{ n }; }
+
+/** conversion functions */
+
+template <class To, typename IofFrom, int NofFrom> inline To to(Degree<IofFrom, NofFrom> x)
+{
+ constexpr sal_Int64 m = Nof<To> / std::gcd(Nof<To>, NofFrom);
+ constexpr sal_Int64 d = NofFrom / std::gcd(Nof<To>, NofFrom);
+ return To{ o3tl::convert(x.get(), m, d) };
+}
+
+template <class D> inline double toRadians(D x) { return basegfx::deg2rad<Nof<D>>(x.get()); }
+template <class D> inline double toDegrees(D x) { return x.get() / static_cast<double>(Nof<D>); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/tools/duration.hxx b/include/tools/duration.hxx
new file mode 100644
index 0000000000..9f032539e1
--- /dev/null
+++ b/include/tools/duration.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <tools/time.hxx>
+
+class DateTime;
+
+namespace tools
+{
+/** Duration in days and time. Can be negative in which case days is 0 and time
+ is negative or both days and time are negative.
+*/
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Duration
+{
+public:
+ Duration() {}
+
+ /** Assumes that DateTime are normalized and there are no Time out-of-range
+ field values. */
+ Duration(const ::DateTime& rStart, const ::DateTime& rEnd);
+
+ /** Time can be a limited duration as well. We don't cater for out-of-range
+ minutes and seconds values here though. */
+ Duration(const Time& rStart, const Time& rEnd);
+
+ constexpr static sal_uInt64 kAccuracyEpsilonNanoseconds = 300;
+ constexpr static sal_uInt64 kAccuracyEpsilonNanosecondsMicroseconds = 999;
+
+ /** Difference in days, like DateTime()-DateTime().
+
+ Can also be used to round a date+time value to, for example, microseconds.
+
+ @param nAccuracyEpsilonNanoseconds
+ Round for example by 1 nanosecond if it's just 1 off to a
+ second, i.e. 0999999999 or 0000000001. This can be loosened if
+ necessary. For example, if fTimeInDays is a date+time in
+ "today's" range with a significant seconds resolution, an
+ accuracy epsilon (=unsharpness) of ~300 is required. Hence default.
+ Must be 0 <= nAccuracyEpsilonNanoseconds <= Time::nanoSecPerSec - 1.
+ */
+ explicit Duration(double fTimeInDays,
+ sal_uInt64 nAccuracyEpsilonNanoseconds = kAccuracyEpsilonNanoseconds);
+
+ /** Time can be a limited duration as well and can have out-of-range
+ values, it will be normalized. Sign of both days and Time must be equal
+ unless one is 0. */
+ Duration(sal_Int32 nDays, const Time& rTime);
+
+ /** Individual time values can be out-of-range, all will be normalized.
+ Additionally, the resulting time overall hour value is not restricted
+ to sal_uInt16 like it is with Time, as values >=24 flow over into days.
+ For a negative duration only a negative nDays can be given, thus a
+ negative duration of less than one day is not possible. */
+ Duration(sal_Int32 nDays, sal_uInt32 nHours, sal_uInt32 nMinutes, sal_uInt32 nSeconds,
+ sal_uInt64 nNanoseconds);
+
+ bool IsNegative() const { return mnDays < 0 || maTime.GetTime() < 0; }
+ sal_Int32 GetDays() const { return mnDays; }
+ const Time& GetTime() const { return maTime; }
+ double GetInDays() const { return static_cast<double>(GetDays()) + GetTime().GetTimeInDays(); }
+
+ /** Whether a duration is set. */
+ operator bool() const { return maTime.GetTime() != 0 || mnDays != 0; }
+
+ /** Unary minus. */
+ Duration operator-() const;
+
+ /** Add a duration to this instance. */
+ Duration& Add(const Duration& rDuration, bool& rbOverflow);
+
+ /** Get multiple of duration. */
+ Duration Mult(sal_Int32 nMult, bool& rbOverflow) const;
+
+private:
+ /** Internal days and Time values. */
+ Duration(sal_Int32 nDays, sal_Int64 nTime);
+
+ /** Prerequisite: mnDays is already set. */
+ void Normalize(sal_uInt64 nHours, sal_uInt64 nMinutes, sal_uInt64 nSeconds,
+ sal_uInt64 nNanoseconds, bool bNegative);
+
+ /** Prerequisite: mnDays is already correctly set and absolute value of
+ nanoseconds less than one day. */
+ void ApplyTime(sal_Int64 nNS);
+
+ /** Prerequisite: mnDays is already correctly set and Time hour values
+ are adjusted. */
+ void SetTimeDiff(const Time& rStart, const Time& rEnd);
+
+private:
+ Time maTime = Time(0);
+ sal_Int32 mnDays = 0;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/tools/extendapplicationenvironment.hxx b/include/tools/extendapplicationenvironment.hxx
new file mode 100644
index 0000000000..0ca8ceca42
--- /dev/null
+++ b/include/tools/extendapplicationenvironment.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_EXTENDAPPLICATIONENVIRONMENT_HXX
+#define INCLUDED_TOOLS_EXTENDAPPLICATIONENVIRONMENT_HXX
+
+#include <sal/config.h>
+#include <tools/toolsdllapi.h>
+
+namespace tools
+{
+// Extend the environment of the process in a platform specific way as necessary
+// for OOo-related applications; must be called first thing in main:
+TOOLS_DLLPUBLIC void extendApplicationEnvironment();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/fileutil.hxx b/include/tools/fileutil.hxx
new file mode 100644
index 0000000000..d2ed87a6df
--- /dev/null
+++ b/include/tools/fileutil.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_TOOLS_FILEUTIL_HXX
+#define INCLUDED_TOOLS_FILEUTIL_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/ustring.hxx>
+
+namespace tools
+{
+// Tests if the path is a UNC or local (drive-based) path that redirects to
+// a WebDAV resource (e.g., using redirectors on Windows).
+// Currently only implemented for Windows; on other platforms, returns false.
+TOOLS_DLLPUBLIC bool IsMappedWebDAVPath(const OUString& rURL, OUString* pRealURL = nullptr);
+}
+
+#endif // INCLUDED_TOOLS_FILEUTIL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/fix16.hxx b/include/tools/fix16.hxx
new file mode 100644
index 0000000000..99de89b28e
--- /dev/null
+++ b/include/tools/fix16.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * libfixmath is Copyright (c) 2011-2021 Flatmush <Flatmush@gmail.com>,
+ * Petteri Aimonen <Petteri.Aimonen@gmail.com>, & libfixmath AUTHORS
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#pragma once
+
+#include <tools/toolsdllapi.h>
+#include <stdint.h>
+
+typedef int32_t fix16_t;
+
+/*! Multiplies the two given fix16_t's and returns the result.
+*/
+TOOLS_DLLPUBLIC fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1);
+
+/*! Divides the first given fix16_t by the second and returns the result.
+*/
+TOOLS_DLLPUBLIC fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/tools/fldunit.hxx b/include/tools/fldunit.hxx
new file mode 100644
index 0000000000..a2838c32ff
--- /dev/null
+++ b/include/tools/fldunit.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_FLDUNIT_HXX
+#define INCLUDED_TOOLS_FLDUNIT_HXX
+
+#include <sal/types.h>
+
+// Corresponds to offapi/com/sun/star/awt/FieldUnit.idl
+enum class FieldUnit : sal_uInt16
+{
+ NONE,
+ MM,
+ CM,
+ M,
+ KM,
+ TWIP,
+ POINT,
+ PICA,
+ INCH,
+ FOOT,
+ MILE,
+ CUSTOM,
+ PERCENT,
+ MM_100TH,
+ CHAR,
+ LINE,
+ PIXEL,
+ DEGREE,
+ SECOND,
+ MILLISECOND,
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/fontenum.hxx b/include/tools/fontenum.hxx
new file mode 100644
index 0000000000..5fac8dfdb9
--- /dev/null
+++ b/include/tools/fontenum.hxx
@@ -0,0 +1,457 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_FONTENUM_HXX
+#define INCLUDED_TOOLS_FONTENUM_HXX
+
+#include <sal/types.h>
+#include <sal/log.hxx>
+#include <o3tl/typed_flags_set.hxx>
+
+#include <ostream>
+
+enum FontFamily { FAMILY_DONTKNOW, FAMILY_DECORATIVE, FAMILY_MODERN,
+ FAMILY_ROMAN, FAMILY_SCRIPT, FAMILY_SWISS, FAMILY_SYSTEM, FontFamily_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontFamily const& family)
+{
+ switch (family)
+ {
+ case FAMILY_DONTKNOW:
+ return stream << "unknown";
+
+ case FAMILY_DECORATIVE:
+ return stream << "decorative";
+
+ case FAMILY_MODERN:
+ return stream << "modern";
+
+ case FAMILY_ROMAN:
+ return stream << "roman";
+
+ case FAMILY_SCRIPT:
+ return stream << "script";
+
+ case FAMILY_SWISS:
+ return stream << "swiss";
+
+ case FAMILY_SYSTEM:
+ return stream << "system";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontFamily out of bounds");
+ assert(false && "FontFamily out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontPitch { PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, FontPitch_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontPitch const& pitch)
+{
+ switch (pitch)
+ {
+ case PITCH_DONTKNOW:
+ return stream << "unknown";
+
+ case PITCH_FIXED:
+ return stream << "fixed";
+
+ case PITCH_VARIABLE:
+ return stream << "variable";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontPitch out of bounds");
+ assert(false && "FontPitch out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum TextAlign { ALIGN_TOP, ALIGN_BASELINE, ALIGN_BOTTOM, TextAlign_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, TextAlign const& align)
+{
+ switch (align)
+ {
+ case ALIGN_TOP:
+ return stream << "top";
+
+ case ALIGN_BASELINE:
+ return stream << "baseline";
+
+ case ALIGN_BOTTOM:
+ return stream << "bottom";
+
+ default:
+ SAL_WARN("vcl.gdi", "TextAlign out of bounds");
+ assert(false && "TextAlign out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontWeight { WEIGHT_DONTKNOW, WEIGHT_THIN, WEIGHT_ULTRALIGHT,
+ WEIGHT_LIGHT, WEIGHT_SEMILIGHT, WEIGHT_NORMAL,
+ WEIGHT_MEDIUM, WEIGHT_SEMIBOLD, WEIGHT_BOLD,
+ WEIGHT_ULTRABOLD, WEIGHT_BLACK, FontWeight_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontWeight const& weight)
+{
+ switch (weight)
+ {
+ case WEIGHT_DONTKNOW:
+ return stream << "unknown";
+
+ case WEIGHT_THIN:
+ return stream << "thin";
+
+ case WEIGHT_ULTRALIGHT:
+ return stream << "ultralight";
+
+ case WEIGHT_LIGHT:
+ return stream << "light";
+
+ case WEIGHT_SEMILIGHT:
+ return stream << "semilight";
+
+ case WEIGHT_NORMAL:
+ return stream << "normal";
+
+ case WEIGHT_MEDIUM:
+ return stream << "medium";
+
+ case WEIGHT_SEMIBOLD:
+ return stream << "semibold";
+
+ case WEIGHT_BOLD:
+ return stream << "bold";
+
+ case WEIGHT_ULTRABOLD:
+ return stream << "ultrabold";
+
+ case WEIGHT_BLACK:
+ return stream << "black";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontWeight out of bounds");
+ assert(false && "FontWeight out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontWidth { WIDTH_DONTKNOW, WIDTH_ULTRA_CONDENSED, WIDTH_EXTRA_CONDENSED,
+ WIDTH_CONDENSED, WIDTH_SEMI_CONDENSED, WIDTH_NORMAL,
+ WIDTH_SEMI_EXPANDED, WIDTH_EXPANDED, WIDTH_EXTRA_EXPANDED,
+ WIDTH_ULTRA_EXPANDED,
+ FontWidth_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontWidth const& width)
+{
+ switch (width)
+ {
+ case WIDTH_DONTKNOW:
+ return stream << "unknown";
+
+ case WIDTH_ULTRA_CONDENSED:
+ return stream << "ultra condensed";
+
+ case WIDTH_EXTRA_CONDENSED:
+ return stream << "extra ultra condensed";
+
+ case WIDTH_CONDENSED:
+ return stream << "condensed";
+
+ case WIDTH_SEMI_CONDENSED:
+ return stream << "semi condensed";
+
+ case WIDTH_NORMAL:
+ return stream << "normal";
+
+ case WIDTH_SEMI_EXPANDED:
+ return stream << "semi expanded";
+
+ case WIDTH_EXPANDED:
+ return stream << "expanded";
+
+ case WIDTH_EXTRA_EXPANDED:
+ return stream << "extra expanded";
+
+ case WIDTH_ULTRA_EXPANDED:
+ return stream << "ultra expanded";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontWidth out of bounds");
+ assert(false && "FontWidth out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontItalic { ITALIC_NONE, ITALIC_OBLIQUE, ITALIC_NORMAL, ITALIC_DONTKNOW, FontItalic_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontItalic const& italic)
+{
+ switch (italic)
+ {
+ case ITALIC_DONTKNOW:
+ return stream << "unknown";
+
+ case ITALIC_OBLIQUE:
+ return stream << "oblique";
+
+ case ITALIC_NORMAL:
+ return stream << "normal";
+
+ case ITALIC_NONE:
+ return stream << "none";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontItalic out of bounds");
+ assert(false && "FontItalic out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontLineStyle { LINESTYLE_NONE, LINESTYLE_SINGLE, LINESTYLE_DOUBLE,
+ LINESTYLE_DOTTED, LINESTYLE_DONTKNOW,
+ LINESTYLE_DASH, LINESTYLE_LONGDASH,
+ LINESTYLE_DASHDOT, LINESTYLE_DASHDOTDOT,
+ LINESTYLE_SMALLWAVE,
+ LINESTYLE_WAVE, LINESTYLE_DOUBLEWAVE,
+ LINESTYLE_BOLD, LINESTYLE_BOLDDOTTED,
+ LINESTYLE_BOLDDASH, LINESTYLE_BOLDLONGDASH,
+ LINESTYLE_BOLDDASHDOT, LINESTYLE_BOLDDASHDOTDOT,
+ LINESTYLE_BOLDWAVE,
+ FontLineStyle_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontLineStyle const& linestyle)
+{
+ switch (linestyle)
+ {
+ case LINESTYLE_NONE:
+ return stream << "none";
+
+ case LINESTYLE_SINGLE:
+ return stream << "single";
+
+ case LINESTYLE_DOUBLE:
+ return stream << "double";
+
+ case LINESTYLE_DOTTED:
+ return stream << "dotted";
+
+ case LINESTYLE_DONTKNOW:
+ return stream << "unknown";
+
+ case LINESTYLE_DASH:
+ return stream << "dash";
+
+ case LINESTYLE_LONGDASH:
+ return stream << "long dash";
+
+ case LINESTYLE_DASHDOT:
+ return stream << "dash dot";
+
+ case LINESTYLE_DASHDOTDOT:
+ return stream << "dash dot dot";
+
+ case LINESTYLE_SMALLWAVE:
+ return stream << "small wave";
+
+ case LINESTYLE_WAVE:
+ return stream << "wave";
+
+ case LINESTYLE_DOUBLEWAVE:
+ return stream << "double wave";
+
+ case LINESTYLE_BOLD:
+ return stream << "bold";
+
+ case LINESTYLE_BOLDDOTTED:
+ return stream << "bold dotted";
+
+ case LINESTYLE_BOLDDASH:
+ return stream << "bold dash";
+
+ case LINESTYLE_BOLDLONGDASH:
+ return stream << "bold long dash";
+
+ case LINESTYLE_BOLDDASHDOT:
+ return stream << "bold dash dot";
+
+ case LINESTYLE_BOLDDASHDOTDOT:
+ return stream << "bold dash dot dot";
+
+ case LINESTYLE_BOLDWAVE:
+ return stream << "bold wave";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontLineStyle out of bounds");
+ assert(false && "FontLineStyle out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontStrikeout { STRIKEOUT_NONE, STRIKEOUT_SINGLE, STRIKEOUT_DOUBLE,
+ STRIKEOUT_DONTKNOW, STRIKEOUT_BOLD,
+ STRIKEOUT_SLASH, STRIKEOUT_X,
+ FontStrikeout_FORCE_EQUAL_SIZE=SAL_MAX_ENUM };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontStrikeout const& strikeout)
+{
+ switch (strikeout)
+ {
+ case STRIKEOUT_NONE:
+ return stream << "none";
+
+ case STRIKEOUT_SINGLE:
+ return stream << "single";
+
+ case STRIKEOUT_DOUBLE:
+ return stream << "double";
+
+ case STRIKEOUT_DONTKNOW:
+ return stream << "unknown";
+
+ case STRIKEOUT_BOLD:
+ return stream << "bold";
+
+ case STRIKEOUT_SLASH:
+ return stream << "slash";
+
+ case STRIKEOUT_X:
+ return stream << "x";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontStrikeout out of bounds");
+ assert(false && "FontStrikeout out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum class FontEmphasisMark {
+ NONE = 0x0000, // capitalisation to avoid conflict with X11 macro
+ Dot = 0x0001,
+ Circle = 0x0002,
+ Disc = 0x0003,
+ Accent = 0x0004,
+ Style = 0x000f,
+ PosAbove = 0x1000,
+ PosBelow = 0x2000
+};
+namespace o3tl
+{
+ template<> struct typed_flags<FontEmphasisMark> : is_typed_flags<FontEmphasisMark, 0x300f> {};
+}
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontEmphasisMark const& emphasismark)
+{
+ switch (emphasismark)
+ {
+ case FontEmphasisMark::NONE:
+ return stream << "none";
+
+ case FontEmphasisMark::Dot:
+ return stream << "Dot";
+
+ case FontEmphasisMark::Circle:
+ return stream << "Circle";
+
+ case FontEmphasisMark::Disc:
+ return stream << "Disc";
+
+ case FontEmphasisMark::Accent:
+ return stream << "Accent";
+
+ case FontEmphasisMark::Style:
+ return stream << "Style";
+
+ case FontEmphasisMark::PosAbove:
+ return stream << "PosAbove";
+
+ case FontEmphasisMark::PosBelow:
+ return stream << "PosBelow";
+
+ default:
+ SAL_WARN("vcl.gdi", "FontEmphasisMark out of bounds");
+ assert(false && "FontEmphasisMark out of bounds");
+ return stream << "unknown";
+ }
+}
+
+enum FontEmbeddedBitmap { EMBEDDEDBITMAP_DONTKNOW, EMBEDDEDBITMAP_FALSE, EMBEDDEDBITMAP_TRUE };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontEmbeddedBitmap const& embeddedbitmap)
+{
+ switch (embeddedbitmap)
+ {
+ case EMBEDDEDBITMAP_DONTKNOW:
+ return stream << "unknown";
+
+ case EMBEDDEDBITMAP_FALSE:
+ return stream << "false";
+
+ case EMBEDDEDBITMAP_TRUE:
+ return stream << "true";
+ }
+
+ return stream << "unknown";
+}
+
+enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE };
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, FontAntiAlias const& antialias)
+{
+ switch (antialias)
+ {
+ case ANTIALIAS_DONTKNOW:
+ return stream << "unknown";
+
+ case ANTIALIAS_FALSE:
+ return stream << "false";
+
+ case ANTIALIAS_TRUE:
+ return stream << "true";
+ }
+
+ return stream << "unknown";
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/fract.hxx b/include/tools/fract.hxx
new file mode 100644
index 0000000000..e1305ca8a8
--- /dev/null
+++ b/include/tools/fract.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_FRACT_HXX
+#define INCLUDED_TOOLS_FRACT_HXX
+
+#include <sal/types.h>
+#include <tools/toolsdllapi.h>
+#include <tools/long.hxx>
+#include <ostream>
+#include <type_traits>
+
+class SvStream;
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Fraction final
+{
+ /// these two fields form a boost::rational, but I didn't want to put more boost headers into the global space
+ sal_Int32 mnNumerator = 0;
+ sal_Int32 mnDenominator = 1;
+ bool mbValid = true;
+public:
+ Fraction() = default;
+ Fraction( const Fraction & rFrac ) = default;
+ Fraction( Fraction && rFrac ) = default;
+ explicit Fraction( double dVal );
+ Fraction( double nNum, double nDen );
+ Fraction( sal_Int64 nNum, sal_Int64 nDen );
+ // just to prevent ambiguity between the sal_Int64 and double constructors
+ template<typename T1, typename T2> Fraction(
+ T1 nNum, T2 nDen,
+ typename std::enable_if<std::is_integral<T1>::value && std::is_integral<T2>::value, int>::type = 0)
+ : Fraction( sal_Int64(nNum), sal_Int64(nDen) ) {}
+
+ bool IsValid() const { return mbValid; }
+
+ sal_Int32 GetNumerator() const;
+ sal_Int32 GetDenominator() const;
+
+ explicit operator sal_Int32() const;
+#if SAL_TYPES_SIZEOFPOINTER == 8
+ explicit operator ::tools::Long() const { return operator sal_Int32(); }
+#endif
+ explicit operator double() const;
+
+ Fraction& operator=( const Fraction& rfrFrac ) = default;
+ Fraction& operator=( Fraction&& rfrFrac ) = default;
+ Fraction& operator=( double v ) { return operator=(Fraction(v)); }
+
+ Fraction& operator+=( const Fraction& rfrFrac );
+ Fraction& operator-=( const Fraction& rfrFrac );
+ Fraction& operator*=( const Fraction& rfrFrac );
+ Fraction& operator/=( const Fraction& rfrFrac );
+ Fraction& operator+=( double v ) { return operator+=(Fraction(v)); }
+ Fraction& operator-=( double v ) { return operator-=(Fraction(v)); }
+ Fraction& operator*=( double v ) { return operator*=(Fraction(v)); }
+ Fraction& operator/=( double v ) { return operator/=(Fraction(v)); }
+
+ void ReduceInaccurate( unsigned nSignificantBits );
+
+ /// Multiply the two fractions represented here and reduce inaccuracy to 32-bits, used by vcl
+ static Fraction MakeFraction(tools::Long nN1, tools::Long nN2, tools::Long nD1, tools::Long nD2);
+
+ // Compute value usable as hash.
+ size_t GetHashValue() const;
+
+ TOOLS_DLLPUBLIC friend Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 );
+
+ TOOLS_DLLPUBLIC friend bool operator==( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator!=( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator< ( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator> ( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator<=( const Fraction& rVal1, const Fraction& rVal2 );
+ TOOLS_DLLPUBLIC friend bool operator>=( const Fraction& rVal1, const Fraction& rVal2 );
+};
+
+TOOLS_DLLPUBLIC Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC bool operator !=( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC bool operator <=( const Fraction& rVal1, const Fraction& rVal2 );
+TOOLS_DLLPUBLIC bool operator >=( const Fraction& rVal1, const Fraction& rVal2 );
+
+inline Fraction operator+( double v1, const Fraction& rVal2 ) { return Fraction(v1) + rVal2; }
+inline Fraction operator-( double v1, const Fraction& rVal2 ) { return Fraction(v1) - rVal2; }
+inline Fraction operator*( double v1, const Fraction& rVal2 ) { return Fraction(v1) * rVal2; }
+inline Fraction operator/( double v1, const Fraction& rVal2 ) { return Fraction(v1) / rVal2; }
+
+inline Fraction operator+( const Fraction& rVal1, double v2 ) { return rVal1 + Fraction(v2); }
+inline Fraction operator-( const Fraction& rVal1, double v2 ) { return rVal1 - Fraction(v2); }
+inline Fraction operator*( const Fraction& rVal1, double v2 ) { return rVal1 * Fraction(v2); }
+inline Fraction operator/( const Fraction& rVal1, double v2 ) { return rVal1 / Fraction(v2); }
+
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & rStream, const Fraction& rFraction)
+{
+ rStream << "(" << rFraction.GetNumerator() << "/" << rFraction.GetDenominator() << ")";
+ return rStream;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/gen.hxx b/include/tools/gen.hxx
new file mode 100644
index 0000000000..d6ac5f2ec7
--- /dev/null
+++ b/include/tools/gen.hxx
@@ -0,0 +1,925 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <tools/toolsdllapi.h>
+
+#include <tools/long.hxx>
+#include <tools/degree.hxx>
+#include <limits.h>
+#include <algorithm>
+#include <ostream>
+#include <o3tl/unit_conversion.hxx>
+
+class SvStream;
+namespace rtl
+{
+ class OString;
+}
+
+enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET };
+
+// Pair
+
+class SAL_WARN_UNUSED Pair
+{
+public:
+ constexpr Pair() : mnA(0), mnB(0) {}
+ constexpr Pair( tools::Long nA, tools::Long nB ) : mnA(nA), mnB(nB) {}
+
+ tools::Long A() const { return mnA; }
+ tools::Long B() const { return mnB; }
+
+ tools::Long& A() { return mnA; }
+ tools::Long& B() { return mnB; }
+
+ TOOLS_DLLPUBLIC rtl::OString toString() const;
+
+ // Compute value usable as hash.
+ TOOLS_DLLPUBLIC size_t GetHashValue() const;
+
+protected:
+ tools::Long mnA;
+ tools::Long mnB;
+};
+
+namespace tools::detail {
+
+// Used to implement operator == for subclasses of Pair:
+inline bool equal(Pair const & p1, Pair const & p2)
+{
+ return p1.A() == p2.A() && p1.B() == p2.B();
+}
+
+}
+
+// Point
+
+class RectangleTemplateBase;
+
+class TOOLS_DLLPUBLIC PointTemplateBase : protected Pair
+{
+friend class RectangleTemplateBase;
+public:
+ PointTemplateBase() = default;
+protected:
+ constexpr PointTemplateBase( tools::Long nX, tools::Long nY ) : Pair( nX, nY ) {}
+ // Rotate parameter point using This as origin; store result back into parameter point
+ void RotateAround( tools::Long& rX, tools::Long& rY, Degree10 nOrientation ) const;
+ void RotateAround( PointTemplateBase&, Degree10 nOrientation ) const;
+
+public:
+ constexpr tools::Long X() const { return mnA; }
+ constexpr tools::Long Y() const { return mnB; }
+};
+
+template<class PointT, class SizeT>
+class PointTemplate : public PointTemplateBase
+{
+public:
+ using SizeType = SizeT;
+
+ constexpr PointTemplate() {}
+ constexpr PointTemplate( tools::Long nX, tools::Long nY ) : PointTemplateBase( nX, nY ) {}
+
+ void Move( tools::Long nHorzMove, tools::Long nVertMove )
+ {
+ mnA += nHorzMove;
+ mnB += nVertMove;
+ }
+ void Move( SizeT const & s )
+ {
+ AdjustX(s.Width());
+ AdjustY(s.Height());
+ }
+
+ tools::Long AdjustX( tools::Long nHorzMove ) { mnA += nHorzMove; return mnA; }
+ tools::Long AdjustY( tools::Long nVertMove ) { mnB += nVertMove; return mnB; }
+
+ void RotateAround( tools::Long& rX, tools::Long& rY, Degree10 nOrientation ) const
+ { PointTemplateBase::RotateAround(rX, rY, nOrientation); }
+ void RotateAround( PointT& p, Degree10 nOrientation ) const
+ { PointTemplateBase::RotateAround(p, nOrientation); }
+
+ PointT& operator+=( const PointT& rPoint )
+ {
+ mnA += rPoint.mnA;
+ mnB += rPoint.mnB;
+ return static_cast<PointT&>(*this);
+ }
+ PointT& operator-=( const PointT& rPoint )
+ {
+ mnA -= rPoint.mnA;
+ mnB -= rPoint.mnB;
+ return static_cast<PointT&>(*this);
+ }
+ PointT& operator*=( const tools::Long nVal )
+ {
+ mnA *= nVal;
+ mnB *= nVal;
+ return static_cast<PointT&>(*this);
+ }
+ PointT& operator/=( const tools::Long nVal )
+ {
+ mnA /= nVal;
+ mnB /= nVal;
+ return static_cast<PointT&>(*this);
+ }
+
+ constexpr tools::Long getX() const { return X(); }
+ constexpr tools::Long getY() const { return Y(); }
+ void setX(tools::Long nX) { mnA = nX; }
+ void setY(tools::Long nY) { mnB = nY; }
+
+ Pair const & toPair() const { return *this; }
+ Pair & toPair() { return *this; }
+
+ // Scales relative to 0,0
+ constexpr PointT scale(sal_Int64 nMulX, sal_Int64 nDivX,
+ sal_Int64 nMulY, sal_Int64 nDivY) const
+ {
+ return PointT(o3tl::convert(getX(), nMulX, nDivX),
+ o3tl::convert(getY(), nMulY, nDivY));
+ }
+
+ using Pair::toString;
+ using Pair::GetHashValue;
+};
+
+class Size;
+class AbsoluteScreenPixelSize;
+class Point;
+class AbsoluteScreenPixelPoint;
+namespace tools { class Rectangle; }
+class AbsoluteScreenPixelRectangle;
+
+class SAL_WARN_UNUSED Point : public PointTemplate<::Point, ::Size>
+{
+public:
+ constexpr Point() {}
+ constexpr Point( tools::Long nX, tools::Long nY ) : PointTemplate( nX, nY ) {}
+ // TODO delete this to expose more problems
+ constexpr explicit Point(const AbsoluteScreenPixelPoint&);
+};
+
+// A point relative to top-level parent or screen, in screen pixels
+class AbsoluteScreenPixelSize;
+class SAL_WARN_UNUSED AbsoluteScreenPixelPoint : public PointTemplate<AbsoluteScreenPixelPoint, AbsoluteScreenPixelSize> {
+public:
+ constexpr AbsoluteScreenPixelPoint() {}
+ constexpr AbsoluteScreenPixelPoint( tools::Long nX, tools::Long nY ) : PointTemplate( nX, nY ) {}
+ constexpr explicit AbsoluteScreenPixelPoint(const Point & pt) : PointTemplate(pt.X(), pt.Y()) {}
+};
+
+inline Point operator+( const Point &rVal1, const Point &rVal2 )
+{
+ return Point( rVal1.X()+rVal2.X(), rVal1.Y()+rVal2.Y() );
+}
+inline AbsoluteScreenPixelPoint operator+( const AbsoluteScreenPixelPoint &rVal1, const AbsoluteScreenPixelPoint &rVal2 )
+{
+ return AbsoluteScreenPixelPoint( rVal1.X()+rVal2.X(), rVal1.Y()+rVal2.Y() );
+}
+
+inline Point operator-( const Point &rVal1, const Point &rVal2 )
+{
+ return Point( rVal1.X()-rVal2.X(), rVal1.Y()-rVal2.Y() );
+}
+inline AbsoluteScreenPixelPoint operator-( const AbsoluteScreenPixelPoint &rVal1, const AbsoluteScreenPixelPoint &rVal2 )
+{
+ return AbsoluteScreenPixelPoint( rVal1.X()-rVal2.X(), rVal1.Y()-rVal2.Y() );
+}
+
+inline Point operator*( const Point &rVal1, const tools::Long nVal2 )
+{
+ return Point( rVal1.X()*nVal2, rVal1.Y()*nVal2 );
+}
+inline AbsoluteScreenPixelPoint operator*( const AbsoluteScreenPixelPoint &rVal1, const tools::Long nVal2 )
+{
+ return AbsoluteScreenPixelPoint( rVal1.X()*nVal2, rVal1.Y()*nVal2 );
+}
+
+inline Point operator/( const Point &rVal1, const tools::Long nVal2 )
+{
+ return Point( rVal1.X()/nVal2, rVal1.Y()/nVal2 );
+}
+inline AbsoluteScreenPixelPoint operator/( const AbsoluteScreenPixelPoint &rVal1, const tools::Long nVal2 )
+{
+ return AbsoluteScreenPixelPoint( rVal1.X()/nVal2, rVal1.Y()/nVal2 );
+}
+
+inline bool operator ==(Point const & p1, Point const & p2)
+{
+ return tools::detail::equal(p1.toPair(), p2.toPair());
+}
+inline bool operator ==(AbsoluteScreenPixelPoint const & p1, AbsoluteScreenPixelPoint const & p2)
+{
+ return tools::detail::equal(p1.toPair(), p2.toPair());
+}
+
+inline bool operator !=(Point const & p1, Point const & p2)
+{
+ return !(p1 == p2);
+}
+inline bool operator !=(AbsoluteScreenPixelPoint const & p1, AbsoluteScreenPixelPoint const & p2)
+{
+ return !(p1 == p2);
+}
+
+
+constexpr Point::Point(const AbsoluteScreenPixelPoint& p) : Point(p.X(), p.Y()) {}
+
+namespace o3tl
+{
+template <class PointT,
+ std::enable_if_t<std::is_base_of_v<PointTemplate<PointT, typename PointT::SizeType>, PointT>, int> = 0>
+constexpr auto convert(const PointT& rPoint, o3tl::Length eFrom, o3tl::Length eTo)
+{
+ const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
+ return rPoint.scale(num, den, num, den);
+}
+} // namespace o3tl
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const PointTemplateBase& point )
+{
+ return stream << point.X() << ',' << point.Y();
+}
+
+// Size
+
+class SizeTemplateBase : protected Pair
+{
+public:
+ constexpr SizeTemplateBase() = default;
+ constexpr SizeTemplateBase( tools::Long nWidth, tools::Long nHeight ) : Pair( nWidth, nHeight ) {}
+
+ constexpr tools::Long Width() const { return mnA; }
+ constexpr tools::Long Height() const { return mnB; }
+
+};
+
+template<class SizeT>
+class SizeTemplate : public SizeTemplateBase
+{
+public:
+ constexpr SizeTemplate() {}
+ constexpr SizeTemplate( tools::Long nWidth, tools::Long nHeight ) : SizeTemplateBase( nWidth, nHeight ) {}
+
+ tools::Long AdjustWidth( tools::Long n ) { mnA += n; return mnA; }
+ tools::Long AdjustHeight( tools::Long n ) { mnB += n; return mnB; }
+
+ constexpr tools::Long getWidth() const { return Width(); }
+ constexpr tools::Long getHeight() const { return Height(); }
+ void setWidth(tools::Long nWidth) { mnA = nWidth; }
+ void setHeight(tools::Long nHeight) { mnB = nHeight; }
+
+ bool IsEmpty() const { return mnA <= 0 || mnB <= 0; }
+
+ void extendBy(tools::Long x, tools::Long y)
+ {
+ mnA += x;
+ mnB += y;
+ }
+
+ Pair const & toPair() const { return *this; }
+ Pair & toPair() { return *this; }
+
+ using Pair::toString;
+ using Pair::GetHashValue;
+
+ SizeT& operator += ( const SizeT& rSize )
+ {
+ mnA += rSize.mnA;
+ mnB += rSize.mnB;
+ return static_cast<SizeT&>(*this);
+ }
+ SizeT& operator -= ( const SizeT& rSize )
+ {
+ mnA -= rSize.mnA;
+ mnB -= rSize.mnB;
+ return static_cast<SizeT&>(*this);
+ }
+ SizeT& operator *= ( const tools::Long nVal )
+ {
+ mnA *= nVal;
+ mnB *= nVal;
+ return static_cast<SizeT&>(*this);
+ }
+ SizeT& operator /= ( const tools::Long nVal )
+ {
+ mnA /= nVal;
+ mnB /= nVal;
+ return static_cast<SizeT&>(*this);
+ }
+
+ constexpr SizeT scale(sal_Int64 nMulX, sal_Int64 nDivX,
+ sal_Int64 nMulY, sal_Int64 nDivY) const
+ {
+ return SizeT(o3tl::convert(Width(), nMulX, nDivX),
+ o3tl::convert(Height(), nMulY, nDivY));
+ }
+};
+
+class SAL_WARN_UNUSED Size : public SizeTemplate<::Size>
+{
+public:
+ constexpr Size() {}
+ constexpr Size( tools::Long nWidth, tools::Long nHeight ) : SizeTemplate( nWidth, nHeight ) {}
+ // TODO delete to find more problems
+ constexpr explicit Size(const AbsoluteScreenPixelSize& pt);
+};
+
+// Screen pixels
+class SAL_WARN_UNUSED AbsoluteScreenPixelSize : public SizeTemplate<AbsoluteScreenPixelSize>
+{
+public:
+ constexpr AbsoluteScreenPixelSize() {}
+ constexpr AbsoluteScreenPixelSize( tools::Long nWidth, tools::Long nHeight ) : SizeTemplate( nWidth, nHeight ) {}
+ constexpr explicit AbsoluteScreenPixelSize(const Size & pt) : SizeTemplate(pt.Width(), pt.Height()) {}
+};
+
+constexpr Size::Size(const AbsoluteScreenPixelSize& pt) : SizeTemplate(pt.Width(), pt.Height()) {}
+
+inline bool operator ==(Size const & s1, Size const & s2)
+{
+ return tools::detail::equal(s1.toPair(), s2.toPair());
+}
+inline bool operator ==(AbsoluteScreenPixelSize const & s1, AbsoluteScreenPixelSize const & s2)
+{
+ return tools::detail::equal(s1.toPair(), s2.toPair());
+}
+
+inline bool operator !=(Size const & s1, Size const & s2)
+{
+ return !(s1 == s2);
+}
+inline bool operator !=(AbsoluteScreenPixelSize const & s1, AbsoluteScreenPixelSize const & s2)
+{
+ return !(s1 == s2);
+}
+
+inline Size operator+( const Size &rVal1, const Size &rVal2 )
+{
+ return Size( rVal1.Width()+rVal2.Width(), rVal1.Height()+rVal2.Height() );
+}
+inline AbsoluteScreenPixelSize operator+( const AbsoluteScreenPixelSize &rVal1, const AbsoluteScreenPixelSize &rVal2 )
+{
+ return AbsoluteScreenPixelSize( rVal1.Width()+rVal2.Width(), rVal1.Height()+rVal2.Height() );
+}
+
+inline Size operator-( const Size &rVal1, const Size &rVal2 )
+{
+ return Size( rVal1.Width()-rVal2.Width(), rVal1.Height()-rVal2.Height() );
+}
+inline AbsoluteScreenPixelSize operator-( const AbsoluteScreenPixelSize &rVal1, const AbsoluteScreenPixelSize &rVal2 )
+{
+ return AbsoluteScreenPixelSize( rVal1.Width()-rVal2.Width(), rVal1.Height()-rVal2.Height() );
+}
+
+inline Size operator*( const Size &rVal1, const tools::Long nVal2 )
+{
+ return Size( rVal1.Width()*nVal2, rVal1.Height()*nVal2 );
+}
+inline AbsoluteScreenPixelSize operator*( const AbsoluteScreenPixelSize &rVal1, const tools::Long nVal2 )
+{
+ return AbsoluteScreenPixelSize( rVal1.Width()*nVal2, rVal1.Height()*nVal2 );
+}
+
+inline Size operator/( const Size &rVal1, const tools::Long nVal2 )
+{
+ return Size( rVal1.Width()/nVal2, rVal1.Height()/nVal2 );
+}
+inline AbsoluteScreenPixelSize operator/( const AbsoluteScreenPixelSize &rVal1, const tools::Long nVal2 )
+{
+ return AbsoluteScreenPixelSize( rVal1.Width()/nVal2, rVal1.Height()/nVal2 );
+}
+
+namespace o3tl
+{
+
+template <class SizeT,
+ std::enable_if_t<std::is_base_of_v<SizeTemplate<SizeT>, SizeT>, int> = 0>
+constexpr auto convert(const SizeT& rSize, o3tl::Length eFrom, o3tl::Length eTo)
+{
+ const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
+ return rSize.scale(num, den, num, den);
+}
+
+} // end o3tl
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const SizeTemplateBase& size )
+{
+ return stream << size.Width() << 'x' << size.Height();
+}
+
+// Range
+
+#define RANGE_MAX LONG_MAX
+
+class SAL_WARN_UNUSED Range final : protected Pair
+{
+public:
+ constexpr Range() {}
+ constexpr Range( tools::Long nMin, tools::Long nMax ) : Pair( nMin, nMax ) {}
+
+ tools::Long Min() const { return mnA; }
+ tools::Long Max() const { return mnB; }
+ tools::Long Len() const { return mnB - mnA + 1; }
+
+ tools::Long& Min() { return mnA; }
+ tools::Long& Max() { return mnB; }
+
+ bool Contains( tools::Long nIs ) const;
+
+ void Normalize();
+
+ Pair const & toPair() const { return *this; }
+ Pair & toPair() { return *this; }
+
+ using Pair::toString;
+};
+
+inline bool Range::Contains( tools::Long nIs ) const
+{
+ return ((mnA <= nIs) && (nIs <= mnB ));
+}
+
+inline void Range::Normalize()
+{
+ if ( mnA > mnB )
+ std::swap(mnA, mnB);
+}
+
+inline bool operator ==(Range const & r1, Range const & r2)
+{
+ return tools::detail::equal(r1.toPair(), r2.toPair());
+}
+
+inline bool operator !=(Range const & r1, Range const & r2)
+{
+ return !(r1 == r2);
+}
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const Range& range )
+{
+ return stream << range.Min() << '-' << range.Max();
+}
+
+// Selection
+
+#define SELECTION_MIN LONG_MIN
+#define SELECTION_MAX LONG_MAX
+
+class SAL_WARN_UNUSED Selection final : protected Pair
+{
+public:
+ Selection() {}
+ Selection( tools::Long nPos ) : Pair( nPos, nPos ) {}
+ Selection( tools::Long nMin, tools::Long nMax ) : Pair( nMin, nMax ) {}
+
+ tools::Long Min() const { return mnA; }
+ tools::Long Max() const { return mnB; }
+ tools::Long Len() const { return mnB - mnA; }
+
+ tools::Long& Min() { return mnA; }
+ tools::Long& Max() { return mnB; }
+
+ bool Contains( tools::Long nIs ) const;
+
+ void Normalize();
+
+ bool operator !() const { return !Len(); }
+
+ tools::Long getMin() const { return Min(); }
+ void setMin(tools::Long nMin) { Min() = nMin; }
+ void setMax(tools::Long nMax) { Max() = nMax; }
+
+ Pair const & toPair() const { return *this; }
+ Pair & toPair() { return *this; }
+
+ using Pair::toString;
+};
+
+inline bool Selection::Contains( tools::Long nIs ) const
+{
+ return ((mnA <= nIs) && (nIs < mnB ));
+}
+
+inline void Selection::Normalize()
+{
+ if ( mnA > mnB )
+ std::swap(mnA, mnB);
+}
+
+inline bool operator ==(Selection const & s1, Selection const & s2)
+{
+ return tools::detail::equal(s1.toPair(), s2.toPair());
+}
+
+inline bool operator !=(Selection const & s1, Selection const & s2)
+{
+ return !(s1 == s2);
+}
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const Selection& selection )
+{
+ return stream << selection.Min() << '-' << selection.Max();
+}
+// Rectangle
+
+#define RECT_MAX LONG_MAX
+#define RECT_MIN LONG_MIN
+
+/// Note: this class is a true marvel of engineering: because the author
+/// could not decide whether it's better to have a closed or half-open
+/// interval, they just implemented *both* in the same class!
+///
+/// If you have the misfortune of having to use this class, don't immediately
+/// despair but first take note that the uppercase GetWidth() / GetHeight()
+/// etc. methods interpret the interval as closed. To use the half open versions,
+/// use GetOpenWidth() / GetOpenHeight().
+///
+/// If you want to work with Size, you must use the closed interval functions!
+/// And don't add GetOpenSize() / setSize; this will probably just introduce
+/// bugs, especially when used in combination with list-initialization.
+///
+/// (Eventually you might notice, that the same engineer was also working on
+/// Qt at some point; see documentation on QRect::bottom / QRect::right ;-).
+
+class TOOLS_DLLPUBLIC RectangleTemplateBase
+{
+public:
+ static constexpr short RECT_EMPTY = -32767;
+
+ constexpr RectangleTemplateBase() = default;
+ constexpr RectangleTemplateBase( tools::Long nLeft, tools::Long nTop,
+ tools::Long nRight, tools::Long nBottom )
+ : mnLeft( nLeft ), mnTop( nTop ), mnRight( nRight ), mnBottom( nBottom )
+ {}
+ /// Constructs an empty Rectangle, with top/left at the specified params
+ constexpr RectangleTemplateBase( tools::Long nLeft, tools::Long nTop )
+ : mnLeft(nLeft), mnTop(nTop)
+ {}
+ /// Constructs a closed interval rectangle
+ constexpr RectangleTemplateBase( const PointTemplateBase& rLT, const SizeTemplateBase& rSize )
+ : mnLeft( rLT.X())
+ , mnTop( rLT.Y())
+ , mnRight(rSize.Width() ? mnLeft + (rSize.Width() + (rSize.Width() > 0 ? -1 : 1)) : RECT_EMPTY)
+ , mnBottom(rSize.Height() ? mnTop + (rSize.Height() + (rSize.Height() > 0 ? -1 : 1)) : RECT_EMPTY)
+ {}
+
+ constexpr tools::Long Left() const { return mnLeft; }
+ constexpr tools::Long Right() const { return IsWidthEmpty() ? mnLeft : mnRight; }
+ constexpr tools::Long Top() const { return mnTop; }
+ constexpr tools::Long Bottom() const { return IsHeightEmpty() ? mnTop : mnBottom; }
+
+ constexpr void SetLeft(tools::Long v) { mnLeft = v; }
+ constexpr void SetRight(tools::Long v) { mnRight = v; }
+ constexpr void SetTop(tools::Long v) { mnTop = v; }
+ constexpr void SetBottom(tools::Long v) { mnBottom = v; }
+
+ void SetEmpty() { mnRight = mnBottom = RECT_EMPTY; }
+ constexpr bool IsEmpty() const { return IsWidthEmpty() || IsHeightEmpty(); }
+ constexpr bool IsWidthEmpty() const { return mnRight == RECT_EMPTY; }
+ constexpr bool IsHeightEmpty() const { return mnBottom == RECT_EMPTY; }
+ void SetWidthEmpty() { mnRight = RECT_EMPTY; }
+ void SetHeightEmpty() { mnBottom = RECT_EMPTY; }
+
+ tools::Long getX() const { return mnLeft; }
+ tools::Long getY() const { return mnTop; }
+ /// Returns the difference between right and left, assuming the range includes one end, but not the other.
+ tools::Long getOpenWidth() const { return Right() - Left(); }
+ /// Returns the difference between bottom and top, assuming the range includes one end, but not the other.
+ tools::Long getOpenHeight() const { return Bottom() - Top(); }
+ void setWidth( tools::Long n ) { mnRight = mnLeft + n; }
+ void setHeight( tools::Long n ) { mnBottom = mnTop + n; }
+
+ /// Returns the difference between right and left, assuming the range is inclusive.
+ constexpr tools::Long GetWidth() const
+ {
+ tools::Long n = 0;
+
+ if (!IsWidthEmpty())
+ {
+ n = mnRight - mnLeft;
+ if (n < 0)
+ n--;
+ else
+ n++;
+ }
+
+ return n;
+ }
+ /// Returns the difference between bottom and top, assuming the range is inclusive.
+ constexpr tools::Long GetHeight() const
+ {
+ tools::Long n = 0;
+
+ if (!IsHeightEmpty())
+ {
+ n = mnBottom - mnTop;
+ if (n < 0)
+ n--;
+ else
+ n++;
+ }
+
+ return n;
+ }
+
+
+ tools::Long AdjustLeft( tools::Long nHorzMoveDelta ) { mnLeft += nHorzMoveDelta; return mnLeft; }
+ tools::Long AdjustRight( tools::Long nHorzMoveDelta );
+ tools::Long AdjustTop( tools::Long nVertMoveDelta ) { mnTop += nVertMoveDelta; return mnTop; }
+ tools::Long AdjustBottom( tools::Long nVertMoveDelta );
+ /// Set the left edge of the rectangle to x, preserving the width
+ void SetPosX(tools::Long x)
+ {
+ if (!IsWidthEmpty())
+ mnRight += x - mnLeft;
+ mnLeft = x;
+ }
+ /// Set the top edge of the rectangle to y, preserving the height
+ void SetPosY(tools::Long y)
+ {
+ if (!IsHeightEmpty())
+ mnBottom += y - mnTop;
+ mnTop = y;
+ }
+
+ void SaturatingSetPosX(tools::Long x);
+ void SaturatingSetPosY(tools::Long y);
+
+ void SetWidth(tools::Long nWidth)
+ {
+ if (nWidth < 0)
+ mnRight = mnLeft + nWidth + 1;
+ else if (nWidth > 0)
+ mnRight = mnLeft + nWidth - 1;
+ else
+ SetWidthEmpty();
+ }
+ void SetHeight(tools::Long nHeight)
+ {
+ if (nHeight < 0)
+ mnBottom = mnTop + nHeight + 1;
+ else if (nHeight > 0)
+ mnBottom = mnTop + nHeight - 1;
+ else
+ SetHeightEmpty();
+ }
+
+ void Normalize();
+
+ /**
+ * Expands the rectangle in all directions by the input value.
+ */
+ void expand(tools::Long nExpandBy);
+ void shrink(tools::Long nShrinkBy);
+
+ /// Move the top and left edges by a delta, preserving width and height
+ void Move( tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta )
+ {
+ mnLeft += nHorzMoveDelta;
+ mnTop += nVertMoveDelta;
+ if (!IsWidthEmpty())
+ mnRight += nHorzMoveDelta;
+ if (!IsHeightEmpty())
+ mnBottom += nVertMoveDelta;
+ }
+
+ /// Returns the string representation of the rectangle, format is "x, y, width, height".
+ rtl::OString toString() const;
+
+protected:
+ void SaturatingSetSize(const SizeTemplateBase& rSize);
+ void Union( const RectangleTemplateBase& rRect );
+ void Intersection( const RectangleTemplateBase& rRect );
+ bool Contains( const PointTemplateBase& rPOINT ) const;
+ bool Contains( const RectangleTemplateBase& rRect ) const;
+ bool Overlaps( const RectangleTemplateBase& rRect ) const;
+
+ tools::Long mnLeft = 0;
+ tools::Long mnTop = 0;
+ tools::Long mnRight = RECT_EMPTY;
+ tools::Long mnBottom = RECT_EMPTY;
+};
+
+template<class RectangleT, class PointT, class SizeT>
+class RectangleTemplate : public RectangleTemplateBase
+{
+friend class ::tools::Rectangle;
+friend class AbsoluteScreenPixelRectangle;
+public:
+ using PointType = PointT;
+ using SizeType = SizeT;
+
+public:
+ constexpr RectangleTemplate() = default;
+ constexpr RectangleTemplate( const PointT& rLT, const PointT& rRB )
+ : RectangleTemplate(rLT.X(), rLT.Y(), rRB.X(), rRB.Y()) {}
+ constexpr RectangleTemplate( tools::Long nLeft, tools::Long nTop,
+ tools::Long nRight, tools::Long nBottom )
+ : RectangleTemplateBase(nLeft, nTop, nRight, nBottom )
+ {}
+ /// Constructs an empty Rectangle, with top/left at the specified params
+ constexpr RectangleTemplate( tools::Long nLeft, tools::Long nTop )
+ : RectangleTemplateBase(nLeft, nTop)
+ {}
+ /// Constructs a closed interval rectangle
+ constexpr RectangleTemplate( const PointT& rLT, const SizeT& rSize )
+ : RectangleTemplateBase( rLT, rSize )
+ {}
+
+ using RectangleTemplateBase::Normalize;
+ constexpr static RectangleT Normalize(const PointT& rLT, const PointT& rRB)
+ {
+ const std::pair<tools::Long, tools::Long> aLeftRight = std::minmax(rLT.X(), rRB.X());
+ const std::pair<tools::Long, tools::Long> aTopBottom = std::minmax(rLT.Y(), rRB.Y());
+ return { aLeftRight.first, aTopBottom.first, aLeftRight.second, aTopBottom.second };
+ }
+
+ constexpr PointT TopLeft() const { return { Left(), Top() }; }
+ constexpr PointT TopRight() const { return { Right(), Top() }; }
+ constexpr PointT TopCenter() const { return { (Left() + Right()) / 2, Top() }; }
+ constexpr PointT BottomLeft() const { return { Left(), Bottom() }; }
+ constexpr PointT BottomRight() const { return { Right(), Bottom() }; }
+ constexpr PointT BottomCenter() const { return { (Left() + Right()) / 2, Bottom() }; }
+ constexpr PointT LeftCenter() const { return { Left(), (Top() + Bottom()) / 2 }; }
+ constexpr PointT RightCenter() const { return { Right(), (Top() + Bottom()) / 2 }; }
+ constexpr PointT Center() const { return { (Left() + Right()) / 2, (Top() + Bottom()) / 2 }; }
+
+ using RectangleTemplateBase::Move;
+ void Move( SizeT const & s ) { Move(s.Width(), s.Height()); }
+ void SetPos( const PointT& rPoint )
+ {
+ SetPosX(rPoint.X());
+ SetPosY(rPoint.Y());
+ }
+ void SetSize(const SizeT& rSize)
+ {
+ SetWidth(rSize.Width());
+ SetHeight(rSize.Height());
+ }
+
+ constexpr PointT GetPos() const { return TopLeft(); }
+ constexpr SizeT GetSize() const { return { GetWidth(), GetHeight() }; }
+
+ RectangleT& Union( const RectangleTemplate& rRect ) { RectangleTemplateBase::Union(rRect); return static_cast<RectangleT&>(*this); }
+ RectangleT& Intersection( const RectangleTemplate& rRect ) { RectangleTemplateBase::Intersection(rRect); return static_cast<RectangleT&>(*this); }
+ RectangleT GetUnion( const RectangleT& rRect ) const
+ {
+ RectangleT aTmpRect( rRect );
+ return aTmpRect.Union( *this );
+ }
+ RectangleT GetIntersection( const RectangleT& rRect ) const
+ {
+ RectangleT aTmpRect( rRect );
+ return aTmpRect.Intersection( *this );
+ }
+
+ bool Contains( const PointT& rPt ) const { return RectangleTemplateBase::Contains(rPt); }
+ bool Contains( const RectangleT& rRect ) const { return RectangleTemplateBase::Contains(rRect); }
+ bool Overlaps( const RectangleT& rRect ) const { return RectangleTemplateBase::Overlaps(rRect); }
+
+ bool operator == ( const RectangleTemplate& rRect ) const
+ {
+ return (mnLeft == rRect.mnLeft ) &&
+ (mnTop == rRect.mnTop ) &&
+ (mnRight == rRect.mnRight ) &&
+ (mnBottom == rRect.mnBottom );
+ }
+ bool operator != ( const RectangleTemplate& rRect ) const
+ {
+ return (mnLeft != rRect.mnLeft ) ||
+ (mnTop != rRect.mnTop ) ||
+ (mnRight != rRect.mnRight ) ||
+ (mnBottom != rRect.mnBottom );
+ }
+
+ RectangleT& operator += ( const PointT& rPt )
+ {
+ Move(rPt.X(), rPt.Y());
+ return static_cast<RectangleT&>(*this);
+ }
+ RectangleT& operator -= ( const PointT& rPt )
+ {
+ Move(-rPt.X(), -rPt.Y());
+ return static_cast<RectangleT&>(*this);
+ }
+
+ RectangleT operator+( const Point& rPt ) const
+ {
+ RectangleT aTmp(mnLeft, mnTop, mnRight, mnBottom);
+ aTmp += rPt;
+ return aTmp;
+ }
+ RectangleT operator-( const Point& rPt ) const
+ {
+ RectangleT aTmp(mnLeft, mnTop, mnRight, mnBottom);
+ aTmp -= rPt;
+ return aTmp;
+ }
+
+ /**
+ * Sanitizing variants for handling data from the outside
+ */
+ void SaturatingSetSize(const SizeT& rSize) { RectangleTemplateBase::SaturatingSetSize(rSize); }
+
+ // Scales relative to 0,0
+ constexpr RectangleT scale(sal_Int64 nMulX, sal_Int64 nDivX,
+ sal_Int64 nMulY, sal_Int64 nDivY) const
+ {
+ // 1. Create an empty rectangle with correct left and top
+ RectangleT aRect(o3tl::convert(Left(), nMulX, nDivX),
+ o3tl::convert(Top(), nMulY, nDivY));
+ // 2. If source has width/height, set respective right and bottom
+ if (!IsWidthEmpty())
+ aRect.SetRight(o3tl::convert(Right(), nMulX, nDivX));
+ if (!IsHeightEmpty())
+ aRect.SetBottom(o3tl::convert(Bottom(), nMulY, nDivY));
+ return aRect;
+ }
+};
+
+namespace tools
+{
+class SAL_WARN_UNUSED Rectangle final : public RectangleTemplate<Rectangle, Point, Size>
+{
+public:
+ using RectangleTemplate::RectangleTemplate;
+ // TODO remove this to find more issues
+ constexpr Rectangle(const AbsoluteScreenPixelPoint& pt, const Size& sz) : RectangleTemplate(Point(pt.X(), pt.Y()), sz) {}
+ // TODO remove this to find more issues
+ constexpr Rectangle(const Point& pt, const AbsoluteScreenPixelSize& sz) : RectangleTemplate(pt, Size(sz.Width(), sz.Height())) {}
+ // TODO remove this to find more issues
+ constexpr explicit Rectangle(const AbsoluteScreenPixelRectangle & r);
+};
+
+} // namespace tools
+
+
+// A rectangle relative to top-level screen, in screen pixels
+class SAL_WARN_UNUSED AbsoluteScreenPixelRectangle : public RectangleTemplate<AbsoluteScreenPixelRectangle, AbsoluteScreenPixelPoint, AbsoluteScreenPixelSize> {
+public:
+ using RectangleTemplate::RectangleTemplate;
+ // TODO remove
+ constexpr explicit AbsoluteScreenPixelRectangle(const tools::Rectangle & r) : RectangleTemplate(r.mnLeft, r.mnTop, r.mnRight, r.mnBottom) {}
+ // TODO remove
+ constexpr AbsoluteScreenPixelRectangle(const AbsoluteScreenPixelPoint& pt, const Size& sz) : RectangleTemplate(pt, AbsoluteScreenPixelSize(sz.Width(), sz.Height())) {}
+};
+
+namespace tools
+{
+ constexpr Rectangle::Rectangle(const AbsoluteScreenPixelRectangle & r) : RectangleTemplate(r.mnLeft, r.mnTop, r.mnRight, r.mnBottom) {}
+}
+
+namespace o3tl
+{
+
+template <class RectangleT,
+ std::enable_if_t<std::is_base_of_v<RectangleTemplate<RectangleT, typename RectangleT::PointType, typename RectangleT::SizeType>, RectangleT>, int> = 0>
+constexpr auto convert(const RectangleT& rRectangle, o3tl::Length eFrom, o3tl::Length eTo)
+{
+ const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
+ return rRectangle.scale(num, den, num, den);
+}
+
+} // end o3tl
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const RectangleTemplateBase& rectangle )
+{
+ if (rectangle.IsEmpty())
+ return stream << "EMPTY";
+ else
+ return stream << rectangle.GetWidth() << 'x' << rectangle.GetHeight()
+ << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")";
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/globname.hxx b/include/tools/globname.hxx
new file mode 100644
index 0000000000..50c3fc27b9
--- /dev/null
+++ b/include/tools/globname.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_GLOBNAME_HXX
+#define INCLUDED_TOOLS_GLOBNAME_HXX
+
+#include <tools/toolsdllapi.h>
+#include <com/sun/star/uno/Sequence.hxx>
+
+struct SAL_WARN_UNUSED SvGUID
+{
+ sal_uInt32 Data1;
+ sal_uInt16 Data2;
+ sal_uInt16 Data3;
+ sal_uInt8 Data4[8];
+};
+
+class SvStream;
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC SvGlobalName
+{
+public:
+ SvGlobalName() = default;
+ SvGlobalName(const SvGlobalName& rObj) = default;
+
+ SvGlobalName( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3,
+ sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11,
+ sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 );
+
+ // create SvGlobalName from a platform independent representation
+ SvGlobalName( const css::uno::Sequence< sal_Int8 >& aSeq );
+
+ SvGlobalName( const SvGUID & rId );
+
+ SvGlobalName & operator = ( const SvGlobalName & rObj ) = default;
+
+ TOOLS_DLLPUBLIC friend SvStream & operator >> ( SvStream &, SvGlobalName & );
+ TOOLS_DLLPUBLIC friend SvStream & WriteSvGlobalName( SvStream &, const SvGlobalName & );
+
+ bool operator < ( const SvGlobalName & rObj ) const;
+
+ bool operator == ( const SvGlobalName & rObj ) const;
+ bool operator != ( const SvGlobalName & rObj ) const
+ { return !(*this == rObj); }
+
+ void MakeFromMemory( void const * pData );
+ bool MakeId( std::u16string_view rId );
+ OUString GetHexName() const;
+
+ const SvGUID& GetCLSID() const { return m_aData; }
+
+ // platform independent representation of a "GlobalName"
+ // maybe transported remotely
+ css::uno::Sequence < sal_Int8 > GetByteSequence() const;
+
+private:
+ SvGUID m_aData = {};
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/helpers.hxx b/include/tools/helpers.hxx
new file mode 100644
index 0000000000..05ee59960f
--- /dev/null
+++ b/include/tools/helpers.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <sal/config.h>
+#include <sal/types.h>
+#include <tools/long.hxx>
+#include <cassert>
+#include <limits>
+#include <type_traits>
+
+inline sal_uInt32 AlignedWidth4Bytes(sal_uInt32 nWidthBits)
+{
+ if (nWidthBits > SAL_MAX_UINT32 - 31)
+ nWidthBits = SAL_MAX_UINT32;
+ else
+ nWidthBits += 31;
+ return (nWidthBits >> 5) << 2;
+}
+
+inline tools::Long FRound( double fVal )
+{
+ return fVal > 0.0
+ ? fVal == double(std::numeric_limits<tools::Long>::max())
+ ? std::numeric_limits<tools::Long>::max() : static_cast<tools::Long>( fVal + 0.5 )
+ : static_cast<tools::Long>( fVal - 0.5 );
+}
+
+//valid range: (-180,180]
+template <typename T>
+[[nodiscard]] inline typename std::enable_if<std::is_signed<T>::value, T>::type
+NormAngle180(T angle)
+{
+ while (angle <= -180)
+ angle += 360;
+ while (angle > 180)
+ angle -= 360;
+ return angle;
+}
+
+//valid range: [0,360)
+template <typename T> [[nodiscard]] inline T NormAngle360(T angle)
+{
+ while (angle < 0)
+ angle += 360;
+ while (angle >= 360)
+ angle -= 360;
+ return angle;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/inetmime.hxx b/include/tools/inetmime.hxx
new file mode 100644
index 0000000000..bd0ba36bb1
--- /dev/null
+++ b/include/tools/inetmime.hxx
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_INETMIME_HXX
+#define INCLUDED_TOOLS_INETMIME_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/character.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+#include <unordered_map>
+
+struct INetContentTypeParameter
+{
+ /** The optional character set specification (see RFC 2231), in US-ASCII
+ encoding and converted to lower case.
+ */
+ OString m_sCharset;
+
+ /** The optional language specification (see RFC 2231), in US-ASCII
+ encoding and converted to lower case.
+ */
+ OString m_sLanguage;
+
+ /** The attribute value. If the value is a quoted-string, it is
+ 'unpacked.' If a character set is specified, and the value can be
+ converted to Unicode, this is done. Also, if no character set is
+ specified, it is first tried to convert the value from UTF-8 encoding
+ to Unicode, and if that doesn't work (because the value is not in
+ UTF-8 encoding), it is converted from ISO-8859-1 encoding to Unicode
+ (which will always work). But if a character set is specified and the
+ value cannot be converted from that character set to Unicode, special
+ action is taken to produce a value that can possibly be transformed
+ back into its original form: Any 8-bit character from a non-encoded
+ part of the original value is directly converted to Unicode
+ (effectively handling it as if it was ISO-8859-1 encoded), and any
+ 8-bit character from an encoded part of the original value is mapped
+ to the range U+F800..U+F8FF at the top of the Corporate Use Subarea
+ within Unicode's Private Use Area (effectively adding 0xF800 to the
+ character's numeric value).
+ */
+ OUString m_sValue;
+
+ /** This is true if the value is successfully converted to Unicode, and
+ false if the value is a special mixture of ISO-LATIN-1 characters and
+ characters from Unicode's Private Use Area.
+ */
+ bool m_bConverted;
+};
+
+/** The key is the name of the attribute, in US-ASCII encoding and converted
+ to lower case. If a parameter value is split as described in RFC 2231,
+ there will only be one item for the complete parameter, with the attribute
+ name lacking any section suffix.
+ */
+typedef std::unordered_map<OString, INetContentTypeParameter>
+ INetContentTypeParameterList;
+
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC INetMIME
+{
+public:
+ /** Check for US-ASCII visible character.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is a US-ASCII visible character (US-ASCII
+ 0x21--0x7E).
+ */
+ static inline bool isVisible(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 822 <atom>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 822 <atom> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
+ '-', '/', '=', '?', '^', '_', '`', '{', '|', '}', or '~').
+ */
+ static bool isAtomChar(sal_uInt32 nChar);
+
+ /** Check whether some character is valid within an RFC 2060 <atom>.
+
+ @param nChar Some UCS-4 character.
+
+ @return True if nChar is valid within an RFC 2060 <atom> (US-ASCII
+ 'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '&', ''', '+', ',', '-',
+ '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`',
+ '|', '}', or '~').
+ */
+ static bool isIMAPAtomChar(sal_uInt32 nChar);
+
+ /** Get the digit weight of a US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII (decimal) digit character (US-ASCII
+ '0'--'9'), return the corresponding weight (0--9); otherwise,
+ return -1.
+ */
+ static inline int getWeight(sal_uInt32 nChar);
+
+ /** Get the hexadecimal digit weight of a US-ASCII character.
+
+ @param nChar Some UCS-4 character.
+
+ @return If nChar is a US-ASCII hexadecimal digit character (US-ASCII
+ '0'--'9', 'A'--'F', or 'a'--'f'), return the corresponding weight
+ (0--15); otherwise, return -1.
+ */
+ static inline int getHexWeight(sal_uInt32 nChar);
+
+ /** Check two US-ASCII strings for equality, ignoring case.
+
+ @param pBegin1 Points to the start of the first string, must not be
+ null.
+
+ @param pEnd1 Points past the end of the first string, must be >=
+ pBegin1.
+
+ @param pString2 Points to the start of the null terminated second
+ string, must not be null.
+
+ @return True if the two strings are equal, ignoring the case of US-
+ ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
+ */
+ static bool equalIgnoreCase(const sal_Unicode * pBegin1,
+ const sal_Unicode * pEnd1,
+ const char * pString2);
+
+ static bool scanUnsigned(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd, bool bLeadingZeroes,
+ sal_uInt32 & rValue);
+
+ /** Parse the body of an RFC 2045 Content-Type header field.
+
+ @param pBegin The range (that must be valid) from non-null pBegin,
+ inclusive. to non-null pEnd, exclusive, forms the body of the
+ Content-Type header field. It must be of the form
+
+ token "/" token *(";" token "=" (token / quoted-string))
+
+ with intervening linear white space and comments (cf. RFCs 822, 2045).
+ The RFC 2231 extensions are supported. The encoding of rMediaType
+ should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF
+ are interpreted 'as appropriate.'
+
+ @param pType If not null, returns the type (the first of the above
+ tokens), in US-ASCII encoding and converted to lower case.
+
+ @param pSubType If not null, returns the sub-type (the second of the
+ above tokens), in US-ASCII encoding and converted to lower case.
+
+ @param pParameters If not null, returns the parameters as a list of
+ INetContentTypeParameters (the attributes are in US-ASCII encoding and
+ converted to lower case, the values are in Unicode encoding). If
+ null, only the syntax of the parameters is checked, but they are not
+ returned.
+
+ @return Null if the syntax of the field body is incorrect (i.e., does
+ not start with type and sub-type tokens). Otherwise, a pointer past the
+ longest valid input prefix. If null is returned, none of the output
+ parameters will be modified.
+ */
+ static sal_Unicode const * scanContentType(
+ std::u16string_view rStr,
+ OUString * pType = nullptr, OUString * pSubType = nullptr,
+ INetContentTypeParameterList * pParameters = nullptr);
+
+ static OUString decodeHeaderFieldBody(const OString& rBody);
+
+ /** Get the UTF-32 character at the head of a UTF-16 encoded string.
+
+ @param rBegin Points to the start of the UTF-16 encoded string, must
+ not be null. On exit, it points past the first UTF-32 character's
+ encoding.
+
+ @param pEnd Points past the end of the UTF-16 encoded string, must be
+ strictly greater than rBegin.
+
+ @return The UCS-4 character at the head of the UTF-16 encoded string.
+ If the string does not start with the UTF-16 encoding of a UCS-32
+ character, the first UTF-16 value is returned.
+ */
+ static inline sal_uInt32 getUTF32Character(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd);
+};
+
+// static
+inline bool INetMIME::isVisible(sal_uInt32 nChar)
+{
+ return nChar >= '!' && nChar <= '~';
+}
+
+// static
+inline int INetMIME::getWeight(sal_uInt32 nChar)
+{
+ return rtl::isAsciiDigit(nChar) ? int(nChar - '0') : -1;
+}
+
+// static
+inline int INetMIME::getHexWeight(sal_uInt32 nChar)
+{
+ return rtl::isAsciiDigit(nChar) ? int(nChar - '0') :
+ nChar >= 'A' && nChar <= 'F' ? int(nChar - 'A' + 10) :
+ nChar >= 'a' && nChar <= 'f' ? int(nChar - 'a' + 10) : -1;
+}
+
+// static
+inline sal_uInt32 INetMIME::getUTF32Character(const sal_Unicode *& rBegin,
+ const sal_Unicode * pEnd)
+{
+ assert(rBegin && rBegin < pEnd &&
+ "INetMIME::getUTF32Character(): Bad sequence");
+ sal_uInt32 nUTF32 = *rBegin++;
+ if (rBegin < pEnd && rtl::isHighSurrogate(nUTF32) && rtl::isLowSurrogate(rBegin[0]))
+ nUTF32 = rtl::combineSurrogates(nUTF32, *rBegin++);
+ return nUTF32;
+}
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/inetmsg.hxx b/include/tools/inetmsg.hxx
new file mode 100644
index 0000000000..8617b0b91b
--- /dev/null
+++ b/include/tools/inetmsg.hxx
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_INETMSG_HXX
+#define INCLUDED_TOOLS_INETMSG_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/inetmime.hxx>
+#include <tools/stream.hxx>
+
+#include <string_view>
+#include <utility>
+#include <vector>
+#include <map>
+#include <memory>
+#include <config_options.h>
+
+class DateTime;
+
+class SAL_WARN_UNUSED INetMessageHeader
+{
+ OString m_aName;
+ OString m_aValue;
+
+public:
+ INetMessageHeader()
+ {}
+
+ INetMessageHeader(OString aName, OString aValue)
+ : m_aName (std::move(aName)), m_aValue (std::move(aValue))
+ {}
+
+ INetMessageHeader (
+ const INetMessageHeader& rHdr)
+ : m_aName (rHdr.m_aName), m_aValue (rHdr.m_aValue)
+ {}
+
+ INetMessageHeader& operator= (const INetMessageHeader& rHdr)
+ {
+ m_aName = rHdr.m_aName;
+ m_aValue = rHdr.m_aValue;
+ return *this;
+ }
+
+ const OString& GetName() const { return m_aName; }
+ const OString& GetValue() const { return m_aValue; }
+};
+
+enum class InetMessageMime
+{
+ VERSION = 0,
+ CONTENT_DISPOSITION = 1,
+ CONTENT_TYPE = 2,
+ CONTENT_TRANSFER_ENCODING = 3,
+ NUMHDR = 4,
+};
+
+class SAL_WARN_UNUSED UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) INetMIMEMessage
+{
+ ::std::vector< std::unique_ptr<INetMessageHeader> >
+ m_aHeaderList;
+
+ SvLockBytesRef m_xDocLB;
+
+ ::std::map<InetMessageMime, sal_uInt32> m_nMIMEIndex;
+ INetMIMEMessage* pParent;
+ ::std::vector< std::unique_ptr<INetMIMEMessage> >
+ aChildren;
+ OString m_aBoundary;
+
+ OUString GetHeaderValue_Impl (
+ sal_uInt32 nIndex) const
+ {
+ if ( nIndex < m_aHeaderList.size() ) {
+ return INetMIME::decodeHeaderFieldBody(m_aHeaderList[ nIndex ]->GetValue());
+ } else {
+ return OUString();
+ }
+ }
+
+ void SetHeaderField_Impl (
+ const INetMessageHeader &rHeader, sal_uInt32 &rnIndex)
+ {
+ INetMessageHeader *p = new INetMessageHeader (rHeader);
+ if (m_aHeaderList.size() <= rnIndex)
+ {
+ rnIndex = m_aHeaderList.size();
+ m_aHeaderList.emplace_back( p );
+ }
+ else
+ {
+ m_aHeaderList[ rnIndex ].reset(p);
+ }
+ }
+
+ void SetHeaderField_Impl (
+ const OString &rName,
+ const OUString &rValue,
+ sal_uInt32 &rnIndex);
+
+ bool IsMessage() const
+ {
+ OUString aType (GetContentType());
+ return aType.matchIgnoreAsciiCase("message/");
+ }
+
+ INetMIMEMessage (const INetMIMEMessage& rMsg) = delete;
+ INetMIMEMessage& operator= (const INetMIMEMessage& rMsg) = delete;
+
+public:
+ INetMIMEMessage();
+ ~INetMIMEMessage();
+
+ sal_uInt32 GetHeaderCount() const { return m_aHeaderList.size(); }
+
+ INetMessageHeader GetHeaderField (sal_uInt32 nIndex) const
+ {
+ if ( nIndex < m_aHeaderList.size() ) {
+ return *m_aHeaderList[ nIndex ];
+ } else {
+ return INetMessageHeader();
+ }
+ }
+
+ SvLockBytes* GetDocumentLB() const { return m_xDocLB.get(); }
+ void SetDocumentLB (SvLockBytes *pDocLB) { m_xDocLB = pDocLB; }
+
+ static bool ParseDateField (
+ std::u16string_view rDateField, DateTime& rDateTime);
+
+ void SetMIMEVersion (const OUString& rVersion);
+ void SetContentDisposition (const OUString& rDisposition);
+ void SetContentType (const OUString& rType);
+ OUString GetContentType() const
+ {
+ return GetHeaderValue_Impl(
+ m_nMIMEIndex.at(InetMessageMime::CONTENT_TYPE));
+ }
+
+ void SetContentTransferEncoding (const OUString& rEncoding);
+
+ OUString GetDefaultContentType ();
+
+ // Message container methods.
+
+ bool IsContainer() const
+ {
+ return (IsMessage() || IsMultipart());
+ }
+ bool IsMultipart() const
+ {
+ OUString aType (GetContentType());
+ return aType.matchIgnoreAsciiCase("multipart/");
+ }
+
+ INetMIMEMessage* GetChild (sal_uInt32 nIndex) const
+ {
+ return ( nIndex < aChildren.size() ) ? aChildren[ nIndex ].get() : nullptr;
+ }
+ INetMIMEMessage* GetParent() const { return pParent; }
+
+ void EnableAttachMultipartFormDataChild();
+ void AttachChild( std::unique_ptr<INetMIMEMessage> pChildMsg );
+
+ const OString& GetMultipartBoundary() const { return m_aBoundary; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/inetstrm.hxx b/include/tools/inetstrm.hxx
new file mode 100644
index 0000000000..50b0d25f43
--- /dev/null
+++ b/include/tools/inetstrm.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <tools/toolsdllapi.h>
+#include <tools/stream.hxx>
+#include <sal/types.h>
+#include <vector>
+#include <memory>
+#include <config_options.h>
+
+class INetMIMEMessage;
+
+class UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) INetMIMEMessageStream
+{
+ INetMIMEMessage *pSourceMsg;
+ bool bHeaderGenerated;
+
+ std::vector<char> mvBuffer;
+ char *pRead;
+ char *pWrite;
+
+ std::unique_ptr<SvStream>
+ pMsgStrm;
+ SvMemoryStream maMsgBuffer;
+ char *pMsgRead;
+ char *pMsgWrite;
+
+ bool done;
+
+ sal_uInt32 nChildIndex;
+ std::unique_ptr<INetMIMEMessageStream> pChildStrm;
+
+ INetMIMEMessageStream (const INetMIMEMessageStream& rStrm) = delete;
+ INetMIMEMessageStream& operator= (const INetMIMEMessageStream& rStrm) = delete;
+
+ int GetHeaderLine(char *pData, sal_uInt32 nSize);
+ int GetBodyLine(char *pData, sal_uInt32 nSize);
+ int GetMsgLine(char *pData, sal_uInt32 nSize);
+
+public:
+ explicit INetMIMEMessageStream(INetMIMEMessage *pMsg, bool headerGenerated);
+ ~INetMIMEMessageStream();
+
+ int Read (char *pData, sal_uInt32 nSize);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/json_writer.hxx b/include/tools/json_writer.hxx
new file mode 100644
index 0000000000..c5faf542f1
--- /dev/null
+++ b/include/tools/json_writer.hxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <tools/toolsdllapi.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+#include <string_view>
+
+/** Simple JSON encoder designed specifically for LibreOfficeKit purposes.
+ *
+ * (1) Minimal allocations/re-allocations/copying
+ * (2) Small/simple JSON documents
+ * (3) ascii property names
+ */
+namespace tools
+{
+class ScopedJsonWriterNode;
+class ScopedJsonWriterArray;
+class ScopedJsonWriterStruct;
+
+class TOOLS_DLLPUBLIC JsonWriter
+{
+ friend class ScopedJsonWriterNode;
+ friend class ScopedJsonWriterArray;
+ friend class ScopedJsonWriterStruct;
+
+ char* mpBuffer;
+ char* mPos;
+ int mSpaceAllocated;
+ int mStartNodeCount;
+ bool mbFirstFieldInNode;
+ bool mbClosed; // cannot add to it anymore
+
+public:
+ JsonWriter();
+ ~JsonWriter();
+
+ [[nodiscard]] ScopedJsonWriterNode startNode(std::string_view);
+ [[nodiscard]] ScopedJsonWriterArray startArray(std::string_view);
+ [[nodiscard]] ScopedJsonWriterStruct startStruct();
+
+ void put(std::u16string_view pPropName, const OUString& rPropValue);
+
+ void put(std::string_view pPropName, const OUString& rPropValue);
+ // Assumes utf-8 property value encoding
+ 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));
+ }
+
+ 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);
+
+ /// This assumes that this data belongs at this point in the stream, and is valid, and properly encoded
+ void putRaw(std::string_view);
+
+ /** 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;
+
+private:
+ void endNode();
+ void endArray();
+ void endStruct();
+ void addCommaBeforeField();
+ void writeEscapedOUString(const OUString& rPropVal);
+ void closeDocument();
+ 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;
+
+ inline void addValidationMark()
+ {
+#ifndef NDEBUG
+ *(mpBuffer + mSpaceAllocated - 1) = JSON_WRITER_DEBUG_MARKER;
+#endif
+ }
+
+ inline void validate()
+ {
+#ifndef NDEBUG
+ unsigned char c = *(mpBuffer + mSpaceAllocated - 1);
+ assert(c == JSON_WRITER_DEBUG_MARKER);
+#endif
+ }
+};
+
+/**
+ * Auto-closes the node.
+ */
+class ScopedJsonWriterNode
+{
+ friend class JsonWriter;
+
+ JsonWriter& mrWriter;
+
+ ScopedJsonWriterNode(JsonWriter& rWriter)
+ : mrWriter(rWriter)
+ {
+ }
+
+public:
+ ~ScopedJsonWriterNode() { mrWriter.endNode(); }
+};
+
+/**
+ * Auto-closes the node.
+ */
+class ScopedJsonWriterArray
+{
+ friend class JsonWriter;
+
+ JsonWriter& mrWriter;
+
+ ScopedJsonWriterArray(JsonWriter& rWriter)
+ : mrWriter(rWriter)
+ {
+ }
+
+public:
+ ~ScopedJsonWriterArray() { mrWriter.endArray(); }
+};
+
+/**
+ * Auto-closes the node.
+ */
+class ScopedJsonWriterStruct
+{
+ friend class JsonWriter;
+
+ JsonWriter& mrWriter;
+
+ ScopedJsonWriterStruct(JsonWriter& rWriter)
+ : mrWriter(rWriter)
+ {
+ }
+
+public:
+ ~ScopedJsonWriterStruct() { mrWriter.endStruct(); }
+};
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/tools/line.hxx b/include/tools/line.hxx
new file mode 100644
index 0000000000..97cf449fc1
--- /dev/null
+++ b/include/tools/line.hxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_LINE_HXX
+#define INCLUDED_TOOLS_LINE_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/gen.hxx>
+
+namespace tools
+{
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Line
+{
+private:
+ Point maStart;
+ Point maEnd;
+
+public:
+ Line( const Point& rStartPt, const Point& rEndPt ) : maStart( rStartPt ), maEnd( rEndPt ) {}
+
+ void SetStart( const Point& rStartPt ) { maStart = rStartPt; }
+ const Point& GetStart() const { return maStart; }
+
+ void SetEnd( const Point& rEndPt ) { maEnd = rEndPt; }
+ const Point& GetEnd() const { return maEnd; }
+
+ double GetLength() const;
+
+ bool Intersection( const tools::Line& rLine, double& rIntersectionX, double& rIntersectionY ) const;
+ bool Intersection( const tools::Line& rLine, Point& rIntersection ) const;
+
+ double GetDistance( const double& rPtX, const double& rPtY ) const;
+ double GetDistance( const Point& rPoint ) const { return GetDistance( rPoint.X(), rPoint.Y() ); }
+};
+
+} // namespace tools
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/lineend.hxx b/include/tools/lineend.hxx
new file mode 100644
index 0000000000..165d8b5495
--- /dev/null
+++ b/include/tools/lineend.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_TOOLS_LINEEND_HXX
+#define INCLUDED_TOOLS_LINEEND_HXX
+
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/toolsdllapi.h>
+
+enum LineEnd { LINEEND_CR, LINEEND_LF, LINEEND_CRLF };
+
+inline LineEnd GetSystemLineEnd()
+{
+#if defined(_WIN32)
+ return LINEEND_CRLF;
+#else
+ return LINEEND_LF;
+#endif
+}
+
+TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd);
+TOOLS_DLLPUBLIC OUString convertLineEnd(const OUString &rIn, LineEnd eLineEnd);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/link.hxx b/include/tools/link.hxx
new file mode 100644
index 0000000000..ec88bf9533
--- /dev/null
+++ b/include/tools/link.hxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_LINK_HXX
+#define INCLUDED_TOOLS_LINK_HXX
+
+#include <sal/config.h>
+
+#include <sal/macros.h>
+#include <sal/types.h>
+
+#define DECL_LINK(Member, ArgType, RetType) \
+ static RetType LinkStub##Member(void *, ArgType); \
+ RetType Member(ArgType)
+
+#define DECL_STATIC_LINK(Class, Member, ArgType, RetType) \
+ static RetType LinkStub##Member(void *, ArgType); \
+ static RetType Member(Class *, ArgType)
+
+#define DECL_DLLPRIVATE_LINK(Member, ArgType, RetType) \
+ SAL_DLLPRIVATE static RetType LinkStub##Member(void *, ArgType); \
+ SAL_DLLPRIVATE RetType Member(ArgType)
+
+#define DECL_DLLPRIVATE_STATIC_LINK(Class, Member, ArgType, RetType) \
+ SAL_DLLPRIVATE static RetType LinkStub##Member(void *, ArgType); \
+ SAL_DLLPRIVATE static RetType Member(Class *, ArgType)
+
+#define IMPL_LINK(Class, Member, ArgType, ArgName, RetType) \
+ RetType Class::LinkStub##Member(void * instance, ArgType data) { \
+ return static_cast<Class *>(instance)->Member(data); \
+ } \
+ RetType Class::Member(ArgType ArgName)
+
+#define IMPL_LINK_NOARG(Class, Member, ArgType, RetType) \
+ RetType Class::LinkStub##Member(void * instance, ArgType data) { \
+ return static_cast<Class *>(instance)->Member(data); \
+ } \
+ RetType Class::Member(SAL_UNUSED_PARAMETER ArgType)
+
+#define IMPL_STATIC_LINK( \
+ Class, Member, ArgType, ArgName, RetType) \
+ RetType Class::LinkStub##Member(void * instance, ArgType data) { \
+ return Member(static_cast<Class *>(instance), data); \
+ } \
+ RetType Class::Member(SAL_UNUSED_PARAMETER Class *, ArgType ArgName)
+
+#define IMPL_STATIC_LINK_NOARG( \
+ Class, Member, ArgType, RetType) \
+ RetType Class::LinkStub##Member(void * instance, ArgType data) { \
+ return Member(static_cast<Class *>(instance), data); \
+ } \
+ RetType Class::Member( \
+ SAL_UNUSED_PARAMETER Class *, SAL_UNUSED_PARAMETER ArgType)
+
+#ifdef DBG_UTIL
+#define LINK(Instance, Class, Member) ::tools::detail::makeLink( \
+ ::tools::detail::castTo<Class *>(Instance), &Class::LinkStub##Member, __FILE__, __LINE__, SAL_STRINGIFY(Class::LinkStub##Member))
+#else
+#define LINK(Instance, Class, Member) ::tools::detail::makeLink( \
+ ::tools::detail::castTo<Class *>(Instance), &Class::LinkStub##Member)
+#endif
+
+template<typename Arg, typename Ret>
+class SAL_WARN_UNUSED Link {
+public:
+ typedef Ret Stub(void *, Arg);
+
+#ifdef DBG_UTIL
+ Link()
+ : function_(nullptr)
+ , instance_(nullptr)
+ , file_("unknown")
+ , line_(0)
+ , target_("unknown")
+ {
+ }
+
+ Link(void* instance, Stub* function, const char* const file = "unknown", const int line = 0,
+ const char* const target = "unknown")
+ : function_(function)
+ , instance_(instance)
+ , file_(file)
+ , line_(line)
+ , target_(target)
+ {
+ }
+#else
+ Link(): function_(nullptr), instance_(nullptr) {}
+
+ Link(void * instance, Stub * function):
+ function_(function), instance_(instance) {}
+#endif
+
+ Ret Call(Arg data) const
+ { return function_ == nullptr ? Ret() : (*function_)(instance_, data); }
+
+ bool IsSet() const { return function_ != nullptr; }
+
+ bool operator !() const { return !IsSet(); }
+
+ bool operator <(Link const & other) const {
+ char* ptr1 = reinterpret_cast<char*>(function_);
+ char* ptr2 = reinterpret_cast<char*>(other.function_);
+ if (ptr1 < ptr2)
+ return true;
+ else if (ptr1 > ptr2)
+ return false;
+ else
+ return instance_ < other.instance_;
+ };
+
+ bool operator ==(Link const & other) const
+ { return function_ == other.function_ && instance_ == other.instance_; };
+
+ void *GetInstance() const { return instance_; }
+
+#ifdef DBG_UTIL
+ const char* getSourceFilename() const { return file_; }
+ int getSourceLineNumber() const { return line_; }
+ const char* getTargetName() const { return target_; }
+#endif
+
+private:
+ Stub * function_;
+ void * instance_;
+
+#ifdef DBG_UTIL
+ /// Support tracing link source and target.
+ /// When debugging async events, it's often critical
+ /// to find out not only where a link leads (i.e. the target
+ /// function), but also where it was created (file:line).
+ const char* file_;
+ int line_;
+ const char* target_;
+#endif
+};
+
+// Class used to indicate that the Call() parameter is not in use:
+class LinkParamNone { LinkParamNone() = delete; };
+
+namespace tools::detail {
+
+// Avoids loplugin:redundantcast in LINK macro, in the common case that Instance
+// is already of type Class * (instead of a derived type):
+template<typename To, typename From> To castTo(From from)
+{ return static_cast<To>(from); }
+
+#ifdef DBG_UTIL
+template<typename Arg, typename Ret>
+Link<Arg, Ret> makeLink(void * instance, Ret (* function)(void *, Arg), const char* file, int line, const char* target) {
+ return Link<Arg, Ret>(instance, function, file, line, target);
+}
+#else
+template<typename Arg, typename Ret>
+Link<Arg, Ret> makeLink(void * instance, Ret (* function)(void *, Arg)) {
+ return Link<Arg, Ret>(instance, function);
+}
+#endif
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/long.hxx b/include/tools/long.hxx
new file mode 100644
index 0000000000..2388565df0
--- /dev/null
+++ b/include/tools/long.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <sal/types.h>
+
+/**
+ * We have an unfortunate problem in that, on Windows (both 32 and 64-bit), long is always 32-bit.
+ * But on Linux (64-bit) long is 64-bit. Which leads to nasty situations where things that work
+ * on Linux, failed on Windows.
+ * So.....,
+ * (1) introduce a typedef that replaces (almost) all previous usage
+ * (2) on 64-bit Windows, this typedef is forced to 64-bit (32-bit platforms, including 32-bit Windows, are left alone)
+ * (3) fix fallout from (2)
+ *
+ * As a consequence of the above, it would be best, over the long term, to regard usage
+ * of tools::Long in the codebase as meaning "we're not sure what the ideal size of the datatype is",
+ * and where possible, replace it with a better datatype like sal_Int32/sal_Int64/etc.
+ *
+ * NOTE: If you change this, make sure HAVE_FEATURE_JUMBO_SHEETS matches this, as it requires at least 64bit tools::Long.
+ */
+namespace tools
+{
+#if defined _WIN64
+typedef sal_Int64 Long;
+typedef sal_uInt64 ULong;
+#else
+typedef long Long;
+typedef unsigned long ULong;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/include/tools/mapunit.hxx b/include/tools/mapunit.hxx
new file mode 100644
index 0000000000..881a90713c
--- /dev/null
+++ b/include/tools/mapunit.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sal/types.h>
+
+enum class MapUnit : sal_uInt8
+{
+ Map100thMM, Map10thMM, MapMM, MapCM,
+ Map1000thInch, Map100thInch, Map10thInch, MapInch,
+ MapPoint, MapTwip,
+ MapPixel,
+ MapSysFont, MapAppFont,
+ MapRelative,
+ LAST = MapRelative,
+ LASTENUMDUMMY // used as an error return
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/multisel.hxx b/include/tools/multisel.hxx
new file mode 100644
index 0000000000..edb572acb1
--- /dev/null
+++ b/include/tools/multisel.hxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_MULTISEL_HXX
+#define INCLUDED_TOOLS_MULTISEL_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/gen.hxx>
+
+#include <cstddef>
+#include <vector>
+#include <o3tl/sorted_vector.hxx>
+
+#define SFX_ENDOFSELECTION (-1)
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC MultiSelection
+{
+private:
+ std::vector< Range >
+ aSels; // array of SV-selections
+ Range aTotRange; // total range of indexes
+ std::size_t nCurSubSel; // index in aSels of current selected index
+ sal_Int32 nCurIndex; // current selected entry
+ sal_Int32 nSelCount; // number of selected indexes
+ bool bCurValid; // are nCurIndex and nCurSubSel valid
+
+ TOOLS_DLLPRIVATE void ImplClear();
+ TOOLS_DLLPRIVATE std::size_t ImplFindSubSelection( sal_Int32 nIndex ) const;
+ TOOLS_DLLPRIVATE void ImplMergeSubSelections( sal_Int32 nPos1, std::size_t nPos2 );
+
+public:
+ MultiSelection();
+ MultiSelection( const MultiSelection& rOrig );
+ MultiSelection( const Range& rRange );
+ ~MultiSelection();
+
+ MultiSelection& operator= ( const MultiSelection& rOrig );
+
+ void SelectAll( bool bSelect = true );
+ bool Select( sal_Int32 nIndex, bool bSelect = true );
+ void Select( const Range& rIndexRange, bool bSelect = true );
+ bool IsSelected( sal_Int32 nIndex ) const;
+ bool IsAllSelected() const
+ { return nSelCount == aTotRange.Len(); }
+ sal_Int32 GetSelectCount() const { return nSelCount; }
+
+ void SetTotalRange( const Range& rTotRange );
+ void Insert( sal_Int32 nIndex, sal_Int32 nCount = 1 );
+ void Remove( sal_Int32 nIndex );
+ void Reset();
+
+ const Range& GetTotalRange() const { return aTotRange; }
+ sal_Int32 FirstSelected();
+ sal_Int32 LastSelected();
+ sal_Int32 NextSelected();
+
+ sal_Int32 GetRangeCount() const { return aSels.size(); }
+ const Range& GetRange( sal_Int32 nRange ) const { return aSels[nRange]; }
+};
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC StringRangeEnumerator
+{
+ struct Range
+ {
+ sal_Int32 nFirst;
+ sal_Int32 nLast;
+
+ Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {}
+ };
+ std::vector< StringRangeEnumerator::Range > maSequence;
+ sal_Int32 mnCount;
+ sal_Int32 mnMin;
+ sal_Int32 mnMax;
+ sal_Int32 mnOffset;
+ bool mbValidInput;
+
+ bool setRange( std::u16string_view i_rNewRange );
+ bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence );
+ void insertJoinedRanges( const std::vector< sal_Int32 >& rNumbers );
+ bool checkValue( sal_Int32, const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues = nullptr ) const;
+public:
+ class TOOLS_DLLPUBLIC Iterator
+ {
+ const StringRangeEnumerator* pEnumerator;
+ const o3tl::sorted_vector< sal_Int32 >* pPossibleValues;
+ sal_Int32 nRangeIndex;
+ sal_Int32 nCurrent;
+
+ friend class StringRangeEnumerator;
+ Iterator( const StringRangeEnumerator* i_pEnum,
+ const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues,
+ sal_Int32 i_nRange,
+ sal_Int32 i_nCurrent )
+ : pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues )
+ , nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {}
+
+ public:
+ Iterator& operator++();
+ sal_Int32 operator*() const { return nCurrent;}
+ bool operator==(const Iterator&) const;
+ bool operator!=(const Iterator& i_rComp) const
+ { return ! (*this == i_rComp); }
+ };
+
+ friend class StringRangeEnumerator::Iterator;
+
+ StringRangeEnumerator( std::u16string_view i_rInput,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset = -1
+ );
+
+ sal_Int32 size() const { return mnCount; }
+ Iterator begin( const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues = nullptr ) const;
+ Iterator end( const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues = nullptr ) const;
+
+ bool hasValue( sal_Int32 nValue, const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues = nullptr ) const;
+
+ /**
+ i_rPageRange: the string to be changed into a sequence of numbers
+ valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well
+ o_rPageVector: the output sequence of numbers
+ i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence
+ example: a user enters page numbers from 1 to n (since that is logical)
+ of course usable page numbers in code would start from 0 and end at n-1
+ so the logical offset would be -1
+ i_nMinNumber: the minimum allowed number
+ i_nMaxNumber: the maximum allowed number
+
+ @returns: true if the input string was valid, o_rPageVector will contain the resulting sequence
+ false if the input string was invalid, o_rPageVector will contain
+ the sequence that parser is able to extract
+
+ behavior:
+ - only non-negative sequence numbers are allowed
+ - only non-negative values in the input string are allowed
+ - the string "-3" means the sequence i_nMinNumber to 3
+ - the string "3-" means the sequence 3 to i_nMaxNumber
+ - the string "-" means the sequence i_nMinNumber to i_nMaxNumber
+ - single number that doesn't fit in [i_nMinNumber,i_nMaxNumber] will be ignored
+ - range that doesn't fit in [i_nMinNumber,i_nMaxNumber] will be adjusted
+ */
+ static bool getRangesFromString( std::u16string_view i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset = -1,
+ o3tl::sorted_vector< sal_Int32 > const * i_pPossibleValues = nullptr
+ );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/pathutils.hxx b/include/tools/pathutils.hxx
new file mode 100644
index 0000000000..045ec4b96b
--- /dev/null
+++ b/include/tools/pathutils.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_PATHUTILS_HXX
+#define INCLUDED_TOOLS_PATHUTILS_HXX
+
+#include <sal/config.h>
+
+#if defined(_WIN32)
+#include <cstddef>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// The compiled code is not part of the tl dynamic library, but is delivered as
+// pathutils-obj and pathutils-slo objects (it is linked into special
+// executables and dynamic libraries that do not link against OOo libraries):
+namespace tools
+{
+/** Determine the filename part of a path.
+ @param path
+ A non-NULL pointer to a null-terminated path.
+ @return
+ A pointer to the trailing filename part of the given path.
+*/
+WCHAR* filename(WCHAR* path);
+
+/** Concatenate two paths.
+
+ Either the first path is empty and the second path is an absolute path. Or
+ the first path is an absolute path that ends in a backslash and the second
+ path is a relative path. In the latter case, to avoid paths that grow too
+ long, leading .. segments of the second path are removed together with
+ trailing segments from the first path. This should not cause problems as long
+ as there are no symbolic links on Windows (as with symbolic links, x\y\.. and
+ x might denote different directories).
+
+ @param path
+ An output parameter taking the resulting path; must point at a valid
+ range of memory of size at least MAX_PATH. If NULL is returned, the
+ content is unspecified.
+ @param frontBegin, frontEnd
+ Forms a valid range [frontBegin .. frontEnd) of less than MAX_PATH size.
+ @param backBegin, backLength
+ Forms a valid range [backBegin .. backBegin + backLength) of less than
+ MAX_PATH size.
+ @return
+ A pointer to the terminating null character of the concatenation, or NULL
+ if a failure occurred.
+*/
+WCHAR* buildPath(WCHAR* path, WCHAR const* frontBegin, WCHAR const* frontEnd,
+ WCHAR const* backBegin, std::size_t backLength);
+}
+
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/poly.hxx b/include/tools/poly.hxx
new file mode 100644
index 0000000000..36aea7a11a
--- /dev/null
+++ b/include/tools/poly.hxx
@@ -0,0 +1,317 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_POLY_HXX
+#define INCLUDED_TOOLS_POLY_HXX
+
+#include <rtl/ustring.hxx>
+#include <tools/toolsdllapi.h>
+#include <tools/gen.hxx>
+#include <tools/degree.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <o3tl/cow_wrapper.hxx>
+
+#include <vector>
+
+#define POLY_APPEND (0xFFFF)
+#define POLYPOLY_APPEND (0xFFFF)
+
+enum class PolyOptimizeFlags {
+ NONE = 0x0000,
+ CLOSE = 0x0001,
+ NO_SAME = 0x0002,
+ EDGES = 0x0004,
+};
+namespace o3tl
+{
+ template<> struct typed_flags<PolyOptimizeFlags> : is_typed_flags<PolyOptimizeFlags, 0x0007> {};
+}
+
+enum class PolyStyle
+{
+ Arc = 1,
+ Pie = 2,
+ Chord = 3
+};
+
+enum class PolyFlags : sal_uInt8
+{
+ Normal, // start-/endpoint of a curve or a line
+ Smooth, // smooth transition between curves
+ Control, // control handles of a Bezier curve
+ Symmetric // smooth and symmetrical transition between curves
+};
+
+class SvStream;
+class ImplPolygon;
+struct ImplPolyPolygon;
+
+namespace basegfx
+{
+ class B2DPolygon;
+ class B2DPolyPolygon;
+}
+
+namespace tools {
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Polygon
+{
+public:
+ typedef o3tl::cow_wrapper<ImplPolygon> ImplType;
+private:
+ ImplType mpImplPolygon;
+
+public:
+ static void ImplReduceEdges( tools::Polygon& rPoly, const double& rArea, sal_uInt16 nPercent );
+ void ImplRead( SvStream& rIStream );
+ void ImplWrite( SvStream& rOStream ) const;
+
+public:
+ Polygon();
+ explicit Polygon( sal_uInt16 nSize );
+ Polygon( sal_uInt16 nPoints, const Point* pPtAry,
+ const PolyFlags* pFlagAry = nullptr );
+ explicit Polygon( const tools::Rectangle& rRect );
+ Polygon( const tools::Rectangle& rRect,
+ sal_uInt32 nHorzRound, sal_uInt32 nVertRound );
+ Polygon( const Point& rCenter,
+ tools::Long nRadX, tools::Long nRadY );
+ Polygon( const tools::Rectangle& rBound,
+ const Point& rStart, const Point& rEnd,
+ PolyStyle ePolyStyle = PolyStyle::Arc,
+ const bool bClockWiseArcDirection = false);
+ Polygon( const Point& rBezPt1, const Point& rCtrlPt1,
+ const Point& rBezPt2, const Point& rCtrlPt2,
+ sal_uInt16 nPoints );
+
+ Polygon( const tools::Polygon& rPoly );
+ Polygon( tools::Polygon&& rPoly) noexcept;
+ ~Polygon();
+
+ void SetPoint( const Point& rPt, sal_uInt16 nPos );
+ const Point& GetPoint( sal_uInt16 nPos ) const;
+
+ void SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
+ PolyFlags GetFlags( sal_uInt16 nPos ) const;
+ bool HasFlags() const;
+
+ bool IsRect() const;
+
+ void SetSize( sal_uInt16 nNewSize );
+ sal_uInt16 GetSize() const;
+ sal_uInt16 size() const { return GetSize(); } //for vector compatibility
+
+ void Clear();
+
+ tools::Rectangle GetBoundRect() const;
+ bool Contains( const Point& rPt ) const;
+ double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 ) const;
+ void Clip( const tools::Rectangle& rRect );
+ void Optimize( PolyOptimizeFlags nOptimizeFlags );
+
+ /** Adaptive subdivision of polygons with curves
+
+ This method adaptively subdivides bezier arcs within the
+ polygon to straight line segments and returns the resulting
+ polygon.
+
+ @param rResult
+ The resulting subdivided polygon
+
+ @param d
+ This parameter controls the amount of subdivision. The
+ original curve is guaranteed to not differ by more than this
+ amount per bezier segment from the subdivided
+ lines. Concretely, if the polygon is in device coordinates and
+ d equals 1.0, then the difference between the subdivided and
+ the original polygon is guaranteed to be smaller than one
+ pixel.
+ */
+ void AdaptiveSubdivide( tools::Polygon& rResult, const double d = 1.0 ) const;
+ static Polygon SubdivideBezier( const Polygon& rPoly );
+
+ void Move( tools::Long nHorzMove, tools::Long nVertMove );
+ void Translate( const Point& rTrans );
+ void Scale( double fScaleX, double fScaleY );
+ void Rotate( const Point& rCenter, double fSin, double fCos );
+ void Rotate( const Point& rCenter, Degree10 nAngle10 );
+
+ void Insert( sal_uInt16 nPos, const Point& rPt );
+ void Insert( sal_uInt16 nPos, const tools::Polygon& rPoly );
+
+ const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); }
+ Point& operator[]( sal_uInt16 nPos );
+
+ tools::Polygon& operator=( const tools::Polygon& rPoly );
+ tools::Polygon& operator=( tools::Polygon&& rPoly ) noexcept;
+ bool operator==( const tools::Polygon& rPoly ) const;
+ bool operator!=( const tools::Polygon& rPoly ) const
+ { return !(Polygon::operator==( rPoly )); }
+ bool IsEqual( const tools::Polygon& rPoly ) const;
+
+ // streaming a Polygon does ignore PolyFlags, so use the Write Or Read
+ // method to take care of PolyFlags
+ TOOLS_DLLPUBLIC friend SvStream& ReadPolygon( SvStream& rIStream, tools::Polygon& rPoly );
+ TOOLS_DLLPUBLIC friend SvStream& WritePolygon( SvStream& rOStream, const tools::Polygon& rPoly );
+
+ void Read( SvStream& rIStream );
+ void Write( SvStream& rOStream ) const;
+
+ Point * GetPointAry();
+ const Point* GetConstPointAry() const;
+ const PolyFlags* GetConstFlagAry() const;
+
+ // convert to ::basegfx::B2DPolygon and return
+ ::basegfx::B2DPolygon getB2DPolygon() const;
+
+ // constructor to convert from ::basegfx::B2DPolygon
+ // #i76339# made explicit
+ explicit Polygon(const ::basegfx::B2DPolygon& rPolygon);
+};
+
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC PolyPolygon
+{
+private:
+ o3tl::cow_wrapper<ImplPolyPolygon> mpImplPolyPolygon;
+
+ enum class PolyClipOp {
+ INTERSECT,
+ UNION
+ };
+ TOOLS_DLLPRIVATE void ImplDoOperation( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult, PolyClipOp nOperation ) const;
+
+public:
+ explicit PolyPolygon( sal_uInt16 nInitSize = 16 );
+ explicit PolyPolygon( const tools::Polygon& rPoly );
+ explicit PolyPolygon( const tools::Rectangle& );
+ PolyPolygon( const tools::PolyPolygon& rPolyPoly );
+ PolyPolygon( tools::PolyPolygon&& rPolyPoly ) noexcept;
+ ~PolyPolygon();
+
+ void Insert( const tools::Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND );
+ void Remove( sal_uInt16 nPos );
+ void Replace( const Polygon& rPoly, sal_uInt16 nPos );
+ const tools::Polygon& GetObject( sal_uInt16 nPos ) const;
+
+ bool IsRect() const;
+
+ void Clear();
+
+ sal_uInt16 Count() const;
+ tools::Rectangle GetBoundRect() const;
+ void Clip( const tools::Rectangle& rRect );
+ void Optimize( PolyOptimizeFlags nOptimizeFlags );
+
+ /** Adaptive subdivision of polygons with curves
+
+ This method adaptively subdivides bezier arcs within the
+ polygon to straight line segments and returns the resulting
+ polygon.
+
+ @param rResult
+ The resulting subdivided polygon
+
+ If the polygon is in device coordinates, then the difference between the subdivided and
+ the original polygon is guaranteed to be smaller than one
+ pixel.
+ */
+ void AdaptiveSubdivide( tools::PolyPolygon& rResult ) const;
+ static tools::PolyPolygon SubdivideBezier( const tools::PolyPolygon& rPolyPoly );
+
+ void GetIntersection( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
+ void GetUnion( const tools::PolyPolygon& rPolyPoly, tools::PolyPolygon& rResult ) const;
+
+ void Move( tools::Long nHorzMove, tools::Long nVertMove );
+ void Translate( const Point& rTrans );
+ void Scale( double fScaleX, double fScaleY );
+ void Rotate( const Point& rCenter, double fSin, double fCos );
+ void Rotate( const Point& rCenter, Degree10 nAngle10 );
+
+ const tools::Polygon& operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); }
+ tools::Polygon& operator[]( sal_uInt16 nPos );
+
+ tools::PolyPolygon& operator=( const tools::PolyPolygon& rPolyPoly );
+ tools::PolyPolygon& operator=( tools::PolyPolygon&& rPolyPoly ) noexcept;
+ bool operator==( const tools::PolyPolygon& rPolyPoly ) const;
+ bool operator!=( const tools::PolyPolygon& rPolyPoly ) const
+ { return !(PolyPolygon::operator==( rPolyPoly )); }
+
+ TOOLS_DLLPUBLIC friend SvStream& ReadPolyPolygon( SvStream& rIStream, tools::PolyPolygon& rPolyPoly );
+ TOOLS_DLLPUBLIC friend SvStream& WritePolyPolygon( SvStream& rOStream, const tools::PolyPolygon& rPolyPoly );
+
+ void Read( SvStream& rIStream );
+ void Write( SvStream& rOStream ) const;
+
+ // convert to ::basegfx::B2DPolyPolygon and return
+ ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const;
+
+ // constructor to convert from ::basegfx::B2DPolyPolygon
+ // #i76339# made explicit
+ explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
+};
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const Polygon& poly )
+{
+ stream << "<" << poly.GetSize() << ":";
+ for (sal_uInt16 i = 0; i < poly.GetSize(); i++)
+ {
+ if (i > 0)
+ stream << "--";
+ stream << poly.GetPoint(i);
+
+ OUString aFlag;
+ if (poly.GetFlags(i) == PolyFlags::Normal)
+ aFlag = "Normal";
+ else if (poly.GetFlags(i) == PolyFlags::Smooth)
+ aFlag = "Smooth";
+ else if (poly.GetFlags(i) == PolyFlags::Control)
+ aFlag = "Control";
+ else if (poly.GetFlags(i) == PolyFlags::Symmetric)
+ aFlag = "Symmetric";
+
+ stream << ";f=" << aFlag;
+ }
+ stream << ">";
+ return stream;
+}
+
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, const PolyPolygon& poly )
+{
+ stream << "[" << poly.Count() << ":";
+ for (sal_uInt16 i = 0; i < poly.Count(); i++)
+ {
+ if (i > 0)
+ stream << ",";
+ stream << poly.GetObject(i);
+ }
+ stream << "]";
+ return stream;
+}
+
+} /* namespace tools */
+
+typedef std::vector< tools::PolyPolygon > PolyPolyVector;
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/ref.hxx b/include/tools/ref.hxx
new file mode 100644
index 0000000000..3f245bf08e
--- /dev/null
+++ b/include/tools/ref.hxx
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_REF_HXX
+#define INCLUDED_TOOLS_REF_HXX
+
+#include <sal/config.h>
+#include <cassert>
+#include <tools/toolsdllapi.h>
+#include <utility>
+
+/**
+ This implements similar functionality to boost::intrusive_ptr
+*/
+
+namespace tools {
+
+/** T must be a class that extends SvRefBase */
+template<typename T> class SAL_DLLPUBLIC_RTTI SvRef final {
+public:
+ SvRef(): pObj(nullptr) {}
+
+ SvRef(SvRef&& rObj) noexcept
+ {
+ pObj = rObj.pObj;
+ rObj.pObj = nullptr;
+ }
+
+ SvRef(SvRef const & rObj): pObj(rObj.pObj)
+ {
+ if (pObj != nullptr) pObj->AddNextRef();
+ }
+
+ SvRef(T * pObjP): pObj(pObjP)
+ {
+ if (pObj != nullptr) pObj->AddFirstRef();
+ }
+
+ ~SvRef()
+ {
+ if (pObj != nullptr) pObj->ReleaseRef();
+ }
+
+ void clear()
+ {
+ if (pObj != nullptr) {
+ T * pRefObj = pObj;
+ pObj = nullptr;
+ pRefObj->ReleaseRef();
+ }
+ }
+
+ SvRef & operator =(SvRef const & rObj)
+ {
+ if (rObj.pObj != nullptr) {
+ rObj.pObj->AddNextRef();
+ }
+ T * pRefObj = pObj;
+ pObj = rObj.pObj;
+ if (pRefObj != nullptr) {
+ pRefObj->ReleaseRef();
+ }
+ return *this;
+ }
+
+ SvRef & operator =(SvRef && rObj)
+ {
+ if (pObj != nullptr) {
+ pObj->ReleaseRef();
+ }
+ pObj = rObj.pObj;
+ rObj.pObj = nullptr;
+ return *this;
+ }
+
+ bool is() const { return pObj != nullptr; }
+
+ explicit operator bool() const { return is(); }
+
+ T * get() const { return pObj; }
+
+ T * operator ->() const { assert(pObj != nullptr); return pObj; }
+
+ T & operator *() const { assert(pObj != nullptr); return *pObj; }
+
+ bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; }
+ bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); }
+
+private:
+ T * pObj;
+};
+
+/**
+ * This implements similar functionality to std::make_shared.
+ */
+template<typename T, typename... Args>
+SvRef<T> make_ref(Args&& ... args)
+{
+ return SvRef<T>(new T(std::forward<Args>(args)...));
+}
+
+}
+
+/** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
+class TOOLS_DLLPUBLIC SvRefBase
+{
+ // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
+ // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
+ unsigned int nRefCount : 31;
+ // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
+ unsigned int bNoDelete : 1;
+
+protected:
+ virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
+
+public:
+ SvRefBase() : nRefCount(0), bNoDelete(1) {}
+ SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {}
+
+ SvRefBase & operator=(const SvRefBase &) { return *this; }
+
+ void RestoreNoDelete()
+ { bNoDelete = 1; }
+
+ void AddNextRef()
+ {
+ assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
+ ++nRefCount;
+ }
+
+ void AddFirstRef()
+ {
+ assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
+ if( bNoDelete )
+ bNoDelete = 0;
+ ++nRefCount;
+ }
+
+ void ReleaseRef()
+ {
+ assert( nRefCount >= 1);
+ if( --nRefCount == 0 && !bNoDelete)
+ {
+ // I'm not sure about the original purpose of this line, but right now
+ // it serves the purpose that anything that attempts to do an AddRef()
+ // after an object is deleted will trip an assert.
+ nRefCount = 1 << 30;
+ delete this;
+ }
+ }
+
+ unsigned int GetRefCount() const
+ { return nRefCount; }
+};
+
+template<typename T>
+class SvCompatWeakBase;
+
+/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
+*/
+template<typename T>
+class SvCompatWeakHdl final : public SvRefBase
+{
+ friend class SvCompatWeakBase<T>;
+ T* _pObj;
+
+ SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
+
+public:
+ void ResetWeakBase( ) { _pObj = nullptr; }
+ T* GetObj() { return _pObj; }
+};
+
+/** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
+ Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
+*/
+template<typename T>
+class SvCompatWeakBase
+{
+ tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
+
+public:
+ /** Does not use initializer due to compiler warnings,
+ because the lifetime of the _xHdl object can exceed the lifetime of this class.
+ */
+ SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
+
+ ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
+
+ SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); }
+};
+
+/** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
+*/
+template<typename T>
+class SAL_WARN_UNUSED SvCompatWeakRef
+{
+ tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
+public:
+ SvCompatWeakRef( ) {}
+ SvCompatWeakRef( T* pObj )
+ { if( pObj ) _xHdl = pObj->GetHdl(); }
+#if defined(__COVERITY__)
+ ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {}
+#endif
+ SvCompatWeakRef& operator = ( T * pObj )
+ { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; }
+ bool is() const
+ { return _xHdl.is() && _xHdl->GetObj(); }
+ explicit operator bool() const { return is(); }
+ T* operator -> () const
+ { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
+ operator T* () const
+ { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/resary.hxx b/include/tools/resary.hxx
new file mode 100644
index 0000000000..9573a9affd
--- /dev/null
+++ b/include/tools/resary.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_RESARY_HXX
+#define INCLUDED_TOOLS_RESARY_HXX
+
+#define RESARRAY_INDEX_NOTFOUND (0xffffffff)
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/simd.hxx b/include/tools/simd.hxx
new file mode 100644
index 0000000000..bdfdb89282
--- /dev/null
+++ b/include/tools/simd.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_TOOLS_SIMD_HXX
+#define INCLUDED_TOOLS_SIMD_HXX
+
+namespace simd
+{
+template <typename T, unsigned int N> inline bool isAligned(const T* pointer)
+{
+ return 0 == (uintptr_t(pointer) % N);
+}
+
+template <typename T> inline T roundDown(T value, unsigned int multiple)
+{
+ return value & ~(multiple - 1);
+}
+
+} // end namespace simd
+
+#endif // INCLUDED_TOOLS_SIMD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/simdsupport.hxx b/include/tools/simdsupport.hxx
new file mode 100644
index 0000000000..fa8923bb09
--- /dev/null
+++ b/include/tools/simdsupport.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+// IMPORTANT: Having CPU-specific routines turned out to be a maintenance
+// problem, because of various problems such as compilers moving CPU-specific
+// code out of #ifdef code into static initialization or our code using C++
+// features that caused the compiler to emit code that used CPU-specific
+// instructions (even cpuid.hxx isn't safe, see the comment there).
+// The only safe usage is using CPU-specific code that's always available,
+// such as SSE2-specific code for x86_64. Do not use for anything else
+// unless you really know what you are doing (and you check git history
+// to learn from past problems).
+
+// Determine the compiler support for SIMD compiler intrinsics.
+// This changes from one compiled unit to the other, depending if
+// the support has been detected and if the compiled unit contains
+// code using intrinsics or not. So we have to (re)set them again
+// every time this file has been included.
+
+// In other words... DO NOT ADD "#pragma once" here
+
+#undef LO_SSE2_AVAILABLE
+#undef LO_SSSE3_AVAILABLE
+#undef LO_AVX_AVAILABLE
+#undef LO_AVX2_AVAILABLE
+#undef LO_AVX512F_AVAILABLE
+
+#if defined(_MSC_VER) // VISUAL STUDIO COMPILER
+
+// With MSVC using -arch is in fact not necessary for being able
+// to use CPU intrinsics, code using AVX512F intrinsics will compile
+// even if compiled with -arch:AVX, the -arch option really only affects
+// instructions generated for C/C++ code.
+#if defined(_M_X64) || defined(_M_X86)
+// As such, if we're building for X86 or X64, support for these is always available
+// with MSVC2019+.
+#define LO_SSE2_AVAILABLE
+#define LO_SSSE3_AVAILABLE
+#define LO_AVX_AVAILABLE
+#define LO_AVX2_AVAILABLE
+#define LO_AVX512F_AVAILABLE
+#include <intrin.h>
+#include <immintrin.h>
+#endif
+
+#else // compiler Clang and GCC
+
+#if defined(__SSE2__) || defined(__x86_64__) // SSE2 is required for X64
+#define LO_SSE2_AVAILABLE
+#include <emmintrin.h>
+#endif // defined(__SSE2__)
+
+#if defined(__SSSE3__)
+#define LO_SSSE3_AVAILABLE
+#include <tmmintrin.h>
+#endif // defined(__SSSE3__)
+
+#if defined(__AVX__)
+#define LO_AVX_AVAILABLE
+#include <immintrin.h>
+#endif // defined(__AVX__)
+
+#if defined(__AVX2__)
+#define LO_AVX2_AVAILABLE
+#include <immintrin.h>
+#endif // defined(__AVX2__)
+
+#if defined(__AVX512F__)
+#define LO_AVX512F_AVAILABLE
+#include <immintrin.h>
+#else
+#endif // defined(__AVX512F__)
+
+#endif // end compiler Clang and GCC
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/solar.h b/include/tools/solar.h
new file mode 100644
index 0000000000..ae7c5288c4
--- /dev/null
+++ b/include/tools/solar.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_SOLAR_H
+#define INCLUDED_TOOLS_SOLAR_H
+
+#include <sal/types.h>
+#include <osl/endian.h>
+
+/** Intermediate type to solve type clash with Windows headers.
+ Should be removed as soon as all code parts have been reviewed
+ and the correct type is known. Most of the times ULONG is meant
+ to be a 32-Bit unsigned integer type as sal_uInt32 is often
+ used for data exchange or for similar method args. */
+typedef sal_uIntPtr sal_uLong; /* Replaces type ULONG */
+
+// misc. macros to leverage platform and compiler differences
+
+// solar binary types
+
+/* Solar (portable) Binary (exchange) Type; OSI 6 subset
+ always little endian;
+ not necessarily aligned */
+
+typedef sal_uInt8 SVBT16[2];
+typedef sal_uInt8 SVBT32[4];
+typedef sal_uInt8 SVBT64[8];
+
+#ifdef __cplusplus
+
+inline sal_uInt16 SVBT16ToUInt16( const SVBT16 p ) { return static_cast<sal_uInt16>
+ (static_cast<sal_uInt16>(p[0])
+ + (static_cast<sal_uInt16>(p[1]) << 8)); }
+inline sal_Int16 SVBT16ToInt16( const SVBT16 p ) { return sal_Int16(SVBT16ToUInt16(p)); }
+inline sal_uInt32 SVBT32ToUInt32 ( const SVBT32 p ) { return static_cast<sal_uInt32>
+ (static_cast<sal_uInt32>(p[0])
+ + (static_cast<sal_uInt32>(p[1]) << 8)
+ + (static_cast<sal_uInt32>(p[2]) << 16)
+ + (static_cast<sal_uInt32>(p[3]) << 24)); }
+#if defined OSL_LITENDIAN
+inline double SVBT64ToDouble( const SVBT64 p )
+{
+ double n;
+ reinterpret_cast<sal_uInt8*>(&n)[0] = p[0];
+ reinterpret_cast<sal_uInt8*>(&n)[1] = p[1];
+ reinterpret_cast<sal_uInt8*>(&n)[2] = p[2];
+ reinterpret_cast<sal_uInt8*>(&n)[3] = p[3];
+ reinterpret_cast<sal_uInt8*>(&n)[4] = p[4];
+ reinterpret_cast<sal_uInt8*>(&n)[5] = p[5];
+ reinterpret_cast<sal_uInt8*>(&n)[6] = p[6];
+ reinterpret_cast<sal_uInt8*>(&n)[7] = p[7];
+ return n;
+}
+#else
+inline double SVBT64ToDouble( const SVBT64 p ) { double n;
+ reinterpret_cast<sal_uInt8*>(&n)[0] = p[7];
+ reinterpret_cast<sal_uInt8*>(&n)[1] = p[6];
+ reinterpret_cast<sal_uInt8*>(&n)[2] = p[5];
+ reinterpret_cast<sal_uInt8*>(&n)[3] = p[4];
+ reinterpret_cast<sal_uInt8*>(&n)[4] = p[3];
+ reinterpret_cast<sal_uInt8*>(&n)[5] = p[2];
+ reinterpret_cast<sal_uInt8*>(&n)[6] = p[1];
+ reinterpret_cast<sal_uInt8*>(&n)[7] = p[0];
+ return n; }
+#endif
+
+inline void ShortToSVBT16( sal_uInt16 n, SVBT16 p )
+{
+ p[0] = static_cast<sal_uInt8>(n);
+ p[1] = static_cast<sal_uInt8>(n >> 8);
+}
+inline void UInt32ToSVBT32 ( sal_uInt32 n, SVBT32 p )
+{
+ p[0] = static_cast<sal_uInt8>(n);
+ p[1] = static_cast<sal_uInt8>(n >> 8);
+ p[2] = static_cast<sal_uInt8>(n >> 16);
+ p[3] = static_cast<sal_uInt8>(n >> 24);
+}
+inline void Int32ToSVBT32 ( sal_Int32 n, SVBT32 p ) { UInt32ToSVBT32(sal_uInt32(n), p); }
+#if defined OSL_LITENDIAN
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = reinterpret_cast<sal_uInt8*>(&n)[0];
+ p[1] = reinterpret_cast<sal_uInt8*>(&n)[1];
+ p[2] = reinterpret_cast<sal_uInt8*>(&n)[2];
+ p[3] = reinterpret_cast<sal_uInt8*>(&n)[3];
+ p[4] = reinterpret_cast<sal_uInt8*>(&n)[4];
+ p[5] = reinterpret_cast<sal_uInt8*>(&n)[5];
+ p[6] = reinterpret_cast<sal_uInt8*>(&n)[6];
+ p[7] = reinterpret_cast<sal_uInt8*>(&n)[7]; }
+#else
+inline void DoubleToSVBT64( double n, SVBT64 p ) { p[0] = reinterpret_cast<sal_uInt8*>(&n)[7];
+ p[1] = reinterpret_cast<sal_uInt8*>(&n)[6];
+ p[2] = reinterpret_cast<sal_uInt8*>(&n)[5];
+ p[3] = reinterpret_cast<sal_uInt8*>(&n)[4];
+ p[4] = reinterpret_cast<sal_uInt8*>(&n)[3];
+ p[5] = reinterpret_cast<sal_uInt8*>(&n)[2];
+ p[6] = reinterpret_cast<sal_uInt8*>(&n)[1];
+ p[7] = reinterpret_cast<sal_uInt8*>(&n)[0]; }
+#endif
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/stream.hxx b/include/tools/stream.hxx
new file mode 100644
index 0000000000..d3e741bbd0
--- /dev/null
+++ b/include/tools/stream.hxx
@@ -0,0 +1,685 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <config_options.h>
+#include <tools/toolsdllapi.h>
+#include <tools/lineend.hxx>
+#include <tools/long.hxx>
+#include <tools/ref.hxx>
+#include <comphelper/errcode.hxx>
+#include <rtl/string.hxx>
+#include <rtl/strbuf.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <memory>
+#include <string_view>
+
+class StreamData;
+
+inline rtl_TextEncoding GetStoreCharSet( rtl_TextEncoding eEncoding )
+{
+ if ( eEncoding == RTL_TEXTENCODING_ISO_8859_1 )
+ return RTL_TEXTENCODING_MS_1252;
+ else
+ return eEncoding;
+}
+
+// StreamTypes
+
+// read, write, create,... options
+enum class StreamMode {
+ NONE = 0x0000,
+ READ = 0x0001, ///< allow read accesses
+ WRITE = 0x0002, ///< allow write accesses
+// file i/o
+ NOCREATE = 0x0004, ///< 1 == Don't create file
+ TRUNC = 0x0008, ///< Truncate _existing_ file to zero length
+ COPY_ON_SYMLINK = 0x0010, ///< copy-on-write for symlinks (Unix-only)
+ TEMPORARY = 0x0020, ///< temporary file attribute (Windows-only)
+ DELETE_ON_CLOSE = 0x0040, ///< only for temporary files (Windows-only)
+// sharing options
+ SHARE_DENYNONE = 0x0100,
+ SHARE_DENYREAD = 0x0200, // overrides denynone
+ SHARE_DENYWRITE = 0x0400, // overrides denynone
+ SHARE_DENYALL = 0x0800, // overrides denyread,write,none
+// masks
+ READWRITE = READ | WRITE,
+ STD_READ = READ | SHARE_DENYNONE | NOCREATE,
+ STD_WRITE = WRITE | SHARE_DENYALL,
+ STD_READWRITE = READWRITE | SHARE_DENYALL
+};
+namespace o3tl
+{
+ template<> struct typed_flags<StreamMode> : is_typed_flags<StreamMode, 0x0f7f> {};
+}
+
+#define STREAM_SEEK_TO_BEGIN 0L
+#define STREAM_SEEK_TO_END SAL_MAX_UINT64
+
+enum class SvStreamEndian { BIG, LITTLE };
+
+enum class SvStreamCompressFlags {
+ NONE = 0x0000,
+ ZBITMAP = 0x0001,
+ NATIVE = 0x0010,
+};
+namespace o3tl
+{
+ template<> struct typed_flags<SvStreamCompressFlags> : is_typed_flags<SvStreamCompressFlags, 0x0011> {};
+}
+
+class SvStream;
+
+typedef SvStream& (*SvStrPtr)( SvStream& );
+
+inline SvStream& operator<<( SvStream& rStr, SvStrPtr f );
+
+// SvLockBytes
+
+struct SvLockBytesStat
+{
+ std::size_t nSize;
+
+ SvLockBytesStat() : nSize(0) {}
+};
+
+class TOOLS_DLLPUBLIC SvLockBytes: public SvRefBase
+{
+ SvStream * m_pStream;
+ bool m_bOwner;
+ bool m_bSync;
+
+protected:
+ void close();
+
+public:
+
+ SvLockBytes() : m_pStream(nullptr), m_bOwner(false), m_bSync(false) {}
+
+ SvLockBytes(SvStream * pTheStream, bool bTheOwner = false) :
+ m_pStream(pTheStream), m_bOwner(bTheOwner), m_bSync(false) {}
+
+ virtual ~SvLockBytes() override { close(); }
+
+ const SvStream * GetStream() const { return m_pStream; }
+
+ void SetSynchronMode(bool bTheSync = true) { m_bSync = bTheSync; }
+ bool IsSynchronMode() const { return m_bSync; }
+
+ virtual ErrCode ReadAt(sal_uInt64 nPos, void * pBuffer, std::size_t nCount,
+ std::size_t * pRead) const;
+ virtual ErrCode WriteAt(sal_uInt64 nPos, const void * pBuffer, std::size_t nCount,
+ std::size_t * pWritten);
+
+ virtual ErrCode Flush() const;
+
+ virtual ErrCode SetSize(sal_uInt64 nSize);
+
+ virtual ErrCode Stat(SvLockBytesStat * pStat) const;
+};
+
+typedef tools::SvRef<SvLockBytes> SvLockBytesRef;
+
+// SvStream
+
+class TOOLS_DLLPUBLIC SvStream
+{
+private:
+ // LockBytes Interface
+ SvLockBytesRef m_xLockBytes; ///< Default implementation
+ sal_uInt64 m_nActPos;
+
+ // buffer management
+ std::unique_ptr<sal_uInt8[]>
+ m_pRWBuf; ///< Points to read/write buffer
+ sal_uInt8* m_pBufPos; ///< m_pRWBuf + m_nBufActualPos
+ sal_uInt16 m_nBufSize; ///< Allocated size of buffer
+ sal_uInt16 m_nBufActualLen; ///< Length of used segment of buffer
+ ///< = m_nBufSize, if EOF did not occur
+ sal_uInt16 m_nBufActualPos; ///< current position in buffer (0..m_nBufSize-1)
+ sal_uInt16 m_nBufFree; ///< number of free slots in buffer to IO of type eIOMode
+ bool m_isIoRead;
+ bool m_isIoWrite;
+
+ // Error codes, conversion, compression, ...
+ bool m_isDirty; ///< true: Stream != buffer content
+ bool m_isSwap;
+ bool m_isEof;
+ ErrCode m_nError;
+ SvStreamCompressFlags m_nCompressMode;
+ LineEnd m_eLineDelimiter;
+ rtl_TextEncoding m_eStreamCharSet;
+
+ // Encryption
+ OString m_aCryptMaskKey;// aCryptMaskKey.getLength != 0 -> Encryption used
+ unsigned char m_nCryptMask;
+
+ // Userdata
+ sal_Int32 m_nVersion; // for external use
+
+ SvStream ( const SvStream& rStream ) = delete;
+ SvStream& operator=( const SvStream& rStream ) = delete;
+
+protected:
+ sal_uInt64 m_nBufFilePos; ///< File position of pBuf[0]
+ StreamMode m_eStreamMode;
+ bool m_isWritable;
+
+ virtual std::size_t GetData( void* pData, std::size_t nSize );
+ virtual std::size_t PutData( const void* pData, std::size_t nSize );
+ virtual sal_uInt64 SeekPos( sal_uInt64 nPos );
+ virtual void FlushData();
+ virtual void SetSize(sal_uInt64 nSize);
+
+ SAL_DLLPRIVATE void ClearError();
+ SAL_DLLPRIVATE void ClearBuffer();
+
+ // encrypt and write in blocks
+ SAL_DLLPRIVATE std::size_t CryptAndWriteBuffer( const void* pStart, std::size_t nLen );
+ SAL_DLLPRIVATE void EncryptBuffer( void* pStart, std::size_t nLen ) const;
+
+public:
+ SvStream();
+ SvStream( SvLockBytes *pLockBytes);
+ virtual ~SvStream();
+
+ SvLockBytes* GetLockBytes() const { return m_xLockBytes.get(); }
+
+ ErrCode GetError() const { return m_nError.IgnoreWarning(); }
+ ErrCode const & GetErrorCode() const { return m_nError; }
+ void SetError( ErrCode nErrorCode );
+ virtual void ResetError();
+
+ void SetEndian( SvStreamEndian SvStreamEndian );
+ SvStreamEndian GetEndian() const;
+ /// returns status of endian swap flag
+ bool IsEndianSwap() const { return m_isSwap; }
+
+ void SetCompressMode( SvStreamCompressFlags nNewMode )
+ { m_nCompressMode = nNewMode; }
+ SvStreamCompressFlags GetCompressMode() const { return m_nCompressMode; }
+
+ void SetCryptMaskKey(const OString& rCryptMaskKey);
+
+ void SetStreamCharSet( rtl_TextEncoding eCharSet )
+ { m_eStreamCharSet = eCharSet; }
+ rtl_TextEncoding GetStreamCharSet() const { return m_eStreamCharSet; }
+
+ void SetLineDelimiter( LineEnd eLineEnd )
+ { m_eLineDelimiter = eLineEnd; }
+ LineEnd GetLineDelimiter() const { return m_eLineDelimiter; }
+
+ SvStream& ReadUInt16( sal_uInt16& rUInt16 );
+ SvStream& ReadUInt32( sal_uInt32& rUInt32 );
+ SvStream& ReadUInt64( sal_uInt64& rUInt64 );
+ SvStream& ReadInt16( sal_Int16& rInt16 );
+ SvStream& ReadInt32( sal_Int32& rInt32 );
+ SvStream& ReadInt64(sal_Int64 & rInt64);
+ SvStream& ReadSChar( signed char& rChar );
+ SvStream& ReadChar( char& rChar );
+ SvStream& ReadUChar( unsigned char& rChar );
+ SvStream& ReadUtf16( sal_Unicode& rUtf16 );
+ SvStream& ReadCharAsBool( bool& rBool );
+ SvStream& ReadFloat( float& rFloat );
+ SvStream& ReadDouble( double& rDouble );
+ SvStream& ReadStream( SvStream& rStream );
+
+ SvStream& WriteUInt16( sal_uInt16 nUInt16 );
+ SvStream& WriteUInt32( sal_uInt32 nUInt32 );
+ SvStream& WriteUInt64( sal_uInt64 nuInt64 );
+ SvStream& WriteInt16( sal_Int16 nInt16 );
+ SvStream& WriteInt32( sal_Int32 nInt32 );
+ SvStream& WriteInt64( sal_Int64 nInt64 );
+ SvStream& WriteUInt8( sal_uInt8 nuInt8 );
+ SvStream& WriteUnicode( sal_Unicode );
+ SvStream& WriteOString(std::string_view rStr)
+ { WriteBytes(rStr.data(), rStr.size()); return *this; }
+ SvStream& WriteStream( SvStream& rStream );
+ sal_uInt64 WriteStream( SvStream& rStream, sal_uInt64 nSize );
+
+ SvStream& WriteBool( bool b )
+ { return WriteUChar(static_cast<unsigned char>(b)); }
+ SvStream& WriteSChar( signed char nChar );
+ SvStream& WriteChar( char nChar );
+ SvStream& WriteUChar( unsigned char nChar );
+ SvStream& WriteFloat( float nFloat );
+ SvStream& WriteDouble( const double& rDouble );
+
+ template <typename N>
+ SvStream& WriteNumberAsString( N n ) { return WriteOString(OString::number(n)); }
+
+ std::size_t ReadBytes( void* pData, std::size_t nSize );
+ std::size_t WriteBytes( const void* pData, std::size_t nSize );
+ sal_uInt64 Seek( sal_uInt64 nPos );
+ sal_uInt64 SeekRel( sal_Int64 nPos );
+ sal_uInt64 Tell() const { return m_nBufFilePos + m_nBufActualPos; }
+ virtual sal_uInt64 TellEnd();
+ // length between current (Tell()) pos and end of stream
+ sal_uInt64 remainingSize();
+ /// If we have data in our internal buffers, write them out
+ void FlushBuffer();
+ /// Call FlushBuffer() and then call flush on the underlying OS stream
+ void Flush();
+ // next Tell() <= nSize
+ bool SetStreamSize( sal_uInt64 nSize );
+
+ /** Read a line of bytes.
+
+ @param nMaxBytesToRead
+ Maximum of bytes to read, if line is longer it will be
+ truncated.
+
+ @note NOTE that the default is one character less than STRING_MAXLEN to
+ prevent problems after conversion to String that may be lurking
+ in various places doing something like
+ @code
+ for (sal_uInt16 i=0; i < aString.Len(); ++i)
+ @endcode
+ causing endless loops ...
+ */
+ bool ReadLine( OStringBuffer& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
+ bool ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE );
+ bool WriteLine( std::string_view rStr );
+
+ /** Read a line of bytes.
+
+ @param nMaxBytesToRead
+ Maximum of bytes to read, if line is longer it will be
+ truncated.
+
+ @note NOTE that the default is one character less than STRING_MAXLEN to
+ prevent problems after conversion to String that may be lurking
+ in various places doing something like
+ @code
+ for (sal_uInt16 i=0; i < aString.Len(); ++i)
+ @endcode
+ causing endless loops ...
+ */
+ bool ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
+ sal_Int32 nMaxBytesToRead = 0xFFFE );
+ bool WriteByteStringLine( std::u16string_view rStr, rtl_TextEncoding eDestCharSet );
+
+ /// Switch to no endian swapping and write 0xfeff
+ void StartWritingUnicodeText();
+
+ /** If eReadBomCharSet==RTL_TEXTENCODING_DONTKNOW: read 16bit, if 0xfeff do
+ nothing (UTF-16), if 0xfffe switch endian swapping (UTF-16), if 0xefbb
+ or 0xbbef read another byte and check for UTF-8. If no UTF-* BOM was
+ detected put all read bytes back. This means that if 2 bytes were read
+ it was an UTF-16 BOM, if 3 bytes were read it was an UTF-8 BOM. There
+ is no UTF-7, UTF-32 or UTF-EBCDIC BOM detection!
+
+ If eReadBomCharSet!=RTL_TEXTENCODING_DONTKNOW: only read a BOM of that
+ encoding and switch endian swapping if UTF-16 and 0xfffe. */
+ void StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet );
+
+ /** Read a line of Unicode.
+
+ @param nMaxCodepointsToRead
+ Maximum of codepoints (UCS-2 or UTF-16 pairs, not bytes) to
+ read, if line is longer it will be truncated.
+ */
+ SAL_DLLPRIVATE bool ReadUniStringLine(OUString& rStr, sal_Int32 nMaxCodepointsToRead);
+ /** Read a 32bit length prefixed sequence of utf-16 if
+ eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise read a 16bit length
+ prefixed sequence of bytes and convert from eSrcCharSet */
+ OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet);
+ /** Write a 32bit length prefixed sequence of utf-16 if
+ eSrcCharSet==RTL_TEXTENCODING_UNICODE, otherwise convert to eSrcCharSet
+ and write a 16bit length prefixed sequence of bytes */
+ SvStream& WriteUniOrByteString( std::u16string_view rStr, rtl_TextEncoding eDestCharSet );
+
+ /** Read a line of Unicode if eSrcCharSet==RTL_TEXTENCODING_UNICODE,
+ otherwise read a line of Bytecode and convert from eSrcCharSet
+
+ @param nMaxCodepointsToRead
+ Maximum of codepoints (2 bytes if Unicode, bytes if not
+ Unicode) to read, if line is longer it will be truncated.
+
+ @note NOTE that the default is one character less than STRING_MAXLEN to
+ prevent problems after conversion to String that may be lurking in
+ various places doing something like
+ @code
+ for (sal_uInt16 i=0; i < aString.Len(); ++i)
+ @endcode
+ causing endless loops ...
+ */
+ bool ReadUniOrByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
+ sal_Int32 nMaxCodepointsToRead = 0xFFFE );
+ /** Write a sequence of Unicode characters if
+ eDestCharSet==RTL_TEXTENCODING_UNICODE, otherwise write a sequence of
+ Bytecodes converted to eDestCharSet */
+ bool WriteUnicodeOrByteText(std::u16string_view rStr, rtl_TextEncoding eDestCharSet );
+ bool WriteUnicodeOrByteText(std::u16string_view rStr )
+ { return WriteUnicodeOrByteText( rStr, GetStreamCharSet() ); }
+
+ /** Write a Unicode character if eDestCharSet==RTL_TEXTENCODING_UNICODE,
+ otherwise write as Bytecode converted to eDestCharSet.
+
+ This may result in more than one byte being written if a multi byte
+ encoding (e.g. UTF7, UTF8) is chosen. */
+ bool WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet );
+ bool WriteUniOrByteChar( sal_Unicode ch )
+ { return WriteUniOrByteChar( ch, GetStreamCharSet() ); }
+
+ void SetBufferSize( sal_uInt16 m_nBufSize );
+ sal_uInt16 GetBufferSize() const { return m_nBufSize; }
+
+ void RefreshBuffer();
+
+ bool IsWritable() const { return m_isWritable; }
+ StreamMode GetStreamMode() const { return m_eStreamMode; }
+
+ sal_Int32 GetVersion() const { return m_nVersion; }
+ void SetVersion( sal_Int32 n ) { m_nVersion = n; }
+
+ friend SvStream& operator<<( SvStream& rStr, SvStrPtr f ); // for Manips
+
+ /// end of input seen during previous i/o operation
+ bool eof() const { return m_isEof; }
+
+ /// stream is broken
+ bool bad() const { return GetError() != ERRCODE_NONE; }
+
+ /** Get state
+
+ If the state is good() the previous i/o operation succeeded.
+
+ If the state is good(), the next input operation might succeed;
+ otherwise, it will fail.
+
+ Applying an input operation to a stream that is not in the good() state
+ is a null operation as far as the variable being read into is concerned.
+
+ If we try to read into a variable v and the operation fails, the value
+ of v should be unchanged,
+ */
+ bool good() const { return !(eof() || bad()); }
+
+private:
+ template <typename T> SvStream& ReadNumber(T& r);
+ template <typename T> SvStream& WriteNumber(T n);
+
+ template<typename T>
+ void readNumberWithoutSwap(T& rDataDest)
+ { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); }
+
+ SAL_DLLPRIVATE void readNumberWithoutSwap_(void * pDataDest, int nDataSize);
+
+ template<typename T>
+ void writeNumberWithoutSwap(T const & rDataSrc)
+ { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); }
+
+ SAL_DLLPRIVATE void writeNumberWithoutSwap_(const void * pDataSrc, int nDataSize);
+};
+
+inline SvStream& operator<<( SvStream& rStr, SvStrPtr f )
+{
+ (*f)(rStr);
+ return rStr;
+}
+
+TOOLS_DLLPUBLIC SvStream& endl( SvStream& rStr );
+/// same as endl() but Unicode
+TOOLS_DLLPUBLIC SvStream& endlu( SvStream& rStr );
+/// call endlu() if m_eStreamCharSet==RTL_TEXTECODING_UNICODE otherwise endl()
+TOOLS_DLLPUBLIC SvStream& endlub( SvStream& rStr );
+
+/// Attempt to read nUnits 8bit units to an OString, returned OString's
+/// length is number of units successfully read
+TOOLS_DLLPUBLIC OString read_uInt8s_ToOString(SvStream& rStrm,
+ std::size_t nUnits);
+
+/// Attempt to read nUnits 8bit units to an OUString
+inline OUString read_uInt8s_ToOUString(SvStream& rStrm,
+ std::size_t nUnits, rtl_TextEncoding eEnc)
+{
+ return OStringToOUString(read_uInt8s_ToOString(rStrm, nUnits), eEnc);
+}
+
+/// Attempt to read nUnits 16bit units to an OUString, returned
+/// OUString's length is number of units successfully read
+TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream& rStrm,
+ std::size_t nUnits);
+
+/// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
+/// 16bit units to an OUString, returned OString's length is number of
+/// units successfully read.
+inline OUString read_uInt16_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
+{
+ sal_uInt16 nUnits = 0;
+ rStrm.ReadUInt16( nUnits );
+ return read_uInt16s_ToOUString(rStrm, nUnits);
+}
+
+inline OUString read_uInt32_lenPrefixed_uInt16s_ToOUString(SvStream& rStrm)
+{
+ sal_uInt32 nUnits = 0;
+ rStrm.ReadUInt32( nUnits );
+ return read_uInt16s_ToOUString(rStrm, nUnits);
+}
+
+/// Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
+/// returned value is number of bytes written
+TOOLS_DLLPUBLIC std::size_t write_uInt16s_FromOUString(SvStream& rStrm,
+ std::u16string_view rStr, std::size_t nUnits);
+
+inline std::size_t write_uInt16s_FromOUString(SvStream& rStrm,
+ std::u16string_view rStr)
+{
+ return write_uInt16s_FromOUString(rStrm, rStr, rStr.size());
+}
+
+/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
+/// of 16bit units from an OUString, returned value is number of bytes written
+/// (including byte-count of prefix)
+std::size_t write_uInt32_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
+ std::u16string_view rStr);
+
+/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
+/// of 16bit units from an OUString, returned value is number of bytes written
+/// (including byte-count of prefix)
+UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm,
+ std::u16string_view rStr);
+
+/// Attempt to read 8bit units to an OString until a zero terminator is
+/// encountered, returned OString's length is number of units *definitely*
+/// successfully read, check SvStream::good() to see if null terminator was
+/// successfully read
+TOOLS_DLLPUBLIC OString read_zeroTerminated_uInt8s_ToOString(SvStream& rStrm);
+
+/// Attempt to read 8bit units assuming source encoding eEnc to an OUString
+/// until a zero terminator is encountered. Check SvStream::good() to see if
+/// null terminator was successfully read
+TOOLS_DLLPUBLIC OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStrm, rtl_TextEncoding eEnc);
+
+/// Attempt to read a pascal-style length (of type prefix) prefixed sequence of
+/// 8bit units to an OString, returned OString's length is number of units
+/// successfully read.
+inline OString read_uInt32_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
+{
+ sal_uInt32 nUnits = 0;
+ rStrm.ReadUInt32(nUnits);
+ return read_uInt8s_ToOString(rStrm, nUnits);
+}
+inline OString read_uInt16_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
+{
+ sal_uInt16 nUnits = 0;
+ rStrm.ReadUInt16(nUnits);
+ return read_uInt8s_ToOString(rStrm, nUnits);
+}
+
+inline OString read_uInt8_lenPrefixed_uInt8s_ToOString(SvStream& rStrm)
+{
+ sal_uInt8 nUnits = 0;
+ rStrm.ReadUChar(nUnits);
+ return read_uInt8s_ToOString(rStrm, nUnits);
+}
+
+inline OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
+ rtl_TextEncoding eEnc)
+{
+ return OStringToOUString(read_uInt16_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
+}
+
+inline OUString read_uInt8_lenPrefixed_uInt8s_ToOUString(SvStream& rStrm,
+ rtl_TextEncoding eEnc)
+{
+ return OStringToOUString(read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm), eEnc);
+}
+
+/// Attempt to write a prefixed sequence of nUnits 8bit units from an OString,
+/// returned value is number of bytes written
+inline std::size_t write_uInt8s_FromOString(SvStream& rStrm, std::string_view rStr,
+ std::size_t nUnits)
+{
+ return rStrm.WriteBytes(rStr.data(), nUnits);
+}
+
+inline std::size_t write_uInt8s_FromOString(SvStream& rStrm, std::string_view rStr)
+{
+ return write_uInt8s_FromOString(rStrm, rStr, rStr.size());
+}
+
+/// Attempt to write a pascal-style length (of type prefix) prefixed
+/// sequence of units from a string-type, returned value is number of bytes
+/// written (including byte-count of prefix)
+TOOLS_DLLPUBLIC std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
+ std::string_view rStr);
+
+/// Attempt to write a pascal-style length (of type prefix) prefixed sequence
+/// of 8bit units from an OUString, returned value is number of bytes written
+/// (including byte-count of prefix)
+inline std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream& rStrm,
+ std::u16string_view rStr,
+ rtl_TextEncoding eEnc)
+{
+ return write_uInt16_lenPrefixed_uInt8s_FromOString(rStrm, OUStringToOString(rStr, eEnc));
+}
+
+[[nodiscard]] TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset);
+
+namespace tools
+{
+/// Is rUrl a file:// URL with no contents?
+TOOLS_DLLPUBLIC bool isEmptyFileUrl(const OUString& rUrl);
+}
+
+// FileStream
+
+class TOOLS_DLLPUBLIC SvFileStream final : public SvStream
+{
+private:
+ void* mxFileHandle = nullptr; // on windows, it is a HANDLE, otherwise, it is a oslFileHandle
+#if defined(_WIN32)
+ sal_uInt16 nLockCounter;
+#endif
+ OUString aFilename;
+ bool bIsOpen;
+
+ SvFileStream (const SvFileStream&) = delete;
+ SvFileStream & operator= (const SvFileStream&) = delete;
+
+ bool LockFile();
+ void UnlockFile();
+
+ virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
+ virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
+ virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
+ virtual void SetSize( sal_uInt64 nSize ) override;
+ virtual void FlushData() override;
+
+public:
+ // Switches to Read StreamMode on failed attempt of Write opening
+ SvFileStream( const OUString& rFileName, StreamMode eOpenMode );
+ SvFileStream();
+ virtual ~SvFileStream() override;
+
+ virtual void ResetError() override;
+
+ void Open( const OUString& rFileName, StreamMode eOpenMode );
+ void Close();
+ bool IsOpen() const { return bIsOpen; }
+
+ const OUString& GetFileName() const { return aFilename; }
+};
+
+// MemoryStream
+
+class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
+{
+ SvMemoryStream (const SvMemoryStream&) = delete;
+ SvMemoryStream & operator= (const SvMemoryStream&) = delete;
+
+protected:
+ std::size_t nSize;
+ std::size_t nResize;
+ std::size_t nPos;
+ std::size_t nEndOfData;
+ sal_uInt8* pBuf;
+ bool bOwnsData;
+
+ virtual std::size_t GetData( void* pData, std::size_t nSize ) override;
+ virtual std::size_t PutData( const void* pData, std::size_t nSize ) override;
+ virtual sal_uInt64 SeekPos( sal_uInt64 nPos ) override;
+ virtual void SetSize( sal_uInt64 nSize ) override;
+ virtual void FlushData() override;
+
+ /// AllocateMemory must update pBuf accordingly
+ /// - pBuf: Address of new block
+ void AllocateMemory( std::size_t nSize );
+
+ /// ReAllocateMemory must update the following variables:
+ /// - pBuf: Address of new block
+ /// - nEndOfData: Set to nNewSize-1 , if outside of block
+ /// Set to 0 , if new block size is 0 bytes
+ /// - nSize: New block size
+ /// - nPos: Set to 0 if position outside of block
+ bool ReAllocateMemory( tools::Long nDiff );
+
+ /// Is called when this stream allocated the buffer or the buffer is
+ /// resized. FreeMemory may need to NULLify handles in derived classes.
+ void FreeMemory();
+
+public:
+ SvMemoryStream( void* pBuf, std::size_t nSize, StreamMode eMode);
+ SvMemoryStream( std::size_t nInitSize=512, std::size_t nResize=64 );
+ virtual ~SvMemoryStream() override;
+
+ virtual void ResetError() override;
+
+ sal_uInt64 GetSize() { return TellEnd(); }
+ std::size_t GetEndOfData() const { return nEndOfData; }
+ const void* GetData() { FlushBuffer(); return pBuf; }
+
+ // return the buffer currently in use, and allocate a new buffer internally
+ void* SwitchBuffer();
+ // the buffer is not owned by this class
+ void SetBuffer( void* pBuf, std::size_t nSize, std::size_t nEOF );
+
+ void ObjectOwnsMemory( bool bOwn ) { bOwnsData = bOwn; }
+ /// Makes the stream read-only after it was (possibly) initially writable,
+ /// without having to copy the data or change buffers.
+ /// @since LibreOffice 7.5
+ void MakeReadOnly();
+ void SetResizeOffset( std::size_t nNewResize ) { nResize = nNewResize; }
+ virtual sal_uInt64 TellEnd() override { FlushBuffer(); return nEndOfData; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/svborder.hxx b/include/tools/svborder.hxx
new file mode 100644
index 0000000000..92f779cac3
--- /dev/null
+++ b/include/tools/svborder.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_SVBORDER_HXX
+#define INCLUDED_TOOLS_SVBORDER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/long.hxx>
+
+namespace tools { class Rectangle; }
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC SvBorder
+{
+ tools::Long nTop, nRight, nBottom, nLeft;
+
+public:
+ SvBorder()
+ {
+ nTop = nRight = nBottom = nLeft = 0;
+ }
+ SvBorder( tools::Long nLeftP, tools::Long nTopP, tools::Long nRightP, tools::Long nBottomP )
+ {
+ nLeft = nLeftP;
+ nTop = nTopP;
+ nRight = nRightP;
+ nBottom = nBottomP;
+ }
+ bool operator == ( const SvBorder & rObj ) const
+ {
+ return nTop == rObj.nTop && nRight == rObj.nRight &&
+ nBottom == rObj.nBottom && nLeft == rObj.nLeft;
+ }
+ bool operator != ( const SvBorder & rObj ) const
+ { return !(*this == rObj); }
+ SvBorder & operator += ( const SvBorder & rBorder )
+ {
+ Left() += rBorder.Left();
+ Top() += rBorder.Top();
+ Right() += rBorder.Right();
+ Bottom() += rBorder.Bottom();
+ return *this;
+ }
+ tools::Long & Top() { return nTop; }
+ tools::Long & Right() { return nRight; }
+ tools::Long & Bottom() { return nBottom; }
+ tools::Long & Left() { return nLeft; }
+ tools::Long Top() const { return nTop; }
+ tools::Long Right() const { return nRight; }
+ tools::Long Bottom() const { return nBottom; }
+ tools::Long Left() const { return nLeft; }
+};
+
+TOOLS_DLLPUBLIC tools::Rectangle & operator += ( tools::Rectangle & rRect, const SvBorder & rBorder );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/svlibrary.h b/include/tools/svlibrary.h
new file mode 100644
index 0000000000..df3f720314
--- /dev/null
+++ b/include/tools/svlibrary.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SVLIBRARY
+#define SVLIBRARY(Base) SAL_MODULENAME(Base "lo")
+#include <osl/module.h>
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/tenccvt.hxx b/include/tools/tenccvt.hxx
new file mode 100644
index 0000000000..1893c73551
--- /dev/null
+++ b/include/tools/tenccvt.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_TENCCVT_HXX
+#define INCLUDED_TOOLS_TENCCVT_HXX
+
+#include <rtl/textenc.h>
+#include <tools/toolsdllapi.h>
+
+// Functions for handling Import/Export
+
+/// return an encoding which has more defined Characters as the given
+/// encoding, but have the same definition for the defined characters
+/// e.g.: windows-1252 for iso-8859-1 or windows-1254 for iso-8859-9
+TOOLS_DLLPUBLIC rtl_TextEncoding GetExtendedCompatibilityTextEncoding(rtl_TextEncoding eEncoding);
+
+/// return an encoding which has more defined Characters as the given
+/// encoding. The encodings could be different.
+/// e.g.: windows-1251 for iso-8859-5
+TOOLS_DLLPUBLIC rtl_TextEncoding GetExtendedTextEncoding(rtl_TextEncoding eEncoding);
+
+/// if the given encoding is an multi-byte encoding (which allows more than
+/// one byte per char, e.g. UTF-8 or Shift-JIS), a one-byte encoding
+/// is returned (normally windows-1252).
+rtl_TextEncoding GetOneByteTextEncoding(rtl_TextEncoding eEncoding);
+
+TOOLS_DLLPUBLIC rtl_TextEncoding GetSOLoadTextEncoding(rtl_TextEncoding eEncoding);
+TOOLS_DLLPUBLIC rtl_TextEncoding GetSOStoreTextEncoding(rtl_TextEncoding eEncoding);
+
+/**
+ * Given a Unicode character, return a legacy Microsoft Encoding which
+ * supports it. Returns RTL_TEXTENCODING_DONTKNOW if there is
+ * no encoding which could support the character
+ *
+ * Useful as a utility to categorize unicode characters into the best fit
+ * windows charset range for exporting to ww6 & wmf or as a hint to non \u
+ * unicode token aware rtf readers
+ */
+TOOLS_DLLPUBLIC rtl_TextEncoding getBestMSEncodingByChar(sal_Unicode c);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/time.hxx b/include/tools/time.hxx
new file mode 100644
index 0000000000..414b28f729
--- /dev/null
+++ b/include/tools/time.hxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_TIME_HXX
+#define INCLUDED_TOOLS_TIME_HXX
+
+#include <tools/toolsdllapi.h>
+#include <com/sun/star/util/Time.hpp>
+
+namespace com::sun::star::util { struct DateTime; }
+
+/**
+ @WARNING: This class can serve both as wall clock time and time duration, and
+ the mixing of these concepts leads to problems such as there being
+ 25 hours or 10 minus 20 seconds being (non-negative) 10 seconds.
+*/
+
+namespace tools {
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Time
+{
+private:
+ sal_Int64 nTime;
+ void init( sal_uInt32 nHour, sal_uInt32 nMin,
+ sal_uInt32 nSec, sal_uInt64 nNanoSec);
+
+public:
+ enum TimeInitSystem
+ {
+ SYSTEM
+ };
+
+ // temporary until all uses are inspected and resolved
+ enum TimeInitEmpty
+ {
+ EMPTY
+ };
+ static const sal_Int64 hourPerDay = 24;
+ static const sal_Int64 minutePerHour = 60;
+ static const sal_Int64 secondPerMinute = 60;
+ static const sal_Int64 nanoSecPerSec = 1000000000;
+ static const sal_Int64 nanoSecPerMinute = nanoSecPerSec * secondPerMinute;
+ static const sal_Int64 nanoSecPerHour = nanoSecPerSec * secondPerMinute * minutePerHour;
+ static const sal_Int64 nanoSecPerDay = nanoSecPerSec * secondPerMinute * minutePerHour * hourPerDay;
+ static const sal_Int64 secondPerHour = secondPerMinute * minutePerHour;
+ static const sal_Int64 secondPerDay = secondPerMinute * minutePerHour * hourPerDay;
+ static const sal_Int64 minutePerDay = minutePerHour * hourPerDay;
+ static const sal_Int64 nanoPerMicro = 1000;
+ static const sal_Int64 nanoPerMilli = 1000000;
+ static const sal_Int64 nanoPerCenti = 10000000;
+
+ explicit Time( TimeInitEmpty )
+ { nTime = 0; }
+ explicit Time( TimeInitSystem );
+ explicit Time( sal_Int64 _nTime ) { Time::nTime = _nTime; }
+ Time( const tools::Time& rTime );
+ Time( const css::util::Time& rTime );
+ explicit Time( const css::util::DateTime& rDateTime );
+ Time( sal_uInt32 nHour, sal_uInt32 nMin,
+ sal_uInt32 nSec = 0, sal_uInt64 nNanoSec = 0 );
+
+ void SetTime( sal_Int64 nNewTime ) { nTime = nNewTime; }
+ sal_Int64 GetTime() const { return nTime; }
+ css::util::Time GetUNOTime() const { return css::util::Time(GetNanoSec(),GetSec(),GetMin(),GetHour(),false); }
+
+ void SetHour( sal_uInt16 nNewHour );
+ void SetMin( sal_uInt16 nNewMin );
+ void SetSec( sal_uInt16 nNewSec );
+ void SetNanoSec( sal_uInt32 nNewNanoSec );
+ sal_uInt16 GetHour() const
+ { sal_uInt64 nTempTime = (nTime >= 0) ? nTime : -nTime;
+ return static_cast<sal_uInt16>(nTempTime / SAL_CONST_UINT64(10000000000000)); }
+ sal_uInt16 GetMin() const
+ { sal_uInt64 nTempTime = (nTime >= 0) ? nTime : -nTime;
+ return static_cast<sal_uInt16>((nTempTime / SAL_CONST_UINT64(100000000000)) % 100); }
+ sal_uInt16 GetSec() const
+ { sal_uInt64 nTempTime = (nTime >= 0) ? nTime : -nTime;
+ return static_cast<sal_uInt16>((nTempTime / SAL_CONST_UINT64(1000000000)) % 100); }
+ sal_uInt32 GetNanoSec() const
+ { sal_uInt64 nTempTime = (nTime >= 0) ? nTime : -nTime;
+ return static_cast<sal_uInt32>( nTempTime % SAL_CONST_UINT64(1000000000)); }
+
+ // TODO: consider removing GetMSFromTime and MakeTimeFromMS?
+ sal_Int32 GetMSFromTime() const;
+ void MakeTimeFromMS( sal_Int32 nMS );
+ sal_Int64 GetNSFromTime() const;
+ void MakeTimeFromNS( sal_Int64 nNS );
+
+ /// 12 hours == 0.5 days
+ double GetTimeInDays() const;
+
+ /** Get the wall clock time particles for a (date+)time value.
+
+ Does the necessary rounding and truncating to obtain hour, minute,
+ second and fraction of second from a double time value (time in days,
+ 0.5 == 12h) such that individual values are not rounded up, i.e.
+ x:59:59.999 does not yield x+1:0:0.00
+
+ A potential date component (fTimeInDays >= 1.0) is discarded.
+
+ @param nFractionDecimals
+ If > 0 fFractionOfSecond is truncated to that amount of
+ decimals.
+ Else fFractionOfSecond returns the full remainder of the
+ fractional second.
+ */
+ static void GetClock( double fTimeInDays,
+ sal_uInt16& nHour, sal_uInt16& nMinute, sal_uInt16& nSecond,
+ double& fFractionOfSecond, int nFractionDecimals );
+
+ bool IsEqualIgnoreNanoSec( const tools::Time& rTime ) const;
+
+ bool operator ==( const tools::Time& rTime ) const
+ { return (nTime == rTime.nTime); }
+ bool operator !=( const tools::Time& rTime ) const
+ { return (nTime != rTime.nTime); }
+ bool operator >( const tools::Time& rTime ) const
+ { return (nTime > rTime.nTime); }
+ bool operator <( const tools::Time& rTime ) const
+ { return (nTime < rTime.nTime); }
+ bool operator >=( const tools::Time& rTime ) const
+ { return (nTime >= rTime.nTime); }
+ bool operator <=( const tools::Time& rTime ) const
+ { return (nTime <= rTime.nTime); }
+
+ static Time GetUTCOffset();
+
+ /**
+ * Elapsed time in milliseconds (1e-3) since some unspecified starting point
+ *
+ * Convenience function, which just calls GetMonotonicTicks() / 1000.
+ */
+ static sal_uInt64 GetSystemTicks();
+
+ /**
+ * Elapsed time in microseconds (1e-6) since some unspecified starting point
+ *
+ * Uses the high-precision, monotonic time sources provided by the OS, if
+ * available. Don't try to relate it to the system time, and also it's long
+ * time accuracy is not the best.
+ *
+ * Currently used to measure the runtime of OpenCL shaders and to set a
+ * message creation timestamp to allow filtering of invalid timer messages.
+ *
+ * @return current system ticks in microseconds (1e-6s)
+ */
+ static sal_uInt64 GetMonotonicTicks();
+
+ tools::Time& operator =( const tools::Time& rTime );
+ Time operator -() const
+ { return Time( -nTime ); }
+ tools::Time& operator +=( const tools::Time& rTime );
+ tools::Time& operator -=( const tools::Time& rTime );
+ TOOLS_DLLPUBLIC friend Time operator +( const tools::Time& rTime1, const tools::Time& rTime2 );
+ TOOLS_DLLPUBLIC friend Time operator -( const tools::Time& rTime1, const tools::Time& rTime2 );
+};
+
+} /* namespace tools */
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/toolsdllapi.h b/include/tools/toolsdllapi.h
new file mode 100644
index 0000000000..0ee778e6f0
--- /dev/null
+++ b/include/tools/toolsdllapi.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_TOOLSDLLAPI_H
+#define INCLUDED_TOOLS_TOOLSDLLAPI_H
+
+#include <sal/types.h>
+
+#if defined(TOOLS_DLLIMPLEMENTATION)
+#define TOOLS_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define TOOLS_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define TOOLS_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/urlobj.hxx b/include/tools/urlobj.hxx
new file mode 100644
index 0000000000..7e7c4a2aaf
--- /dev/null
+++ b/include/tools/urlobj.hxx
@@ -0,0 +1,1305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_URLOBJ_HXX
+#define INCLUDED_TOOLS_URLOBJ_HXX
+
+#include <tools/toolsdllapi.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/textenc.h>
+#include <sal/types.h>
+#include <o3tl/typed_flags_set.hxx>
+
+#include <memory>
+#include <string_view>
+
+class SvMemoryStream;
+
+namespace com::sun::star::util {
+ class XStringWidth;
+}
+
+namespace com::sun::star::uno { template <typename > class Reference; }
+
+// Common URL prefixes for various schemes:
+inline constexpr OUString INET_FTP_SCHEME = u"ftp://"_ustr;
+inline constexpr OUString INET_HTTP_SCHEME = u"http://"_ustr;
+inline constexpr OUString INET_HTTPS_SCHEME = u"https://"_ustr;
+inline constexpr OUString INET_FILE_SCHEME = u"file://"_ustr;
+inline constexpr OUString INET_MAILTO_SCHEME = u"mailto:"_ustr;
+inline constexpr OUString INET_HID_SCHEME = u"hid:"_ustr;
+
+#define URL_PREFIX_PRIV_SOFFICE "private:"
+
+// Schemes:
+enum class INetProtocol
+{
+ NotValid,
+ Ftp,
+ Http,
+ File,
+ Mailto,
+ VndSunStarWebdav,
+ PrivSoffice,
+ VndSunStarHelp,
+ Https,
+ Slot,
+ Macro,
+ Javascript,
+ Data,
+ Cid,
+ VndSunStarHier,
+ Uno,
+ Component,
+ VndSunStarPkg,
+ Ldap,
+ Db,
+ VndSunStarCmd,
+ Telnet,
+ VndSunStarExpand,
+ VndSunStarTdoc,
+ Generic,
+ Smb,
+ Hid,
+ Sftp,
+ Cmis,
+ LAST = Cmis
+};
+
+/** The supported notations for file system paths.
+ */
+enum class FSysStyle
+{
+ /** VOS notation (e.g., "//server/dir/file").
+ */
+ Vos = 0x1,
+
+ /** Unix notation (e.g., "/dir/file").
+ */
+ Unix = 0x2,
+
+ /** DOS notation (e.g., "a:\dir\file" and "\\server\dir\file").
+ */
+ Dos = 0x4,
+
+ /** Detect the used notation.
+
+ @descr For the following descriptions, please note that
+ whereas FSYS_DEFAULT includes all style bits, combinations of only
+ a few style bits are also possible, and are also described.
+
+ @descr When used to translate a file system path to a file URL,
+ the subset of the following productions for which the appropriate
+ style bit is set are checked in order (using the conventions of
+ RFC 2234, RFC 2396, and RFC 2732; UCS4 stands for any UCS4
+ character):
+
+ Production T1 (VOS local; FSysStyle::Vos only):
+ "//." ["/" *UCS4]
+ becomes
+ "file:///" *UCS4
+
+ Production T2 (VOS host; FSysStyle::Vos only):
+ "//" [host] ["/" *UCS4]
+ becomes
+ "file://" host "/" *UCS4
+
+ Production T3 (UNC; FSysStyle::Dos only):
+ "\\" [host] ["\" *UCS4]
+ becomes
+ "file://" host "/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T4 (Unix-like DOS; FSysStyle::Dos only):
+ ALPHA ":" ["/" *UCS4]
+ becomes
+ "file:///" ALPHA ":/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T5 (DOS; FSysStyle::Dos only):
+ ALPHA ":" ["\" *UCS4]
+ becomes
+ "file:///" ALPHA ":/" *UCS4
+ replacing "\" by "/" within <*UCS4>
+
+ Production T6 (any):
+ *UCS4
+ becomes
+ "file:///" *UCS4
+ replacing the delimiter by "/" within <*UCS4>. The delimiter is
+ that character from the set { "/", "\" } which appears most
+ often in <*UCS4> (if FSysStyle::Unix is not among the style bits, "/"
+ is removed from the set; if FSysStyle::Dos is not among the style
+ bits, "\" is removed from the set). If two or more
+ characters appear the same number of times, the character
+ mentioned first in that set is chosen. If the first character
+ of <*UCS4> is the delimiter, that character is not copied.
+
+ @descr When used to translate a file URL to a file system path,
+ the following productions are checked in order (using the
+ conventions of RFC 2234, RFC 2396, and RFC 2732):
+
+ Production F1 (VOS; FSysStyle::Vos):
+ "file://" host "/" fpath ["#" fragment]
+ becomes
+ "//" host "/" fpath
+
+ Production F2 (DOS; FSysStyle::Dos):
+ "file:///" ALPHA ":" ["/" fpath] ["#" fragment]
+ becomes
+ ALPHA ":" ["\" fpath]
+ replacing "/" by "\" in <fpath>
+
+ Production F3 (Unix; FSysStyle::Unix):
+ "file:///" fpath ["#" fragment]
+ becomes
+ "/" fpath
+ */
+ Detect = Vos | Unix | Dos
+};
+namespace o3tl {
+ template<> struct typed_flags<FSysStyle> : is_typed_flags<FSysStyle, 0x07> {};
+}
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC INetURLObject
+{
+public:
+ // Get- and Set-Methods:
+
+ /** The way input strings that represent (parts of) URIs are interpreted
+ in set-methods.
+
+ @descr UTF-32 characters in the range 0x80--0x10FFFF are replaced by
+ sequences of escape sequences, representing the UTF-8 coded characters.
+
+ @descr Along with an EncodeMechanism parameter, the set-methods all
+ take an rtl_TextEncoding parameter, which is ignored unless the
+ EncodeMechanism is EncodeMechanism::WasEncoded.
+ */
+ enum class EncodeMechanism
+ {
+ /** All escape sequences that are already present are ignored, and are
+ interpreted as literal sequences of three characters.
+ */
+ All,
+
+ /** Sequences of escape sequences, that represent characters from the
+ specified character set and that can be converted to UTF-32
+ characters, are first decoded. If they have to be encoded, they
+ are converted to UTF-8 characters and are than translated into
+ (sequences of) escape sequences. Other escape sequences are
+ copied verbatim (but using upper case hex digits).
+ */
+ WasEncoded,
+
+ /** All escape sequences that are already present are copied verbatim
+ (but using upper case hex digits).
+ */
+ NotCanonical
+ };
+
+ /** The way strings that represent (parts of) URIs are returned from get-
+ methods.
+
+ @descr Along with a DecodeMechanism parameter, the get-methods all
+ take an rtl_TextEncoding parameter, which is ignored unless the
+ DecodeMechanism is DecodeMechanism::WithCharset or DecodeMechanism::Unambiguous.
+ */
+ enum class DecodeMechanism
+ {
+ /** The (part of the) URI is returned unchanged. Since URIs are
+ written using a subset of US-ASCII, the returned string is
+ guaranteed to contain only US-ASCII characters.
+ */
+ NONE,
+
+ /** All sequences of escape sequences that represent UTF-8 coded
+ UTF-32 characters with a numerical value greater than 0x7F, are
+ replaced by the respective UTF-16 characters. All other escape
+ sequences are not decoded.
+ */
+ ToIUri,
+
+ /** All (sequences of) escape sequences that represent characters from
+ the specified character set, and that can be converted to UTF-32,
+ are replaced by the respective UTF-16 characters. All other
+ escape sequences are not decoded.
+ */
+ WithCharset,
+
+ /** All (sequences of) escape sequences that represent characters from
+ the specified character set, that can be converted to UTF-32, and
+ that (in the case of ASCII characters) can safely be decoded
+ without altering the meaning of the (part of the) URI, are
+ replaced by the respective UTF-16 characters. All other escape
+ sequences are not decoded.
+ */
+ Unambiguous
+ };
+
+ // General Structure:
+
+ INetURLObject():
+ m_aAbsURIRef(256), m_eScheme(INetProtocol::NotValid), m_eSmartScheme(INetProtocol::Http) {}
+
+ bool HasError() const { return m_eScheme == INetProtocol::NotValid; }
+
+ OUString GetMainURL(DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aAbsURIRef, eMechanism, eCharset); }
+
+ OUString GetURLNoPass(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ OUString GetURLNoMark(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ OUString
+ getAbbreviated(css::uno::Reference< css::util::XStringWidth > const & rStringWidth,
+ sal_Int32 nWidth,
+ DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ bool operator ==(INetURLObject const & rObject) const;
+
+ bool operator !=(INetURLObject const & rObject) const
+ { return !(*this == rObject); }
+
+ // Strict Parsing:
+
+ inline explicit INetURLObject(
+ std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ inline bool SetURL(std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ bool ConcatData(INetProtocol eTheScheme, std::u16string_view rTheUser,
+ std::u16string_view rThePassword,
+ std::u16string_view rTheHost, sal_uInt32 nThePort,
+ std::u16string_view rThePath);
+
+ // Smart Parsing:
+
+ inline INetURLObject(std::u16string_view rTheAbsURIRef,
+ INetProtocol eTheSmartScheme,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSysStyle::Detect);
+
+ void SetSmartProtocol(INetProtocol eTheSmartScheme)
+ { m_eSmartScheme = eTheSmartScheme; }
+
+ inline bool
+ SetSmartURL(std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSysStyle::Detect);
+
+ inline INetURLObject
+ smartRel2Abs(OUString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment = false,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ bool bRelativeNonURIs = false,
+ FSysStyle eStyle = FSysStyle::Detect) const;
+
+ // Relative URLs:
+
+ inline bool
+ GetNewAbsURL(OUString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef)
+ const;
+
+ /** @descr If rTheRelURIRef cannot be converted to an absolute URL
+ (because of syntactic reasons), either rTheRelURIRef or an empty
+ string is returned: If all of the parameters eEncodeMechanism,
+ eDecodeMechanism and eCharset have their respective default values,
+ then rTheRelURIRef is returned unmodified; otherwise, an empty string
+ is returned.
+ */
+ static OUString
+ GetAbsURL(std::u16string_view rTheBaseURIRef,
+ OUString const & rTheRelURIRef,
+ EncodeMechanism eEncodeMechanism = EncodeMechanism::WasEncoded,
+ DecodeMechanism eDecodeMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ static inline OUString
+ GetRelURL(std::u16string_view rTheBaseURIRef,
+ OUString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism = EncodeMechanism::WasEncoded,
+ DecodeMechanism eDecodeMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8,
+ FSysStyle eStyle = FSysStyle::Detect);
+
+ // External URLs:
+
+ OUString getExternalURL() const;
+
+ static inline bool translateToExternal(std::u16string_view rTheIntURIRef,
+ OUString & rTheExtURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static inline bool translateToInternal(std::u16string_view rTheExtURIRef,
+ OUString & rTheIntURIRef,
+ DecodeMechanism eDecodeMechanism
+ = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ // Scheme:
+
+ struct SchemeInfo;
+
+ INetProtocol GetProtocol() const { return m_eScheme; }
+
+ bool isSchemeEqualTo(INetProtocol scheme) const { return scheme == m_eScheme; }
+
+ bool isSchemeEqualTo(std::u16string_view scheme) const;
+
+ /** Check if the scheme is one of the WebDAV scheme
+ * we know about.
+ *
+ * @return true is one other scheme either public scheme or private scheme.
+ */
+ bool isAnyKnownWebDAVScheme() const;
+
+ /** Return the URL 'prefix' for a given scheme.
+
+ @param eTheScheme One of the supported URL schemes.
+
+ @return The 'prefix' of URLs of the given scheme.
+ */
+ static OUString GetScheme(INetProtocol eTheScheme);
+
+ /** Return the human-readable name for a given scheme.
+
+ @param eTheScheme One of the supported URL schemes.
+
+ @return The protocol name of URLs of the given scheme.
+ */
+ static const OUString & GetSchemeName(INetProtocol eTheScheme);
+
+ static INetProtocol CompareProtocolScheme(std::u16string_view aTheAbsURIRef);
+
+ // User Info:
+
+ bool HasUserData() const { return m_aUser.isPresent(); }
+
+ OUString GetUser(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aUser, eMechanism, eCharset); }
+
+ OUString GetPass(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aAuth, eMechanism, eCharset); }
+
+ bool SetUser(std::u16string_view rTheUser)
+ { return setUser(rTheUser, RTL_TEXTENCODING_UTF8); }
+
+ inline bool SetPass(std::u16string_view rThePassword);
+
+ // Host and Port:
+
+ bool HasPort() const { return m_aPort.isPresent(); }
+
+ OUString GetHost(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aHost, eMechanism, eCharset); }
+
+ OUString GetHostPort(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8) const;
+
+ sal_uInt32 GetPort() const;
+
+ bool SetHost(std::u16string_view rTheHost)
+ { return setHost(rTheHost, RTL_TEXTENCODING_UTF8); }
+
+ bool SetPort(sal_uInt32 nThePort);
+
+ // Path:
+
+ bool HasURLPath() const { return !m_aPath.isEmpty(); }
+
+ OUString GetURLPath(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aPath, eMechanism, eCharset); }
+
+ bool SetURLPath(std::u16string_view rThePath,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ { return setPath(rThePath, eMechanism, eCharset); }
+
+ // Hierarchical Path:
+
+ /** A constant to address the last segment in various methods dealing with
+ hierarchical paths.
+
+ @descr It is often more efficient to address the last segment using
+ this constant, than to determine its ordinal value using
+ getSegmentCount().
+ */
+ enum { LAST_SEGMENT = -1 };
+
+ /** The number of segments in the hierarchical path.
+
+ @descr Using RFC 2396 and RFC 2234, a hierarchical path is of the
+ form
+
+ hierarchical-path = 1*("/" segment)
+
+ segment = name *(";" param)
+
+ name = [base ["." extension]]
+
+ base = 1*pchar
+
+ extension = *<any pchar except ".">
+
+ param = *pchar
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return The number of segments in the hierarchical path. If the path
+ is not hierarchical, 0 is returned.
+ */
+ sal_Int32 getSegmentCount(bool bIgnoreFinalSlash = true) const;
+
+ /** Remove a segment from the hierarchical path.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return True if the segment has successfully been removed (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool removeSegment(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true);
+
+ /** Insert a new segment into the hierarchical path.
+ A final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param rTheName The name part of the new segment. The new segment
+ will contain no parameters.
+
+ @param bAppendFinalSlash If the new segment is appended at the end of
+ the hierarchical path, this parameter specifies whether to add a final
+ slash after it or not.
+
+ @param nIndex The non-negative index of the segment before which
+ to insert the new segment. LAST_SEGMENT or an nIndex that equals
+ getSegmentCount() inserts the new segment at the end of the
+ hierarchical path.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the segment has successfully been inserted (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified place to insert the new segment does not exist, false is
+ returned. If false is returned, the object is not modified.
+ */
+ bool insertName(std::u16string_view rTheName,
+ bool bAppendFinalSlash = false,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Get the name of a segment of the hierarchical path.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The name part of the specified segment. If the path is not
+ hierarchical, or the specified segment does not exits, an empty string
+ is returned.
+ */
+ OUString getName(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the name of the last segment (preserving any parameters and any query or
+ fragment part).
+
+ @param rTheName The new name.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return True if the name has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ a last segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setName(std::u16string_view rTheName,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Get the base of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The base part of the specified segment. If the path is
+ not hierarchical, or the specified segment does not exits, an empty
+ string is returned.
+ */
+ OUString getBase(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the base of the name of a segment (preserving the extension).
+ A final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param rTheBase The new base.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the base has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setBase(std::u16string_view rTheBase,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Determine whether the name of the last segment has an extension.
+
+ @return True if the name of the specified segment has an extension.
+ If the path is not hierarchical, or the specified segment does not
+ exist, false is returned.
+ */
+ bool hasExtension() const;
+
+ /** Get the extension of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The extension part of the specified segment. If the path is
+ not hierarchical, or the specified segment does not exits, an empty
+ string is returned.
+ */
+ OUString getExtension(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Set the extension of the name of a segment (replacing an already
+ existing extension).
+
+ @param rTheExtension The new extension.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return True if the extension has successfully been modified (and the
+ resulting URI is still valid). If the path is not hierarchical, or
+ the specified segment does not exist, false is returned. If false is
+ returned, the object is not modified.
+ */
+ bool setExtension(std::u16string_view rTheExtension,
+ sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ /** Remove the extension of the name of a segment.
+
+ @param nIndex The non-negative index of the segment, or LAST_SEGMENT
+ if addressing the last segment.
+
+ @param bIgnoreFinalSlash If true, a final slash at the end of the
+ hierarchical path does not denote an empty segment, but is ignored.
+
+ @return True if the extension has successfully been removed (and the
+ resulting URI is still valid), or if the name did not have an
+ extension. If the path is not hierarchical, or the specified segment
+ does not exist, false is returned. If false is returned, the object
+ is not modified.
+ */
+ bool removeExtension(sal_Int32 nIndex = LAST_SEGMENT,
+ bool bIgnoreFinalSlash = true);
+
+ /** Determine whether the hierarchical path ends in a final slash.
+
+ @return True if the hierarchical path ends in a final slash. If the
+ path is not hierarchical, false is returned.
+ */
+ bool hasFinalSlash() const;
+
+ /** Make the hierarchical path end in a final slash (if it does not
+ already do so).
+
+ @return True if a final slash has successfully been appended (and the
+ resulting URI is still valid), or if the hierarchical path already
+ ended in a final slash. If the path is not hierarchical, false is
+ returned. If false is returned, the object is not modified.
+ */
+ bool setFinalSlash();
+
+ /** Remove a final slash from the hierarchical path.
+
+ @return True if a final slash has successfully been removed (and the
+ resulting URI is still valid), or if the hierarchical path already did
+ not end in a final slash. If the path is not hierarchical, false is
+ returned. If false is returned, the object is not modified.
+ */
+ bool removeFinalSlash();
+
+ // Query:
+
+ bool HasParam() const { return m_aQuery.isPresent(); }
+
+ OUString GetParam(rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aQuery, DecodeMechanism::NONE, eCharset); }
+
+ inline bool SetParam(std::u16string_view rTheQuery,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ // Fragment:
+
+ bool HasMark() const { return m_aFragment.isPresent(); }
+
+ OUString GetMark(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8) const
+ { return decode(m_aFragment, eMechanism, eCharset); }
+
+ inline bool SetMark(std::u16string_view rTheFragment,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ // File URLs:
+
+ /** Return the file system path represented by a file URL (ignoring any
+ fragment part).
+
+ @param eStyle The notation of the returned file system path.
+
+ @param pDelimiter Upon successful return, this parameter can return
+ the character that is the 'main' delimiter within the returned file
+ system path (e.g., "/" for Unix, "\" for DOS). This is
+ especially useful for routines that later try to shorten the returned
+ file system path at a 'good' position, e.g. to fit it into some
+ limited display space.
+
+ @return The file system path represented by this file URL. If this
+ file URL does not represent a file system path according to the
+ specified notation, or if this is not a file URL at all, an empty
+ string is returned.
+ */
+ OUString getFSysPath(FSysStyle eStyle, sal_Unicode * pDelimiter = nullptr)
+ const;
+
+ // Data URLs:
+ std::unique_ptr<SvMemoryStream> getData() const;
+
+ // Coding:
+
+ enum Part
+ {
+ PART_USER_PASSWORD = 0x00001,
+ PART_FPATH = 0x00008,
+ PART_AUTHORITY = 0x00010,
+ PART_REL_SEGMENT_EXTRA = 0x00020,
+ PART_URIC = 0x00040,
+ PART_HTTP_PATH = 0x00080,
+ PART_MESSAGE_ID_PATH = 0x00100,
+ PART_MAILTO = 0x00200,
+ PART_PATH_BEFORE_QUERY = 0x00400,
+ PART_PCHAR = 0x00800,
+ PART_VISIBLE = 0x01000,
+ PART_VISIBLE_NONSPECIAL = 0x02000,
+ PART_UNO_PARAM_VALUE = 0x04000,
+ PART_UNAMBIGUOUS = 0x08000,
+ PART_URIC_NO_SLASH = 0x10000,
+ PART_HTTP_QUERY = 0x20000, //TODO! unused?
+ };
+
+ enum class EscapeType
+ {
+ NONE,
+ Octet,
+ Utf32
+ };
+
+ /** Encode some text as part of a URI.
+
+ @param rText Some text (for its interpretation, see the general
+ discussion for set-methods).
+
+ @param ePart The part says which characters are 'forbidden' and must
+ be encoded (replaced by escape sequences). Characters outside the US-
+ ASCII range are always 'forbidden.'
+
+ @param eMechanism See the general discussion for set-methods.
+
+ @param eCharset See the general discussion for set-methods.
+
+ @return The text, encoded according to the given mechanism and
+ charset ('forbidden' characters replaced by escape sequences).
+ */
+ static OUString encode( std::u16string_view rText, Part ePart,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+
+ /** Decode some text.
+
+ @param rText Some (encoded) text.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return The text, decoded according to the given mechanism and
+ charset (escape sequences replaced by 'raw' characters).
+ */
+ static inline OUString decode(std::u16string_view rText,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset
+ = RTL_TEXTENCODING_UTF8);
+
+ static void appendUCS4Escape(OUStringBuffer & rTheText, sal_uInt32 nUCS4);
+
+ static void appendUCS4(OUStringBuffer & rTheText, sal_uInt32 nUCS4,
+ EscapeType eEscapeType, Part ePart,
+ rtl_TextEncoding eCharset, bool bKeepVisibleEscapes);
+
+ static sal_uInt32 getUTF32(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ EscapeType & rEscapeType);
+
+ // Specialized helpers:
+
+ static sal_uInt32 scanDomain(sal_Unicode const *& rBegin,
+ sal_Unicode const * pEnd,
+ bool bEager = true);
+
+ // OBSOLETE Hierarchical Path:
+
+ OUString GetPartBeforeLastName() const;
+
+ /** Get the last segment in the path.
+
+ @param eMechanism See the general discussion for get-methods.
+
+ @param eCharset See the general discussion for get-methods.
+
+ @return For a hierarchical URL, the last segment (everything after
+ the last unencoded '/'). Note that this last segment may be empty. If
+ the URL is not hierarchical, an empty string is returned.
+ */
+ OUString GetLastName(DecodeMechanism eMechanism = DecodeMechanism::ToIUri,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8)
+ const;
+
+ /** Get the 'extension' of the last segment in the path.
+
+ @return For a hierarchical URL, everything after the first unencoded
+ '.' in the last segment of the path. Note that this 'extension' may
+ be empty. If the URL is not hierarchical, or if the last segment does
+ not contain an unencoded '.', an empty string is returned.
+ */
+ OUString GetFileExtension() const;
+
+ bool Append(std::u16string_view rTheSegment,
+ EncodeMechanism eMechanism = EncodeMechanism::WasEncoded,
+ rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8);
+
+ void CutLastName();
+
+ // OBSOLETE File URLs:
+
+ OUString PathToFileName() const;
+
+ OUString GetFull() const;
+
+ OUString GetPath() const;
+
+ void SetBase(std::u16string_view rTheBase);
+
+ OUString GetBase() const;
+
+ void SetExtension(std::u16string_view rTheExtension);
+
+ OUString CutExtension();
+
+ static bool IsCaseSensitive() { return true; }
+
+ void changeScheme(INetProtocol eTargetScheme);
+
+ // INetProtocol::Macro, INetProtocol::Uno, INetProtocol::Slot,
+ // vnd.sun.star.script, etc. All the types of URLs which shouldn't
+ // be accepted from an outside controlled source
+ bool IsExoticProtocol() const;
+
+private:
+ // General Structure:
+
+ class SAL_DLLPRIVATE SubString
+ {
+ sal_Int32 m_nBegin;
+ sal_Int32 m_nLength;
+
+ public:
+ explicit SubString(sal_Int32 nTheBegin = -1,
+ sal_Int32 nTheLength = 0):
+ m_nBegin(nTheBegin), m_nLength(nTheLength) {}
+
+ bool isPresent() const { return m_nBegin != -1; }
+
+ bool isEmpty() const { return m_nLength == 0; }
+
+ sal_Int32 getBegin() const { return m_nBegin; }
+
+ sal_Int32 getLength() const { return m_nLength; }
+
+ sal_Int32 getEnd() const { return m_nBegin + m_nLength; }
+
+ sal_Int32 clear();
+
+ sal_Int32 set(OUStringBuffer & rString,
+ std::u16string_view rSubString,
+ sal_Int32 nTheBegin);
+
+ sal_Int32 set(OUString & rString,
+ std::u16string_view rSubString);
+
+ sal_Int32 set(OUStringBuffer & rString,
+ std::u16string_view rSubString);
+
+ inline void operator +=(sal_Int32 nDelta);
+
+ int compare(SubString const & rOther,
+ OUStringBuffer const & rThisString,
+ OUStringBuffer const & rOtherString) const;
+ };
+
+ OUStringBuffer m_aAbsURIRef;
+ SubString m_aScheme;
+ SubString m_aUser;
+ SubString m_aAuth;
+ SubString m_aHost;
+ SubString m_aPort;
+ SubString m_aPath;
+ SubString m_aQuery;
+ SubString m_aFragment;
+ INetProtocol m_eScheme;
+ INetProtocol m_eSmartScheme;
+
+ TOOLS_DLLPRIVATE void setInvalid();
+
+ bool setAbsURIRef(
+ std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bSmart,
+ FSysStyle eStyle);
+
+ // Relative URLs:
+
+ bool convertRelToAbs(
+ OUString const & rTheRelURIRef,
+ INetURLObject & rTheAbsURIRef, bool & rWasAbsolute,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bIgnoreFragment, bool bSmart, bool bRelativeNonURIs,
+ FSysStyle eStyle) const;
+
+ bool convertAbsToRel(
+ OUString const & rTheAbsURIRef,
+ OUString & rTheRelURIRef, EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset,
+ FSysStyle eStyle) const;
+
+ // External URLs:
+
+ static bool convertIntToExt(
+ std::u16string_view rTheIntURIRef,
+ OUString & rTheExtURIRef, DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset);
+
+ static bool convertExtToInt(
+ std::u16string_view rTheExtURIRef,
+ OUString & rTheIntURIRef, DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset);
+
+ // Scheme:
+
+ struct PrefixInfo;
+
+ TOOLS_DLLPRIVATE static inline SchemeInfo const & getSchemeInfo(
+ INetProtocol eTheScheme);
+
+ TOOLS_DLLPRIVATE inline SchemeInfo const & getSchemeInfo() const;
+
+ TOOLS_DLLPRIVATE static PrefixInfo const * getPrefix(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
+
+ // Authority:
+
+ TOOLS_DLLPRIVATE sal_Int32 getAuthorityBegin() const;
+
+ TOOLS_DLLPRIVATE SubString getAuthority() const;
+
+ // User Info:
+
+ bool setUser(
+ std::u16string_view rTheUser,
+ rtl_TextEncoding eCharset);
+
+ bool clearPassword();
+
+ bool setPassword(
+ std::u16string_view rThePassword,
+ rtl_TextEncoding eCharset);
+
+ // Host and Port:
+
+ TOOLS_DLLPRIVATE static bool parseHost(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd,
+ OUStringBuffer* pCanonic);
+
+ TOOLS_DLLPRIVATE static bool parseHostOrNetBiosName(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bNetBiosName, OUStringBuffer* pCanonic);
+
+ bool setHost(
+ std::u16string_view rTheHost,
+ rtl_TextEncoding eCharset);
+
+ // Path:
+
+ TOOLS_DLLPRIVATE static bool parsePath(
+ INetProtocol eScheme, sal_Unicode const ** pBegin,
+ sal_Unicode const * pEnd, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset, bool bSkippedInitialSlash,
+ sal_uInt32 nSegmentDelimiter, sal_uInt32 nAltSegmentDelimiter,
+ sal_uInt32 nQueryDelimiter, sal_uInt32 nFragmentDelimiter,
+ OUStringBuffer &rSynPath);
+
+ bool setPath(
+ std::u16string_view rThePath,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Hierarchical Path:
+
+ TOOLS_DLLPRIVATE bool checkHierarchical() const;
+
+ TOOLS_DLLPRIVATE SubString getSegment(
+ sal_Int32 nIndex, bool bIgnoreFinalSlash) const;
+
+ // Query:
+
+ void clearQuery();
+
+ bool setQuery(
+ std::u16string_view rTheQuery,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // Fragment:
+
+ bool clearFragment();
+
+ bool setFragment(
+ std::u16string_view rTheMark,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset);
+
+ // FILE URLs:
+
+ TOOLS_DLLPRIVATE bool hasDosVolume(FSysStyle eStyle) const;
+
+ // Coding:
+
+ TOOLS_DLLPRIVATE static inline void appendEscape(
+ OUStringBuffer & rTheText, sal_uInt32 nOctet);
+
+ static void encodeText(
+ OUStringBuffer& rOutputBuffer,
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd,
+ Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes);
+
+ static inline void encodeText(
+ OUStringBuffer& rOutputBuffer,
+ std::u16string_view rTheText, Part ePart,
+ EncodeMechanism eMechanism, rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes);
+
+ static OUString decode(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd,
+ DecodeMechanism, rtl_TextEncoding eCharset);
+
+ inline OUString decode(
+ SubString const & rSubString,
+ DecodeMechanism eMechanism, rtl_TextEncoding eCharset) const;
+
+ // Specialized helpers:
+
+ TOOLS_DLLPRIVATE static bool scanIPv6reference(
+ sal_Unicode const *& rBegin, sal_Unicode const * pEnd);
+};
+
+// static
+inline void INetURLObject::encodeText( OUStringBuffer& rOutputBuffer,
+ std::u16string_view rTheText,
+ Part ePart,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes)
+{
+ encodeText(rOutputBuffer,
+ rTheText.data(),
+ rTheText.data() + rTheText.size(), ePart,
+ eMechanism, eCharset, bKeepVisibleEscapes);
+}
+
+inline OUString INetURLObject::decode(SubString const & rSubString,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset) const
+{
+ return rSubString.isPresent() ?
+ decode(m_aAbsURIRef.getStr() + rSubString.getBegin(),
+ m_aAbsURIRef.getStr() + rSubString.getEnd(),
+ eMechanism, eCharset) :
+ OUString();
+}
+
+inline INetURLObject::INetURLObject(std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset):
+ m_aAbsURIRef(rTheAbsURIRef.size() * 2), m_eScheme(INetProtocol::NotValid), m_eSmartScheme(INetProtocol::Http)
+{
+ setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, false,
+ FSysStyle(0));
+}
+
+inline bool INetURLObject::SetURL(std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, false,
+ FSysStyle(0));
+}
+
+inline INetURLObject::INetURLObject(std::u16string_view rTheAbsURIRef,
+ INetProtocol eTheSmartScheme,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle):
+ m_eScheme(INetProtocol::NotValid), m_eSmartScheme(eTheSmartScheme)
+{
+ setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, true, eStyle);
+}
+
+inline bool INetURLObject::SetSmartURL(std::u16string_view rTheAbsURIRef,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ return setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, true,
+ eStyle);
+}
+
+inline INetURLObject
+INetURLObject::smartRel2Abs(OUString const & rTheRelURIRef,
+ bool & rWasAbsolute,
+ bool bIgnoreFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bRelativeNonURIs,
+ FSysStyle eStyle) const
+{
+ INetURLObject aTheAbsURIRef;
+ convertRelToAbs(rTheRelURIRef, aTheAbsURIRef, rWasAbsolute,
+ eMechanism, eCharset, bIgnoreFragment, true,
+ bRelativeNonURIs, eStyle);
+ return aTheAbsURIRef;
+}
+
+inline bool INetURLObject::GetNewAbsURL(OUString const & rTheRelURIRef,
+ INetURLObject * pTheAbsURIRef)
+ const
+{
+ INetURLObject aTheAbsURIRef;
+ bool bWasAbsolute;
+ if (!convertRelToAbs(rTheRelURIRef, aTheAbsURIRef, bWasAbsolute,
+ EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false/*bIgnoreFragment*/, false, false,
+ FSysStyle::Detect))
+ return false;
+ if (pTheAbsURIRef)
+ *pTheAbsURIRef = aTheAbsURIRef;
+ return true;
+}
+
+// static
+inline OUString INetURLObject::GetRelURL(std::u16string_view rTheBaseURIRef,
+ OUString const & rTheAbsURIRef,
+ EncodeMechanism eEncodeMechanism,
+ DecodeMechanism eDecodeMechanism,
+ rtl_TextEncoding eCharset,
+ FSysStyle eStyle)
+{
+ OUString aTheRelURIRef;
+ INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
+ convertAbsToRel(rTheAbsURIRef, aTheRelURIRef, eEncodeMechanism,
+ eDecodeMechanism, eCharset, eStyle);
+ return aTheRelURIRef;
+}
+
+// static
+inline bool INetURLObject::translateToExternal(std::u16string_view
+ rTheIntURIRef,
+ OUString & rTheExtURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return convertIntToExt(rTheIntURIRef, rTheExtURIRef,
+ eDecodeMechanism, eCharset);
+}
+
+// static
+inline bool INetURLObject::translateToInternal(std::u16string_view
+ rTheExtURIRef,
+ OUString & rTheIntURIRef,
+ DecodeMechanism
+ eDecodeMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return convertExtToInt(rTheExtURIRef, rTheIntURIRef,
+ eDecodeMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetPass(std::u16string_view rThePassword)
+{
+ return rThePassword.empty() ?
+ clearPassword() :
+ setPassword(rThePassword, RTL_TEXTENCODING_UTF8);
+}
+
+inline bool INetURLObject::SetParam(std::u16string_view rTheQuery,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ if (rTheQuery.empty())
+ {
+ clearQuery();
+ return false;
+ }
+ return setQuery(rTheQuery, eMechanism, eCharset);
+}
+
+inline bool INetURLObject::SetMark(std::u16string_view rTheFragment,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return rTheFragment.empty() ?
+ clearFragment() :
+ setFragment(rTheFragment, eMechanism, eCharset);
+}
+
+// static
+inline OUString INetURLObject::encode(std::u16string_view rText, Part ePart,
+ EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ OUStringBuffer aBuf;
+ encodeText(aBuf, rText, ePart, eMechanism, eCharset, false);
+ return aBuf.makeStringAndClear();
+}
+
+// static
+inline OUString INetURLObject::decode(std::u16string_view rText,
+ DecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ return decode(rText.data(), rText.data() + rText.size(),
+ eMechanism, eCharset);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/vcompat.hxx b/include/tools/vcompat.hxx
new file mode 100644
index 0000000000..39cd0cd0bd
--- /dev/null
+++ b/include/tools/vcompat.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_VCOMPAT_HXX
+#define INCLUDED_TOOLS_VCOMPAT_HXX
+
+#include <tools/toolsdllapi.h>
+
+inline sal_uInt32 COMPAT_FORMAT(char char1, char char2, char char3, char char4)
+{
+ return static_cast<sal_uInt32>(char1) | (static_cast<sal_uInt32>(char2) << 8)
+ | (static_cast<sal_uInt32>(char3) << 16) | (static_cast<sal_uInt32>(char4) << 24);
+};
+
+class SvStream;
+
+class TOOLS_DLLPUBLIC VersionCompatRead
+{
+ SvStream& mrRStm;
+ sal_uInt32 mnCompatPos;
+ sal_uInt32 mnTotalSize;
+ sal_uInt16 mnVersion;
+
+ VersionCompatRead(const VersionCompatRead&) = delete;
+ VersionCompatRead& operator=(const VersionCompatRead&) = delete;
+
+public:
+ VersionCompatRead(SvStream& rStm);
+ ~VersionCompatRead();
+
+ sal_uInt16 GetVersion() const { return mnVersion; }
+};
+
+class TOOLS_DLLPUBLIC VersionCompatWrite
+{
+ SvStream& mrWStm;
+ sal_uInt32 mnCompatPos;
+ sal_uInt32 mnTotalSize;
+
+ VersionCompatWrite(const VersionCompatWrite&) = delete;
+ VersionCompatWrite& operator=(const VersionCompatWrite&) = delete;
+
+public:
+ VersionCompatWrite(SvStream& rStm, sal_uInt16 nVersion = 1);
+ ~VersionCompatWrite();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/weakbase.h b/include/tools/weakbase.h
new file mode 100644
index 0000000000..f5a79e635b
--- /dev/null
+++ b/include/tools/weakbase.h
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_WEAKBASE_H
+#define INCLUDED_TOOLS_WEAKBASE_H
+
+#include <sal/types.h>
+#include <rtl/ref.hxx>
+#include <tools/toolsdllapi.h>
+
+/** the template classes in this header are helper to implement weak references
+ to implementation objects that are not refcounted.
+
+ THIS IS NOT THREADSAFE
+
+ Use this only to have 'safe' pointers to implementation objects that you
+ don't own but that you reference with a pointer.
+
+ Example:
+
+ class ImplClass : public tools::WeakBase< ImplClass >
+ {
+ ~ImplClass() { clearWeek(); } // not needed but safer, see method description
+ ...
+ };
+
+ class UserClass
+ {
+ tools::WeakReference< ImplClass > mxWeakRef;
+
+ UserClass( ImplClass* pObject ) : mxWeakRef( pObject ) {}
+
+ DoSomething()
+ {
+ if( mxWeakRef.is() )
+ mxWeakRef->DoSomethingMore();
+ }
+ };
+*/
+namespace tools
+{
+class WeakBase;
+
+/** private connection helper, do not use directly */
+struct WeakConnection
+{
+ sal_Int32 mnRefCount;
+ WeakBase* mpReference;
+
+ WeakConnection() : mnRefCount( 0 ), mpReference( nullptr ) {};
+ WeakConnection( WeakBase* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
+ void acquire() { mnRefCount++; }
+ void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
+};
+
+/** template implementation to hold a weak reference to an instance of type reference_type */
+template <class reference_type>
+class SAL_WARN_UNUSED WeakReference
+{
+public:
+ /** constructs an empty reference */
+ inline WeakReference();
+
+ /** constructs a reference with a pointer to a class derived from WeakBase */
+ inline WeakReference( reference_type* pReference );
+
+ /** constructs a reference from another reference */
+ inline WeakReference( const WeakReference< reference_type >& rWeakRef );
+
+ /** move a reference from another reference */
+ inline WeakReference( WeakReference< reference_type >&& rWeakRef );
+
+ /** returns true if the reference object is not null and still alive */
+ inline bool is() const;
+
+ /** returns true if the reference object is not null and still alive */
+ operator bool() const { return is(); }
+
+ /** returns the pointer to the reference object or null */
+ inline reference_type * get() const;
+
+ /** sets this reference to the given object or null */
+ inline void reset( reference_type* pReference );
+
+ /** resets this reference to null */
+ inline void reset();
+
+ /** returns the pointer to the reference object or null */
+ inline reference_type * operator->() const;
+
+ /** returns a ref to the reference object */
+ inline reference_type& operator*() const;
+
+ /** returns true if this instance references pReferenceObject */
+ inline bool operator== (const reference_type * pReferenceObject) const;
+
+ /** returns true if this instance and the given weakref reference the same object */
+ inline bool operator== (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline bool operator!= (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline bool operator< (const WeakReference<reference_type> & handle) const;
+
+ /** only needed for using this class with stl containers */
+ inline bool operator> (const WeakReference<reference_type> & handle) const;
+
+ /** the assignment operator */
+ inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
+
+ /** the move assignment operator */
+ inline WeakReference<reference_type>& operator= (WeakReference<reference_type> && handle);
+
+private:
+ rtl::Reference<WeakConnection> mpWeakConnection;
+};
+
+/** derive your implementation classes from this class if you want them to support weak references */
+class TOOLS_DLLPUBLIC WeakBase
+{
+ template<typename T> friend class WeakReference;
+
+public:
+ WeakBase() {}
+ virtual ~WeakBase();
+ /** clears the reference pointer in all living weak references for this instance.
+ Further created weak references will also be invalid.
+ You should call this method in the d'tor of your derived classes for an early
+ invalidate of all living weak references while your object is already inside
+ it d'tor.
+ */
+ inline void clearWeak();
+
+private:
+ inline WeakConnection* getWeakConnection();
+ rtl::Reference<WeakConnection> mpWeakConnection;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/weakbase.hxx b/include/tools/weakbase.hxx
new file mode 100644
index 0000000000..ca6bdc37e6
--- /dev/null
+++ b/include/tools/weakbase.hxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_WEAKBASE_HXX
+#define INCLUDED_TOOLS_WEAKBASE_HXX
+
+#include <tools/weakbase.h>
+
+/// see weakbase.h for documentation
+
+namespace tools
+{
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference()
+{
+ mpWeakConnection = new WeakConnection;
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference( reference_type* pReference )
+{
+ reset( pReference );
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference( const WeakReference< reference_type >& rWeakRef )
+{
+ mpWeakConnection = rWeakRef.mpWeakConnection;
+}
+
+template< class reference_type >
+inline WeakReference< reference_type >::WeakReference( WeakReference< reference_type >&& rWeakRef )
+{
+ mpWeakConnection = std::move(rWeakRef.mpWeakConnection);
+ rWeakRef.reset();
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::is() const
+{
+ return mpWeakConnection->mpReference != nullptr;
+}
+
+template< class reference_type >
+inline reference_type * WeakReference< reference_type >::get() const
+{
+ auto pWeakBase = mpWeakConnection->mpReference;
+ if (!pWeakBase)
+ return nullptr;
+ assert(dynamic_cast<reference_type *>(pWeakBase));
+ return static_cast<reference_type *>(pWeakBase);
+}
+
+template< class reference_type >
+inline void WeakReference< reference_type >::reset( reference_type* pReference )
+{
+ if( pReference )
+ mpWeakConnection = pReference->getWeakConnection();
+ else
+ reset();
+}
+
+template< class reference_type >
+inline void WeakReference< reference_type >::reset()
+{
+ mpWeakConnection = new WeakConnection;
+}
+
+template< class reference_type >
+inline reference_type * WeakReference< reference_type >::operator->() const
+{
+ return get();
+}
+
+template< class reference_type >
+inline reference_type& WeakReference< reference_type >::operator*() const
+{
+ return *get();
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::operator==(const reference_type * pReferenceObject) const
+{
+ return mpWeakConnection->mpReference == pReferenceObject;
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::operator==(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection == handle.mpWeakConnection;
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::operator!=(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection != handle.mpWeakConnection;
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::operator<(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection->mpReference < handle.mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline bool WeakReference< reference_type >::operator>(const WeakReference<reference_type> & handle) const
+{
+ return mpWeakConnection->mpReference > handle.mpWeakConnection->mpReference;
+}
+
+template< class reference_type >
+inline WeakReference<reference_type>& WeakReference<reference_type>::operator= (
+ const WeakReference<reference_type>& rReference)
+{
+ if (&rReference != this)
+ mpWeakConnection = rReference.mpWeakConnection;
+ return *this;
+}
+
+template< class reference_type >
+inline WeakReference<reference_type>& WeakReference<reference_type>::operator= (
+ WeakReference<reference_type>&& rReference)
+{
+ mpWeakConnection = std::move(rReference.mpWeakConnection);
+ return *this;
+}
+
+inline void WeakBase::clearWeak()
+{
+ if( mpWeakConnection.is() )
+ mpWeakConnection->mpReference = nullptr;
+}
+
+inline WeakConnection* WeakBase::getWeakConnection()
+{
+ if( !mpWeakConnection.is() )
+ mpWeakConnection = new WeakConnection( this );
+ return mpWeakConnection.get();
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/wldcrd.hxx b/include/tools/wldcrd.hxx
new file mode 100644
index 0000000000..5c18ad20fc
--- /dev/null
+++ b/include/tools/wldcrd.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_TOOLS_WLDCRD_HXX
+#define INCLUDED_TOOLS_WLDCRD_HXX
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <tools/toolsdllapi.h>
+#include <rtl/ustring.hxx>
+
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC WildCard
+{
+private:
+ OUString aWildString;
+ char cSepSymbol;
+
+ static bool ImpMatch( std::u16string_view aWild, std::u16string_view aStr );
+
+public:
+ WildCard()
+ : aWildString('*')
+ , cSepSymbol('\0')
+ {
+ }
+
+ WildCard(std::u16string_view rWildCard, const char cSeparator = '\0')
+ : aWildString(rWildCard)
+ , cSepSymbol(cSeparator)
+ {
+ }
+
+ const OUString & getGlob() const
+ {
+ return aWildString;
+ }
+
+ void setGlob(std::u16string_view rString)
+ {
+ aWildString = rString;
+ }
+
+ bool Matches( std::u16string_view rStr ) const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/zcodec.hxx b/include/tools/zcodec.hxx
new file mode 100644
index 0000000000..a86dbec70b
--- /dev/null
+++ b/include/tools/zcodec.hxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_TOOLS_ZCODEC_HXX
+#define INCLUDED_TOOLS_ZCODEC_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/long.hxx>
+#include <memory>
+#include <rtl/string.hxx>
+
+#define ZCODEC_NO_COMPRESSION 0
+#define ZCODEC_DEFAULT_COMPRESSION 6
+
+class SvStream;
+
+// The overall client call protocol is one of:
+// * BeginCompression, Compress, EndCompression
+// * BeginCompression, SetCompressionMetadata, Compress, EndCompression (for gz files)
+// * BeginCompression, Decompress, EndCompression
+// * BeginCompression, Write*, EndCompression
+// * BeginCompression, Read*, EndCompression
+// * BeginCompression, ReadAsynchron*, EndCompression
+class SAL_WARN_UNUSED TOOLS_DLLPUBLIC ZCodec
+{
+ enum State { STATE_INIT, STATE_DECOMPRESS, STATE_COMPRESS };
+ State meState;
+ bool mbStatus;
+ bool mbFinish;
+ std::unique_ptr<sal_uInt8[]> mpInBuf;
+ size_t mnInBufSize;
+ size_t mnInToRead;
+ SvStream* mpOStm;
+ std::unique_ptr<sal_uInt8[]> mpOutBuf;
+ size_t mnOutBufSize;
+ sal_uInt32 mnUncompressedSize;
+ sal_uInt32 mnInBufCRC32;
+ sal_uInt32 mnLastModifiedTime;
+ OString msFilename;
+
+ int mnCompressLevel;
+ bool mbGzLib;
+ void* mpsC_Stream;
+
+ void InitCompress();
+ void InitDecompress(SvStream & inStream);
+ void ImplWriteBack();
+
+public:
+ ZCodec( size_t nInBufSize = 32768, size_t nOutBufSize = 32768 );
+ ~ZCodec();
+ /**
+ * @brief Checks whether a stream is Z compressed
+ *
+ * @param rIStm the stream to check
+ */
+ static bool IsZCompressed( SvStream& rIStm );
+
+ void BeginCompression( int nCompressLevel = ZCODEC_DEFAULT_COMPRESSION, bool gzLib = false );
+ tools::Long EndCompression();
+
+ /**
+ * @brief Set metadata for gzlib compression
+ *
+ * @param sFilename the uncompressed file filename
+ * @param nLastModifiedTime the files last modified time in unix format
+ */
+ void SetCompressionMetadata( const OString& sFilename,
+ sal_uInt32 nLastModifiedTime, sal_uInt32 nInBufCRC32 );
+ void Compress( SvStream& rIStm, SvStream& rOStm );
+ tools::Long Decompress( SvStream& rIStm, SvStream& rOStm );
+ bool AttemptDecompression( SvStream& rIStm, SvStream& rOStm );
+
+ void Write( SvStream& rOStm, const sal_uInt8* pData, sal_uInt32 nSize );
+ tools::Long Read( SvStream& rIStm, sal_uInt8* pData, sal_uInt32 nSize );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */