diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /include/tools | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/tools')
51 files changed, 8054 insertions, 0 deletions
diff --git a/include/tools/GenericTypeSerializer.hxx b/include/tools/GenericTypeSerializer.hxx new file mode 100644 index 000000000..cb54e693c --- /dev/null +++ b/include/tools/GenericTypeSerializer.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_GENERICTYPESERIALIZER_HXX +#define INCLUDED_TOOLS_GENERICTYPESERIALIZER_HXX + +#include <tools/toolsdllapi.h> +#include <tools/color.hxx> +#include <tools/gen.hxx> +#include <tools/stream.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); +}; + +} // end namespace tools + +#endif // INCLUDED_TOOLS_GENERICTYPESERIALIZER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/UnitConversion.hxx b/include/tools/UnitConversion.hxx new file mode 100644 index 000000000..e59077d8a --- /dev/null +++ b/include/tools/UnitConversion.hxx @@ -0,0 +1,31 @@ +/* -*- 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 + +constexpr sal_Int64 convertTwipToMm100(sal_Int64 n) +{ + return (n >= 0) ? (n * 127 + 36) / 72 : (n * 127 - 36) / 72; +} + +constexpr sal_Int64 convertPointToMm100(sal_Int64 n) { return convertTwipToMm100(n * 20); } + +constexpr sal_Int64 convertMm100ToTwip(sal_Int64 n) +{ + return (n >= 0) ? (n * 72 + 63) / 127 : (n * 72 - 63) / 127; +} + +// Convert PPT's "master unit" (1/576 inch) to twips +constexpr sal_Int64 convertMasterUnitToTwip(sal_Int64 n) { return n * 2540.0 / 576.0; } + +// Convert twips to PPT's "master unit" +constexpr sal_Int64 convertTwipToMasterUnit(sal_Int64 n) { return n / (2540.0 / 576.0); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/XmlWalker.hxx b/include/tools/XmlWalker.hxx new file mode 100644 index 000000000..204d71b5f --- /dev/null +++ b/include/tools/XmlWalker.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/. + */ + +#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 content(); + void children(); + void parent(); + void next(); + bool isValid() const; + OString attribute(const OString& sName); +}; + +} // 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 000000000..7efe3a573 --- /dev/null +++ b/include/tools/XmlWriter.hxx @@ -0,0 +1,67 @@ +/* -*- 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/ustring.hxx> +#include <memory> +#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 OString& sName); + void startElement(const OString& sPrefix, const OString& sName, const OString& sNamespaceUri); + void endElement(); + + void attribute(const OString& sTagName, const OString& aValue); + void attribute(const OString& sTagName, const OUString& aValue); + void attribute(const OString& sTagName, sal_Int32 aNumber); + void attributeDouble(const OString& sTagName, double aNumber); + void attributeBase64(const OString& sTagName, std::vector<sal_uInt8> const& rValueInBytes); + void attributeBase64(const OString& sTagName, std::vector<char> const& rValueInBytes); + + void content(const OString& sValue); + void content(const OUString& sValue); + + void element(const OString& 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 000000000..c0747cfca --- /dev/null +++ b/include/tools/b3dtrans.hxx @@ -0,0 +1,218 @@ +/* -*- 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 <config_options.h> +#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 UNLESS_MERGELIBS(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 UNLESS_MERGELIBS(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 UNLESS_MERGELIBS(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 000000000..66ce1dd3b --- /dev/null +++ b/include/tools/bigint.hxx @@ -0,0 +1,254 @@ +/* -*- 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 <rtl/ustring.hxx> +#include <tools/toolsdllapi.h> + +#define MAX_DIGITS 8 + +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC BigInt +{ +private: + sal_Int32 nVal; + sal_uInt16 nNum[MAX_DIGITS]; + sal_uInt8 nLen : 5; // current length + bool bIsNeg : 1, // Is Sign negative? + bIsBig : 1, // sal_True == BigInt + bIsSet : 1; // Not "Null" (not "not 0") + + 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) + , bIsBig(false) + , bIsSet(false) + { + } + + BigInt(sal_Int32 nValue) + : nVal(nValue) + , nLen(0) + , bIsNeg(false) + , bIsBig(false) + , bIsSet(true) + { + } + +#if SAL_TYPES_SIZEOFLONG == 4 + BigInt(int nValue) + : nVal(nValue) + , nLen(0) + , bIsNeg(false) + , bIsBig(false) + , bIsSet(true) + { + } +#endif + + BigInt( double nVal ); + BigInt( sal_uInt32 nVal ); + BigInt( sal_Int64 nVal ); + BigInt( const BigInt& rBigInt ); + BigInt( const OUString& rString ); + + operator sal_Int16() const; + operator sal_uInt16() const; + operator sal_Int32() const; + operator sal_uInt32() const; + operator double() const; +#if SAL_TYPES_SIZEOFLONG == 8 + operator long() const; +#endif + + bool IsSet() const { return bIsSet; } + bool IsNeg() const; + bool IsZero() const; + bool IsLong() const { return !bIsBig; } + + 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 ); + + 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 ); + 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 class Fraction; +}; + +inline BigInt::operator sal_Int16() const +{ + if ( !bIsBig && 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 ( !bIsBig && 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 (!bIsBig) + return nVal; + assert(false && "out of range"); + return 0; +} + +inline BigInt::operator sal_uInt32() const +{ + if ( !bIsBig && nVal >= 0 ) + return static_cast<sal_uInt32>(nVal); + assert(false && "out of range"); + return 0; +} + +#if SAL_TYPES_SIZEOFLONG == 8 +inline BigInt::operator long() const +{ + // Clamp to int32 since long is int32 on Windows. + if (!bIsBig) + return nVal; + assert(false && "out of range"); + return 0; +} +#endif + +inline BigInt& BigInt::operator =( sal_Int32 nValue ) +{ + bIsSet = true; + bIsBig = false; + nVal = nValue; + + return *this; +} + +inline bool BigInt::IsNeg() const +{ + if ( !bIsBig ) + return (nVal < 0); + else + return bIsNeg; +} + +inline bool BigInt::IsZero() const +{ + if ( bIsBig ) + return false; + else + return (nVal == 0); +} + +inline void BigInt::Abs() +{ + if ( bIsBig ) + 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 !( 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 000000000..afdb30d9e --- /dev/null +++ b/include/tools/color.hxx @@ -0,0 +1,336 @@ +/* -*- 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 <basegfx/color/bcolor.hxx> +#include <osl/endian.h> + +namespace color +{ + +constexpr sal_uInt32 extractRGB(sal_uInt32 nColorNumber) +{ + return nColorNumber & 0x00FFFFFF; +} + +} + +// Color + +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Color +{ + // data intentionally public; read the commit log! +public: + union + { + sal_uInt32 mValue; + struct + { +#ifdef OSL_BIGENDIAN + sal_uInt8 A; + sal_uInt8 R; + sal_uInt8 G; + sal_uInt8 B; +#else + sal_uInt8 B; + sal_uInt8 G; + sal_uInt8 R; + sal_uInt8 A; +#endif + }; + }; + +public: + constexpr Color() + : mValue(0) // black + {} + + constexpr Color(sal_uInt32 nColor) + : mValue(nColor) + {} + + constexpr Color(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(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue) + : Color(0, nRed, nGreen, nBlue) + {} + + // constructor to create a tools-Color from ::basegfx::BColor + explicit Color(const basegfx::BColor& rBColor) + : Color(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))) + {} + + /** Primarily used when passing Color objects to UNO API */ + constexpr explicit operator sal_uInt32() const + { + return mValue; + } + + constexpr explicit operator sal_Int32() const + { + return sal_Int32(mValue); + } + + bool operator<(const Color& aCompareColor) const + { + return mValue < aCompareColor.mValue; + } + + void SetRed(sal_uInt8 nRed); + sal_uInt8 GetRed() const + { + return R; + } + void SetGreen(sal_uInt8 nGreen); + sal_uInt8 GetGreen() const + { + return G; + } + void SetBlue(sal_uInt8 nBlue); + sal_uInt8 GetBlue() const + { + return B; + } + void SetTransparency(sal_uInt8 nTransparency); + sal_uInt8 GetTransparency() const + { + return A; + } + + Color GetRGBColor() const + { + return color::extractRGB(mValue); + } + + sal_uInt16 GetColorError(const Color& rCompareColor) const; + + sal_uInt8 GetLuminance() const; + void IncreaseLuminance(sal_uInt8 cLumInc); + void DecreaseLuminance(sal_uInt8 cLumDec); + + void DecreaseContrast(sal_uInt8 cContDec); + + /** + * 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); + + void Invert(); + + void Merge(const Color& rMergeColor, sal_uInt8 cTransparency); + + bool IsRGBEqual(const Color& rColor) const; + + // comparison with luminance thresholds + bool IsDark() const; + bool IsBright() const; + + // color space conversion tools + // the range for h/s/b is: + // Hue: 0-360 degree + // Saturation: 0-100% + // Brightness: 0-100% + static Color HSBtoRGB(sal_uInt16 nHue, sal_uInt16 nSaturation, sal_uInt16 nBrightness); + void RGBtoHSB(sal_uInt16& nHue, sal_uInt16& nSaturation, sal_uInt16& nBrightness) const; + + bool operator==(const Color& rColor) const + { + return mValue == rColor.mValue; + } + bool operator!=(const Color& rColor) const + { + return !(Color::operator==(rColor)); + } + + // Return color as RGB hex string + // for example "00ff00" for green color + OUString AsRGBHexString() const; + + // get ::basegfx::BColor from this color + basegfx::BColor getBColor() const + { + return basegfx::BColor(GetRed() / 255.0, GetGreen() / 255.0, GetBlue() / 255.0); + } +}; + +inline void Color::SetRed( sal_uInt8 nRed ) +{ + R = nRed; +} + +inline void Color::SetGreen( sal_uInt8 nGreen ) +{ + G = nGreen; +} + +inline void Color::SetBlue( sal_uInt8 nBlue ) +{ + B = nBlue; +} + +inline void Color::SetTransparency( sal_uInt8 nTransparency ) +{ + A = nTransparency; +} + +inline bool Color::IsRGBEqual( const Color& rColor ) const +{ + return color::extractRGB(mValue) == color::extractRGB(rColor.mValue); +} + +inline sal_uInt8 Color::GetLuminance() const +{ + return sal_uInt8((B * 29UL + G * 151UL + R * 76UL) >> 8); +} + +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); +} + +inline void Color::Invert() +{ + R = ~R; + G = ~G; + B = ~B; +} + +inline sal_uInt16 Color::GetColorError( const Color& rColor ) const +{ + return static_cast<sal_uInt16>( + abs(static_cast<int>(GetBlue()) - rColor.GetBlue()) + + abs(static_cast<int>(GetGreen()) - rColor.GetGreen()) + + abs(static_cast<int>(GetRed()) - rColor.GetRed())); +} + +inline void Color::Merge( const Color& rMergeColor, sal_uInt8 cTransparency ) +{ + R = ColorChannelMerge(R, rMergeColor.R, cTransparency); + G = ColorChannelMerge(G, rMergeColor.G, cTransparency); + B = ColorChannelMerge(B, rMergeColor.B, cTransparency); +} + +// 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(nTmp); + return true; +} + +inline void operator <<=( css::uno::Any & rAny, Color value ) +{ + rAny <<= sal_Int32(value); +} +namespace com::sun::star::uno { + template<> + inline Any makeAny( Color const & value ) + { + return Any(sal_Int32(value)); + } +} + +// Test compile time conversion of Color to sal_uInt32 + +static_assert (sal_uInt32(Color(0x00, 0x12, 0x34, 0x56)) == 0x00123456); +static_assert (sal_uInt32(Color(0x12, 0x34, 0x56)) == 0x00123456); + +// Color types + +constexpr ::Color COL_BLACK ( 0x00, 0x00, 0x00 ); +constexpr ::Color COL_BLUE ( 0x00, 0x00, 0x80 ); +constexpr ::Color COL_GREEN ( 0x00, 0x80, 0x00 ); +constexpr ::Color COL_CYAN ( 0x00, 0x80, 0x80 ); +constexpr ::Color COL_RED ( 0x80, 0x00, 0x00 ); +constexpr ::Color COL_MAGENTA ( 0x80, 0x00, 0x80 ); +constexpr ::Color COL_BROWN ( 0x80, 0x80, 0x00 ); +constexpr ::Color COL_GRAY ( 0x80, 0x80, 0x80 ); +constexpr ::Color COL_GRAY3 ( 0xCC, 0xCC, 0xCC ); +constexpr ::Color COL_GRAY7 ( 0x66, 0x66, 0x66 ); +constexpr ::Color COL_LIGHTGRAY ( 0xC0, 0xC0, 0xC0 ); +constexpr ::Color COL_LIGHTBLUE ( 0x00, 0x00, 0xFF ); +constexpr ::Color COL_LIGHTGREEN ( 0x00, 0xFF, 0x00 ); +constexpr ::Color COL_LIGHTCYAN ( 0x00, 0xFF, 0xFF ); +constexpr ::Color COL_LIGHTRED ( 0xFF, 0x00, 0x00 ); +constexpr ::Color COL_LIGHTMAGENTA ( 0xFF, 0x00, 0xFF ); +constexpr ::Color COL_LIGHTGRAYBLUE ( 0xE0, 0xE0, 0xFF ); +constexpr ::Color COL_YELLOW ( 0xFF, 0xFF, 0x00 ); +constexpr ::Color COL_WHITE ( 0xFF, 0xFF, 0xFF ); +constexpr ::Color COL_TRANSPARENT ( 0xFF, 0xFF, 0xFF, 0xFF ); +constexpr ::Color COL_AUTO ( 0xFF, 0xFF, 0xFF, 0xFF ); +constexpr ::Color COL_AUTHOR1_DARK ( 198, 146, 0 ); +constexpr ::Color COL_AUTHOR1_NORMAL ( 255, 255, 158 ); +constexpr ::Color COL_AUTHOR1_LIGHT ( 255, 255, 195 ); +constexpr ::Color COL_AUTHOR2_DARK ( 6, 70, 162 ); +constexpr ::Color COL_AUTHOR2_NORMAL ( 216, 232, 255 ); +constexpr ::Color COL_AUTHOR2_LIGHT ( 233, 242, 255 ); +constexpr ::Color COL_AUTHOR3_DARK ( 87, 157, 28 ); +constexpr ::Color COL_AUTHOR3_NORMAL ( 218, 248, 193 ); +constexpr ::Color COL_AUTHOR3_LIGHT ( 226, 250, 207 ); +constexpr ::Color COL_AUTHOR4_DARK ( 105, 43, 157 ); +constexpr ::Color COL_AUTHOR4_NORMAL ( 228, 210, 245 ); +constexpr ::Color COL_AUTHOR4_LIGHT ( 239, 228, 248 ); +constexpr ::Color COL_AUTHOR5_DARK ( 197, 0, 11 ); +constexpr ::Color COL_AUTHOR5_NORMAL ( 254, 205, 208 ); +constexpr ::Color COL_AUTHOR5_LIGHT ( 255, 227, 229 ); +constexpr ::Color COL_AUTHOR6_DARK ( 0, 128, 128 ); +constexpr ::Color COL_AUTHOR6_NORMAL ( 210, 246, 246 ); +constexpr ::Color COL_AUTHOR6_LIGHT ( 230, 250, 250 ); +constexpr ::Color COL_AUTHOR7_DARK ( 140, 132, 0 ); +constexpr ::Color COL_AUTHOR7_NORMAL ( 237, 252, 163 ); +constexpr ::Color COL_AUTHOR7_LIGHT ( 242, 254, 181 ); +constexpr ::Color COL_AUTHOR8_DARK ( 53, 85, 107 ); +constexpr ::Color COL_AUTHOR8_NORMAL ( 211, 222, 232 ); +constexpr ::Color COL_AUTHOR8_LIGHT ( 226, 234, 241 ); +constexpr ::Color COL_AUTHOR9_DARK ( 209, 118, 0 ); +constexpr ::Color COL_AUTHOR9_NORMAL ( 255, 226, 185 ); +constexpr ::Color COL_AUTHOR9_LIGHT ( 255, 231, 199 ); + +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 << "c[" << 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.GetTransparency()) << "]"; + 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 000000000..76e4270b5 --- /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(const OString& rGroup); + OString GetGroupName(sal_uInt16 nGroup) const; + sal_uInt16 GetGroupCount() const; + bool HasGroup(const OString& 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(const OString& 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 000000000..716cbf242 --- /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 <limits.h> + +#define TREELIST_APPEND (ULONG_MAX) +#define TREELIST_ENTRY_NOTFOUND (ULONG_MAX) + +#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 000000000..90c7d37b4 --- /dev/null +++ b/include/tools/cpuid.hxx @@ -0,0 +1,82 @@ +/* -*- 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> + +namespace cpuid { + +enum class InstructionSetFlags +{ + NONE = 0x00, + HYPER = 0x01, + SSE2 = 0x02, + SSSE3 = 0x04, + SSE41 = 0x08, + SSE42 = 0x10, + AVX = 0x20, + AVX2 = 0x40 +}; + +} // end cpuid + +namespace o3tl { + template<> struct typed_flags<cpuid::InstructionSetFlags> : is_typed_flags<cpuid::InstructionSetFlags, 0x07f> {}; +} + +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 AVX2 is supported by the CPU + */ +inline bool hasAVX2() +{ + return isCpuInstructionSetSupported(InstructionSetFlags::AVX2); +} + +/** 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 000000000..cd69d16b1 --- /dev/null +++ b/include/tools/date.hxx @@ -0,0 +1,254 @@ +/* -*- 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; + + /** 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 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 000000000..7b78b29bd --- /dev/null +++ b/include/tools/datetime.hxx @@ -0,0 +1,131 @@ +/* -*- 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> + +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 ); + + 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 ); + TOOLS_DLLPUBLIC friend double operator -( 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; } + + 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 000000000..28766ee8a --- /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 000000000..c72da4d06 --- /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/diagnose_ex.h b/include/tools/diagnose_ex.h new file mode 100644 index 000000000..558420e54 --- /dev/null +++ b/include/tools/diagnose_ex.h @@ -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_DIAGNOSE_EX_H +#define INCLUDED_TOOLS_DIAGNOSE_EX_H + +#include <osl/diagnose.h> +#include <rtl/ustring.hxx> + +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <sal/log.hxx> +#include <tools/toolsdllapi.h> +#include <cppuhelper/exc_hlp.hxx> + +TOOLS_DLLPUBLIC void DbgUnhandledException(const css::uno::Any& caughtException, + const char* currentFunction, const char* fileAndLineNo, + const char* area, const char* explanatory = nullptr); + +//getCaughtException throws exceptions in never-going-to-happen situations which +//floods coverity with warnings +inline css::uno::Any DbgGetCaughtException() +{ +#if defined(__COVERITY__) + try + { + return ::cppu::getCaughtException(); + } + catch (...) + { + std::abort(); + } +#else + return ::cppu::getCaughtException(); +#endif +} + +/** reports a caught UNO exception via OSL diagnostics + + Note that whenever you use this, it might be an indicator that your error + handling is not correct... + This takes two optional parameters: area and explanatory +*/ +#define DBG_UNHANDLED_EXCEPTION_0_ARGS() \ + DbgUnhandledException( DbgGetCaughtException(), OSL_THIS_FUNC, SAL_DETAIL_WHERE ); +#define DBG_UNHANDLED_EXCEPTION_1_ARGS(area) \ + DbgUnhandledException( DbgGetCaughtException(), OSL_THIS_FUNC, SAL_DETAIL_WHERE, area ); +#define DBG_UNHANDLED_EXCEPTION_2_ARGS(area, explanatory) \ + DbgUnhandledException( DbgGetCaughtException(), OSL_THIS_FUNC, SAL_DETAIL_WHERE, area, explanatory ); + +#define DBG_UNHANDLED_FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3 +#define DBG_UNHANDLED_FUNC_RECOMPOSER(argsWithParentheses) DBG_UNHANDLED_FUNC_CHOOSER argsWithParentheses +#define DBG_UNHANDLED_CHOOSE_FROM_ARG_COUNT(...) DBG_UNHANDLED_FUNC_RECOMPOSER((__VA_ARGS__, DBG_UNHANDLED_EXCEPTION_2_ARGS, DBG_UNHANDLED_EXCEPTION_1_ARGS, DBG_UNHANDLED_EXCEPTION_0_ARGS, )) +#define DBG_UNHANDLED_NO_ARG_EXPANDER() ,,DBG_UNHANDLED_EXCEPTION_0_ARGS +#define DBG_UNHANDLED_MACRO_CHOOSER(...) DBG_UNHANDLED_CHOOSE_FROM_ARG_COUNT(DBG_UNHANDLED_NO_ARG_EXPANDER __VA_ARGS__ ()) +#define DBG_UNHANDLED_EXCEPTION(...) DBG_UNHANDLED_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) + + +/** This macro asserts the given condition (in debug mode), and throws + an IllegalArgumentException afterwards. + */ +#define ENSURE_ARG_OR_THROW(c, m) if( !(c) ) { \ + OSL_ENSURE(c, m); \ + throw css::lang::IllegalArgumentException( \ + OUStringLiteral(OSL_THIS_FUNC) \ + + ",\n" m, \ + css::uno::Reference< css::uno::XInterface >(), \ + 0 ); } +#define ENSURE_ARG_OR_THROW2(c, m, ifc, arg) if( !(c) ) { \ + OSL_ENSURE(c, m); \ + throw css::lang::IllegalArgumentException( \ + OUStringLiteral(OSL_THIS_FUNC) \ + + ",\n" m, \ + ifc, \ + arg ); } + +/** This macro asserts the given condition (in debug mode), and throws + a RuntimeException afterwards. + */ +#define ENSURE_OR_THROW(c, m) \ + if( !(c) ){ \ + OSL_ENSURE(c, m); \ + throw css::uno::RuntimeException( \ + OUStringLiteral(OSL_THIS_FUNC) + ",\n" m, \ + css::uno::Reference< css::uno::XInterface >() ); } + +#define ENSURE_OR_THROW2(c, m, ifc) \ + if( !(c) ) { \ + OSL_ENSURE(c, m); \ + throw css::uno::RuntimeException( \ + OUStringLiteral(OSL_THIS_FUNC) + ",\n" m, \ + ifc ); } + +/** This macro asserts the given condition (in debug mode), and + returns the given value afterwards. + */ +#define ENSURE_OR_RETURN(c, m, r) if( !(c) ) { \ + OSL_ENSURE(c, m); \ + return r; } + +/** This macro asserts the given condition (in debug mode), and + returns false afterwards. + */ +#define ENSURE_OR_RETURN_FALSE(c, m) \ + ENSURE_OR_RETURN(c, m, false) + +/** This macro asserts the given condition (in debug mode), and + returns afterwards, without return value "void". + */ +#define ENSURE_OR_RETURN_VOID( c, m ) \ + if( !(c) ) \ + { \ + OSL_ENSURE( c, m ); \ + return; \ + } + +/** Convert a caught exception to a string suitable for logging. +*/ +TOOLS_DLLPUBLIC OString exceptionToString(css::uno::Any const & caughtEx); + +/** + Logs an message along with a nicely formatted version of the current exception. + This must be called as the FIRST thing in a catch block. +*/ +#define TOOLS_WARN_EXCEPTION(area, stream) \ + do { \ + css::uno::Any tools_warn_exception( DbgGetCaughtException() ); \ + SAL_WARN(area, stream << " " << exceptionToString(tools_warn_exception)); \ + } while (false) + +/** + Logs an message along with a nicely formatted version of the current exception. + This must be called as the FIRST thing in a catch block. +*/ +#define TOOLS_WARN_EXCEPTION_IF(cond, area, stream) \ + do { \ + css::uno::Any tools_warn_exception( DbgGetCaughtException() ); \ + SAL_WARN_IF(cond, area, stream << " " << exceptionToString(tools_warn_exception)); \ + } while (false) + +/** + Logs an message along with a nicely formatted version of the current exception. + This must be called as the FIRST thing in a catch block. +*/ +#define TOOLS_INFO_EXCEPTION(area, stream) \ + do { \ + css::uno::Any tools_warn_exception( DbgGetCaughtException() ); \ + SAL_INFO(area, stream << " " << exceptionToString(tools_warn_exception)); \ + } while (false) + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/extendapplicationenvironment.hxx b/include/tools/extendapplicationenvironment.hxx new file mode 100644 index 000000000..9a610a0b8 --- /dev/null +++ b/include/tools/extendapplicationenvironment.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 . + */ +#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 000000000..d2ed87a6d --- /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/fldunit.hxx b/include/tools/fldunit.hxx new file mode 100644 index 000000000..c300ef2ef --- /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, + CHAR, + LINE, + CUSTOM, + PERCENT, + MM_100TH, + 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 000000000..eeb35be19 --- /dev/null +++ b/include/tools/fontenum.hxx @@ -0,0 +1,84 @@ +/* -*- 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 <o3tl/typed_flags_set.hxx> + +enum FontFamily { FAMILY_DONTKNOW, FAMILY_DECORATIVE, FAMILY_MODERN, + FAMILY_ROMAN, FAMILY_SCRIPT, FAMILY_SWISS, FAMILY_SYSTEM, FontFamily_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; + +enum FontPitch { PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, FontPitch_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; + +enum TextAlign { ALIGN_TOP, ALIGN_BASELINE, ALIGN_BOTTOM, TextAlign_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; + +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 }; + +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 }; + +enum FontItalic { ITALIC_NONE, ITALIC_OBLIQUE, ITALIC_NORMAL, ITALIC_DONTKNOW, FontItalic_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; + +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 }; + +enum FontStrikeout { STRIKEOUT_NONE, STRIKEOUT_SINGLE, STRIKEOUT_DOUBLE, + STRIKEOUT_DONTKNOW, STRIKEOUT_BOLD, + STRIKEOUT_SLASH, STRIKEOUT_X, + FontStrikeout_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; + +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> {}; +} + + +enum FontEmbeddedBitmap { EMBEDDEDBITMAP_DONTKNOW, EMBEDDEDBITMAP_FALSE, EMBEDDEDBITMAP_TRUE }; + +enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE }; + +#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 000000000..ed1f5f0be --- /dev/null +++ b/include/tools/fract.hxx @@ -0,0 +1,120 @@ +/* -*- 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 <memory> +#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_SIZEOFLONG == 8 + explicit operator long() const { return sal_Int32(*this); } +#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 ); + + 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 friend SvStream& ReadFraction( SvStream& rIStream, Fraction & rFract ); + TOOLS_DLLPUBLIC friend SvStream& WriteFraction( SvStream& rOStream, const Fraction& rFract ); +}; + +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 000000000..e069717bb --- /dev/null +++ b/include/tools/gen.hxx @@ -0,0 +1,739 @@ +/* -*- 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_GEN_HXX +#define INCLUDED_TOOLS_GEN_HXX + +#include <tools/toolsdllapi.h> + +#include <limits.h> +#include <algorithm> +#include <ostream> +#include <config_options.h> +#include <cassert> + +class SvStream; +namespace rtl +{ + class OString; +} + +enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET }; + +// Pair + +class SAL_WARN_UNUSED Pair +{ +public: + Pair() : nA(0), nB(0) {} + Pair( long _nA, long _nB ) : nA(_nA), nB(_nB) {} + + long A() const { return nA; } + long B() const { return nB; } + + long& A() { return nA; } + long& B() { return nB; } + + TOOLS_DLLPUBLIC rtl::OString toString() const; + +protected: + long nA; + long nB; +}; + +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 Size; +class SAL_WARN_UNUSED UNLESS_MERGELIBS(SAL_DLLPUBLIC_EXPORT) Point final : protected Pair +{ +public: + Point() {} + Point( long nX, long nY ) : Pair( nX, nY ) {} + + long X() const { return nA; } + long Y() const { return nB; } + + void Move( long nHorzMove, long nVertMove ); + void Move( Size const & s ); + long AdjustX( long nHorzMove ) { nA += nHorzMove; return nA; } + long AdjustY( long nVertMove ) { nB += nVertMove; return nB; } + + void RotateAround( long& rX, long& rY, short nOrientation ) const; + void RotateAround( Point&, short nOrientation ) const; + + Point& operator += ( const Point& rPoint ); + Point& operator -= ( const Point& rPoint ); + Point& operator *= ( const long nVal ); + Point& operator /= ( const long nVal ); + + friend inline Point operator+( const Point &rVal1, const Point &rVal2 ); + friend inline Point operator-( const Point &rVal1, const Point &rVal2 ); + friend inline Point operator*( const Point &rVal1, const long nVal2 ); + friend inline Point operator/( const Point &rVal1, const long nVal2 ); + + long getX() const { return X(); } + long getY() const { return Y(); } + void setX(long nX) { nA = nX; } + void setY(long nY) { nB = nY; } + + Pair const & toPair() const { return *this; } + Pair & toPair() { return *this; } + + using Pair::toString; +}; + +inline void Point::Move( long nHorzMove, long nVertMove ) +{ + nA += nHorzMove; + nB += nVertMove; +} + +inline Point& Point::operator += ( const Point& rPoint ) +{ + nA += rPoint.nA; + nB += rPoint.nB; + return *this; +} + +inline Point& Point::operator -= ( const Point& rPoint ) +{ + nA -= rPoint.nA; + nB -= rPoint.nB; + return *this; +} + +inline Point& Point::operator *= ( const long nVal ) +{ + nA *= nVal; + nB *= nVal; + return *this; +} + +inline Point& Point::operator /= ( const long nVal ) +{ + nA /= nVal; + nB /= nVal; + return *this; +} + +inline Point operator+( const Point &rVal1, const Point &rVal2 ) +{ + return Point( rVal1.nA+rVal2.nA, rVal1.nB+rVal2.nB ); +} + +inline Point operator-( const Point &rVal1, const Point &rVal2 ) +{ + return Point( rVal1.nA-rVal2.nA, rVal1.nB-rVal2.nB ); +} + +inline Point operator*( const Point &rVal1, const long nVal2 ) +{ + return Point( rVal1.nA*nVal2, rVal1.nB*nVal2 ); +} + +inline Point operator/( const Point &rVal1, const long nVal2 ) +{ + return Point( rVal1.nA/nVal2, rVal1.nB/nVal2 ); +} + +inline bool operator ==(Point const & p1, Point const & p2) +{ + return tools::detail::equal(p1.toPair(), p2.toPair()); +} + +inline bool operator !=(Point const & p1, Point const & p2) +{ + return !(p1 == p2); +} + +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, const Point& point ) +{ + return stream << point.X() << ',' << point.Y(); +} + +// Size + +class SAL_WARN_UNUSED Size final : protected Pair +{ +public: + Size() {} + Size( long nWidth, long nHeight ) : Pair( nWidth, nHeight ) {} + + long Width() const { return nA; } + long Height() const { return nB; } + + long AdjustWidth( long n ) { nA += n; return nA; } + long AdjustHeight( long n ) { nB += n; return nB; } + + long getWidth() const { return Width(); } + long getHeight() const { return Height(); } + void setWidth(long nWidth) { nA = nWidth; } + void setHeight(long nHeight) { nB = nHeight; } + + bool IsEmpty() const { return nA <= 0 || nB <= 0; } + + void extendBy(long x, long y) + { + nA += x; + nB += y; + } + + Pair const & toPair() const { return *this; } + Pair & toPair() { return *this; } + + using Pair::toString; +}; + +inline bool operator ==(Size const & s1, Size const & s2) +{ + return tools::detail::equal(s1.toPair(), s2.toPair()); +} + +inline bool operator !=(Size const & s1, Size const & s2) +{ + return !(s1 == s2); +} + +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, const Size& size ) +{ + return stream << size.Width() << 'x' << size.Height(); +} + +inline void Point::Move( Size const & s ) +{ + AdjustX(s.Width()); + AdjustY(s.Height()); +} + +// Range + +#define RANGE_MAX LONG_MAX + +class SAL_WARN_UNUSED Range final : protected Pair +{ +public: + Range() {} + Range( long nMin, long nMax ) : Pair( nMin, nMax ) {} + + long Min() const { return nA; } + long Max() const { return nB; } + long Len() const { return nB - nA + 1; } + + long& Min() { return nA; } + long& Max() { return nB; } + + bool IsInside( long nIs ) const; + + void Justify(); + + Pair const & toPair() const { return *this; } + Pair & toPair() { return *this; } + + using Pair::toString; +}; + +inline bool Range::IsInside( long nIs ) const +{ + return ((nA <= nIs) && (nIs <= nB )); +} + +inline void Range::Justify() +{ + if ( nA > nB ) + { + long nHelp = nA; + nA = nB; + nB = nHelp; + } +} + +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( long nPos ) : Pair( nPos, nPos ) {} + Selection( long nMin, long nMax ) : Pair( nMin, nMax ) {} + + long Min() const { return nA; } + long Max() const { return nB; } + long Len() const { return nB - nA; } + + long& Min() { return nA; } + long& Max() { return nB; } + + bool IsInside( long nIs ) const; + + void Justify(); + + bool operator !() const { return !Len(); } + + long getMin() const { return Min(); } + void setMin(long nMin) { Min() = nMin; } + void setMax(long nMax) { Max() = nMax; } + + Pair const & toPair() const { return *this; } + Pair & toPair() { return *this; } + + using Pair::toString; +}; + +inline bool Selection::IsInside( long nIs ) const +{ + return ((nA <= nIs) && (nIs < nB )); +} + +inline void Selection::Justify() +{ + if ( nA > nB ) + { + long nHelp = nA; + nA = nB; + nB = nHelp; + } +} + +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, while the lowercase +/// getWidth() / getHeight() etc. methods interpret the interval as half-open. +/// Ok, now is the time for despair. +namespace tools +{ +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final +{ + static constexpr short RECT_EMPTY = -32767; +public: + Rectangle(); + Rectangle( const Point& rLT, const Point& rRB ); + Rectangle( long nLeft, long nTop, + long nRight, long nBottom ); + /// Constructs an empty Rectangle, with top/left at the specified params + Rectangle( long nLeft, long nTop ); + Rectangle( const Point& rLT, const Size& rSize ); + + static Rectangle Justify( const Point& rLT, const Point& rRB ); + + long Left() const { return nLeft; } + long Right() const; + long Top() const { return nTop; } + long Bottom() const; + + void SetLeft(long v) { nLeft = v; } + void SetRight(long v) { nRight = v; } + void SetTop(long v) { nTop = v; } + void SetBottom(long v) { nBottom = v; } + + inline Point TopLeft() const; + inline Point TopRight() const; + inline Point TopCenter() const; + inline Point BottomLeft() const; + inline Point BottomRight() const; + inline Point BottomCenter() const; + inline Point LeftCenter() const; + inline Point RightCenter() const; + inline Point Center() const; + + /// Move the top and left edges by a delta, preserving width and height + inline void Move( long nHorzMoveDelta, long nVertMoveDelta ); + void Move( Size const & s ) { Move(s.Width(), s.Height()); } + long AdjustLeft( long nHorzMoveDelta ) { nLeft += nHorzMoveDelta; return nLeft; } + long AdjustRight( long nHorzMoveDelta ); + long AdjustTop( long nVertMoveDelta ) { nTop += nVertMoveDelta; return nTop; } + long AdjustBottom( long nVertMoveDelta ); + inline void SetPos( const Point& rPoint ); + void SetSize( const Size& rSize ); + inline Size GetSize() const; + + /// Returns the difference between right and left, assuming the range is inclusive. + inline long GetWidth() const; + /// Returns the difference between bottom and top, assuming the range is inclusive. + inline long GetHeight() const; + + tools::Rectangle& Union( const tools::Rectangle& rRect ); + tools::Rectangle& Intersection( const tools::Rectangle& rRect ); + inline tools::Rectangle GetUnion( const tools::Rectangle& rRect ) const; + inline tools::Rectangle GetIntersection( const tools::Rectangle& rRect ) const; + + void Justify(); + + bool IsInside( const Point& rPOINT ) const; + bool IsInside( const tools::Rectangle& rRect ) const; + bool IsOver( const tools::Rectangle& rRect ) const; + + void SetEmpty() { nRight = nBottom = RECT_EMPTY; } + void SetWidthEmpty() { nRight = RECT_EMPTY; } + void SetHeightEmpty() { nBottom = RECT_EMPTY; } + inline bool IsEmpty() const; + bool IsWidthEmpty() const { return nRight == RECT_EMPTY; } + bool IsHeightEmpty() const { return nBottom == RECT_EMPTY; } + + inline bool operator == ( const tools::Rectangle& rRect ) const; + inline bool operator != ( const tools::Rectangle& rRect ) const; + + inline tools::Rectangle& operator += ( const Point& rPt ); + inline tools::Rectangle& operator -= ( const Point& rPt ); + + friend inline tools::Rectangle operator + ( const tools::Rectangle& rRect, const Point& rPt ); + friend inline tools::Rectangle operator - ( const tools::Rectangle& rRect, const Point& rPt ); + + // ONE + long getX() const { return nLeft; } + long getY() const { return nTop; } + /// Returns the difference between right and left, assuming the range includes one end, but not the other. + long getWidth() const; + /// Returns the difference between bottom and top, assuming the range includes one end, but not the other. + long getHeight() const; + /// Set the left edge of the rectangle to x, preserving the width + void setX( long x ); + /// Set the top edge of the rectangle to y, preserving the height + void setY( long y ); + void setWidth( long n ) { nRight = nLeft + n; } + void setHeight( long n ) { nBottom = nTop + n; } + /// Returns the string representation of the rectangle, format is "x, y, width, height". + rtl::OString toString() const; + + /** + * Expands the rectangle in all directions by the input value. + */ + void expand(long nExpandBy); + void shrink(long nShrinkBy); + + /** + * Sanitizing variants for handling data from the outside + */ + void SaturatingSetSize(const Size& rSize); + void SaturatingSetX(long x); + void SaturatingSetY(long y); + +private: + long nLeft; + long nTop; + long nRight; + long nBottom; +}; +} + +inline tools::Rectangle::Rectangle() +{ + nLeft = nTop = 0; + nRight = nBottom = RECT_EMPTY; +} + +inline tools::Rectangle::Rectangle( const Point& rLT, const Point& rRB ) +{ + nLeft = rLT.X(); + nTop = rLT.Y(); + nRight = rRB.X(); + nBottom = rRB.Y(); +} + +inline tools::Rectangle::Rectangle( long _nLeft, long _nTop, + long _nRight, long _nBottom ) +{ + nLeft = _nLeft; + nTop = _nTop; + nRight = _nRight; + nBottom = _nBottom; +} + +inline tools::Rectangle::Rectangle( long _nLeft, long _nTop ) +{ + nLeft = _nLeft; + nTop = _nTop; + nRight = nBottom = RECT_EMPTY; +} + +inline tools::Rectangle::Rectangle( const Point& rLT, const Size& rSize ) +{ + nLeft = rLT.X(); + nTop = rLT.Y(); + nRight = rSize.Width() ? nLeft+(rSize.Width()-1) : RECT_EMPTY; + nBottom = rSize.Height() ? nTop+(rSize.Height()-1) : RECT_EMPTY; +} + +inline bool tools::Rectangle::IsEmpty() const +{ + return (nRight == RECT_EMPTY) || (nBottom == RECT_EMPTY); +} + +inline Point tools::Rectangle::TopLeft() const +{ + return Point( nLeft, nTop ); +} + +inline Point tools::Rectangle::TopRight() const +{ + return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, nTop ); +} + +inline Point tools::Rectangle::BottomLeft() const +{ + return Point( nLeft, (nBottom == RECT_EMPTY) ? nTop : nBottom ); +} + +inline Point tools::Rectangle::BottomRight() const +{ + return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, + (nBottom == RECT_EMPTY) ? nTop : nBottom ); +} + +inline Point tools::Rectangle::TopCenter() const +{ + if ( IsEmpty() ) + return Point( nLeft, nTop ); + else + return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ), + std::min( nTop, nBottom) ); +} + +inline Point tools::Rectangle::BottomCenter() const +{ + if ( IsEmpty() ) + return Point( nLeft, nTop ); + else + return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ), + std::max( nTop, nBottom) ); +} + +inline Point tools::Rectangle::LeftCenter() const +{ + if ( IsEmpty() ) + return Point( nLeft, nTop ); + else + return Point( std::min( nLeft, nRight ), nTop + (nBottom - nTop)/2 ); +} + +inline Point tools::Rectangle::RightCenter() const +{ + if ( IsEmpty() ) + return Point( nLeft, nTop ); + else + return Point( std::max( nLeft, nRight ), nTop + (nBottom - nTop)/2 ); +} + +inline Point tools::Rectangle::Center() const +{ + if ( IsEmpty() ) + return Point( nLeft, nTop ); + else + return Point( nLeft+(nRight-nLeft)/2 , nTop+(nBottom-nTop)/2 ); +} + +inline void tools::Rectangle::Move( long nHorzMove, long nVertMove ) +{ + nLeft += nHorzMove; + nTop += nVertMove; + if ( nRight != RECT_EMPTY ) + nRight += nHorzMove; + if ( nBottom != RECT_EMPTY ) + nBottom += nVertMove; +} + +inline void tools::Rectangle::SetPos( const Point& rPoint ) +{ + if ( nRight != RECT_EMPTY ) + nRight += rPoint.X() - nLeft; + if ( nBottom != RECT_EMPTY ) + nBottom += rPoint.Y() - nTop; + nLeft = rPoint.X(); + nTop = rPoint.Y(); +} + +inline long tools::Rectangle::GetWidth() const +{ + long n; + if ( nRight == RECT_EMPTY ) + n = 0; + else + { + n = nRight - nLeft; + if( n < 0 ) + n--; + else + n++; + } + + return n; +} + +inline long tools::Rectangle::GetHeight() const +{ + long n; + if ( nBottom == RECT_EMPTY ) + n = 0; + else + { + n = nBottom - nTop; + if ( n < 0 ) + n--; + else + n++; + } + + return n; +} + +inline Size tools::Rectangle::GetSize() const +{ + return Size( GetWidth(), GetHeight() ); +} + +inline tools::Rectangle tools::Rectangle::GetUnion( const tools::Rectangle& rRect ) const +{ + tools::Rectangle aTmpRect( *this ); + return aTmpRect.Union( rRect ); +} + +inline tools::Rectangle tools::Rectangle::GetIntersection( const tools::Rectangle& rRect ) const +{ + tools::Rectangle aTmpRect( *this ); + return aTmpRect.Intersection( rRect ); +} + +inline bool tools::Rectangle::operator == ( const tools::Rectangle& rRect ) const +{ + return (nLeft == rRect.nLeft ) && + (nTop == rRect.nTop ) && + (nRight == rRect.nRight ) && + (nBottom == rRect.nBottom ); +} + +inline bool tools::Rectangle::operator != ( const tools::Rectangle& rRect ) const +{ + return (nLeft != rRect.nLeft ) || + (nTop != rRect.nTop ) || + (nRight != rRect.nRight ) || + (nBottom != rRect.nBottom ); +} + +inline tools::Rectangle& tools::Rectangle::operator +=( const Point& rPt ) +{ + nLeft += rPt.X(); + nTop += rPt.Y(); + if ( nRight != RECT_EMPTY ) + nRight += rPt.X(); + if ( nBottom != RECT_EMPTY ) + nBottom += rPt.Y(); + return *this; +} + +inline tools::Rectangle& tools::Rectangle::operator -= ( const Point& rPt ) +{ + nLeft -= rPt.X(); + nTop -= rPt.Y(); + if ( nRight != RECT_EMPTY ) + nRight -= rPt.X(); + if ( nBottom != RECT_EMPTY ) + nBottom -= rPt.Y(); + return *this; +} + +namespace tools +{ +inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt ) +{ + return rRect.IsEmpty() + ? Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y() ) + : Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y(), + rRect.nRight + rPt.X(), rRect.nBottom + rPt.Y() ); +} + +inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt ) +{ + return rRect.IsEmpty() + ? Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y() ) + : Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y(), + rRect.nRight - rPt.X(), rRect.nBottom - rPt.Y() ); +} +} + +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, const tools::Rectangle& rectangle ) +{ + if (rectangle.IsEmpty()) + return stream << "EMPTY"; + else + return stream << rectangle.getWidth() << 'x' << rectangle.getHeight() + << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")"; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/globname.hxx b/include/tools/globname.hxx new file mode 100644 index 000000000..88a5e492d --- /dev/null +++ b/include/tools/globname.hxx @@ -0,0 +1,103 @@ +/* -*- 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> +#include <o3tl/cow_wrapper.hxx> + +struct SAL_WARN_UNUSED SvGUID +{ + sal_uInt32 Data1; + sal_uInt16 Data2; + sal_uInt16 Data3; + sal_uInt8 Data4[8]; +}; + +struct SAL_WARN_UNUSED ImpSvGlobalName +{ + struct SvGUID szData = {}; + + ImpSvGlobalName(const SvGUID &rData) + : szData(rData) + { + } + ImpSvGlobalName(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); + ImpSvGlobalName( const ImpSvGlobalName & rObj ); + ImpSvGlobalName() = default; + + bool operator == ( const ImpSvGlobalName & rObj ) const; +}; + +class SvStream; + +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC SvGlobalName +{ + ::o3tl::cow_wrapper< ImpSvGlobalName > pImp; + +public: + SvGlobalName(); + SvGlobalName( const SvGlobalName & rObj ) : + pImp( rObj.pImp ) + { + } + SvGlobalName( SvGlobalName && rObj ) noexcept : + pImp( std::move(rObj.pImp) ) + { + } + + 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 ); + SvGlobalName & operator = ( SvGlobalName && rObj ) noexcept; + ~SvGlobalName(); + + 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( const OUString & rId ); + OUString GetHexName() const; + + const SvGUID& GetCLSID() const { return pImp->szData; } + + // platform independent representation of a "GlobalName" + // maybe transported remotely + css::uno::Sequence < sal_Int8 > GetByteSequence() const; +}; + +#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 000000000..1d00bad71 --- /dev/null +++ b/include/tools/helpers.hxx @@ -0,0 +1,131 @@ +/* -*- 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_HELPERS_HXX +#define INCLUDED_TOOLS_HELPERS_HXX + +#include <sal/config.h> +#include <sal/types.h> +#include <o3tl/safeint.hxx> +#include <cassert> +#include <type_traits> + +template<typename T> +inline +typename std::enable_if< + std::is_signed<T>::value || std::is_floating_point<T>::value, long >::type +MinMax(T nVal, long nMin, long nMax) +{ + assert(nMin <= nMax); + if (nVal >= nMin) + { + if (nVal <= nMax) + return static_cast<long>(nVal); + else + return nMax; + } + else + { + return nMin; + } +} + +template<typename T> +inline +typename std::enable_if< + std::is_unsigned<T>::value, long >::type +MinMax(T nVal, long nMin, long nMax) +{ + assert(nMin <= nMax); + if (nMax < 0) + { + return nMax; + } + else + { + if (nMin < 0 || nVal >= static_cast<unsigned long>(nMin)) + { + if (nVal <= static_cast<unsigned long>(nMax)) + return static_cast<long>(nVal); + else + return nMax; + } + else + { + return nMin; + } + } +} + +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 long FRound( double fVal ) +{ + return fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<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; +} + +/** Convert 100th-mm to twips + + A twip is 1/20 of a point, one inch is equal to 72 points, and + one inch is 2,540 100th-mm. + + Thus: + twips = n * 72 / 2,540 / 20 + = n * 72 / 127 + + Adding 63 (half of 127) fixes truncation issues in int arithmetic. + + This formula is (n>=0) ? (n*72+63) / 127 : (n*72-63) / 127 + */ +inline sal_Int64 sanitiseMm100ToTwip(sal_Int64 n) +{ + if (n >= 0) + { + if (o3tl::checked_multiply<sal_Int64>(n, 72, n) || o3tl::checked_add<sal_Int64>(n, 63, n)) + n = SAL_MAX_INT64; + } + else + { + if (o3tl::checked_multiply<sal_Int64>(n, 72, n) || o3tl::checked_sub<sal_Int64>(n, 63, n)) + n = SAL_MIN_INT64; + } + return n / 127; // 127 is 2,540 100th-mm divided by 20pts +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/inetmime.hxx b/include/tools/inetmime.hxx new file mode 100644 index 000000000..ce0469fa1 --- /dev/null +++ b/include/tools/inetmime.hxx @@ -0,0 +1,245 @@ +/* -*- 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 <tools/debug.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( + OUString const & 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) +{ + DBG_ASSERT(rBegin && rBegin < pEnd, + "INetMIME::getUTF32Character(): Bad sequence"); + if (rBegin + 1 < pEnd && rBegin[0] >= 0xD800 && rBegin[0] <= 0xDBFF + && rBegin[1] >= 0xDC00 && rBegin[1] <= 0xDFFF) + { + sal_uInt32 nUTF32 = sal_uInt32(*rBegin++ & 0x3FF) << 10; + return (nUTF32 | (*rBegin++ & 0x3FF)) + 0x10000; + } + else + return *rBegin++; +} + + +#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 000000000..dd8073d61 --- /dev/null +++ b/include/tools/inetmsg.hxx @@ -0,0 +1,186 @@ +/* -*- 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 <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 ( + const OString& rName, const OString& rValue) + : m_aName (rName), m_aValue (rValue) + {} + + 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 ( + const OUString& 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 000000000..50b0d25f4 --- /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/line.hxx b/include/tools/line.hxx new file mode 100644 index 000000000..97cf449fc --- /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 000000000..165d8b549 --- /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 000000000..ec88bf953 --- /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/mapunit.hxx b/include/tools/mapunit.hxx new file mode 100644 index 000000000..6112bc7ef --- /dev/null +++ b/include/tools/mapunit.hxx @@ -0,0 +1,40 @@ +/* -*- 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_MAPUNIT_HXX +#define INCLUDED_TOOLS_MAPUNIT_HXX + +#include <sal/types.h> +#include <tools/UnitConversion.hxx> + +enum class MapUnit +{ + Map100thMM, Map10thMM, MapMM, MapCM, + Map1000thInch, Map100thInch, Map10thInch, MapInch, + MapPoint, MapTwip, + MapPixel, + MapSysFont, MapAppFont, + MapRelative, + LAST = MapRelative, + LASTENUMDUMMY // used as an error return +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/multisel.hxx b/include/tools/multisel.hxx new file mode 100644 index 000000000..3e06a3dce --- /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 <rtl/ustring.hxx> + +#include <vector> +#include <set> + +#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 + sal_Int32 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 sal_Int32 ImplFindSubSelection( sal_Int32 nIndex ) const; + TOOLS_DLLPRIVATE void ImplMergeSubSelections( sal_Int32 nPos1, sal_Int32 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( const OUString& 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 std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const; +public: + class TOOLS_DLLPUBLIC Iterator + { + const StringRangeEnumerator* pEnumerator; + const std::set< sal_Int32 >* pPossibleValues; + sal_Int32 nRangeIndex; + sal_Int32 nCurrent; + + friend class StringRangeEnumerator; + Iterator( const StringRangeEnumerator* i_pEnum, + const std::set< 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( const OUString& i_rInput, + sal_Int32 i_nMinNumber, + sal_Int32 i_nMaxNumber, + sal_Int32 i_nLogicalOffset = -1 + ); + + sal_Int32 size() const { return mnCount; } + Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const; + Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const; + + bool hasValue( sal_Int32 nValue, const std::set< 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( const OUString& i_rPageRange, + std::vector< sal_Int32 >& o_rPageVector, + sal_Int32 i_nMinNumber, + sal_Int32 i_nMaxNumber, + sal_Int32 i_nLogicalOffset = -1, + std::set< 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 000000000..3fa5cc0d1 --- /dev/null +++ b/include/tools/pathutils.hxx @@ -0,0 +1,74 @@ +/* -*- 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 000000000..765865b5a --- /dev/null +++ b/include/tools/poly.hxx @@ -0,0 +1,271 @@ +/* -*- 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 <tools/toolsdllapi.h> +#include <tools/gen.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(); + Polygon( sal_uInt16 nSize ); + Polygon( sal_uInt16 nPoints, const Point* pPtAry, + const PolyFlags* pFlagAry = nullptr ); + Polygon( const tools::Rectangle& rRect ); + Polygon( const tools::Rectangle& rRect, + sal_uInt32 nHorzRound, sal_uInt32 nVertRound ); + Polygon( const Point& rCenter, + long nRadX, long nRadY ); + Polygon( const tools::Rectangle& rBound, + const Point& rStart, const Point& rEnd, + PolyStyle ePolyStyle = PolyStyle::Arc, + bool bWholeCircle = 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; + + void Clear(); + + tools::Rectangle GetBoundRect() const; + bool IsInside( 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( long nHorzMove, 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, sal_uInt16 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: + PolyPolygon( sal_uInt16 nInitSize = 16 ); + PolyPolygon( const tools::Polygon& rPoly ); + 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( long nHorzMove, 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, sal_uInt16 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); +}; + +} /* 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 000000000..3f245bf08 --- /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 000000000..9573a9aff --- /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 000000000..bdfdb8928 --- /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 000000000..4ef7a6980 --- /dev/null +++ b/include/tools/simdsupport.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/. + * + */ + +// 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. + +#undef LO_SSE2_AVAILABLE +#undef LO_SSSE3_AVAILABLE +#undef LO_AVX_AVAILABLE +#undef LO_AVX2_AVAILABLE + +#if defined(_MSC_VER) // VISUAL STUDIO COMPILER + +// SSE2 is required for X64 +#if (defined(_M_X64) || defined(_M_IX86_FP) && _M_IX86_FP >= 2) +#define LO_SSE2_AVAILABLE +#endif // end SSE2 + +// compiled with /arch:AVX +#if defined(__AVX__) +#ifndef LO_SSE2_AVAILABLE +#define LO_SSE2_AVAILABLE +#endif +#define LO_SSSE3_AVAILABLE +#define LO_AVX_AVAILABLE +#endif // defined(__AVX__) + +// compiled with /arch:AVX2 +#if defined(__AVX2__) +#define LO_AVX2_AVAILABLE +#endif // defined(__AVX2__) + +#else // compiler Clang and GCC + +#if defined(__SSE2__) || defined(__x86_64__) // SSE2 is required for X64 +#define LO_SSE2_AVAILABLE +#endif // defined(__SSE2__) + +#if defined(__SSSE3__) +#define LO_SSSE3_AVAILABLE +#endif // defined(__SSSE3__) + +#if defined(__AVX__) +#define LO_AVX_AVAILABLE +#endif // defined(__AVX__) + +#if defined(__AVX2__) +#define LO_AVX2_AVAILABLE +#endif // defined(__AVX2__) + +#endif // end compiler Clang and GCC + +// If we detect any SIMD intrinsics, include the headers automatically +#if defined(LO_SSE2_AVAILABLE) +#include <emmintrin.h> +#elif defined(LO_SSSE3_AVAILABLE) +#include <tmmintrin.h> +#elif defined(LO_AVX_AVAILABLE) || defined(LO_AVX2_AVAILABLE) +#include <immintrin.h> +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/solar.h b/include/tools/solar.h new file mode 100644 index 000000000..721573287 --- /dev/null +++ b/include/tools/solar.h @@ -0,0 +1,121 @@ +/* -*- 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 + +#define DELETEZ( p ) ( delete p,p = NULL ) + +// 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 000000000..4cbe1a3e9 --- /dev/null +++ b/include/tools/stream.hxx @@ -0,0 +1,670 @@ +/* -*- 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_STREAM_HXX +#define INCLUDED_TOOLS_STREAM_HXX + +#include <tools/toolsdllapi.h> +#include <tools/lineend.hxx> +#include <tools/ref.hxx> +#include <vcl/errcode.hxx> +#include <rtl/string.hxx> +#include <o3tl/typed_flags_set.hxx> +#include <memory> + +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) + TEMPORARY = 0x0020, ///< temporary file attribute (Windows) +// 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, 0x0f3f> {}; +} + +#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 virtual 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; + SvStreamEndian m_nEndian; + 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); + + void FlushBuffer(); + void ClearError(); + void ClearBuffer(); + + // encrypt and write in blocks + std::size_t CryptAndWriteBuffer( const void* pStart, std::size_t nLen ); + 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 { return m_nEndian; } + /// 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(const OString& rStr) + { WriteBytes(rStr.getStr(), rStr.getLength()); 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 ); + SvStream& WriteCharPtr( const char* pBuf ); + + SvStream& WriteUInt32AsString( sal_uInt32 nUInt32 ); + SvStream& WriteInt32AsString( sal_Int32 nInt32 ); + + 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(); + 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( OString& rStr, sal_Int32 nMaxBytesToRead = 0xFFFE ); + bool WriteLine( const OString& 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( const OUString& 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. + */ + 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( const OUString& 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( const OUString& rStr, rtl_TextEncoding eDestCharSet ); + bool WriteUnicodeOrByteText( const OUString& 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> + void readNumberWithoutSwap(T& rDataDest) + { readNumberWithoutSwap_(&rDataDest, sizeof(rDataDest)); } + + void readNumberWithoutSwap_(void * pDataDest, int nDataSize); + + template<typename T> + void writeNumberWithoutSwap(T const & rDataSrc) + { writeNumberWithoutSwap_(&rDataSrc, sizeof(rDataSrc)); } + + 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, + const OUString& rStr, std::size_t nUnits); + +inline std::size_t write_uInt16s_FromOUString(SvStream& rStrm, + const OUString& rStr) +{ + return write_uInt16s_FromOUString(rStrm, rStr, rStr.getLength()); +} + +/// 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, + const OUString &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) +TOOLS_DLLPUBLIC std::size_t write_uInt16_lenPrefixed_uInt16s_FromOUString(SvStream& rStrm, + const OUString &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, const OString& rStr, + std::size_t nUnits) +{ + return rStrm.WriteBytes(rStr.getStr(), nUnits); +} + +inline std::size_t write_uInt8s_FromOString(SvStream& rStrm, const OString& rStr) +{ + return write_uInt8s_FromOString(rStrm, rStr, rStr.getLength()); +} + +/// 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, + const OString &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, + const OUString &rStr, + rtl_TextEncoding eEnc) +{ + return write_uInt16_lenPrefixed_uInt8s_FromOString(rStrm, OUStringToOString(rStr, eEnc)); +} + +[[nodiscard]] TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset); + +// FileStream + +class TOOLS_DLLPUBLIC SvFileStream final : public SvStream +{ +private: + std::unique_ptr<StreamData> + pInstanceData; + OUString aFilename; +#if defined(_WIN32) + sal_uInt16 nLockCounter; +#endif + 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( 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(); + std::size_t GetEndOfData() const { return nEndOfData; } + const void* GetData() { Flush(); 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; } + void SetResizeOffset( std::size_t nNewResize ) { nResize = nNewResize; } + virtual sal_uInt64 TellEnd() override { FlushBuffer(); return nEndOfData; } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/tools/svborder.hxx b/include/tools/svborder.hxx new file mode 100644 index 000000000..61e1270e1 --- /dev/null +++ b/include/tools/svborder.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_SVBORDER_HXX +#define INCLUDED_TOOLS_SVBORDER_HXX + +#include <tools/toolsdllapi.h> + +namespace tools { class Rectangle; } + +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC SvBorder +{ + long nTop, nRight, nBottom, nLeft; + +public: + SvBorder() + { + nTop = nRight = nBottom = nLeft = 0; + } + SvBorder( long nLeftP, long nTopP, long nRightP, 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; + } + long & Top() { return nTop; } + long & Right() { return nRight; } + long & Bottom() { return nBottom; } + long & Left() { return nLeft; } + long Top() const { return nTop; } + long Right() const { return nRight; } + long Bottom() const { return nBottom; } + 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 000000000..2a46d8c88 --- /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 000000000..4d1cdcff3 --- /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 000000000..414b28f72 --- /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 000000000..6c13b6f40 --- /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 000000000..1fb5f4e86 --- /dev/null +++ b/include/tools/urlobj.hxx @@ -0,0 +1,1319 @@ +/* -*- 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: +#define INET_FTP_SCHEME "ftp://" +#define INET_HTTP_SCHEME "http://" +#define INET_HTTPS_SCHEME "https://" +#define INET_FILE_SCHEME "file://" +#define INET_MAILTO_SCHEME "mailto:" +#define INET_HID_SCHEME "hid:" + +#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_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( + OUString const & rTheAbsURIRef, + EncodeMechanism eMechanism = EncodeMechanism::WasEncoded, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8); + + inline bool SetURL(OUString const & rTheAbsURIRef, + EncodeMechanism eMechanism = EncodeMechanism::WasEncoded, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8); + + bool ConcatData(INetProtocol eTheScheme, OUString const & rTheUser, + OUString const & rThePassword, + OUString const & rTheHost, sal_uInt32 nThePort, + OUString const & rThePath); + + // Smart Parsing: + + inline INetURLObject(OUString const & 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(OUString const & 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(OUString const & rTheBaseURIRef, + OUString const & rTheRelURIRef, + EncodeMechanism eEncodeMechanism = EncodeMechanism::WasEncoded, + DecodeMechanism eDecodeMechanism = DecodeMechanism::ToIUri, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8); + + static inline OUString + GetRelURL(OUString const & 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(OUString const & rTheIntURIRef, + OUString & rTheExtURIRef, + DecodeMechanism eDecodeMechanism + = DecodeMechanism::ToIUri, + rtl_TextEncoding eCharset + = RTL_TEXTENCODING_UTF8); + + static inline bool translateToInternal(OUString const & 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 OUString GetSchemeName(INetProtocol eTheScheme); + + static INetProtocol CompareProtocolScheme(OUString const & + rTheAbsURIRef); + + // 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(OUString const & rTheUser) + { return setUser(rTheUser, RTL_TEXTENCODING_UTF8); } + + inline bool SetPass(OUString const & rThePassword); + + inline bool SetUserAndPass(OUString const & rTheUser, + OUString const & 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(OUString const & 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(OUString const & 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(OUString const & 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(OUString const& 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(OUString const & 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(OUString const & 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(OUString const & 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(OUString const & 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 inline OUString encode(OUString const & 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(OUString const & rText, + DecodeMechanism eMechanism, + rtl_TextEncoding eCharset + = RTL_TEXTENCODING_UTF8); + + static inline OUString decode(OUStringBuffer const & 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(OUString const & 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(OUString const & rTheBase); + + OUString GetBase() const; + + void SetExtension(OUString const & rTheExtension); + + OUString CutExtension(); + + static bool IsCaseSensitive() { return true; } + + void changeScheme(INetProtocol eTargetScheme); + +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; } + + inline sal_Int32 clear(); + + inline sal_Int32 set(OUStringBuffer & rString, + OUString const & rSubString, + sal_Int32 nTheBegin); + + inline sal_Int32 set(OUString & rString, + OUString const & rSubString); + + inline sal_Int32 set(OUStringBuffer & rString, + OUString const & 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( + OUString const & 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( + OUString const & rTheIntURIRef, + OUString & rTheExtURIRef, DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset); + + static bool convertExtToInt( + OUString const & 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( + OUString const & rTheUser, + rtl_TextEncoding eCharset); + + bool clearPassword(); + + bool setPassword( + OUString const & rThePassword, + rtl_TextEncoding eCharset); + + // Host and Port: + + TOOLS_DLLPRIVATE static bool parseHost( + sal_Unicode const *& rBegin, sal_Unicode const * pEnd, + OUString & rCanonic); + + TOOLS_DLLPRIVATE static bool parseHostOrNetBiosName( + sal_Unicode const * pBegin, sal_Unicode const * pEnd, + EncodeMechanism eMechanism, rtl_TextEncoding eCharset, + bool bNetBiosName, OUStringBuffer* pCanonic); + + bool setHost( + OUString const & 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( + OUString const & 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( + OUString const & rTheQuery, + EncodeMechanism eMechanism, rtl_TextEncoding eCharset); + + // Fragment: + + bool clearFragment(); + + bool setFragment( + OUString const & 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 OUString encodeText( + sal_Unicode const * pBegin, sal_Unicode const * pEnd, + Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset, + bool bKeepVisibleEscapes); + + static inline OUString encodeText( + OUString const & 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 OUString INetURLObject::encodeText(OUString const & rTheText, + Part ePart, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset, + bool bKeepVisibleEscapes) +{ + return encodeText(rTheText.getStr(), + rTheText.getStr() + rTheText.getLength(), 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(OUString const & rTheAbsURIRef, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset): + m_eScheme(INetProtocol::NotValid), m_eSmartScheme(INetProtocol::Http) +{ + setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, false, + FSysStyle(0)); +} + +inline bool INetURLObject::SetURL(OUString const & rTheAbsURIRef, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return setAbsURIRef(rTheAbsURIRef, eMechanism, eCharset, false, + FSysStyle(0)); +} + +inline INetURLObject::INetURLObject(OUString const & 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(OUString const & 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(OUString const & 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(OUString const & + rTheIntURIRef, + OUString & rTheExtURIRef, + DecodeMechanism + eDecodeMechanism, + rtl_TextEncoding eCharset) +{ + return convertIntToExt(rTheIntURIRef, rTheExtURIRef, + eDecodeMechanism, eCharset); +} + +// static +inline bool INetURLObject::translateToInternal(OUString const & + rTheExtURIRef, + OUString & rTheIntURIRef, + DecodeMechanism + eDecodeMechanism, + rtl_TextEncoding eCharset) +{ + return convertExtToInt(rTheExtURIRef, rTheIntURIRef, + eDecodeMechanism, eCharset); +} + +inline bool INetURLObject::SetPass(OUString const & rThePassword) +{ + return rThePassword.isEmpty() ? + clearPassword() : + setPassword(rThePassword, RTL_TEXTENCODING_UTF8); +} + +inline bool INetURLObject::SetUserAndPass(OUString const & rTheUser, + OUString const & rThePassword) +{ + return setUser(rTheUser, RTL_TEXTENCODING_UTF8) + && (rThePassword.isEmpty() ? + clearPassword() : + setPassword(rThePassword, RTL_TEXTENCODING_UTF8)); +} + +inline bool INetURLObject::SetParam(OUString const & rTheQuery, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + if (rTheQuery.isEmpty()) + { + clearQuery(); + return false; + } + return setQuery(rTheQuery, eMechanism, eCharset); +} + +inline bool INetURLObject::SetMark(OUString const & rTheFragment, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return rTheFragment.isEmpty() ? + clearFragment() : + setFragment(rTheFragment, eMechanism, eCharset); +} + +// static +inline OUString INetURLObject::encode(OUString const & rText, Part ePart, + EncodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return encodeText(rText, ePart, eMechanism, eCharset, false); +} + +// static +inline OUString INetURLObject::decode(OUString const & rText, + DecodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return decode(rText.getStr(), rText.getStr() + rText.getLength(), + eMechanism, eCharset); +} + +inline OUString INetURLObject::decode(OUStringBuffer const & rText, + DecodeMechanism eMechanism, + rtl_TextEncoding eCharset) +{ + return decode(rText.getStr(), rText.getStr() + rText.getLength(), + 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 000000000..edf61c7dd --- /dev/null +++ b/include/tools/vcompat.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/. + * + * 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> +#include <config_options.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; +enum class StreamMode; + +class UNLESS_MERGELIBS(TOOLS_DLLPUBLIC) VersionCompat +{ + SvStream* mpRWStm; + sal_uInt32 mnCompatPos; + sal_uInt32 mnTotalSize; + StreamMode mnStmMode; + sal_uInt16 mnVersion; + + VersionCompat( const VersionCompat& ) = delete; + VersionCompat& operator=( const VersionCompat& ) { return *this; } + +public: + VersionCompat( SvStream& rStm, StreamMode nStreamMode, sal_uInt16 nVersion = 1 ); + ~VersionCompat(); + + sal_uInt16 GetVersion() const { return mnVersion; } +}; + +#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 000000000..0f9a500bb --- /dev/null +++ b/include/tools/weakbase.h @@ -0,0 +1,156 @@ +/* -*- 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* pOjbect ) : 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 ); + + /** constructs 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 ); + + /** 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 000000000..5c1645e69 --- /dev/null +++ b/include/tools/weakbase.hxx @@ -0,0 +1,155 @@ +/* -*- 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); +} + +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 + 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/wintypes.hxx b/include/tools/wintypes.hxx new file mode 100644 index 000000000..58050521c --- /dev/null +++ b/include/tools/wintypes.hxx @@ -0,0 +1,270 @@ +/* -*- 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_WINTYPES_HXX +#define INCLUDED_TOOLS_WINTYPES_HXX + +#include <sal/types.h> + +// Window-Types + +enum class WindowType : sal_uInt16 +{ + NONE = 0, + FIRST = 0x0130, // 304 + MESSBOX = FIRST, // 0 + INFOBOX , + WARNINGBOX , + ERRORBOX , + QUERYBOX , + WINDOW , + WORKWINDOW , + CONTAINER , + FLOATINGWINDOW , + DIALOG , + MODELESSDIALOG , // 10 (314) + MODALDIALOG , + CONTROL , + PUSHBUTTON , + OKBUTTON , + CANCELBUTTON , + HELPBUTTON , + IMAGEBUTTON , + MENUBUTTON , + MOREBUTTON , + SPINBUTTON , // 20 (324) + RADIOBUTTON , + CHECKBOX , + TRISTATEBOX , + EDIT , + MULTILINEEDIT , + COMBOBOX , + LISTBOX , + MULTILISTBOX , + FIXEDTEXT , + FIXEDLINE , // 30 (334) + FIXEDBITMAP , + FIXEDIMAGE , + GROUPBOX , + SCROLLBAR , + SCROLLBARBOX , + SPLITTER , + SPLITWINDOW , + SPINFIELD , + PATTERNFIELD , + NUMERICFIELD , // 40 (344) + METRICFIELD , + FORMATTEDFIELD , + CURRENCYFIELD , + DATEFIELD , + TIMEFIELD , + PATTERNBOX , + NUMERICBOX , + METRICBOX , + CURRENCYBOX , + DATEBOX , + TIMEBOX , // 50 (354) + LONGCURRENCYFIELD , + LONGCURRENCYBOX , + SCROLLWINDOW , + TOOLBOX , + DOCKINGWINDOW , + STATUSBAR , + TABPAGE , + TABCONTROL , + TABDIALOG , + BORDERWINDOW , // 60 (364) + BUTTONDIALOG , + SYSTEMCHILDWINDOW , + SLIDER , + MENUBARWINDOW , + TREELISTBOX , + HELPTEXTWINDOW , + INTROWINDOW , + LISTBOXWINDOW , + DOCKINGAREA , + RULER , // 70 (374) + CALCINPUTLINE , + HEADERBAR , + VERTICALTABCONTROL , + LAST = VERTICALTABCONTROL, + // only used in vclxtoolkit.cxx + TOOLKIT_FRAMEWINDOW = 0x1000, + TOOLKIT_SYSTEMCHILDWINDOW = 0x1001, +}; + +// Window-Bits + +typedef sal_Int64 WinBits; + +// Window-Bits for Window +WinBits const WB_CLIPCHILDREN = 0x00000001; +WinBits const WB_DIALOGCONTROL = 0x00000002; +WinBits const WB_NODIALOGCONTROL = 0x00000004; +WinBits const WB_BORDER = 0x00000008; +WinBits const WB_NOBORDER = 0x00000010; +WinBits const WB_SIZEABLE = 0x00000020; +WinBits const WB_3DLOOK = 0x00000040; +WinBits const WB_ALLOWMENUBAR = 0x00000080; + +// Window-Bits for SystemWindows +WinBits const WB_MOVEABLE = 0x00000100; +WinBits const WB_ROLLABLE = 0x00000200; +WinBits const WB_CLOSEABLE = 0x00000400; +WinBits const WB_STANDALONE = 0x00000800; +WinBits const WB_APP = 0x00001000; +WinBits const WB_SYSTEMWINDOW = SAL_CONST_INT64(0x40000000); +// warning: do not confuse WB_SYSTEMCHILDWINDOW with the SystemChildWindow class +// +// the SystemChildWindow class was there first and is a very specialized +// system child window type for plugged applications. The SystemChildWindow class +// explicitly should never use the WB_SYSTEMCHILDWINDOW WinBit +// +// WB_SYSTEMCHILDWINDOW on the other hand is to be used on system windows +// which should be created as system child windows with (more or less) +// normal event handling +WinBits const WB_SYSTEMCHILDWINDOW = SAL_CONST_INT64(0x8000000000); +WinBits const WB_SIZEMOVE = (WB_SIZEABLE | WB_MOVEABLE); + +// Standard-Window-Bits for ChildWindows +WinBits const WB_TABSTOP = 0x00000100; +WinBits const WB_NOTABSTOP = 0x00000200; +WinBits const WB_GROUP = 0x00000400; +WinBits const WB_NOGROUP = 0x00000800; +WinBits const WB_HORZ = 0x00001000; +WinBits const WB_VERT = 0x00002000; +WinBits const WB_LEFT = 0x00004000; +WinBits const WB_CENTER = 0x00008000; +WinBits const WB_RIGHT = 0x00010000; +WinBits const WB_TOP = 0x00020000; +WinBits const WB_VCENTER = 0x00040000; +WinBits const WB_BOTTOM = 0x00080000; +WinBits const WB_DRAG = 0x00100000; +WinBits const WB_SPIN = 0x00200000; +WinBits const WB_REPEAT = 0x00400000; +WinBits const WB_NOPOINTERFOCUS = 0x00800000; +WinBits const WB_WORDBREAK = 0x01000000; +WinBits const WB_NOLABEL = 0x02000000; +WinBits const WB_SORT = 0x04000000; +WinBits const WB_DROPDOWN = 0x08000000; +WinBits const WB_HIDE = SAL_CONST_INT64(0x80000000); +WinBits const WB_AUTOHSCROLL = SAL_CONST_INT64(0x10000000); +WinBits const WB_DOCKABLE = SAL_CONST_INT64(0x20000000); +WinBits const WB_AUTOVSCROLL = SAL_CONST_INT64(0x40000000); +WinBits const WB_HYPHENATION = SAL_CONST_INT64(0x800000000) | WB_WORDBREAK; +// #i93011# style bit for some child windows, that want their children checked for accelerators +WinBits const WB_CHILDDLGCTRL = SAL_CONST_INT64(0x100000000000); + +// system floating window +WinBits const WB_SYSTEMFLOATWIN = SAL_CONST_INT64(0x100000000); +WinBits const WB_INTROWIN = SAL_CONST_INT64(0x200000000); +WinBits const WB_NOSHADOW = SAL_CONST_INT64(0x400000000); +WinBits const WB_TOOLTIPWIN = SAL_CONST_INT64(0x800000000); +WinBits const WB_OWNERDRAWDECORATION = SAL_CONST_INT64(0x2000000000); +WinBits const WB_DEFAULTWIN = SAL_CONST_INT64(0x4000000000); +WinBits const WB_POPUP = SAL_CONST_INT64(0x20000000); + +WinBits const WB_HSCROLL = WB_HORZ; +WinBits const WB_VSCROLL = WB_VERT; + +// Window-Bits for PushButtons +WinBits const WB_DEFBUTTON = 0x10000000; +WinBits const WB_NOLIGHTBORDER = 0x20000000; +WinBits const WB_RECTSTYLE = 0x08000000; +WinBits const WB_SMALLSTYLE = 0x04000000; +WinBits const WB_TOGGLE = SAL_CONST_INT64(0x1000000000); +WinBits const WB_BEVELBUTTON = SAL_CONST_INT64(0x2000000000); +WinBits const WB_FLATBUTTON = SAL_CONST_INT64(0x4000000000); + +// Window-Bits for FixedText +WinBits const WB_PATHELLIPSIS = 0x00100000; +WinBits const WB_EXTRAOFFSET = 0x02000000; +WinBits const WB_NOMULTILINE = 0x10000000; + +// Window-Bits for Edit +WinBits const WB_READONLY = 0x02000000; +WinBits const WB_NOHIDESELECTION = SAL_CONST_INT64(0x1000000000); + +// Window-Bits for MultiLineEdit +WinBits const WB_IGNORETAB = 0x20000000; + +// Window-Bits for ListBox and MultiListBox +WinBits const WB_SIMPLEMODE = 0x20000000; + +// Window-Bits for FixedBitmap +WinBits const WB_SCALE = 0x08000000; + +// Window-Bits for ToolBox +WinBits const WB_SCROLL = 0x02000000; + +// Window-Bits for SplitWindow +WinBits const WB_NOSPLITDRAW = 0x01000000; + +// Standard-WinBits +WinBits const WB_STDWORK = WB_SIZEMOVE | WB_CLOSEABLE; +WinBits const WB_STDDOCKWIN = WB_DOCKABLE | WB_MOVEABLE | WB_CLOSEABLE; +WinBits const WB_STDFLOATWIN = WB_SIZEMOVE | WB_CLOSEABLE | WB_ROLLABLE; +WinBits const WB_STDDIALOG = WB_MOVEABLE | WB_CLOSEABLE; +WinBits const WB_STDMODELESS = WB_STDDIALOG; +WinBits const WB_STDMODAL = WB_STDDIALOG; +WinBits const WB_STDTABCONTROL = 0; +WinBits const WB_STDPOPUP = WB_BORDER | WB_POPUP | WB_SYSTEMWINDOW | WB_3DLOOK | WB_DIALOGCONTROL; + +// For TreeListBox +WinBits const WB_HASBUTTONS = SAL_CONST_INT64(0x000100000000); +WinBits const WB_HASLINES = SAL_CONST_INT64(0x000200000000); +WinBits const WB_HASLINESATROOT = SAL_CONST_INT64(0x000400000000); +WinBits const WB_HASBUTTONSATROOT = SAL_CONST_INT64(0x000800000000); +WinBits const WB_NOINITIALSELECTION = SAL_CONST_INT64(0x001000000000); +WinBits const WB_HIDESELECTION = SAL_CONST_INT64(0x002000000000); +// DO NOT USE: 0x008000000000, that's WB_SYSTEMCHILDWINDOW + + +enum class WindowAlign { Left, Top, Right, Bottom }; + +enum class ImageAlign { Left, Top, Right, Bottom, + LeftTop, LeftBottom, TopLeft, + TopRight, RightTop, RightBottom, + BottomLeft, BottomRight, Center }; + +enum class SymbolAlign { LEFT, RIGHT }; + +// ButtonDialog-Types + +enum class StandardButtonType +{ + OK = 0, + Cancel = 1, + Yes = 2, + No = 3, + Retry = 4, + Help = 5, + Close = 6, + More = 7, + Ignore = 8, + Abort = 9, + Less = 10, + Back = 11, + Next = 12, + Finish = 13, + Count = 14, +}; + +#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 000000000..5fc3d87e4 --- /dev/null +++ b/include/tools/wldcrd.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_WLDCRD_HXX +#define INCLUDED_TOOLS_WLDCRD_HXX + +#include <tools/toolsdllapi.h> +#include <osl/thread.h> +#include <rtl/ustring.hxx> + +class SAL_WARN_UNUSED TOOLS_DLLPUBLIC WildCard +{ +private: + OString aWildString; + char cSepSymbol; + + static bool ImpMatch( const char *pWild, const char *pStr ); + +public: + WildCard() + : aWildString('*') + , cSepSymbol('\0') + { + } + + WildCard(const OUString& rWildCard, const char cSeparator = '\0') + : aWildString(OUStringToOString(rWildCard, osl_getThreadTextEncoding())) + , cSepSymbol(cSeparator) + { + } + + OUString getGlob() const + { + return OStringToOUString(aWildString, osl_getThreadTextEncoding()); + } + + void setGlob(const OUString& rString) + { + aWildString = OUStringToOString(rString, osl_getThreadTextEncoding()); + } + + bool Matches( const OUString& 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 000000000..23922e197 --- /dev/null +++ b/include/tools/zcodec.hxx @@ -0,0 +1,78 @@ +/* -*- 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> + +#define ZCODEC_NO_COMPRESSION 0 +#define ZCODEC_DEFAULT_COMPRESSION 6 + +class SvStream; + +// The overall client call protocol is one of: +// * BeginCompression, Compress, EndCompression +// * 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; + sal_uInt8* mpInBuf; + size_t mnInBufSize; + size_t mnInToRead; + SvStream* mpOStm; + sal_uInt8* mpOutBuf; + size_t mnOutBufSize; + + 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(); + + void BeginCompression( int nCompressLevel = ZCODEC_DEFAULT_COMPRESSION, bool gzLib = false ); + long EndCompression(); + + void Compress( SvStream& rIStm, SvStream& rOStm ); + long Decompress( SvStream& rIStm, SvStream& rOStm ); + bool AttemptDecompression( SvStream& rIStm, SvStream& rOStm ); + + void Write( SvStream& rOStm, const sal_uInt8* pData, sal_uInt32 nSize ); + long Read( SvStream& rIStm, sal_uInt8* pData, sal_uInt32 nSize ); + long ReadAsynchron( SvStream& rIStm, sal_uInt8* pData, sal_uInt32 nSize ); + + void SetBreak( size_t ); + size_t GetBreak() const; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |