summaryrefslogtreecommitdiff
path: root/tools/source
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source')
-rw-r--r--tools/source/datetime/datetime.cxx117
-rw-r--r--tools/source/datetime/duration.cxx328
-rw-r--r--tools/source/datetime/tdate.cxx241
-rw-r--r--tools/source/datetime/ttime.cxx25
-rw-r--r--tools/source/debug/debug.cxx373
-rw-r--r--tools/source/fsys/fileutil.cxx7
-rw-r--r--tools/source/fsys/urlobj.cxx526
-rw-r--r--tools/source/fsys/wldcrd.cxx105
-rw-r--r--tools/source/generic/b3dtrans.cxx2
-rw-r--r--tools/source/generic/bigint.cxx715
-rw-r--r--tools/source/generic/color.cxx26
-rw-r--r--tools/source/generic/config.cxx6
-rw-r--r--tools/source/generic/fract.cxx141
-rw-r--r--tools/source/generic/gen.cxx154
-rw-r--r--tools/source/generic/line.cxx33
-rw-r--r--tools/source/generic/point.cxx17
-rw-r--r--tools/source/generic/poly.cxx136
-rw-r--r--tools/source/generic/poly2.cxx4
-rw-r--r--tools/source/inet/hostfilter.cxx31
-rw-r--r--tools/source/inet/inetmime.cxx97
-rw-r--r--tools/source/inet/inetmsg.cxx37
-rw-r--r--tools/source/inet/inetstrm.cxx10
-rw-r--r--tools/source/memtools/multisel.cxx73
-rw-r--r--tools/source/misc/extendapplicationenvironment.cxx2
-rw-r--r--tools/source/misc/fix16.cxx151
-rw-r--r--tools/source/misc/json_writer.cxx343
-rw-r--r--tools/source/misc/pathutils.cxx59
-rw-r--r--tools/source/ref/globname.cxx280
-rw-r--r--tools/source/reversemap/bestreversemap.cxx7
-rw-r--r--tools/source/stream/GenericTypeSerializer.cxx18
-rw-r--r--tools/source/stream/stream.cxx256
-rw-r--r--tools/source/stream/strmunx.cxx85
-rw-r--r--tools/source/stream/strmwnt.cxx64
-rw-r--r--tools/source/xml/XmlWalker.cxx9
-rw-r--r--tools/source/xml/XmlWriter.cxx64
-rw-r--r--tools/source/zcodec/zcodec.cxx78
36 files changed, 2165 insertions, 2455 deletions
diff --git a/tools/source/datetime/datetime.cxx b/tools/source/datetime/datetime.cxx
index 00790ff78dd4..6f9dea26c6e8 100644
--- a/tools/source/datetime/datetime.cxx
+++ b/tools/source/datetime/datetime.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <tools/datetime.hxx>
+#include <tools/duration.hxx>
#include <rtl/math.hxx>
#include <sal/log.hxx>
@@ -94,32 +95,37 @@ sal_Int64 DateTime::GetSecFromDateTime( const Date& rDate ) const
}
}
-DateTime& DateTime::operator +=( const tools::Time& rTime )
+void DateTime::NormalizeTimeRemainderAndApply( tools::Time& rTime )
{
- tools::Time aTime = *this;
- aTime += rTime;
- sal_uInt16 nHours = aTime.GetHour();
- if ( aTime.GetTime() > 0 )
+ sal_uInt16 nHours = rTime.GetHour();
+ if ( rTime.GetTime() > 0 )
{
- while ( nHours >= 24 )
+ if (nHours >= 24)
{
- Date::operator++();
- nHours -= 24;
+ AddDays( nHours / 24 );
+ nHours %= 24;
+ rTime.SetHour( nHours );
}
- aTime.SetHour( nHours );
}
- else if ( aTime.GetTime() != 0 )
+ else if ( rTime.GetTime() != 0 )
{
- while ( nHours >= 24 )
+ if (nHours >= 24)
{
- Date::operator--();
- nHours -= 24;
+ AddDays( -static_cast<sal_Int32>(nHours) / 24 );
+ nHours %= 24;
+ rTime.SetHour( nHours );
}
Date::operator--();
- aTime = Time( 24, 0, 0 )+aTime;
+ rTime = Time( 24, 0, 0 ) + rTime;
}
- tools::Time::operator=( aTime );
+ tools::Time::operator=( rTime );
+}
+DateTime& DateTime::operator +=( const tools::Time& rTime )
+{
+ tools::Time aTime = *this;
+ aTime += rTime;
+ NormalizeTimeRemainderAndApply(aTime);
return *this;
}
@@ -127,28 +133,14 @@ DateTime& DateTime::operator -=( const tools::Time& rTime )
{
tools::Time aTime = *this;
aTime -= rTime;
- sal_uInt16 nHours = aTime.GetHour();
- if ( aTime.GetTime() > 0 )
- {
- while ( nHours >= 24 )
- {
- Date::operator++();
- nHours -= 24;
- }
- aTime.SetHour( nHours );
- }
- else if ( aTime.GetTime() != 0 )
- {
- while ( nHours >= 24 )
- {
- Date::operator--();
- nHours -= 24;
- }
- Date::operator--();
- aTime = Time( 24, 0, 0 )+aTime;
- }
- tools::Time::operator=( aTime );
+ NormalizeTimeRemainderAndApply(aTime);
+ return *this;
+}
+DateTime& DateTime::operator +=( const tools::Duration& rDuration )
+{
+ AddDays(rDuration.GetDays());
+ operator+=(rDuration.GetTime());
return *this;
}
@@ -180,27 +172,19 @@ DateTime operator -( const DateTime& rDateTime, const tools::Time& rTime )
return aDateTime;
}
+DateTime operator +( const DateTime& rDateTime, const tools::Duration& rDuration )
+{
+ DateTime aDateTime(rDateTime);
+ aDateTime.AddDays( rDuration.GetDays());
+ aDateTime += rDuration.GetTime();
+ return aDateTime;
+}
+
void DateTime::AddTime( double fTimeInDays )
{
- double fInt, fFrac;
- if ( fTimeInDays < 0.0 )
- {
- fInt = ::rtl::math::approxCeil( fTimeInDays );
- fFrac = fInt <= fTimeInDays ? 0.0 : fTimeInDays - fInt;
- }
- else
- {
- fInt = ::rtl::math::approxFloor( fTimeInDays );
- fFrac = fInt >= fTimeInDays ? 0.0 : fTimeInDays - fInt;
- }
- AddDays( sal_Int32(fInt) ); // full days
- if ( fFrac )
- {
- tools::Time aTime(0); // default ctor calls system time, we don't need that
- fFrac *= ::tools::Time::nanoSecPerDay; // time expressed in nanoseconds
- aTime.MakeTimeFromNS( static_cast<sal_Int64>(fFrac) ); // method handles negative ns
- operator+=( aTime );
- }
+ // Use Duration to diminish floating point accuracy errors.
+ tools::Duration aDuration(fTimeInDays);
+ operator+=(aDuration);
}
DateTime operator +( const DateTime& rDateTime, double fTimeInDays )
@@ -210,20 +194,21 @@ DateTime operator +( const DateTime& rDateTime, double fTimeInDays )
return aDateTime;
}
-double operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 )
+tools::Duration operator -( const DateTime& rDateTime1, const DateTime& rDateTime2 )
+{
+ return tools::Duration( rDateTime2, rDateTime1);
+}
+
+// static
+double DateTime::Sub( const DateTime& rDateTime1, const DateTime& rDateTime2 )
{
- sal_Int32 nDays = static_cast<const Date&>(rDateTime1)
- - static_cast<const Date&>(rDateTime2);
- sal_Int64 nTime = rDateTime1.GetNSFromTime() - rDateTime2.GetNSFromTime();
- if ( nTime )
+ if (static_cast<const tools::Time&>(rDateTime1) != static_cast<const tools::Time&>(rDateTime2))
{
- double fTime = double(nTime);
- fTime /= ::tools::Time::nanoSecPerDay; // convert from nanoseconds to fraction
- if ( nDays < 0 && fTime > 0.0 )
- fTime = 1.0 - fTime;
- return double(nDays) + fTime;
+ // Use Duration to diminish floating point accuracy errors.
+ const tools::Duration aDuration( rDateTime2, rDateTime1);
+ return aDuration.GetInDays();
}
- return double(nDays);
+ return static_cast<const Date&>(rDateTime1) - static_cast<const Date&>(rDateTime2);
}
void DateTime::GetWin32FileDateTime( sal_uInt32 & rLower, sal_uInt32 & rUpper ) const
diff --git a/tools/source/datetime/duration.cxx b/tools/source/datetime/duration.cxx
new file mode 100644
index 000000000000..a655f016a1bc
--- /dev/null
+++ b/tools/source/datetime/duration.cxx
@@ -0,0 +1,328 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <tools/duration.hxx>
+#include <tools/datetime.hxx>
+#include <rtl/math.hxx>
+#include <o3tl/safeint.hxx>
+#include <cmath>
+
+namespace tools
+{
+Duration::Duration(const ::DateTime& rStart, const ::DateTime& rEnd)
+ : mnDays(static_cast<const Date&>(rEnd) - static_cast<const Date&>(rStart))
+{
+ SetTimeDiff(rStart, rEnd);
+}
+
+Duration::Duration(const Time& rStart, const Time& rEnd)
+{
+ const sal_uInt16 nStartHour = rStart.GetHour();
+ const sal_uInt16 nEndHour = rEnd.GetHour();
+ if (nStartHour >= 24 || nEndHour >= 24)
+ {
+ Time aEnd(rEnd);
+ if (nEndHour >= 24)
+ {
+ mnDays = (nEndHour / 24) * (aEnd.GetTime() < 0 ? -1 : 1);
+ aEnd.SetHour(nEndHour % 24);
+ }
+ Time aStart(rStart);
+ if (nStartHour >= 24)
+ {
+ mnDays -= (nStartHour / 24) * (aStart.GetTime() < 0 ? -1 : 1);
+ aStart.SetHour(nStartHour % 24);
+ }
+ SetTimeDiff(aStart, aEnd);
+ }
+ else
+ {
+ SetTimeDiff(rStart, rEnd);
+ }
+}
+
+Duration::Duration(double fTimeInDays, sal_uInt64 nAccuracyEpsilonNanoseconds)
+{
+ assert(nAccuracyEpsilonNanoseconds <= Time::nanoSecPerSec - 1);
+ double fInt, fFrac;
+ if (fTimeInDays < 0.0)
+ {
+ fInt = ::rtl::math::approxCeil(fTimeInDays);
+ fFrac = fInt <= fTimeInDays ? 0.0 : fTimeInDays - fInt;
+ }
+ else
+ {
+ fInt = ::rtl::math::approxFloor(fTimeInDays);
+ fFrac = fInt >= fTimeInDays ? 0.0 : fTimeInDays - fInt;
+ }
+ mnDays = static_cast<sal_Int32>(fInt);
+ if (fFrac)
+ {
+ fFrac *= Time::nanoSecPerDay;
+ fFrac = ::rtl::math::approxFloor(fFrac);
+ sal_Int64 nNS = static_cast<sal_Int64>(fFrac);
+ const sal_Int64 nN = nNS % Time::nanoSecPerSec;
+ if (nN)
+ {
+ const sal_uInt64 nA = std::abs(nN);
+ if (nA <= nAccuracyEpsilonNanoseconds)
+ nNS -= (nNS < 0) ? -nN : nN;
+ else if (nA >= Time::nanoSecPerSec - nAccuracyEpsilonNanoseconds)
+ {
+ const sal_Int64 nD = Time::nanoSecPerSec - nA;
+ nNS += (nNS < 0) ? -nD : nD;
+ if (std::abs(nNS) >= Time::nanoSecPerDay)
+ {
+ mnDays += nNS / Time::nanoSecPerDay;
+ nNS %= Time::nanoSecPerDay;
+ }
+ }
+ }
+ maTime.MakeTimeFromNS(nNS);
+ assert(mnDays == 0 || maTime.GetTime() == 0 || (mnDays < 0) == (nNS < 0));
+ }
+}
+
+Duration::Duration(sal_Int32 nDays, const Time& rTime)
+ : mnDays(nDays)
+{
+ assert(nDays == 0 || rTime.GetTime() == 0 || (nDays < 0) == (rTime.GetTime() < 0));
+ Normalize(rTime.GetHour(), rTime.GetMin(), rTime.GetSec(), rTime.GetNanoSec(),
+ ((nDays < 0) || (rTime.GetTime() < 0)));
+}
+
+Duration::Duration(sal_Int32 nDays, sal_uInt32 nHours, sal_uInt32 nMinutes, sal_uInt32 nSeconds,
+ sal_uInt64 nNanoseconds)
+ : mnDays(nDays)
+{
+ Normalize(nHours, nMinutes, nSeconds, nNanoseconds, nDays < 0);
+}
+
+Duration::Duration(sal_Int32 nDays, sal_Int64 nTime)
+ : maTime(nTime)
+ , mnDays(nDays)
+{
+}
+
+void Duration::Normalize(sal_uInt64 nHours, sal_uInt64 nMinutes, sal_uInt64 nSeconds,
+ sal_uInt64 nNanoseconds, bool bNegative)
+{
+ if (nNanoseconds >= Time::nanoSecPerSec)
+ {
+ nSeconds += nNanoseconds / Time::nanoSecPerSec;
+ nNanoseconds %= Time::nanoSecPerSec;
+ }
+ if (nSeconds >= Time::secondPerMinute)
+ {
+ nMinutes += nSeconds / Time::secondPerMinute;
+ nSeconds %= Time::secondPerMinute;
+ }
+ if (nMinutes >= Time::minutePerHour)
+ {
+ nHours += nMinutes / Time::minutePerHour;
+ nMinutes %= Time::minutePerHour;
+ }
+ if (nHours >= Time::hourPerDay)
+ {
+ sal_Int64 nDiff = nHours / Time::hourPerDay;
+ nHours %= Time::hourPerDay;
+ bool bOverflow = false;
+ if (bNegative)
+ {
+ nDiff = -nDiff;
+ bOverflow = (nDiff < SAL_MIN_INT32);
+ bOverflow |= o3tl::checked_add(mnDays, static_cast<sal_Int32>(nDiff), mnDays);
+ if (bOverflow)
+ mnDays = SAL_MIN_INT32;
+ }
+ else
+ {
+ bOverflow = (nDiff > SAL_MAX_INT32);
+ bOverflow |= o3tl::checked_add(mnDays, static_cast<sal_Int32>(nDiff), mnDays);
+ if (bOverflow)
+ mnDays = SAL_MAX_INT32;
+ }
+ assert(!bOverflow);
+ if (bOverflow)
+ {
+ nHours = Time::hourPerDay - 1;
+ nMinutes = Time::minutePerHour - 1;
+ nSeconds = Time::secondPerMinute - 1;
+ nNanoseconds = Time::nanoSecPerSec - 1;
+ }
+ }
+ maTime = Time(nHours, nMinutes, nSeconds, nNanoseconds);
+ if (bNegative)
+ maTime = -maTime;
+ assert(mnDays == 0 || maTime.GetTime() == 0 || (mnDays < 0) == (maTime.GetTime() < 0));
+}
+
+void Duration::ApplyTime(sal_Int64 nNS)
+{
+ if (mnDays > 0 && nNS < 0)
+ {
+ --mnDays;
+ nNS = Time::nanoSecPerDay + nNS;
+ }
+ else if (mnDays < 0 && nNS > 0)
+ {
+ ++mnDays;
+ nNS = -Time::nanoSecPerDay + nNS;
+ }
+ maTime.MakeTimeFromNS(nNS);
+ assert(mnDays == 0 || maTime.GetTime() == 0 || (mnDays < 0) == (maTime.GetTime() < 0));
+}
+
+void Duration::SetTimeDiff(const Time& rStart, const Time& rEnd)
+{
+ const sal_Int64 nNS = rEnd.GetNSFromTime() - rStart.GetNSFromTime();
+ ApplyTime(nNS);
+}
+
+Duration Duration::operator-() const
+{
+ Duration aD(-mnDays, -maTime.GetTime());
+ return aD;
+}
+
+Duration& Duration::Add(const Duration& rDuration, bool& rbOverflow)
+{
+ rbOverflow = o3tl::checked_add(mnDays, rDuration.mnDays, mnDays);
+ // Duration is always normalized, time values >= 24h don't occur.
+ sal_Int64 nNS = maTime.GetNSFromTime() + rDuration.maTime.GetNSFromTime();
+ if (nNS < -Time::nanoSecPerDay)
+ {
+ rbOverflow |= o3tl::checked_sub(mnDays, sal_Int32(1), mnDays);
+ nNS += Time::nanoSecPerDay;
+ }
+ else if (nNS > Time::nanoSecPerDay)
+ {
+ rbOverflow |= o3tl::checked_add(mnDays, sal_Int32(1), mnDays);
+ nNS -= Time::nanoSecPerDay;
+ }
+ ApplyTime(nNS);
+ return *this;
+}
+
+Duration Duration::Mult(sal_Int32 nMult, bool& rbOverflow) const
+{
+ // First try a simple calculation in nanoseconds.
+ bool bBadNS = false;
+ sal_Int64 nNS;
+ sal_Int64 nDays;
+ if (o3tl::checked_multiply(static_cast<sal_Int64>(mnDays), static_cast<sal_Int64>(nMult), nDays)
+ || o3tl::checked_multiply(nDays, Time::nanoSecPerDay, nDays)
+ || o3tl::checked_multiply(maTime.GetNSFromTime(), static_cast<sal_Int64>(nMult), nNS)
+ || o3tl::checked_add(nDays, nNS, nNS))
+ {
+ bBadNS = rbOverflow = true;
+ }
+ else
+ {
+ const sal_Int64 nD = nNS / Time::nanoSecPerDay;
+ if (nD < SAL_MIN_INT32 || SAL_MAX_INT32 < nD)
+ rbOverflow = true;
+ else
+ {
+ rbOverflow = false;
+ nNS -= nD * Time::nanoSecPerDay;
+ Duration aD(static_cast<sal_Int32>(nD), 0);
+ aD.ApplyTime(nNS);
+ return aD;
+ }
+ }
+ if (bBadNS)
+ {
+ // Simple calculation in overall nanoseconds overflowed, try with
+ // individual components.
+ const sal_uInt64 nMult64 = (nMult < 0) ? -nMult : nMult;
+ do
+ {
+ sal_uInt64 nN;
+ if (o3tl::checked_multiply(static_cast<sal_uInt64>(maTime.GetNanoSec()), nMult64, nN))
+ break;
+ sal_uInt64 nS;
+ if (o3tl::checked_multiply(static_cast<sal_uInt64>(maTime.GetSec()), nMult64, nS))
+ break;
+ sal_uInt64 nM;
+ if (o3tl::checked_multiply(static_cast<sal_uInt64>(maTime.GetMin()), nMult64, nM))
+ break;
+ sal_uInt64 nH;
+ if (o3tl::checked_multiply(static_cast<sal_uInt64>(maTime.GetHour()), nMult64, nH))
+ break;
+ sal_uInt64 nD;
+ if (o3tl::checked_multiply(
+ mnDays < 0 ? static_cast<sal_uInt64>(-static_cast<sal_Int64>(mnDays))
+ : static_cast<sal_uInt64>(mnDays),
+ nMult64, nD))
+ break;
+ if (nN > Time::nanoSecPerSec)
+ {
+ const sal_uInt64 nC = nN / Time::nanoSecPerSec;
+ if (o3tl::checked_add(nS, nC, nS))
+ break;
+ nN -= nC * Time::nanoSecPerSec;
+ }
+ if (nS > Time::secondPerMinute)
+ {
+ const sal_uInt64 nC = nS / Time::secondPerMinute;
+ if (o3tl::checked_add(nM, nC, nM))
+ break;
+ nS -= nC * Time::secondPerMinute;
+ }
+ if (nM > Time::minutePerHour)
+ {
+ const sal_uInt64 nC = nM / Time::minutePerHour;
+ if (o3tl::checked_add(nH, nC, nH))
+ break;
+ nM -= nC * Time::minutePerHour;
+ }
+ if (nH > Time::hourPerDay)
+ {
+ const sal_uInt64 nC = nH / Time::hourPerDay;
+ if (o3tl::checked_add(nD, nC, nD))
+ break;
+ nH -= nC * Time::hourPerDay;
+ }
+ if (IsNegative() ? (static_cast<sal_uInt64>(SAL_MAX_INT32) + 1) < nD
+ || -static_cast<sal_Int64>(nD) < SAL_MIN_INT32
+ : SAL_MAX_INT32 < nD)
+ break;
+
+ rbOverflow = false;
+ Time aTime(nH, nM, nS, nN);
+ if (IsNegative() == (nMult < 0))
+ {
+ Duration aD(nD, aTime.GetTime());
+ return aD;
+ }
+ else
+ {
+ Duration aD(-static_cast<sal_Int64>(nD), -aTime.GetTime());
+ return aD;
+ }
+ } while (false);
+ }
+ assert(rbOverflow);
+ if (IsNegative() == (nMult < 0))
+ {
+ Duration aD(SAL_MAX_INT32, 0);
+ aD.ApplyTime(Time::nanoSecPerDay - 1);
+ return aD;
+ }
+ else
+ {
+ Duration aD(SAL_MIN_INT32, 0);
+ aD.ApplyTime(-(Time::nanoSecPerDay - 1));
+ return aD;
+ }
+}
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
index 979611333813..e20add430353 100644
--- a/tools/source/datetime/tdate.cxx
+++ b/tools/source/datetime/tdate.cxx
@@ -21,25 +21,7 @@
#include <com/sun/star/util/DateTime.hpp>
#include <systemdatetime.hxx>
-
-const sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31 };
-
-// Once upon a time the number of days we internally handled was limited to
-// MAX_DAYS 3636532. That changed with a full 16-bit year.
-// Assuming the first valid positive date in a proleptic Gregorian calendar is
-// 0001-01-01, this resulted in an end date of 9957-06-26.
-// Hence we documented that years up to and including 9956 are handled.
-/* XXX: it is unclear history why this value was chosen, the representable
- * 9999-12-31 would be 3652060 days from 0001-01-01. Even 9998-12-31 to
- * distinguish from a maximum possible date would be 3651695.
- * There is connectivity/source/commontools/dbconversion.cxx that still has the
- * same value to calculate with css::util::Date */
-/* XXX can that dbconversion cope with years > 9999 or negative years at all?
- * Database fields may be limited to positive 4 digits. */
-
-const sal_Int32 MIN_DAYS = -11968265; // -32768-01-01
-const sal_Int32 MAX_DAYS = 11967900; // 32767-12-31
+#include <comphelper/date.hxx>
namespace
{
@@ -47,54 +29,6 @@ namespace
const sal_Int16 kYearMax = SAL_MAX_INT16;
const sal_Int16 kYearMin = SAL_MIN_INT16;
-// Days until start of year from zero, so month and day of month can be added.
-// year 1 => 0 days, year 2 => 365 days, ...
-// year -1 => -366 days, year -2 => -731 days, ...
-sal_Int32 ImpYearToDays( sal_Int16 nYear )
-{
- assert( nYear != 0 );
- sal_Int32 nOffset;
- sal_Int32 nYr;
- if (nYear < 0)
- {
- nOffset = -366;
- nYr = nYear + 1;
- }
- else
- {
- nOffset = 0;
- nYr = nYear - 1;
- }
- return nOffset + nYr*365 + nYr/4 - nYr/100 + nYr/400;
-}
-
-bool ImpIsLeapYear( sal_Int16 nYear )
-{
- // Leap years BCE are -1, -5, -9, ...
- // See
- // https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar#Usage
- // https://en.wikipedia.org/wiki/0_(year)#History_of_astronomical_usage
- assert( nYear != 0 );
- if (nYear < 0)
- nYear = -nYear - 1;
- return ( ( ((nYear % 4) == 0) && ((nYear % 100) != 0) ) ||
- ( (nYear % 400) == 0 ) );
-}
-
-// All callers must have sanitized or normalized month and year values!
-sal_uInt16 ImplDaysInMonth( sal_uInt16 nMonth, sal_Int16 nYear )
-{
- if ( nMonth != 2 )
- return aDaysInMonth[nMonth-1];
- else
- {
- if (ImpIsLeapYear(nYear))
- return aDaysInMonth[nMonth-1] + 1;
- else
- return aDaysInMonth[nMonth-1];
- }
-}
-
}
void Date::setDateFromDMY( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear )
@@ -130,7 +64,7 @@ sal_uInt16 Date::GetDaysInMonth( sal_uInt16 nMonth, sal_Int16 nYear )
nMonth = 1;
else if (12 < nMonth)
nMonth = 12;
- return ImplDaysInMonth( nMonth, nYear);
+ return comphelper::date::getDaysInMonth( nMonth, nYear);
}
sal_Int32 Date::GetAsNormalizedDays() const
@@ -138,71 +72,33 @@ sal_Int32 Date::GetAsNormalizedDays() const
// This is a very common datum we often calculate from.
if (mnDate == 18991230) // 1899-12-30
{
- assert(DateToDays( GetDay(), GetMonth(), GetYear() ) == 693594);
+#ifndef NDEBUG
+ static sal_Int32 nDays = DateToDays( GetDay(), GetMonth(), GetYear());
+ assert(nDays == 693594);
+#endif
return 693594;
}
- return DateToDays( GetDay(), GetMonth(), GetYear() );
+ // Not calling comphelper::date::convertDateToDaysNormalizing() here just
+ // avoids a second check on null-date handling like above.
+ sal_uInt16 nDay = GetDay();
+ sal_uInt16 nMonth = GetMonth();
+ sal_Int16 nYear = GetYear();
+ comphelper::date::normalize( nDay, nMonth, nYear);
+ return comphelper::date::convertDateToDays( nDay, nMonth, nYear);
}
sal_Int32 Date::DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear )
{
- Normalize( nDay, nMonth, nYear);
-
- sal_Int32 nDays = ImpYearToDays(nYear);
- for( sal_uInt16 i = 1; i < nMonth; i++ )
- nDays += ImplDaysInMonth(i,nYear);
- nDays += nDay;
- return nDays;
+ return comphelper::date::convertDateToDaysNormalizing( nDay, nMonth, nYear);
}
static Date lcl_DaysToDate( sal_Int32 nDays )
{
- if ( nDays <= MIN_DAYS )
- return Date( 1, 1, kYearMin );
- if ( nDays >= MAX_DAYS )
- return Date( 31, 12, kYearMax );
-
- // Day 0 is -0001-12-31, day 1 is 0001-01-01
- const sal_Int16 nSign = (nDays <= 0 ? -1 : 1);
- sal_Int32 nTempDays;
- sal_Int32 i = 0;
- bool bCalc;
-
+ sal_uInt16 nDay;
+ sal_uInt16 nMonth;
sal_Int16 nYear;
- do
- {
- nYear = static_cast<sal_Int16>((nDays / 365) - (i * nSign));
- if (nYear == 0)
- nYear = nSign;
- nTempDays = nDays - ImpYearToDays(nYear);
- bCalc = false;
- if ( nTempDays < 1 )
- {
- i += nSign;
- bCalc = true;
- }
- else
- {
- if ( nTempDays > 365 )
- {
- if ( (nTempDays != 366) || !ImpIsLeapYear( nYear ) )
- {
- i -= nSign;
- bCalc = true;
- }
- }
- }
- }
- while ( bCalc );
-
- sal_uInt16 nMonth = 1;
- while ( nTempDays > ImplDaysInMonth( nMonth, nYear ) )
- {
- nTempDays -= ImplDaysInMonth( nMonth, nYear );
- ++nMonth;
- }
-
- return Date( static_cast<sal_uInt16>(nTempDays), nMonth, nYear );
+ comphelper::date::convertDaysToDate( nDays, nDay, nMonth, nYear);
+ return Date( nDay, nMonth, nYear);
}
Date::Date( DateInitSystem )
@@ -269,7 +165,7 @@ void Date::AddYears( sal_Int16 nAddYears )
}
SetYear( nYear );
- if (GetMonth() == 2 && GetDay() == 29 && !ImpIsLeapYear( nYear))
+ if (GetMonth() == 2 && GetDay() == 29 && !comphelper::date::isLeapYear( nYear))
SetDay(28);
}
@@ -306,7 +202,7 @@ sal_uInt16 Date::GetDayOfYear() const
Normalize( nDay, nMonth, nYear);
for( sal_uInt16 i = 1; i < nMonth; i++ )
- nDay += ::ImplDaysInMonth( i, nYear );
+ nDay += comphelper::date::getDaysInMonth( i, nYear );
return nDay;
}
@@ -403,13 +299,13 @@ sal_uInt16 Date::GetDaysInMonth() const
sal_Int16 nYear = GetYear();
Normalize( nDay, nMonth, nYear);
- return ImplDaysInMonth( nMonth, nYear );
+ return comphelper::date::getDaysInMonth( nMonth, nYear );
}
bool Date::IsLeapYear() const
{
sal_Int16 nYear = GetYear();
- return ImpIsLeapYear( nYear );
+ return comphelper::date::isLeapYear( nYear );
}
bool Date::IsValidAndGregorian() const
@@ -420,7 +316,7 @@ bool Date::IsValidAndGregorian() const
if ( !nMonth || (nMonth > 12) )
return false;
- if ( !nDay || (nDay > ImplDaysInMonth( nMonth, nYear )) )
+ if ( !nDay || (nDay > comphelper::date::getDaysInMonth( nMonth, nYear )) )
return false;
else if ( nYear <= 1582 )
{
@@ -437,19 +333,13 @@ bool Date::IsValidAndGregorian() const
bool Date::IsValidDate() const
{
- return IsValidDate( GetDay(), GetMonth(), GetYear());
+ return comphelper::date::isValidDate( GetDay(), GetMonth(), GetYear());
}
//static
bool Date::IsValidDate( sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear )
{
- if (nYear == 0)
- return false;
- if ( !nMonth || (nMonth > 12) )
- return false;
- if ( !nDay || (nDay > ImplDaysInMonth( nMonth, nYear )) )
- return false;
- return true;
+ return comphelper::date::isValidDate( nDay, nMonth, nYear);
}
bool Date::IsEndOfMonth() const
@@ -460,7 +350,8 @@ bool Date::IsEndOfMonth() const
//static
bool Date::IsEndOfMonth(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear)
{
- return IsValidDate(nDay, nMonth, nYear) && ImplDaysInMonth(nMonth, nYear) == nDay;
+ return comphelper::date::isValidDate(nDay, nMonth, nYear)
+ && comphelper::date::getDaysInMonth(nMonth, nYear) == nDay;
}
void Date::Normalize()
@@ -478,83 +369,7 @@ void Date::Normalize()
//static
bool Date::Normalize( sal_uInt16 & rDay, sal_uInt16 & rMonth, sal_Int16 & rYear )
{
- if (IsValidDate( rDay, rMonth, rYear))
- return false;
-
- if (rDay == 0 && rMonth == 0 && rYear == 0)
- return false; // empty date
-
- if (rDay == 0)
- {
- if (rMonth == 0)
- ; // nothing, handled below
- else
- --rMonth;
- // Last day of month is determined at the end.
- }
-
- if (rMonth > 12)
- {
- rYear += rMonth / 12;
- rMonth = rMonth % 12;
- if (rYear == 0)
- rYear = 1;
- }
- if (rMonth == 0)
- {
- --rYear;
- if (rYear == 0)
- rYear = -1;
- rMonth = 12;
- }
-
- if (rYear < 0)
- {
- sal_uInt16 nDays;
- while (rDay > (nDays = ImplDaysInMonth( rMonth, rYear)))
- {
- rDay -= nDays;
- if (rMonth > 1)
- --rMonth;
- else
- {
- if (rYear == kYearMin)
- {
- rDay = 1;
- rMonth = 1;
- return true;
- }
- --rYear;
- rMonth = 12;
- }
- }
- }
- else
- {
- sal_uInt16 nDays;
- while (rDay > (nDays = ImplDaysInMonth( rMonth, rYear)))
- {
- rDay -= nDays;
- if (rMonth < 12)
- ++rMonth;
- else
- {
- if (rYear == kYearMax)
- {
- rDay = 31;
- rMonth = 12;
- return true;
- }
- ++rYear;
- rMonth = 1;
- }
- }
- }
-
- if (rDay == 0)
- rDay = ImplDaysInMonth( rMonth, rYear);
-
- return true;
+ return comphelper::date::normalize( rDay, rMonth, rYear);
}
void Date::AddDays( sal_Int32 nDays )
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
index c6c89c934886..fcfa2e080e99 100644
--- a/tools/source/datetime/ttime.cxx
+++ b/tools/source/datetime/ttime.cxx
@@ -125,6 +125,18 @@ void tools::Time::init( sal_uInt32 nHour, sal_uInt32 nMin, sal_uInt32 nSec, sal_
nHour += nMin / minInHour;
nMin %= minInHour;
+ // 922337 * HOUR_MASK = 9223370000000000000 largest possible value, 922338
+ // would be -9223364073709551616.
+ assert(HOUR_MASK * nHour >= 0 && "use tools::Duration with days instead!");
+ if (HOUR_MASK * nHour < 0)
+ nHour = 922337;
+
+ // But as is, GetHour() retrieves only sal_uInt16. Though retrieving in
+ // nanoseconds or milliseconds might be possible this is all crap.
+ assert(nHour <= SAL_MAX_UINT16 && "use tools::Duration with days instead!");
+ if (nHour > SAL_MAX_UINT16)
+ nHour = SAL_MAX_UINT16;
+
// construct time
nTime = nNanoSec +
nSec * SEC_MASK +
@@ -412,17 +424,17 @@ Time tools::Time::GetUTCOffset()
{
nTime = time( nullptr );
localtime_r( &nTime, &aTM );
- sal_Int32 nLocalTime = mktime( &aTM );
+ auto nLocalTime = mktime( &aTM );
#if defined(__sun)
// Solaris gmtime_r() seems not to handle daylight saving time
// flags correctly
- nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
+ auto nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
#elif defined( LINUX )
// Linux mktime() seems not to handle tm_isdst correctly
- sal_Int32 nUTC = nLocalTime - aTM.tm_gmtoff;
+ auto nUTC = nLocalTime - aTM.tm_gmtoff;
#else
gmtime_r( &nTime, &aTM );
- sal_Int32 nUTC = mktime( &aTM );
+ auto nUTC = mktime( &aTM );
#endif
nCacheTicks = nTicks;
nCacheSecOffset = (nLocalTime-nUTC) / 60;
@@ -477,11 +489,12 @@ sal_uInt64 tools::Time::GetMonotonicTicks()
#if defined(_POSIX_TIMERS)
struct timespec currentTime;
clock_gettime( CLOCK_MONOTONIC, &currentTime );
- nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_nsec / 1000;
+ nMicroSeconds
+ = static_cast<sal_uInt64>(currentTime.tv_sec) * 1000 * 1000 + currentTime.tv_nsec / 1000;
#else
struct timeval currentTime;
gettimeofday( &currentTime, nullptr );
- nMicroSeconds = currentTime.tv_sec * 1000 * 1000 + currentTime.tv_usec;
+ nMicroSeconds = static_cast<sal_uInt64>(currentTime.tv_sec) * 1000 * 1000 + currentTime.tv_usec;
#endif
#endif // __MACH__
return nMicroSeconds;
diff --git a/tools/source/debug/debug.cxx b/tools/source/debug/debug.cxx
index 82406a3624ff..197ba2450493 100644
--- a/tools/source/debug/debug.cxx
+++ b/tools/source/debug/debug.cxx
@@ -17,49 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
-#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
-#include <com/sun/star/configuration/backend/MalformedDataException.hpp>
-#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
-#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
-#include <com/sun/star/deployment/DependencyException.hpp>
-#include <com/sun/star/deployment/DeploymentException.hpp>
-#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
-#include <com/sun/star/document/UndoFailedException.hpp>
-#include <com/sun/star/lang/IllegalArgumentException.hpp>
-#include <com/sun/star/lang/WrappedTargetException.hpp>
-#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
-#include <com/sun/star/ldap/LdapGenericException.hpp>
-#include <com/sun/star/script/BasicErrorException.hpp>
-#include <com/sun/star/script/CannotConvertException.hpp>
-#include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
-#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
-#include <com/sun/star/sdbc/SQLException.hpp>
-#include <com/sun/star/system/SystemShellExecuteException.hpp>
-#include <com/sun/star/task/ErrorCodeIOException.hpp>
-#include <com/sun/star/ucb/CommandFailedException.hpp>
-#include <com/sun/star/ucb/ContentCreationException.hpp>
-#include <com/sun/star/ucb/MissingPropertiesException.hpp>
-#include <com/sun/star/ucb/NameClashException.hpp>
-#include <com/sun/star/ucb/InteractiveIOException.hpp>
-#include <com/sun/star/util/MalformedNumberFormatException.hpp>
-#include <com/sun/star/xml/dom/DOMException.hpp>
-#include <com/sun/star/xml/sax/SAXException.hpp>
-#include <com/sun/star/xml/sax/SAXParseException.hpp>
-#include <comphelper/anytostring.hxx>
#include <tools/debug.hxx>
#include <sal/log.hxx>
-#include <osl/thread.h>
-#include <rtl/strbuf.hxx>
-
-#include <cstdlib>
-#include <typeinfo>
-
-#include <tools/diagnose_ex.h>
-
-#if defined __GLIBCXX__
-#include <cxxabi.h>
-#endif
namespace {
@@ -95,336 +54,4 @@ void DbgTestSolarMutex()
aDebugData.pDbgTestSolarMutex();
}
-static void exceptionToStringImpl(OStringBuffer& sMessage, const css::uno::Any & caught)
-{
- auto toOString = [](OUString const & s) {
- return OUStringToOString( s, osl_getThreadTextEncoding() );
- };
- sMessage.append(toOString(caught.getValueTypeName()));
- css::uno::Exception exception;
- caught >>= exception;
- if ( !exception.Message.isEmpty() )
- {
- sMessage.append(" message: ");
- sMessage.append(toOString(exception.Message));
- }
-/* TODO FIXME (see https://gerrit.libreoffice.org/#/c/83245/)
- if ( exception.Context.is() )
- {
- const char* pContext = typeid( *exception.Context ).name();
-#if defined __GLIBCXX__
- // demangle the type name, not necessary under windows, we already get demangled names there
- int status;
- pContext = abi::__cxa_demangle( pContext, nullptr, nullptr, &status);
-#endif
- sMessage.append(" context: ");
- sMessage.append(pContext);
-#if defined __GLIBCXX__
- std::free(const_cast<char *>(pContext));
-#endif
- }
-*/
- {
- css::configuration::CorruptedConfigurationException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" details: ");
- sMessage.append(toOString(specialized.Details));
- }
- }
- {
- css::configuration::InvalidBootstrapFileException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" BootstrapFileURL: ");
- sMessage.append(toOString(specialized.BootstrapFileURL));
- }
- }
- {
- css::configuration::MissingBootstrapFileException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" BootstrapFileURL: ");
- sMessage.append(toOString(specialized.BootstrapFileURL));
- }
- }
- {
- css::configuration::backend::MalformedDataException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.ErrorDetails));
- }
- }
- {
- css::configuration::backend::BackendSetupException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.BackendException));
- }
- }
- {
- css::deployment::DependencyException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" UnsatisfiedDependencies: ");
- sMessage.append(toOString(comphelper::anyToString(css::uno::Any(specialized.UnsatisfiedDependencies))));
- }
- }
- {
- css::deployment::DeploymentException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.Cause));
- }
- }
- {
- css::document::CorruptedFilterConfigurationException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Details: ");
- sMessage.append(toOString(specialized.Details));
- }
- }
- {
- css::document::UndoFailedException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Reason: ");
- sMessage.append(toOString(comphelper::anyToString(specialized.Reason)));
- }
- }
- {
- css::lang::IllegalArgumentException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" ArgumentPosition: ");
- sMessage.append(static_cast<sal_Int32>(specialized.ArgumentPosition));
- }
- }
- {
- css::lang::WrappedTargetException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.TargetException));
- }
- }
- {
- css::lang::WrappedTargetRuntimeException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.TargetException));
- }
- }
- {
- css::ldap::LdapGenericException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" ErrorCode: ");
- sMessage.append(specialized.ErrorCode);
- }
- }
- {
- css::script::BasicErrorException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" ErrorCode: ");
- sMessage.append(specialized.ErrorCode);
- sMessage.append(" ErrorMessageArgument: ");
- sMessage.append(toOString(specialized.ErrorMessageArgument));
- }
- }
- {
- css::script::CannotConvertException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" DestinationTypeClass: ");
- sMessage.append(toOString(comphelper::anyToString(css::uno::Any(specialized.DestinationTypeClass))));
- sMessage.append(" Reason: ");
- sMessage.append(specialized.Reason);
- sMessage.append(" ArgumentIndex: ");
- sMessage.append(specialized.ArgumentIndex);
- }
- }
- {
- css::script::provider::ScriptErrorRaisedException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" scriptName: ");
- sMessage.append(toOString(specialized.scriptName));
- sMessage.append(" language: ");
- sMessage.append(toOString(specialized.language));
- sMessage.append(" lineNum: ");
- sMessage.append(specialized.lineNum);
- }
- }
- {
- css::script::provider::ScriptExceptionRaisedException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" exceptionType: ");
- sMessage.append(toOString(specialized.exceptionType));
- }
- }
- {
- css::script::provider::ScriptFrameworkErrorException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" scriptName: ");
- sMessage.append(toOString(specialized.scriptName));
- sMessage.append(" language: ");
- sMessage.append(toOString(specialized.language));
- sMessage.append(" errorType: ");
- sMessage.append(specialized.errorType);
- }
- }
- {
- css::sdbc::SQLException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" SQLState: ");
- sMessage.append(toOString(specialized.SQLState));
- sMessage.append(" ErrorCode: ");
- sMessage.append(specialized.ErrorCode);
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString(specialized.NextException));
- }
- }
- {
- css::system::SystemShellExecuteException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" PosixError: ");
- sMessage.append(specialized.PosixError);
- }
- }
- {
- css::task::ErrorCodeIOException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" errcode: ");
- sMessage.append( specialized.ErrCode );
- }
- }
- {
- css::ucb::CommandFailedException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n Reason: ");
- sMessage.append(exceptionToString( specialized.Reason ));
- }
- }
- {
- css::ucb::ContentCreationException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" eError: ");
- sMessage.append(toOString(comphelper::anyToString( css::uno::Any(specialized.eError) )));
- }
- }
- {
- css::ucb::MissingPropertiesException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Properties: ");
- sMessage.append(toOString(comphelper::anyToString( css::uno::Any(specialized.Properties) )));
- }
- }
- {
- css::ucb::NameClashException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Name: ");
- sMessage.append(toOString( specialized.Name ));
- }
- }
- {
- css::util::MalformedNumberFormatException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" CheckPos: ");
- sMessage.append( specialized.CheckPos );
- }
- }
- {
- css::xml::dom::DOMException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Code: ");
- sMessage.append(toOString(comphelper::anyToString( css::uno::Any(specialized.Code) )));
- }
- }
- {
- css::xml::dom::DOMException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Code: ");
- sMessage.append(toOString(comphelper::anyToString( css::uno::Any(specialized.Code) )));
- }
- }
- {
- css::xml::sax::SAXException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append("\n wrapped: ");
- sMessage.append(exceptionToString( specialized.WrappedException ));
- }
- }
- {
- css::xml::sax::SAXParseException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" PublicId: ");
- sMessage.append(toOString( specialized.PublicId ));
- sMessage.append(" SystemId: ");
- sMessage.append(toOString( specialized.SystemId ));
- sMessage.append(" LineNumber: ");
- sMessage.append( specialized.LineNumber );
- sMessage.append(" ColumnNumber: ");
- sMessage.append( specialized.ColumnNumber );
- }
- }
- {
- css::ucb::InteractiveIOException specialized;
- if ( caught >>= specialized )
- {
- sMessage.append(" Code: ");
- sMessage.append( static_cast<sal_Int32>(specialized.Code) );
- }
- }
-}
-
-OString exceptionToString(const css::uno::Any & caught)
-{
- OStringBuffer sMessage(512);
- exceptionToStringImpl(sMessage, caught);
- return sMessage.makeStringAndClear();
-}
-
-void DbgUnhandledException(const css::uno::Any & caught, const char* currentFunction, const char* fileAndLineNo,
- const char* area, const char* explanatory)
-{
- OStringBuffer sMessage( 512 );
- sMessage.append( "DBG_UNHANDLED_EXCEPTION in " );
- sMessage.append(currentFunction);
- if (explanatory)
- {
- sMessage.append("\n when: ");
- sMessage.append(explanatory);
- }
- sMessage.append(" exception: ");
- exceptionToStringImpl(sMessage, caught);
-
- if (area == nullptr)
- area = "legacy.osl";
-
- SAL_DETAIL_LOG_FORMAT(
- SAL_DETAIL_ENABLE_LOG_WARN, SAL_DETAIL_LOG_LEVEL_WARN,
- area, fileAndLineNo, "%s", sMessage.getStr());
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/fileutil.cxx b/tools/source/fsys/fileutil.cxx
index ec20e0a513bf..0e3512e5a160 100644
--- a/tools/source/fsys/fileutil.cxx
+++ b/tools/source/fsys/fileutil.cxx
@@ -10,6 +10,7 @@
#include <tools/fileutil.hxx>
#if defined _WIN32
#include <osl/file.hxx>
+#include <rtl/uri.hxx>
#include <o3tl/char16_t2wchar_t.hxx>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -29,7 +30,11 @@ OUString UNCToDavURL(LPCWSTR sUNC)
bufURL = std::make_unique<wchar_t[]>(nSize);
nResult = DavGetHTTPFromUNCPath(sUNC, bufURL.get(), &nSize);
}
- return nResult == ERROR_SUCCESS ? OUString(o3tl::toU(bufURL.get())) : OUString();
+ // looks like on different Windowses this may or may not be URL encoded?
+ return nResult == ERROR_SUCCESS
+ ? ::rtl::Uri::encode(OUString(o3tl::toU(bufURL.get())), rtl_UriCharClassUric,
+ rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8)
+ : OUString();
}
#endif
}
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index 8c3d2845eab2..b1e3073f39b4 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -45,6 +45,7 @@
#include <com/sun/star/uno/Sequence.hxx>
#include <comphelper/base64.hxx>
+#include <comphelper/string.hxx>
using namespace css;
@@ -291,7 +292,7 @@ int INetURLObject::SubString::compare(SubString const & rOther,
struct INetURLObject::SchemeInfo
{
- rtl::OUStringConstExpr m_sScheme;
+ OUString m_sScheme;
char const * m_pPrefix;
bool m_bAuthority;
bool m_bUser;
@@ -317,36 +318,37 @@ struct INetURLObject::PrefixInfo
inline INetURLObject::SchemeInfo const &
INetURLObject::getSchemeInfo(INetProtocol eTheScheme)
{
- static constexpr OUStringLiteral EMPTY = u"";
- static constexpr OUStringLiteral FTP = u"ftp";
- static constexpr OUStringLiteral HTTP = u"http";
- static constexpr OUStringLiteral FILE1 = u"file"; // because FILE is already defined
- static constexpr OUStringLiteral MAILTO = u"mailto";
- static constexpr OUStringLiteral VND_WEBDAV = u"vnd.sun.star.webdav";
- static constexpr OUStringLiteral PRIVATE = u"private";
- static constexpr OUStringLiteral VND_HELP = u"vnd.sun.star.help";
- static constexpr OUStringLiteral HTTPS = u"https";
- static constexpr OUStringLiteral SLOT = u"slot";
- static constexpr OUStringLiteral MACRO = u"macro";
- static constexpr OUStringLiteral JAVASCRIPT = u"javascript";
- static constexpr OUStringLiteral DATA = u"data";
- static constexpr OUStringLiteral CID = u"cid";
- static constexpr OUStringLiteral VND_HIER = u"vnd.sun.star.hier";
- static constexpr OUStringLiteral UNO = u".uno";
- static constexpr OUStringLiteral COMPONENT = u".component";
- static constexpr OUStringLiteral VND_PKG = u"vnd.sun.star.pkg";
- static constexpr OUStringLiteral LDAP = u"ldap";
- static constexpr OUStringLiteral DB = u"db";
- static constexpr OUStringLiteral VND_CMD = u"vnd.sun.star.cmd";
- static constexpr OUStringLiteral TELNET = u"telnet";
- static constexpr OUStringLiteral VND_EXPAND = u"vnd.sun.star.expand";
- static constexpr OUStringLiteral VND_TDOC = u"vnd.sun.star.tdoc";
- static constexpr OUStringLiteral SMB = u"smb";
- static constexpr OUStringLiteral HID = u"hid";
- static constexpr OUStringLiteral SFTP = u"sftp";
- static constexpr OUStringLiteral VND_CMIS = u"vnd.libreoffice.cmis";
-
- static o3tl::enumarray<INetProtocol, SchemeInfo> const map = {
+ static constexpr OUString EMPTY = u""_ustr;
+ static constexpr OUString FTP = u"ftp"_ustr;
+ static constexpr OUString HTTP = u"http"_ustr;
+ static constexpr OUString FILE1 = u"file"_ustr; // because FILE is already defined
+ static constexpr OUString MAILTO = u"mailto"_ustr;
+ static constexpr OUString VND_WEBDAV = u"vnd.sun.star.webdav"_ustr;
+ static constexpr OUString PRIVATE = u"private"_ustr;
+ static constexpr OUString VND_HELP = u"vnd.sun.star.help"_ustr;
+ static constexpr OUString HTTPS = u"https"_ustr;
+ static constexpr OUString SLOT = u"slot"_ustr;
+ static constexpr OUString MACRO = u"macro"_ustr;
+ static constexpr OUString JAVASCRIPT = u"javascript"_ustr;
+ static constexpr OUString DATA = u"data"_ustr;
+ static constexpr OUString CID = u"cid"_ustr;
+ static constexpr OUString VND_HIER = u"vnd.sun.star.hier"_ustr;
+ static constexpr OUString UNO = u".uno"_ustr;
+ static constexpr OUString COMPONENT = u".component"_ustr;
+ static constexpr OUString VND_PKG = u"vnd.sun.star.pkg"_ustr;
+ static constexpr OUString LDAP = u"ldap"_ustr;
+ static constexpr OUString DB = u"db"_ustr;
+ static constexpr OUString VND_CMD = u"vnd.sun.star.cmd"_ustr;
+ static constexpr OUString TELNET = u"telnet"_ustr;
+ static constexpr OUString VND_EXPAND = u"vnd.sun.star.expand"_ustr;
+ static constexpr OUString VND_TDOC = u"vnd.sun.star.tdoc"_ustr;
+ static constexpr OUString SMB = u"smb"_ustr;
+ static constexpr OUString HID = u"hid"_ustr;
+ static constexpr OUString SFTP = u"sftp"_ustr;
+ static constexpr OUString VND_CMIS = u"vnd.libreoffice.cmis"_ustr;
+
+ static o3tl::enumarray<INetProtocol, SchemeInfo> constexpr map = {
+ // [-loplugin:redundantfcast]:
SchemeInfo{
EMPTY, "", false, false, false, false, false, false, false, false},
SchemeInfo{
@@ -616,6 +618,7 @@ std::unique_ptr<SvMemoryStream> memoryStream(
std::unique_ptr<SvMemoryStream> s(
new SvMemoryStream(b.get(), length, StreamMode::READ));
s->ObjectOwnsMemory(true);
+ // coverity[leaked_storage : FALSE] - belongs to SvMemoryStream s at this point
b.release();
return s;
}
@@ -646,10 +649,10 @@ std::unique_ptr<SvMemoryStream> INetURLObject::getData() const
else if (sURLPath.matchIgnoreAsciiCase(";base64,", nCharactersSkipped))
{
nCharactersSkipped += strlen(";base64,");
- OUString sBase64Data = sURLPath.copy( nCharactersSkipped );
+ std::u16string_view sBase64Data = sURLPath.subView( nCharactersSkipped );
css::uno::Sequence< sal_Int8 > aDecodedData;
if (comphelper::Base64::decodeSomeChars(aDecodedData, sBase64Data)
- == sBase64Data.getLength())
+ == sBase64Data.size())
{
return memoryStream(
aDecodedData.getArray(), aDecodedData.getLength());
@@ -719,14 +722,14 @@ OUString parseScheme(
}
-bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
+bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef,
EncodeMechanism eMechanism,
rtl_TextEncoding eCharset,
bool bSmart,
FSysStyle eStyle)
{
- sal_Unicode const * pPos = rTheAbsURIRef.getStr();
- sal_Unicode const * pEnd = pPos + rTheAbsURIRef.getLength();
+ sal_Unicode const * pPos = rTheAbsURIRef.data();
+ sal_Unicode const * pEnd = pPos + rTheAbsURIRef.size();
setInvalid();
@@ -806,6 +809,17 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
eMechanism = EncodeMechanism::All;
nFragmentDelimiter = 0x80000000;
}
+ else if (eStyle & FSysStyle::Dos
+ && pEnd - p1 >= 6
+ && p1[0] == '\\' && p1[1] == '\\' && p1[2] == '?' && p1[3] == '\\'
+ && rtl::isAsciiAlpha(p1[4])
+ && p1[5] == ':'
+ && (pEnd - p1 == 6 || p1[6] == '/' || p1[6] == '\\'))
+ {
+ m_eScheme = INetProtocol::File; // 8th, 9th
+ eMechanism = EncodeMechanism::All;
+ nFragmentDelimiter = 0x80000000;
+ }
else if (pEnd - p1 >= 2 && p1[0] == '/' && p1[1] == '/')
{
p1 += 2;
@@ -825,6 +839,14 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
&& p1[1] == '\\')
{
p1 += 2;
+ if (pEnd - p1 >= 6 && p1[0] == '?' && p1[1] == '\\' && p1[5] == '\\'
+ && rtl::toAsciiLowerCase(p1[2]) == 'u'
+ && rtl::toAsciiLowerCase(p1[3]) == 'n'
+ && rtl::toAsciiLowerCase(p1[4]) == 'c')
+ {
+ p1 += 6; // "\\?\UNC\Servername\..."
+ }
+
sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
p1, pEnd - p1, '\\');
sal_Unicode const * pe = n == -1 ? pEnd : p1 + n;
@@ -869,8 +891,34 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
aSynScheme = parseScheme(&p1, pEnd, nFragmentDelimiter);
if (!aSynScheme.isEmpty())
{
- m_eScheme = INetProtocol::Generic;
- pPos = p1;
+ if (bSmart && m_eSmartScheme != m_eScheme && p1 != pEnd && rtl::isAsciiDigit(*p1))
+ {
+ // rTheAbsURIRef doesn't define a known scheme (handled by the "if (pPrefix)"
+ // branch above); but a known scheme is defined in m_eSmartScheme. If this
+ // scheme may have a port in authority component, then avoid misinterpreting
+ // URLs like www.foo.bar:123/baz as using unknown "www.foo.bar" scheme with
+ // 123/baz rootless path. For now, do not try to handle possible colons in
+ // user information, require such ambiguous URLs to have explicit scheme part.
+ // Also ignore possibility of empty port.
+ const SchemeInfo& rInfo = getSchemeInfo(m_eSmartScheme);
+ if (rInfo.m_bAuthority && rInfo.m_bPort)
+ {
+ // Make sure that all characters from colon to [/?#] or to EOL are digits.
+ // Or maybe make it simple, and just assume that "xyz:1..." is more likely
+ // to be host "xyz" and port "1...", than scheme "xyz" and path "1..."?
+ sal_Unicode const* p2 = p1 + 1;
+ while (p2 != pEnd && rtl::isAsciiDigit(*p2))
+ ++p2;
+ if (p2 == pEnd || *p2 == '/' || *p2 == '?' || *p2 == '#')
+ m_eScheme = m_eSmartScheme;
+ }
+ }
+
+ if (m_eScheme == INetProtocol::NotValid)
+ {
+ m_eScheme = INetProtocol::Generic;
+ pPos = p1;
+ }
}
}
@@ -887,7 +935,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
}
if (m_eScheme != INetProtocol::Generic) {
- aSynScheme = static_cast<const OUString&>(getSchemeInfo().m_sScheme);
+ aSynScheme = getSchemeInfo().m_sScheme;
}
m_aScheme.set(m_aAbsURIRef, aSynScheme, m_aAbsURIRef.getLength());
m_aAbsURIRef.append(':');
@@ -930,7 +978,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
PART_AUTHORITY, eCharset, false);
}
m_aHost.set(m_aAbsURIRef,
- aSynAuthority.makeStringAndClear(),
+ aSynAuthority,
m_aAbsURIRef.getLength());
// misusing m_aHost to store the authority
break;
@@ -966,7 +1014,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
return false;
}
m_aHost.set(m_aAbsURIRef,
- aSynAuthority.makeStringAndClear(),
+ aSynAuthority,
m_aAbsURIRef.getLength());
// misusing m_aHost to store the authority
}
@@ -1007,7 +1055,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
else
{
m_aUser.set(m_aAbsURIRef,
- aSynUser.makeStringAndClear(),
+ aSynUser,
m_aAbsURIRef.getLength());
m_aAbsURIRef.append("@");
++pPos;
@@ -1030,7 +1078,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
return false;
}
m_aHost.set(m_aAbsURIRef,
- aSynAuthority.makeStringAndClear(),
+ aSynAuthority,
m_aAbsURIRef.getLength());
// misusing m_aHost to store the authority
break;
@@ -1132,6 +1180,16 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
&& pPos[1] == '\\')
{
sal_Unicode const * p1 = pPos + 2;
+ sal_Unicode const * pHostPortTentativeBegin = p1;
+ if (pEnd - p1 >= 6 && p1[0] == '?' && p1[1] == '\\' && p1[5] == '\\'
+ && rtl::toAsciiLowerCase(p1[2]) == 'u'
+ && rtl::toAsciiLowerCase(p1[3]) == 'n'
+ && rtl::toAsciiLowerCase(p1[4]) == 'c')
+ {
+ p1 += 6; // "\\?\UNC\Servername\..."
+ pHostPortTentativeBegin = p1;
+ }
+
sal_Unicode const * pe = p1;
while (pe < pEnd && *pe != '\\' &&
*pe != nFragmentDelimiter)
@@ -1146,7 +1204,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
)
{
m_aAbsURIRef.append("//");
- pHostPortBegin = pPos + 2;
+ pHostPortBegin = pHostPortTentativeBegin;
pHostPortEnd = pe;
pPos = pe;
nSegmentDelimiter = '\\';
@@ -1164,18 +1222,26 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
// becomes
// "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
// replacing "\" by "/" within <*path>
- if (eStyle & FSysStyle::Dos
- && pEnd - pPos >= 2
- && rtl::isAsciiAlpha(pPos[0])
- && pPos[1] == ':'
- && (pEnd - pPos == 2
- || pPos[2] == '/'
- || pPos[2] == '\\'))
+ if (eStyle & FSysStyle::Dos)
{
- m_aAbsURIRef.append("//");
- nAltSegmentDelimiter = '\\';
- bSkippedInitialSlash = true;
- break;
+ sal_Unicode const* p1 = pPos;
+ if (pEnd - p1 >= 4 && p1[0] == '\\' && p1[1] == '\\' && p1[2] == '?'
+ && p1[3] == '\\')
+ p1 += 4; // "\\?\c:\..."
+
+ if (pEnd - p1 >= 2
+ && rtl::isAsciiAlpha(p1[0])
+ && p1[1] == ':'
+ && (pEnd - p1 == 2
+ || p1[2] == '/'
+ || p1[2] == '\\'))
+ {
+ pPos = p1;
+ m_aAbsURIRef.append("//");
+ nAltSegmentDelimiter = '\\';
+ bSkippedInitialSlash = true;
+ break;
+ }
}
// 9th Production (any):
@@ -1314,8 +1380,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
appendUCS4(aSynUser, nUTF32, eEscapeType, ePart,
eCharset, false);
}
- m_aUser.set(m_aAbsURIRef, aSynUser.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aUser.set(m_aAbsURIRef, aSynUser, m_aAbsURIRef.getLength());
if (bHasAuth)
{
if (bSupportsPassword)
@@ -1331,8 +1396,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
appendUCS4(aSynAuth, nUTF32, eEscapeType,
ePart, eCharset, false);
}
- m_aAuth.set(m_aAbsURIRef, aSynAuth.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aAuth.set(m_aAbsURIRef, aSynAuth, m_aAbsURIRef.getLength());
}
else
{
@@ -1352,8 +1416,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
appendUCS4(aSynAuth, nUTF32, eEscapeType,
ePart, eCharset, false);
}
- m_aAuth.set(m_aAbsURIRef, aSynAuth.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aAuth.set(m_aAbsURIRef, aSynAuth, m_aAbsURIRef.getLength());
}
}
if (pHostPortBegin)
@@ -1444,8 +1507,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
appendUCS4(aSynQuery, nUTF32, eEscapeType,
PART_URIC, eCharset, true);
}
- m_aQuery.set(m_aAbsURIRef, aSynQuery.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aQuery.set(m_aAbsURIRef, aSynQuery, m_aAbsURIRef.getLength());
}
// Parse #<fragment>
@@ -1461,8 +1523,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef,
appendUCS4(aSynFragment, nUTF32, eEscapeType, PART_URIC,
eCharset, true);
}
- m_aFragment.set(m_aAbsURIRef, aSynFragment.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aFragment.set(m_aAbsURIRef, aSynFragment, m_aAbsURIRef.getLength());
}
if (pPos != pEnd)
@@ -1557,12 +1618,35 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef,
q += 2;
sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
q, pEnd - q, '\\');
- sal_Unicode const * qe = n == -1 ? pEnd : q + n;
- if (parseHostOrNetBiosName(
- q, qe, EncodeMechanism::All, RTL_TEXTENCODING_DONTKNOW,
- true, nullptr))
+ if (n == 1 && q[0] == '?')
+ {
+ // "\\?\c:\..." or "\\?\UNC\servername\..."
+ q += 2;
+ if (pEnd - q >= 2
+ && rtl::isAsciiAlpha(q[0])
+ && q[1] == ':'
+ && (pEnd - q == 2 || q[2] == '/' || q[2] == '\\'))
+ {
+ bFSys = true; // 2nd, 3rd
+ }
+ else if (pEnd - q >= 4
+ && q[3] == '\\'
+ && rtl::toAsciiLowerCase(q[0]) == 'u'
+ && rtl::toAsciiLowerCase(q[1]) == 'n'
+ && rtl::toAsciiLowerCase(q[2]) == 'c')
+ {
+ q += 4; // Check if it's 1st below
+ }
+ }
+ if (!bFSys)
{
- bFSys = true; // 1st
+ sal_Unicode const * qe = n == -1 ? pEnd : q + n;
+ if (parseHostOrNetBiosName(
+ q, qe, EncodeMechanism::All, RTL_TEXTENCODING_DONTKNOW,
+ true, nullptr))
+ {
+ bFSys = true; // 1st
+ }
}
}
if (bFSys)
@@ -1645,7 +1729,7 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef,
// is empty ("") in that case, so take the scheme from m_aAbsURIRef
if (m_eScheme != INetProtocol::Generic)
{
- aSynAbsURIRef.append(getSchemeInfo().m_sScheme.asView());
+ aSynAbsURIRef.append(getSchemeInfo().m_sScheme);
}
else
{
@@ -1875,7 +1959,7 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef,
}
}
- INetURLObject aNewURI(aSynAbsURIRef.makeStringAndClear());
+ INetURLObject aNewURI(aSynAbsURIRef);
if (aNewURI.HasError())
{
// Detect cases where a relative input could not be made absolute
@@ -2038,15 +2122,13 @@ bool INetURLObject::convertAbsToRel(OUString const & rTheAbsURIRef,
// to the new relative URL:
if (aSubject.m_aQuery.isPresent())
{
- aSynRelURIRef.append('?');
- aSynRelURIRef.append(aSubject.decode(aSubject.m_aQuery,
- eDecodeMechanism, eCharset));
+ aSynRelURIRef.append("?"
+ + aSubject.decode(aSubject.m_aQuery, eDecodeMechanism, eCharset));
}
if (aSubject.m_aFragment.isPresent())
{
- aSynRelURIRef.append('#');
- aSynRelURIRef.append(aSubject.decode(aSubject.m_aFragment,
- eDecodeMechanism, eCharset));
+ aSynRelURIRef.append("#"
+ + aSubject.decode(aSubject.m_aFragment, eDecodeMechanism, eCharset));
}
rTheRelURIRef = aSynRelURIRef.makeStringAndClear();
@@ -2059,8 +2141,9 @@ bool INetURLObject::convertIntToExt(std::u16string_view rTheIntURIRef,
DecodeMechanism eDecodeMechanism,
rtl_TextEncoding eCharset)
{
- OUString aSynExtURIRef(encodeText(rTheIntURIRef, PART_VISIBLE,
- EncodeMechanism::NotCanonical, eCharset, true));
+ OUStringBuffer aSynExtURIRef(256);
+ encodeText(aSynExtURIRef, rTheIntURIRef, PART_VISIBLE,
+ EncodeMechanism::NotCanonical, eCharset, true);
sal_Unicode const * pBegin = aSynExtURIRef.getStr();
sal_Unicode const * pEnd = pBegin + aSynExtURIRef.getLength();
sal_Unicode const * p = pBegin;
@@ -2068,8 +2151,7 @@ bool INetURLObject::convertIntToExt(std::u16string_view rTheIntURIRef,
bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::Internal;
if (bConvert)
{
- aSynExtURIRef =
- aSynExtURIRef.replaceAt(0, p - pBegin,
+ comphelper::string::replaceAt(aSynExtURIRef, 0, p - pBegin,
OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
}
rTheExtURIRef = decode(aSynExtURIRef, eDecodeMechanism, eCharset);
@@ -2082,8 +2164,9 @@ bool INetURLObject::convertExtToInt(std::u16string_view rTheExtURIRef,
DecodeMechanism eDecodeMechanism,
rtl_TextEncoding eCharset)
{
- OUString aSynIntURIRef(encodeText(rTheExtURIRef, PART_VISIBLE,
- EncodeMechanism::NotCanonical, eCharset, true));
+ OUStringBuffer aSynIntURIRef(256);
+ encodeText(aSynIntURIRef, rTheExtURIRef, PART_VISIBLE,
+ EncodeMechanism::NotCanonical, eCharset, true);
sal_Unicode const * pBegin = aSynIntURIRef.getStr();
sal_Unicode const * pEnd = pBegin + aSynIntURIRef.getLength();
sal_Unicode const * p = pBegin;
@@ -2091,9 +2174,8 @@ bool INetURLObject::convertExtToInt(std::u16string_view rTheExtURIRef,
bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::External;
if (bConvert)
{
- aSynIntURIRef =
- aSynIntURIRef.replaceAt(0, p - pBegin,
- OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
+ comphelper::string::replaceAt(aSynIntURIRef, 0, p - pBegin,
+ OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
}
rTheIntURIRef = decode(aSynIntURIRef, eDecodeMechanism, eCharset);
return bConvert;
@@ -2262,8 +2344,9 @@ bool INetURLObject::setUser(std::u16string_view rTheUser,
return false;
}
- OUString aNewUser(encodeText(rTheUser, PART_USER_PASSWORD,
- EncodeMechanism::WasEncoded, eCharset, false));
+ OUStringBuffer aNewUser;
+ encodeText(aNewUser, rTheUser, PART_USER_PASSWORD,
+ EncodeMechanism::WasEncoded, eCharset, false);
sal_Int32 nDelta;
if (m_aUser.isPresent())
nDelta = m_aUser.set(m_aAbsURIRef, aNewUser);
@@ -2317,8 +2400,9 @@ bool INetURLObject::setPassword(std::u16string_view rThePassword,
{
if (!getSchemeInfo().m_bPassword)
return false;
- OUString aNewAuth(encodeText(rThePassword, PART_USER_PASSWORD,
- EncodeMechanism::WasEncoded, eCharset, false));
+ OUStringBuffer aNewAuth;
+ encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD,
+ EncodeMechanism::WasEncoded, eCharset, false);
sal_Int32 nDelta;
if (m_aAuth.isPresent())
nDelta = m_aAuth.set(m_aAbsURIRef, aNewAuth);
@@ -2831,63 +2915,47 @@ bool INetURLObject::parseHostOrNetBiosName(
EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bNetBiosName,
OUStringBuffer* pCanonic)
{
+ if (pBegin >= pEnd)
+ return true;
sal_Int32 nOriginalCanonicLength = pCanonic ? pCanonic->getLength() : 0;
- if (pBegin < pEnd)
+ if (sal_Unicode const* p = pBegin; parseHost(p, pEnd, pCanonic) && p == pEnd)
+ return true;
+ if (pCanonic)
+ pCanonic->setLength(nOriginalCanonicLength); // discard parseHost results
+ if (!bNetBiosName)
+ return false;
+ while (pBegin < pEnd)
{
- sal_Unicode const * p = pBegin;
- if (!parseHost(p, pEnd, pCanonic) || p != pEnd)
+ EscapeType eEscapeType;
+ switch (sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, eMechanism, eCharset, eEscapeType))
{
- if (bNetBiosName)
- {
- OUStringBuffer buf;
- while (pBegin < pEnd)
+ default:
+ if (INetMIME::isVisible(nUTF32))
{
- EscapeType eEscapeType;
- sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd,
- eMechanism, eCharset,
- eEscapeType);
- if (!INetMIME::isVisible(nUTF32))
- {
- if (pCanonic)
- pCanonic->setLength(nOriginalCanonicLength);
- return false;
- }
- if (!rtl::isAsciiAlphanumeric(nUTF32))
- switch (nUTF32)
- {
- case '"':
- case '*':
- case '+':
- case ',':
- case '/':
- case ':':
- case ';':
- case '<':
- case '=':
- case '>':
- case '?':
- case '[':
- case '\\':
- case ']':
- case '`':
- case '|':
- return false;
- }
- if (pCanonic != nullptr) {
- appendUCS4(
- buf, nUTF32, eEscapeType, PART_URIC,
- eCharset, true);
- }
+ if (pCanonic)
+ appendUCS4(*pCanonic, nUTF32, eEscapeType, PART_URIC, eCharset, true);
+ break;
}
- if (pCanonic)
- pCanonic->append(buf);
- }
- else
- {
+ [[fallthrough]];
+ case '"':
+ case '*':
+ case '+':
+ case ',':
+ case '/':
+ case ':':
+ case ';':
+ case '<':
+ case '=':
+ case '>':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '`':
+ case '|':
if (pCanonic)
pCanonic->setLength(nOriginalCanonicLength);
return false;
- }
}
}
return true;
@@ -2904,8 +2972,7 @@ bool INetURLObject::setHost(std::u16string_view rTheHost,
{
case INetProtocol::File:
{
- OUString sTemp(aSynHost.toString());
- if (sTemp.equalsIgnoreAsciiCase("localhost"))
+ if (OUString::unacquired(aSynHost).equalsIgnoreAsciiCase("localhost"))
{
aSynHost.setLength(0);
}
@@ -2926,7 +2993,7 @@ bool INetURLObject::setHost(std::u16string_view rTheHost,
aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(),
EncodeMechanism::WasEncoded, eCharset, bNetBiosName, &aSynHost))
return false;
- sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear());
+ sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost);
m_aPort += nDelta;
m_aPath += nDelta;
m_aQuery += nDelta;
@@ -2976,7 +3043,8 @@ bool INetURLObject::parsePath(INetProtocol eScheme,
case INetProtocol::Https:
case INetProtocol::Smb:
case INetProtocol::Cmis:
- if (pPos < pEnd && *pPos != '/' && *pPos != nFragmentDelimiter)
+ if (pPos < pEnd && *pPos != '/' && *pPos != nQueryDelimiter
+ && *pPos != nFragmentDelimiter)
goto failed;
while (pPos < pEnd && *pPos != nQueryDelimiter
&& *pPos != nFragmentDelimiter)
@@ -3191,18 +3259,18 @@ failed:
return false;
}
-bool INetURLObject::setPath(OUString const & rThePath,
+bool INetURLObject::setPath(std::u16string_view rThePath,
EncodeMechanism eMechanism,
rtl_TextEncoding eCharset)
{
OUStringBuffer aSynPath(256);
- sal_Unicode const * p = rThePath.getStr();
- sal_Unicode const * pEnd = p + rThePath.getLength();
+ sal_Unicode const * p = rThePath.data();
+ sal_Unicode const * pEnd = p + rThePath.size();
if (!parsePath(m_eScheme, &p, pEnd, eMechanism, eCharset, false,
'/', 0x80000000, 0x80000000, 0x80000000, aSynPath)
|| p != pEnd)
return false;
- sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear());
+ sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath);
m_aQuery += nDelta;
m_aFragment += nDelta;
return true;
@@ -3344,16 +3412,17 @@ bool INetURLObject::insertName(std::u16string_view rTheName,
}
OUStringBuffer aNewPath(256);
- aNewPath.append(pPathBegin, pPrefixEnd - pPathBegin);
- aNewPath.append('/');
- aNewPath.append(encodeText(rTheName, PART_PCHAR,
- eMechanism, eCharset, true));
+ aNewPath.append(
+ OUString::Concat(std::u16string_view(pPathBegin, pPrefixEnd - pPathBegin))
+ + "/");
+ encodeText(aNewPath, rTheName, PART_PCHAR,
+ eMechanism, eCharset, true);
if (bInsertSlash) {
aNewPath.append('/');
}
aNewPath.append(pSuffixBegin, pPathEnd - pSuffixBegin);
- return setPath(aNewPath.makeStringAndClear(), EncodeMechanism::NotCanonical,
+ return setPath(aNewPath, EncodeMechanism::NotCanonical,
RTL_TEXTENCODING_UTF8);
}
@@ -3375,8 +3444,9 @@ bool INetURLObject::setQuery(std::u16string_view rTheQuery,
{
if (!getSchemeInfo().m_bQuery)
return false;
- OUString aNewQuery(encodeText(rTheQuery, PART_URIC,
- eMechanism, eCharset, true));
+ OUStringBuffer aNewQuery;
+ encodeText(aNewQuery, rTheQuery, PART_URIC,
+ eMechanism, eCharset, true);
sal_Int32 nDelta;
if (m_aQuery.isPresent())
nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery);
@@ -3408,8 +3478,9 @@ bool INetURLObject::setFragment(std::u16string_view rTheFragment,
{
if (HasError())
return false;
- OUString aNewFragment(encodeText(rTheFragment, PART_URIC,
- eMechanism, eCharset, true));
+ OUStringBuffer aNewFragment;
+ encodeText(aNewFragment, rTheFragment, PART_URIC,
+ eMechanism, eCharset, true);
if (m_aFragment.isPresent())
m_aFragment.set(m_aAbsURIRef, aNewFragment);
else
@@ -3432,22 +3503,21 @@ bool INetURLObject::hasDosVolume(FSysStyle eStyle) const
}
// static
-OUString INetURLObject::encodeText(sal_Unicode const * pBegin,
- sal_Unicode const * pEnd,
- Part ePart, EncodeMechanism eMechanism,
- rtl_TextEncoding eCharset,
- bool bKeepVisibleEscapes)
+void INetURLObject::encodeText( OUStringBuffer& rOutputBuffer,
+ sal_Unicode const * pBegin,
+ sal_Unicode const * pEnd,
+ Part ePart, EncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ bool bKeepVisibleEscapes)
{
- OUStringBuffer aResult(256);
while (pBegin < pEnd)
{
EscapeType eEscapeType;
sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd,
eMechanism, eCharset, eEscapeType);
- appendUCS4(aResult, nUTF32, eEscapeType, ePart,
+ appendUCS4(rOutputBuffer, nUTF32, eEscapeType, ePart,
eCharset, bKeepVisibleEscapes);
}
- return aResult.makeStringAndClear();
}
// static
@@ -3536,7 +3606,7 @@ INetURLObject::getAbbreviated(
// is empty ("") in that case, so take the scheme from m_aAbsURIRef
if (m_eScheme != INetProtocol::Generic)
{
- aBuffer.append(getSchemeInfo().m_sScheme.asView());
+ aBuffer.append(getSchemeInfo().m_sScheme);
}
else
{
@@ -3596,9 +3666,7 @@ INetURLObject::getAbbreviated(
OUStringBuffer aResult(aBuffer);
if (pSuffixEnd != pBegin)
aResult.append("...");
- aResult.append(aSegment);
- aResult.append(aTrailer);
- aResult.append(aRest);
+ aResult.append(aSegment + aTrailer + aRest);
if (rStringWidth->
queryStringWidth(aResult.makeStringAndClear())
<= nWidth)
@@ -3633,12 +3701,10 @@ INetURLObject::getAbbreviated(
eMechanism,
eCharset));
pPrefixBegin = p;
- OUStringBuffer aResult(aBuffer);
- aResult.append(aSegment);
+ OUStringBuffer aResult(aBuffer + aSegment);
if (pPrefixBegin != pEnd)
aResult.append("...");
- aResult.append(aTrailer);
- aResult.append(aRest);
+ aResult.append(aTrailer + aRest);
if (rStringWidth->
queryStringWidth(aResult.makeStringAndClear())
<= nWidth)
@@ -3670,13 +3736,11 @@ INetURLObject::getAbbreviated(
eCharset));
if (m_aQuery.isPresent())
{
- aBuffer.append('?');
- aBuffer.append(decode(m_aQuery, eMechanism, eCharset));
+ aBuffer.append("?" + decode(m_aQuery, eMechanism, eCharset));
}
if (m_aFragment.isPresent())
{
- aBuffer.append('#');
- aBuffer.append(decode(m_aFragment, eMechanism, eCharset));
+ aBuffer.append("#" + decode(m_aFragment, eMechanism, eCharset));
}
if (!aBuffer.isEmpty())
{
@@ -3711,7 +3775,7 @@ bool INetURLObject::operator ==(INetURLObject const & rObject) const
if (m_eScheme != rObject.m_eScheme)
return false;
if (m_eScheme == INetProtocol::NotValid)
- return m_aAbsURIRef.toString() == rObject.m_aAbsURIRef.toString();
+ return std::u16string_view(m_aAbsURIRef) == std::u16string_view(rObject.m_aAbsURIRef);
if ((m_aScheme.compare(
rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef)
!= 0)
@@ -3764,14 +3828,14 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
std::u16string_view rThePassword,
std::u16string_view rTheHost,
sal_uInt32 nThePort,
- OUString const & rThePath)
+ std::u16string_view rThePath)
{
setInvalid();
m_eScheme = eTheScheme;
if (HasError() || m_eScheme == INetProtocol::Generic)
return false;
m_aAbsURIRef.setLength(0);
- m_aAbsURIRef.append(getSchemeInfo().m_sScheme.asView());
+ m_aAbsURIRef.append(getSchemeInfo().m_sScheme);
m_aAbsURIRef.append(':');
if (getSchemeInfo().m_bAuthority)
{
@@ -3781,10 +3845,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
{
if (!rTheUser.empty())
{
- m_aUser.set(m_aAbsURIRef,
- encodeText(rTheUser, PART_USER_PASSWORD,
- EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false),
- m_aAbsURIRef.getLength());
+ OUStringBuffer aNewUser;
+ encodeText(aNewUser, rTheUser, PART_USER_PASSWORD,
+ EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false);
+ m_aUser.set(m_aAbsURIRef, aNewUser, m_aAbsURIRef.getLength());
bUserInfo = true;
}
}
@@ -3798,10 +3862,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
if (getSchemeInfo().m_bPassword)
{
m_aAbsURIRef.append(':');
- m_aAuth.set(m_aAbsURIRef,
- encodeText(rThePassword, PART_USER_PASSWORD,
- EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false),
- m_aAbsURIRef.getLength());
+ OUStringBuffer aNewAuth;
+ encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD,
+ EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false);
+ m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aAbsURIRef.getLength());
bUserInfo = true;
}
else
@@ -3820,8 +3884,7 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
{
case INetProtocol::File:
{
- OUString sTemp(aSynHost.toString());
- if (sTemp.equalsIgnoreAsciiCase( "localhost" ))
+ if (OUString::unacquired(aSynHost).equalsIgnoreAsciiCase( "localhost" ))
{
aSynHost.setLength(0);
}
@@ -3852,8 +3915,7 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
setInvalid();
return false;
}
- m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aHost.set(m_aAbsURIRef, aSynHost, m_aAbsURIRef.getLength());
if (nThePort != 0)
{
if (getSchemeInfo().m_bPort)
@@ -3877,8 +3939,8 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
}
}
OUStringBuffer aSynPath(256);
- sal_Unicode const * p = rThePath.getStr();
- sal_Unicode const * pEnd = p + rThePath.getLength();
+ sal_Unicode const * p = rThePath.data();
+ sal_Unicode const * pEnd = p + rThePath.size();
if (!parsePath(m_eScheme, &p, pEnd, EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false, '/',
0x80000000, 0x80000000, 0x80000000, aSynPath)
|| p != pEnd)
@@ -3886,13 +3948,12 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme,
setInvalid();
return false;
}
- m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear(),
- m_aAbsURIRef.getLength());
+ m_aPath.set(m_aAbsURIRef, aSynPath, m_aAbsURIRef.getLength());
return true;
}
// static
-OUString INetURLObject::GetAbsURL(OUString const & rTheBaseURIRef,
+OUString INetURLObject::GetAbsURL(std::u16string_view rTheBaseURIRef,
OUString const & rTheRelURIRef,
EncodeMechanism eEncodeMechanism,
DecodeMechanism eDecodeMechanism,
@@ -3920,7 +3981,7 @@ OUString INetURLObject::getExternalURL() const
{
OUString aTheExtURIRef;
translateToExternal(
- m_aAbsURIRef.toString(), aTheExtURIRef);
+ m_aAbsURIRef, aTheExtURIRef);
return aTheExtURIRef;
}
@@ -3955,11 +4016,10 @@ const OUString & INetURLObject::GetSchemeName(INetProtocol eTheScheme)
}
// static
-INetProtocol INetURLObject::CompareProtocolScheme(OUString const &
- rTheAbsURIRef)
+INetProtocol INetURLObject::CompareProtocolScheme(std::u16string_view aTheAbsURIRef)
{
- sal_Unicode const * p = rTheAbsURIRef.getStr();
- PrefixInfo const * pPrefix = getPrefix(p, p + rTheAbsURIRef.getLength());
+ sal_Unicode const * p = aTheAbsURIRef.data();
+ PrefixInfo const * pPrefix = getPrefix(p, p + aTheAbsURIRef.size());
return pPrefix ? pPrefix->m_eScheme : INetProtocol::NotValid;
}
@@ -3973,8 +4033,7 @@ OUString INetURLObject::GetHostPort(DecodeMechanism eMechanism,
OUStringBuffer aHostPort(decode(m_aHost, eMechanism, eCharset));
if (m_aPort.isPresent())
{
- aHostPort.append(':');
- aHostPort.append(decode(m_aPort, eMechanism, eCharset));
+ aHostPort.append(":" + decode(m_aPort, eMechanism, eCharset));
}
return aHostPort.makeStringAndClear();
}
@@ -4049,7 +4108,7 @@ bool INetURLObject::removeSegment(sal_Int32 nIndex, bool bIgnoreFinalSlash)
aNewPath.append('/');
}
- return setPath(aNewPath.makeStringAndClear(), EncodeMechanism::NotCanonical,
+ return setPath(aNewPath, EncodeMechanism::NotCanonical,
RTL_TEXTENCODING_UTF8);
}
@@ -4094,12 +4153,11 @@ bool INetURLObject::setName(std::u16string_view rTheName, EncodeMechanism eMecha
while (p != pSegEnd && *p != ';')
++p;
- return setPath(
- std::u16string_view(pPathBegin, pSegBegin - pPathBegin)
- + encodeText(rTheName, PART_PCHAR, eMechanism, eCharset, true)
- + std::u16string_view(p, pPathEnd - p),
- EncodeMechanism::NotCanonical,
- RTL_TEXTENCODING_UTF8);
+ OUStringBuffer aNewPath(256);
+ aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin));
+ encodeText(aNewPath, rTheName, PART_PCHAR, eMechanism, eCharset, true);
+ aNewPath.append(std::u16string_view(p, pPathEnd - p));
+ return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8);
}
bool INetURLObject::hasExtension()
@@ -4171,12 +4229,11 @@ bool INetURLObject::setBase(std::u16string_view rTheBase, sal_Int32 nIndex,
if (!pExtension)
pExtension = p;
- return setPath(
- std::u16string_view(pPathBegin, pSegBegin - pPathBegin)
- + encodeText(rTheBase, PART_PCHAR, eMechanism, eCharset, true)
- + std::u16string_view(pExtension, pPathEnd - pExtension),
- EncodeMechanism::NotCanonical,
- RTL_TEXTENCODING_UTF8);
+ OUStringBuffer aNewPath(256);
+ aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin));
+ encodeText(aNewPath, rTheBase, PART_PCHAR, eMechanism, eCharset, true);
+ aNewPath.append(std::u16string_view(pExtension, pPathEnd - pExtension));
+ return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8);
}
OUString INetURLObject::getExtension(sal_Int32 nIndex,
@@ -4231,12 +4288,11 @@ bool INetURLObject::setExtension(std::u16string_view rTheExtension,
if (!pExtension)
pExtension = p;
- return setPath(
- OUString::Concat(std::u16string_view(pPathBegin, pExtension - pPathBegin)) + "."
- + encodeText(rTheExtension, PART_PCHAR, EncodeMechanism::WasEncoded, eCharset, true)
- + std::u16string_view(p, pPathEnd - p),
- EncodeMechanism::NotCanonical,
- RTL_TEXTENCODING_UTF8);
+ OUStringBuffer aNewPath(256);
+ aNewPath.append(OUString::Concat(std::u16string_view(pPathBegin, pExtension - pPathBegin)) + ".");
+ encodeText(aNewPath, rTheExtension, PART_PCHAR, EncodeMechanism::WasEncoded, eCharset, true);
+ aNewPath.append(std::u16string_view(p, pPathEnd - p));
+ return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8);
}
bool INetURLObject::removeExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)
@@ -4358,8 +4414,7 @@ OUString INetURLObject::getFSysPath(FSysStyle eStyle,
if (pDelimiter)
*pDelimiter = '/';
- OUStringBuffer aSynFSysPath;
- aSynFSysPath.append("//");
+ OUStringBuffer aSynFSysPath("//");
if (m_aHost.isPresent() && m_aHost.getLength() > 0)
aSynFSysPath.append(decode(m_aHost, DecodeMechanism::WithCharset,
RTL_TEXTENCODING_UTF8));
@@ -4389,10 +4444,9 @@ OUString INetURLObject::getFSysPath(FSysStyle eStyle,
OUStringBuffer aSynFSysPath(64);
if (m_aHost.isPresent() && m_aHost.getLength() > 0)
{
- aSynFSysPath.append("\\\\");
- aSynFSysPath.append(decode(m_aHost, DecodeMechanism::WithCharset,
- RTL_TEXTENCODING_UTF8));
- aSynFSysPath.append('\\');
+ aSynFSysPath.append("\\\\"
+ + decode(m_aHost, DecodeMechanism::WithCharset, RTL_TEXTENCODING_UTF8)
+ + "\\");
}
sal_Unicode const * p
= m_aAbsURIRef.getStr() + m_aPath.getBegin();
@@ -4822,8 +4876,18 @@ void INetURLObject::SetExtension(std::u16string_view rTheExtension)
OUString INetURLObject::CutExtension()
{
OUString aTheExtension(getExtension(LAST_SEGMENT, false));
- return removeExtension(LAST_SEGMENT, false)
- ? aTheExtension : OUString();
+ if (removeExtension(LAST_SEGMENT, false))
+ return aTheExtension;
+ return OUString();
+}
+
+bool INetURLObject::IsExoticProtocol() const
+{
+ return m_eScheme == INetProtocol::Slot ||
+ m_eScheme == INetProtocol::Macro ||
+ m_eScheme == INetProtocol::Uno ||
+ isSchemeEqualTo(u"vnd.sun.star.script") ||
+ isSchemeEqualTo(u"service");
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/fsys/wldcrd.cxx b/tools/source/fsys/wldcrd.cxx
index 6e0259696aca..e8199975c6e5 100644
--- a/tools/source/fsys/wldcrd.cxx
+++ b/tools/source/fsys/wldcrd.cxx
@@ -25,85 +25,96 @@
* '?' in pWild mean match exactly one character.
*
*/
-bool WildCard::ImpMatch( const sal_Unicode *pWild, const sal_Unicode *pStr )
+bool WildCard::ImpMatch( std::u16string_view aWild, std::u16string_view aStr )
{
- int pos=0;
- int flag=0;
+ const sal_Unicode* pPosAfterAsterisk = nullptr;
+ const sal_Unicode* pWild = aWild.data();
+ const sal_Unicode* pWildEnd = aWild.data() + aWild.size();
+ const sal_Unicode* pStr = aStr.data();
+ const sal_Unicode* pStrEnd = aStr.data() + aStr.size();
- while ( *pWild || flag )
+ while (pWild != pWildEnd)
{
switch (*pWild)
{
case '?':
- if ( *pStr == '\0' )
+ if ( pStr == pStrEnd )
return false;
- break;
-
- default:
- if ( (*pWild == '\\') && ((*(pWild+1)=='?') || (*(pWild+1) == '*')) )
+ break; // Match -> proceed to the next character
+ case '\\': // Escaping '?' and '*'; don't we need to escape '\\'?
+ if ((pWild + 1 != pWildEnd) && ((*(pWild + 1) == '?') || (*(pWild + 1) == '*')))
pWild++;
- if ( *pWild != *pStr )
- if ( !pos )
- return false;
- else
- pWild += pos;
- else
- break;
- // WARNING/TODO: may cause execution of next case in some
- // circumstances!
+ [[fallthrough]];
+ default: // No wildcard, literal match
+ if (pStr == pStrEnd)
+ return false;
+ if (*pWild == *pStr)
+ break; // Match -> proceed to the next character
+ if (!pPosAfterAsterisk)
+ return false;
+ pWild = pPosAfterAsterisk;
[[fallthrough]];
case '*':
- while ( *pWild == '*' )
+ while ( pWild != pWildEnd && *pWild == '*' )
pWild++;
- if ( *pWild == '\0' )
+ if ( pWild == pWildEnd )
return true;
- flag = 1;
- pos = 0;
- if ( *pStr == '\0' )
- return ( *pWild == '\0' );
- while ( *pStr && *pStr != *pWild )
+ // Consider strange things like "**?*?*"
+ while (*pWild == '?')
{
- if ( *pWild == '?' ) {
+ if (pStr == pStrEnd)
+ return false;
+ pWild++;
+ pStr++;
+ while (pWild != pWildEnd && *pWild == '*')
pWild++;
- while ( *pWild == '*' )
- pWild++;
- }
+ if (pWild == pWildEnd)
+ return true;
+ }
+ // At this point, we are past wildcards, and a literal match must follow
+ if ( pStr == pStrEnd )
+ return false;
+ pPosAfterAsterisk = pWild;
+ if ((*pWild == '\\') && (pWild + 1 != pWildEnd) && ((*(pWild + 1) == '?') || (*(pWild + 1) == '*')))
+ pWild++;
+ while (*pStr != *pWild)
+ {
pStr++;
- if ( *pStr == '\0' )
- return ( *pWild == '\0' );
+ if ( pStr == pStrEnd )
+ return false;
}
- break;
+ break; // Match -> proceed to the next character
}
- if ( *pWild != '\0' )
- pWild++;
- if ( *pStr != '\0' )
- pStr++;
- else
- flag = 0;
- if ( flag )
- pos--;
+ // We arrive here when the current characters in pWild and pStr match
+ assert(pWild != pWildEnd);
+ pWild++;
+ assert(pStr != pStrEnd);
+ pStr++;
+ if (pWild == pWildEnd && pPosAfterAsterisk && pStr != pStrEnd)
+ pWild = pPosAfterAsterisk; // Try again on the rest of pStr
}
- return ( *pStr == '\0' ) && ( *pWild == '\0' );
+ assert(pWild == pWildEnd);
+ return pStr == pStrEnd;
}
bool WildCard::Matches( std::u16string_view rString ) const
{
- OUString aTmpWild = aWildString;
+ std::u16string_view aTmpWild = aWildString;
- sal_Int32 nSepPos;
+ size_t nSepPos;
if ( cSepSymbol != '\0' )
{
- while ( (nSepPos = aTmpWild.indexOf(cSepSymbol)) != -1 )
+ while ( (nSepPos = aTmpWild.find(cSepSymbol)) != std::u16string_view::npos )
{
// Check all split wildcards
- if ( ImpMatch( aTmpWild.subView( 0, nSepPos ).data(), rString.data() ) )
+ if ( ImpMatch( aTmpWild.substr( 0, nSepPos ), rString ) )
return true;
- aTmpWild = aTmpWild.copy(nSepPos + 1); // remove separator
+ aTmpWild = aTmpWild.substr(nSepPos + 1); // remove separator
}
}
- return ImpMatch( aTmpWild.getStr(), rString.data() );
+ return ImpMatch( aTmpWild, rString );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/b3dtrans.cxx b/tools/source/generic/b3dtrans.cxx
index 0215610956a8..0cae750da0dc 100644
--- a/tools/source/generic/b3dtrans.cxx
+++ b/tools/source/generic/b3dtrans.cxx
@@ -252,7 +252,7 @@ void B3dTransformationSet::CalcViewport()
// #i36281#
// OpenGL needs a little more rough additional size to not let
// the front face vanish. Changed from SMALL_DVALUE to 0.000001,
- // which is 1/10000th, comared with 1/tenth of a million from SMALL_DVALUE.
+ // which is 1/10000th, compared with 1/tenth of a million from SMALL_DVALUE.
const double fDistPart((gfFarBound - gfNearBound) * 0.0001);
// To avoid critical clipping, set Near & Far generously
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
index f6627200a61c..80b86af6013c 100644
--- a/tools/source/generic/bigint.cxx
+++ b/tools/source/generic/bigint.cxx
@@ -17,13 +17,15 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <math.h>
+#include <sal/config.h>
#include <osl/diagnose.h>
#include <tools/bigint.hxx>
#include <algorithm>
-#include <string.h>
+#include <cmath>
+#include <cstring>
+#include <span>
/**
* The range in which we can perform add/sub without fear of overflow
@@ -38,123 +40,116 @@ const sal_Int32 MY_MINLONG = -MY_MAXLONG;
* chapter 4.3.1. The Classical Algorithms.
*/
-// TODO: Needs conversion to sal_uInt16/INT16/sal_uInt32/sal_Int32
-void BigInt::MakeBigInt( const BigInt& rVal )
+BigInt BigInt::MakeBig() const
{
- if ( rVal.nLen != 0 )
+ if (IsBig())
{
- memcpy( static_cast<void*>(this), static_cast<const void*>(&rVal), sizeof( BigInt ) );
- while ( nLen > 1 && nNum[nLen-1] == 0 )
- nLen--;
+ BigInt ret(*this);
+ while ( ret.nLen > 1 && ret.nNum[ret.nLen-1] == 0 )
+ ret.nLen--;
+ return ret;
+ }
+
+ BigInt ret;
+ if (nVal < 0)
+ {
+ ret.bIsNeg = true;
+ ret.nNum[0] = -static_cast<sal_Int64>(nVal);
}
else
{
- nVal = rVal.nVal;
- sal_uInt32 nTmp;
- if (nVal < 0)
- {
- bIsNeg = true;
- nTmp = -static_cast<sal_Int64>(nVal);
- }
- else
- {
- bIsNeg = false;
- nTmp = nVal;
- }
-
- nNum[0] = static_cast<sal_uInt16>(nTmp & 0xffffL);
- nNum[1] = static_cast<sal_uInt16>(nTmp >> 16);
- if ( nTmp & 0xffff0000L )
- nLen = 2;
- else
- nLen = 1;
+ ret.bIsNeg = false;
+ ret.nNum[0] = nVal;
}
+ ret.nLen = 1;
+ return ret;
}
void BigInt::Normalize()
{
- if ( nLen != 0 )
+ if (IsBig())
{
while ( nLen > 1 && nNum[nLen-1] == 0 )
nLen--;
- if ( nLen < 3 )
+ if (nLen < 2)
{
- sal_Int32 newVal;
- if ( nLen < 2 )
- newVal = nNum[0];
- else if ( nNum[1] & 0x8000 )
- return;
- else
- newVal = (static_cast<sal_Int32>(nNum[1]) << 16) + nNum[0];
-
- nLen = 0;
- nVal = newVal;
-
- if ( bIsNeg )
- nVal = -nVal;
+ constexpr sal_uInt32 maxForPosInt32 = std::numeric_limits<sal_Int32>::max();
+ constexpr sal_uInt32 maxForNegInt32 = -sal_Int64(std::numeric_limits<sal_Int32>::min());
+ sal_uInt32 nNum0 = nNum[0];
+ if (bIsNeg && nNum0 <= maxForNegInt32)
+ {
+ nVal = -sal_Int64(nNum0);
+ nLen = 0;
+ }
+ else if (!bIsNeg && nNum0 <= maxForPosInt32)
+ {
+ nVal = nNum0;
+ nLen = 0;
+ }
}
- // else nVal is undefined !!! W.P.
}
- // why? nVal is undefined ??? W.P.
- else if ( nVal & 0xFFFF0000L )
- nLen = 2;
- else
- nLen = 1;
}
-void BigInt::Mult( const BigInt &rVal, sal_uInt16 nMul )
+// Normalization in DivLong requires that dividend is multiplied by a number, and the resulting
+// value has 1 more 32-bit "digits". 'ret' provides enough room for that. Use of std::span gives
+// run-time index checking in debug builds.
+static std::span<sal_uInt32> Mult(std::span<const sal_uInt32> aNum, sal_uInt32 nMul, std::span<sal_uInt32> retBuf)
{
- sal_uInt16 nK = 0;
- for ( int i = 0; i < rVal.nLen; i++ )
+ assert(retBuf.size() >= aNum.size());
+ sal_uInt64 nK = 0;
+ for (size_t i = 0; i < aNum.size(); i++)
{
- sal_uInt32 nTmp = static_cast<sal_uInt32>(rVal.nNum[i]) * static_cast<sal_uInt32>(nMul) + nK;
- nK = static_cast<sal_uInt16>(nTmp >> 16);
- nNum[i] = static_cast<sal_uInt16>(nTmp);
+ sal_uInt64 nTmp = static_cast<sal_uInt64>(aNum[i]) * nMul + nK;
+ nK = nTmp >> 32;
+ retBuf[i] = static_cast<sal_uInt32>(nTmp);
}
if ( nK )
{
- nNum[rVal.nLen] = nK;
- nLen = rVal.nLen + 1;
+ assert(retBuf.size() > aNum.size());
+ retBuf[aNum.size()] = nK;
+ return retBuf.subspan(0, aNum.size() + 1);
}
- else
- nLen = rVal.nLen;
- bIsNeg = rVal.bIsNeg;
+ return retBuf.subspan(0, aNum.size());
}
-void BigInt::Div( sal_uInt16 nDiv, sal_uInt16& rRem )
+static size_t DivInPlace(std::span<sal_uInt32> aNum, sal_uInt32 nDiv, sal_uInt32& rRem)
{
- sal_uInt32 nK = 0;
- for ( int i = nLen - 1; i >= 0; i-- )
+ assert(aNum.size() > 0);
+ sal_uInt64 nK = 0;
+ for (int i = aNum.size() - 1; i >= 0; i--)
{
- sal_uInt32 nTmp = static_cast<sal_uInt32>(nNum[i]) + (nK << 16);
- nNum[i] = static_cast<sal_uInt16>(nTmp / nDiv);
+ sal_uInt64 nTmp = aNum[i] + (nK << 32);
+ aNum[i] = nTmp / nDiv;
nK = nTmp % nDiv;
}
- rRem = static_cast<sal_uInt16>(nK);
+ rRem = nK;
- if ( nNum[nLen-1] == 0 )
- nLen -= 1;
+ if (aNum[aNum.size() - 1] == 0)
+ return aNum.size() - 1;
+
+ return aNum.size();
}
-bool BigInt::IsLess( const BigInt& rVal ) const
+bool BigInt::ABS_IsLessBig(const BigInt& rVal) const
{
+ assert(IsBig() && rVal.IsBig());
if ( rVal.nLen < nLen)
- return true;
- if ( rVal.nLen > nLen )
return false;
+ if ( rVal.nLen > nLen )
+ return true;
- int i;
- for ( i = nLen - 1; i > 0 && nNum[i] == rVal.nNum[i]; i-- )
- {
- }
- return rVal.nNum[i] < nNum[i];
+ int i = nLen - 1;
+ while (i > 0 && nNum[i] == rVal.nNum[i])
+ --i;
+ return nNum[i] < rVal.nNum[i];
}
-void BigInt::AddLong( BigInt& rB, BigInt& rErg )
+void BigInt::AddBig(BigInt& rB, BigInt& rRes)
{
+ assert(IsBig() && rB.IsBig());
if ( bIsNeg == rB.bIsNeg )
{
int i;
@@ -176,189 +171,176 @@ void BigInt::AddLong( BigInt& rB, BigInt& rErg )
}
// Add numerals, starting from the back
- sal_Int32 k;
- sal_Int32 nZ = 0;
- for (i = 0, k = 0; i < len; i++) {
- nZ = static_cast<sal_Int32>(nNum[i]) + static_cast<sal_Int32>(rB.nNum[i]) + k;
- if (nZ & 0xff0000L)
+ sal_Int64 k = 0;
+ for (i = 0; i < len; i++) {
+ sal_Int64 nZ = static_cast<sal_Int64>(nNum[i]) + static_cast<sal_Int64>(rB.nNum[i]) + k;
+ if (nZ > sal_Int64(std::numeric_limits<sal_uInt32>::max()))
k = 1;
else
k = 0;
- rErg.nNum[i] = static_cast<sal_uInt16>(nZ & 0xffffL);
+ rRes.nNum[i] = static_cast<sal_uInt32>(nZ);
}
// If an overflow occurred, add to solution
- if (nZ & 0xff0000L) // or if(k)
+ if (k)
{
- rErg.nNum[i] = 1;
+ assert(i < MAX_DIGITS);
+ rRes.nNum[i] = 1;
len++;
}
// Set length and sign
- rErg.nLen = len;
- rErg.bIsNeg = bIsNeg && rB.bIsNeg;
+ rRes.nLen = len;
+ rRes.bIsNeg = bIsNeg;
}
// If one of the values is negative, perform subtraction instead
- else if (bIsNeg)
- {
- bIsNeg = false;
- rB.SubLong(*this, rErg);
- bIsNeg = true;
- }
else
{
- rB.bIsNeg = false;
- SubLong(rB, rErg);
- rB.bIsNeg = true;
+ bIsNeg = !bIsNeg;
+ rB.SubBig(*this, rRes);
+ bIsNeg = !bIsNeg;
}
}
-void BigInt::SubLong( BigInt& rB, BigInt& rErg )
+void BigInt::SubBig(BigInt& rB, BigInt& rRes)
{
+ assert(IsBig() && rB.IsBig());
if ( bIsNeg == rB.bIsNeg )
{
- int i;
char len;
- sal_Int32 nZ, k;
// if length of the two values differ, fill remaining positions
// of the smaller value with zeros.
if (nLen >= rB.nLen)
{
len = nLen;
- for (i = rB.nLen; i < len; i++)
+ for (int i = rB.nLen; i < len; i++)
rB.nNum[i] = 0;
}
else
{
len = rB.nLen;
- for (i = nLen; i < len; i++)
+ for (int i = nLen; i < len; i++)
nNum[i] = 0;
}
- if ( IsLess(rB) )
- {
- for (i = 0, k = 0; i < len; i++)
- {
- nZ = static_cast<sal_Int32>(nNum[i]) - static_cast<sal_Int32>(rB.nNum[i]) + k;
- if (nZ < 0)
- k = -1;
- else
- k = 0;
- rErg.nNum[i] = static_cast<sal_uInt16>(nZ & 0xffffL);
- }
- rErg.bIsNeg = bIsNeg;
- }
- else
+ const bool bThisIsLess = ABS_IsLessBig(rB);
+ BigInt& rGreater = bThisIsLess ? rB : *this;
+ BigInt& rSmaller = bThisIsLess ? *this : rB;
+
+ sal_Int64 k = 0;
+ for (int i = 0; i < len; i++)
{
- for (i = 0, k = 0; i < len; i++)
- {
- nZ = static_cast<sal_Int32>(rB.nNum[i]) - static_cast<sal_Int32>(nNum[i]) + k;
- if (nZ < 0)
- k = -1;
- else
- k = 0;
- rErg.nNum[i] = static_cast<sal_uInt16>(nZ & 0xffffL);
- }
- // if a < b, revert sign
- rErg.bIsNeg = !bIsNeg;
+ sal_Int64 nZ = static_cast<sal_Int64>(rGreater.nNum[i]) - static_cast<sal_Int64>(rSmaller.nNum[i]) + k;
+ if (nZ < 0)
+ k = -1;
+ else
+ k = 0;
+ rRes.nNum[i] = static_cast<sal_uInt32>(nZ);
}
- rErg.nLen = len;
+
+ // if a < b, revert sign
+ rRes.bIsNeg = bThisIsLess ? !bIsNeg : bIsNeg;
+ rRes.nLen = len;
}
// If one of the values is negative, perform addition instead
- else if (bIsNeg)
- {
- bIsNeg = false;
- AddLong(rB, rErg);
- bIsNeg = true;
- rErg.bIsNeg = true;
- }
else
{
- rB.bIsNeg = false;
- AddLong(rB, rErg);
- rB.bIsNeg = true;
- rErg.bIsNeg = false;
+ bIsNeg = !bIsNeg;
+ AddBig(rB, rRes);
+ bIsNeg = !bIsNeg;
+ rRes.bIsNeg = bIsNeg;
}
}
-void BigInt::MultLong( const BigInt& rB, BigInt& rErg ) const
+void BigInt::MultBig(const BigInt& rB, BigInt& rRes) const
{
- int i, j;
- sal_uInt32 nZ, k;
+ assert(IsBig() && rB.IsBig());
- rErg.bIsNeg = bIsNeg != rB.bIsNeg;
- rErg.nLen = nLen + rB.nLen;
+ rRes.bIsNeg = bIsNeg != rB.bIsNeg;
+ rRes.nLen = nLen + rB.nLen;
+ assert(rRes.nLen <= MAX_DIGITS);
- for (i = 0; i < rErg.nLen; i++)
- rErg.nNum[i] = 0;
+ for (int i = 0; i < rRes.nLen; i++)
+ rRes.nNum[i] = 0;
- for (j = 0; j < rB.nLen; j++)
+ for (int j = 0; j < rB.nLen; j++)
{
- for (i = 0, k = 0; i < nLen; i++)
+ sal_uInt64 k = 0;
+ int i;
+ for (i = 0; i < nLen; i++)
{
- nZ = static_cast<sal_uInt32>(nNum[i]) * static_cast<sal_uInt32>(rB.nNum[j]) +
- static_cast<sal_uInt32>(rErg.nNum[i + j]) + k;
- rErg.nNum[i + j] = static_cast<sal_uInt16>(nZ & 0xffffU);
- k = nZ >> 16;
+ sal_uInt64 nZ = static_cast<sal_uInt64>(nNum[i]) * static_cast<sal_uInt64>(rB.nNum[j]) +
+ static_cast<sal_uInt64>(rRes.nNum[i + j]) + k;
+ rRes.nNum[i + j] = static_cast<sal_uInt32>(nZ);
+ k = nZ >> 32;
}
- rErg.nNum[i + j] = static_cast<sal_uInt16>(k);
+ rRes.nNum[i + j] = k;
}
}
-void BigInt::DivLong( const BigInt& rB, BigInt& rErg ) const
+void BigInt::DivModBig(const BigInt& rB, BigInt* pDiv, BigInt* pMod) const
{
- int i, j;
- sal_uInt16 nK, nQ, nMult;
- sal_uInt16 nLenB = rB.nLen;
- sal_uInt16 nLenB1 = rB.nLen - 1;
- BigInt aTmpA, aTmpB;
+ assert(IsBig() && rB.IsBig());
+ assert(nLen >= rB.nLen);
- nMult = static_cast<sal_uInt16>(0x10000L / (static_cast<sal_Int32>(rB.nNum[nLenB1]) + 1));
+ assert(rB.nNum[rB.nLen - 1] != 0);
+ sal_uInt32 nMult = static_cast<sal_uInt32>(0x100000000 / (static_cast<sal_Int64>(rB.nNum[rB.nLen - 1]) + 1));
- aTmpA.Mult( *this, nMult );
- if ( aTmpA.nLen == nLen )
+ sal_uInt32 numBuf[MAX_DIGITS + 1]; // normalized dividend
+ auto num = Mult({ nNum, nLen }, nMult, numBuf);
+ if (num.size() == nLen)
{
- aTmpA.nNum[aTmpA.nLen] = 0;
- aTmpA.nLen++;
+ num = std::span(numBuf, nLen + 1);
+ num[nLen] = 0;
}
- aTmpB.Mult( rB, nMult );
+ sal_uInt32 denBuf[MAX_DIGITS + 1]; // normalized divisor
+ const auto den = Mult({ rB.nNum, rB.nLen }, nMult, denBuf);
+ assert(den.size() == rB.nLen);
+ const sal_uInt64 nDenMostSig = den[rB.nLen - 1];
+ assert(nDenMostSig >= 0x100000000 / 2);
+ const sal_uInt64 nDen2ndSig = rB.nLen > 1 ? den[rB.nLen - 2] : 0;
+
+ BigInt aTmp;
+ BigInt& rRes = pDiv ? *pDiv : aTmp;
- for (j = aTmpA.nLen - 1; j >= nLenB; j--)
+ for (size_t j = num.size() - 1; j >= den.size(); j--)
{ // guess divisor
- sal_uInt32 nTmp = ( static_cast<sal_uInt32>(aTmpA.nNum[j]) << 16 ) + aTmpA.nNum[j - 1];
- if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
- nQ = 0xFFFF;
+ assert(num[j] < nDenMostSig || (num[j] == nDenMostSig && num[j - 1] == 0));
+ sal_uInt64 nTmp = ( static_cast<sal_uInt64>(num[j]) << 32 ) + num[j - 1];
+ sal_uInt32 nQ;
+ if (num[j] == nDenMostSig)
+ nQ = 0xFFFFFFFF;
else
- nQ = static_cast<sal_uInt16>(nTmp / aTmpB.nNum[nLenB1]);
+ nQ = static_cast<sal_uInt32>(nTmp / nDenMostSig);
- if ( (static_cast<sal_uInt32>(aTmpB.nNum[nLenB1 - 1]) * nQ) >
- ((nTmp - static_cast<sal_uInt32>(aTmpB.nNum[nLenB1]) * nQ) << 16) + aTmpA.nNum[j - 2])
+ if (nDen2ndSig && (nDen2ndSig * nQ) > ((nTmp - nDenMostSig * nQ) << 32) + num[j - 2])
nQ--;
// Start division
- nK = 0;
- for (i = 0; i < nLenB; i++)
+ sal_uInt32 nK = 0;
+ size_t i;
+ for (i = 0; i < den.size(); i++)
{
- nTmp = static_cast<sal_uInt32>(aTmpA.nNum[j - nLenB + i])
- - (static_cast<sal_uInt32>(aTmpB.nNum[i]) * nQ)
+ nTmp = static_cast<sal_uInt64>(num[j - den.size() + i])
+ - (static_cast<sal_uInt64>(den[i]) * nQ)
- nK;
- aTmpA.nNum[j - nLenB + i] = static_cast<sal_uInt16>(nTmp);
- nK = static_cast<sal_uInt16>(nTmp >> 16);
+ num[j - den.size() + i] = static_cast<sal_uInt32>(nTmp);
+ nK = static_cast<sal_uInt32>(nTmp >> 32);
if ( nK )
- nK = static_cast<sal_uInt16>(0x10000U - nK);
+ nK = static_cast<sal_uInt32>(0x100000000 - nK);
}
- sal_uInt16& rNum( aTmpA.nNum[j - nLenB + i] );
+ sal_uInt32& rNum(num[j - den.size() + i]);
rNum -= nK;
- if (aTmpA.nNum[j - nLenB + i] == 0)
- rErg.nNum[j - nLenB] = nQ;
+ if (num[j - den.size() + i] == 0)
+ rRes.nNum[j - den.size()] = nQ;
else
{
- rErg.nNum[j - nLenB] = nQ - 1;
+ rRes.nNum[j - den.size()] = nQ - 1;
nK = 0;
- for (i = 0; i < nLenB; i++)
+ for (i = 0; i < den.size(); i++)
{
- nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
- aTmpA.nNum[j - nLenB + i] = static_cast<sal_uInt16>(nTmp & 0xFFFFL);
- if (nTmp & 0xFFFF0000L)
+ nTmp = num[j - den.size() + i] + den[i] + nK;
+ num[j - den.size() + i] = static_cast<sal_uInt32>(nTmp & 0xFFFFFFFF);
+ if (nTmp > std::numeric_limits<sal_uInt32>::max())
nK = 1;
else
nK = 0;
@@ -366,135 +348,47 @@ void BigInt::DivLong( const BigInt& rB, BigInt& rErg ) const
}
}
- rErg.bIsNeg = bIsNeg != rB.bIsNeg;
- rErg.nLen = nLen - rB.nLen + 1;
-}
-
-void BigInt::ModLong( const BigInt& rB, BigInt& rErg ) const
-{
- sal_uInt16 i, j;
- sal_uInt16 nK, nQ, nMult;
- sal_Int16 nLenB = rB.nLen;
- sal_Int16 nLenB1 = rB.nLen - 1;
- BigInt aTmpA, aTmpB;
-
- nMult = static_cast<sal_uInt16>(0x10000L / (static_cast<sal_Int32>(rB.nNum[nLenB1]) + 1));
-
- aTmpA.Mult( *this, nMult);
- if ( aTmpA.nLen == nLen )
+ if (pMod)
{
- aTmpA.nNum[aTmpA.nLen] = 0;
- aTmpA.nLen++;
- }
-
- aTmpB.Mult( rB, nMult);
-
- for (j = aTmpA.nLen - 1; j >= nLenB; j--)
- { // Guess divisor
- sal_uInt32 nTmp = ( static_cast<sal_uInt32>(aTmpA.nNum[j]) << 16 ) + aTmpA.nNum[j - 1];
- if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
- nQ = 0xFFFF;
- else
- nQ = static_cast<sal_uInt16>(nTmp / aTmpB.nNum[nLenB1]);
-
- if ( (static_cast<sal_uInt32>(aTmpB.nNum[nLenB1 - 1]) * nQ) >
- ((nTmp - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
- nQ--;
- // Start division
- nK = 0;
- for (i = 0; i < nLenB; i++)
- {
- nTmp = static_cast<sal_uInt32>(aTmpA.nNum[j - nLenB + i])
- - (static_cast<sal_uInt32>(aTmpB.nNum[i]) * nQ)
- - nK;
- aTmpA.nNum[j - nLenB + i] = static_cast<sal_uInt16>(nTmp);
- nK = static_cast<sal_uInt16>(nTmp >> 16);
- if ( nK )
- nK = static_cast<sal_uInt16>(0x10000U - nK);
- }
- sal_uInt16& rNum( aTmpA.nNum[j - nLenB + i] );
- rNum = rNum - nK;
- if (aTmpA.nNum[j - nLenB + i] == 0)
- rErg.nNum[j - nLenB] = nQ;
- else
- {
- rErg.nNum[j - nLenB] = nQ - 1;
- nK = 0;
- for (i = 0; i < nLenB; i++) {
- nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
- aTmpA.nNum[j - nLenB + i] = static_cast<sal_uInt16>(nTmp & 0xFFFFL);
- if (nTmp & 0xFFFF0000L)
- nK = 1;
- else
- nK = 0;
- }
- }
+ pMod->nLen = DivInPlace(num, nMult, nMult);
+ assert(pMod->nLen <= MAX_DIGITS);
+ pMod->bIsNeg = bIsNeg;
+ std::copy_n(num.begin(), pMod->nLen, pMod->nNum);
+ pMod->Normalize();
}
-
- rErg = aTmpA;
- rErg.Div( nMult, nQ );
-}
-
-bool BigInt::ABS_IsLess( const BigInt& rB ) const
-{
- if (nLen != 0 || rB.nLen != 0)
+ if (pDiv) // rRes references pDiv
{
- BigInt nA, nB;
- nA.MakeBigInt( *this );
- nB.MakeBigInt( rB );
- if (nA.nLen == nB.nLen)
- {
- int i;
- for (i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i--)
- {
- }
- return nA.nNum[i] < nB.nNum[i];
- }
- else
- return nA.nLen < nB.nLen;
+ pDiv->bIsNeg = bIsNeg != rB.bIsNeg;
+ pDiv->nLen = nLen - rB.nLen + 1;
+ pDiv->Normalize();
}
- if ( nVal < 0 )
- if ( rB.nVal < 0 )
- return nVal > rB.nVal;
- else
- return nVal > -rB.nVal;
- else
- if ( rB.nVal < 0 )
- return nVal < -rB.nVal;
- else
- return nVal < rB.nVal;
-}
-
-BigInt::BigInt( const BigInt& rBigInt )
- : nLen(0)
- , bIsNeg(false)
-{
- if ( rBigInt.nLen != 0 )
- memcpy( static_cast<void*>(this), static_cast<const void*>(&rBigInt), sizeof( BigInt ) );
- else
- nVal = rBigInt.nVal;
}
-BigInt::BigInt( const OUString& rString )
+BigInt::BigInt( std::u16string_view rString )
: nLen(0)
{
bIsNeg = false;
nVal = 0;
bool bNeg = false;
- const sal_Unicode* p = rString.getStr();
+ auto p = rString.begin();
+ auto pEnd = rString.end();
+ if (p == pEnd)
+ return;
if ( *p == '-' )
{
bNeg = true;
p++;
}
- while( *p >= '0' && *p <= '9' )
+ if (p == pEnd)
+ return;
+ while( p != pEnd && *p >= '0' && *p <= '9' )
{
*this *= 10;
*this += *p - '0';
p++;
}
- if ( nLen != 0 )
+ if (IsBig())
bIsNeg = bNeg;
else if( bNeg )
nVal = -nVal;
@@ -522,36 +416,34 @@ BigInt::BigInt( double nValue )
{
int i=0;
- while ( ( nValue > 65536.0 ) && ( i < MAX_DIGITS ) )
+ while ( ( nValue > 0x100000000 ) && ( i < MAX_DIGITS ) )
{
- nNum[i] = static_cast<sal_uInt16>(fmod( nValue, 65536.0 ));
+ nNum[i] = static_cast<sal_uInt32>(fmod( nValue, 0x100000000 ));
nValue -= nNum[i];
- nValue /= 65536.0;
+ nValue /= 0x100000000;
i++;
}
if ( i < MAX_DIGITS )
- nNum[i++] = static_cast<sal_uInt16>(nValue);
+ nNum[i++] = static_cast<sal_uInt32>(nValue);
nLen = i;
- if ( i < 3 )
+ if ( i < 2 )
Normalize();
}
}
BigInt::BigInt( sal_uInt32 nValue )
: nVal(0)
+ , bIsNeg(false)
{
if ( nValue & 0x80000000U )
{
- bIsNeg = false;
- nNum[0] = static_cast<sal_uInt16>(nValue & 0xffffU);
- nNum[1] = static_cast<sal_uInt16>(nValue >> 16);
- nLen = 2;
+ nNum[0] = nValue;
+ nLen = 1;
}
else
{
- bIsNeg = false;
nVal = nValue;
nLen = 0;
}
@@ -569,30 +461,25 @@ BigInt::BigInt( sal_Int64 nValue )
}
else
{
- sal_uInt64 nUValue = static_cast<sal_uInt64>(bIsNeg ? -nValue : nValue);
- for (int i = 0; (i != sizeof(sal_uInt64) / 2) && (nUValue != 0); ++i)
- {
- nNum[i] = static_cast<sal_uInt16>(nUValue & 0xffffUL);
- nUValue = nUValue >> 16;
- ++nLen;
- }
+ for (sal_uInt64 n = static_cast<sal_uInt64>(bIsNeg ? -nValue : nValue); n != 0; n >>= 32)
+ nNum[nLen++] = static_cast<sal_uInt32>(n);
}
}
BigInt::operator double() const
{
- if ( nLen == 0 )
+ if (!IsBig())
return static_cast<double>(nVal);
else
{
int i = nLen-1;
- double nRet = static_cast<double>(static_cast<sal_uInt32>(nNum[i]));
+ double nRet = static_cast<double>(nNum[i]);
while ( i )
{
- nRet *= 65536.0;
+ nRet *= 0x100000000;
i--;
- nRet += static_cast<double>(static_cast<sal_uInt32>(nNum[i]));
+ nRet += static_cast<double>(nNum[i]);
}
if ( bIsNeg )
@@ -607,7 +494,7 @@ BigInt& BigInt::operator=( const BigInt& rBigInt )
if (this == &rBigInt)
return *this;
- if ( rBigInt.nLen != 0 )
+ if (rBigInt.IsBig())
memcpy( static_cast<void*>(this), static_cast<const void*>(&rBigInt), sizeof( BigInt ) );
else
{
@@ -619,7 +506,7 @@ BigInt& BigInt::operator=( const BigInt& rBigInt )
BigInt& BigInt::operator+=( const BigInt& rVal )
{
- if ( nLen == 0 && rVal.nLen == 0 )
+ if (!IsBig() && !rVal.IsBig())
{
if( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG
&& nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
@@ -635,17 +522,15 @@ BigInt& BigInt::operator+=( const BigInt& rVal )
}
}
- BigInt aTmp1, aTmp2;
- aTmp1.MakeBigInt( *this );
- aTmp2.MakeBigInt( rVal );
- aTmp1.AddLong( aTmp2, *this );
+ BigInt aTmp2 = rVal.MakeBig();
+ MakeBig().AddBig(aTmp2, *this);
Normalize();
return *this;
}
BigInt& BigInt::operator-=( const BigInt& rVal )
{
- if ( nLen == 0 && rVal.nLen == 0 )
+ if (!IsBig() && !rVal.IsBig())
{
if ( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG &&
nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
@@ -661,10 +546,8 @@ BigInt& BigInt::operator-=( const BigInt& rVal )
}
}
- BigInt aTmp1, aTmp2;
- aTmp1.MakeBigInt( *this );
- aTmp2.MakeBigInt( rVal );
- aTmp1.SubLong( aTmp2, *this );
+ BigInt aTmp2 = rVal.MakeBig();
+ MakeBig().SubBig(aTmp2, *this);
Normalize();
return *this;
}
@@ -674,7 +557,7 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
static const sal_Int32 MY_MAXSHORT = 0x00007fff;
static const sal_Int32 MY_MINSHORT = -MY_MAXSHORT;
- if ( nLen == 0 && rVal.nLen == 0
+ if (!IsBig() && !rVal.IsBig()
&& nVal <= MY_MAXSHORT && rVal.nVal <= MY_MAXSHORT
&& nVal >= MY_MINSHORT && rVal.nVal >= MY_MINSHORT )
// TODO: not optimal !!! W.P.
@@ -683,149 +566,147 @@ BigInt& BigInt::operator*=( const BigInt& rVal )
}
else
{
- BigInt aTmp1, aTmp2;
- aTmp1.MakeBigInt( rVal );
- aTmp2.MakeBigInt( *this );
- aTmp1.MultLong(aTmp2, *this);
+ rVal.MakeBig().MultBig(MakeBig(), *this);
Normalize();
}
return *this;
}
-BigInt& BigInt::operator/=( const BigInt& rVal )
+void BigInt::DivMod(const BigInt& rVal, BigInt* pDiv, BigInt* pMod) const
{
- if ( rVal.nLen == 0 )
+ assert(pDiv || pMod); // Avoid useless calls
+ if (!rVal.IsBig())
{
if ( rVal.nVal == 0 )
{
OSL_FAIL( "BigInt::operator/ --> divide by zero" );
- return *this;
+ return;
}
- if ( nLen == 0 )
+ if (rVal.nVal == 1)
{
- // No overflows may occur here
- nVal /= rVal.nVal;
- return *this;
+ if (pDiv)
+ {
+ *pDiv = *this;
+ pDiv->Normalize();
+ }
+ if (pMod)
+ *pMod = 0;
+ return;
}
- if ( rVal.nVal == 1 )
- return *this;
-
- if ( rVal.nVal == -1 )
+ if (!IsBig())
{
- bIsNeg = !bIsNeg;
- return *this;
+ // No overflows may occur here
+ const sal_Int32 nDiv = nVal / rVal.nVal; // Compilers usually optimize adjacent
+ const sal_Int32 nMod = nVal % rVal.nVal; // / and % into a single instruction
+ if (pDiv)
+ *pDiv = nDiv;
+ if (pMod)
+ *pMod = nMod;
+ return;
}
- if ( rVal.nVal <= 0xFFFF && rVal.nVal >= -0xFFFF )
+ if ( rVal.nVal == -1 )
{
- // Divide BigInt with an sal_uInt16
- sal_uInt16 nTmp;
- if ( rVal.nVal < 0 )
+ if (pDiv)
{
- nTmp = static_cast<sal_uInt16>(-rVal.nVal);
- bIsNeg = !bIsNeg;
+ *pDiv = *this;
+ pDiv->bIsNeg = !bIsNeg;
+ pDiv->Normalize();
}
- else
- nTmp = static_cast<sal_uInt16>(rVal.nVal);
-
- Div( nTmp, nTmp );
- Normalize();
- return *this;
+ if (pMod)
+ *pMod = 0;
+ return;
}
- }
-
- if ( ABS_IsLess( rVal ) )
- {
- *this = BigInt( 0 );
- return *this;
- }
-
- // Divide BigInt with BigInt
- BigInt aTmp1, aTmp2;
- aTmp1.MakeBigInt( *this );
- aTmp2.MakeBigInt( rVal );
- aTmp1.DivLong(aTmp2, *this);
- Normalize();
- return *this;
-}
-BigInt& BigInt::operator%=( const BigInt& rVal )
-{
- if ( rVal.nLen == 0 )
- {
- if ( rVal.nVal == 0 )
+ // Divide BigInt with an sal_uInt32
+ sal_uInt32 nTmp;
+ bool bNegate;
+ if ( rVal.nVal < 0 )
{
- OSL_FAIL( "BigInt::operator/ --> divide by zero" );
- return *this;
+ nTmp = static_cast<sal_uInt32>(-rVal.nVal);
+ bNegate = true;
}
-
- if ( nLen == 0 )
+ else
{
- // No overflows may occur here
- nVal %= rVal.nVal;
- return *this;
+ nTmp = static_cast<sal_uInt32>(rVal.nVal);
+ bNegate = false;
}
- if ( rVal.nVal <= 0xFFFF && rVal.nVal >= -0xFFFF )
+ BigInt aTmp;
+ BigInt& rDiv = pDiv ? *pDiv : aTmp;
+ rDiv = *this;
+ rDiv.nLen = DivInPlace({ rDiv.nNum, rDiv.nLen }, nTmp, nTmp);
+ if (pDiv)
{
- // Divide Bigint by int16
- sal_uInt16 nTmp;
- if ( rVal.nVal < 0 )
- {
- nTmp = static_cast<sal_uInt16>(-rVal.nVal);
- bIsNeg = !bIsNeg;
- }
- else
- nTmp = static_cast<sal_uInt16>(rVal.nVal);
-
- Div( nTmp, nTmp );
- *this = BigInt( nTmp );
- return *this;
+ if (bNegate)
+ pDiv->bIsNeg = !pDiv->bIsNeg;
+ pDiv->Normalize();
+ }
+ if (pMod)
+ {
+ *pMod = BigInt(nTmp);
}
+ return;
}
- if ( ABS_IsLess( rVal ) )
- return *this;
+ BigInt tmpA = MakeBig(), tmpB = rVal.MakeBig();
+ if (tmpA.ABS_IsLessBig(tmpB))
+ {
+ // First store *this to *pMod, then nullify *pDiv, to handle 'pDiv == this' case
+ if (pMod)
+ {
+ *pMod = *this;
+ pMod->Normalize();
+ }
+ if (pDiv)
+ *pDiv = 0;
+ return;
+ }
// Divide BigInt with BigInt
- BigInt aTmp1, aTmp2;
- aTmp1.MakeBigInt( *this );
- aTmp2.MakeBigInt( rVal );
- aTmp1.ModLong(aTmp2, *this);
- Normalize();
+ tmpA.DivModBig(tmpB, pDiv, pMod);
+}
+
+BigInt& BigInt::operator/=( const BigInt& rVal )
+{
+ DivMod(rVal, this, nullptr);
+ return *this;
+}
+
+BigInt& BigInt::operator%=( const BigInt& rVal )
+{
+ DivMod(rVal, nullptr, this);
return *this;
}
bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
{
- if (rVal1.nLen == 0 && rVal2.nLen == 0)
+ if (!rVal1.IsBig() && !rVal2.IsBig())
return rVal1.nVal == rVal2.nVal;
- BigInt nA, nB;
- nA.MakeBigInt(rVal1);
- nB.MakeBigInt(rVal2);
+ BigInt nA = rVal1.MakeBig(), nB = rVal2.MakeBig();
return nA.bIsNeg == nB.bIsNeg && nA.nLen == nB.nLen
&& std::equal(nA.nNum, nA.nNum + nA.nLen, nB.nNum);
}
-bool operator<( const BigInt& rVal1, const BigInt& rVal2 )
+std::strong_ordering operator<=>(const BigInt& rVal1, const BigInt& rVal2)
{
- if (rVal1.nLen == 0 && rVal2.nLen == 0)
- return rVal1.nVal < rVal2.nVal;
+ if (!rVal1.IsBig() && !rVal2.IsBig())
+ return rVal1.nVal <=> rVal2.nVal;
- BigInt nA, nB;
- nA.MakeBigInt(rVal1);
- nB.MakeBigInt(rVal2);
+ BigInt nA = rVal1.MakeBig(), nB = rVal2.MakeBig();
if (nA.bIsNeg != nB.bIsNeg)
- return !nB.bIsNeg;
- if (nA.nLen != nB.nLen)
- return nA.bIsNeg ? (nA.nLen > nB.nLen) : (nA.nLen < nB.nLen);
+ return nB.bIsNeg ? std::strong_ordering::less : std::strong_ordering::greater;
+ if (nA.nLen < nB.nLen)
+ return nB.bIsNeg ? std::strong_ordering::greater : std::strong_ordering::less;
+ if (nA.nLen > nB.nLen)
+ return nB.bIsNeg ? std::strong_ordering::less : std::strong_ordering::greater;
int i = nA.nLen - 1;
while (i > 0 && nA.nNum[i] == nB.nNum[i])
--i;
- return nA.bIsNeg ? (nA.nNum[i] > nB.nNum[i]) : (nA.nNum[i] < nB.nNum[i]);
+ return nB.bIsNeg ? (nB.nNum[i] <=> nA.nNum[i]) : (nA.nNum[i] <=> nB.nNum[i]);
}
tools::Long BigInt::Scale( tools::Long nVal, tools::Long nMul, tools::Long nDiv )
diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx
index 5df32719eb2c..208a6caee883 100644
--- a/tools/source/generic/color.cxx
+++ b/tools/source/generic/color.cxx
@@ -27,7 +27,9 @@
#include <tools/color.hxx>
#include <tools/helpers.hxx>
#include <tools/long.hxx>
+#include <o3tl/string_view.hxx>
#include <basegfx/color/bcolortools.hxx>
+#include <basegfx/numeric/ftools.hxx>
void Color::IncreaseLuminance(sal_uInt8 cLumInc)
{
@@ -50,9 +52,9 @@ void Color::DecreaseContrast(sal_uInt8 nContDec)
const double fM = (128.0 - 0.4985 * nContDec) / 128.0;
const double fOff = 128.0 - fM * 128.0;
- R = sal_uInt8(std::clamp(FRound(R * fM + fOff), tools::Long(0), tools::Long(255)));
- G = sal_uInt8(std::clamp(FRound(G * fM + fOff), tools::Long(0), tools::Long(255)));
- B = sal_uInt8(std::clamp(FRound(B * fM + fOff), tools::Long(0), tools::Long(255)));
+ R = basegfx::fround<sal_uInt8>(R * fM + fOff);
+ G = basegfx::fround<sal_uInt8>(G * fM + fOff);
+ B = basegfx::fround<sal_uInt8>(B * fM + fOff);
}
}
@@ -158,30 +160,30 @@ Color Color::HSBtoRGB( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri )
return Color( cR, cG, cB );
}
-Color Color::STRtoRGB(const OUString& colorname)
+Color Color::STRtoRGB(std::u16string_view colorname)
{
Color col;
- if(colorname.isEmpty()) return col;
+ if(colorname.empty()) return col;
- switch(colorname.getLength()){
+ switch(colorname.size()){
case 7:
- col.mValue = colorname.copy(1,6).toUInt32(16);
+ col.mValue = o3tl::toUInt32(colorname.substr(1,6), 16);
break;
case 6:
- col.mValue = colorname.toUInt32(16);
+ col.mValue = o3tl::toUInt32(colorname, 16);
break;
case 4:
{
sal_Unicode data[6] = { colorname[1], colorname[1], colorname[2],
colorname[2], colorname[3], colorname[3] };
- col.mValue = OUString(data,6).toUInt32(16);
+ col.mValue = o3tl::toUInt32(std::u16string_view(data,6), 16);
break;
}
case 3:
{
sal_Unicode data[6] = { colorname[0], colorname[0], colorname[1],
colorname[1], colorname[2], colorname[2] };
- col.mValue = OUString(data,6).toUInt32(16);
+ col.mValue = o3tl::toUInt32(std::u16string_view(data,6), 16);
break;
}
default:
@@ -194,14 +196,14 @@ OUString Color::AsRGBHexString() const
{
std::stringstream ss;
ss << std::hex << std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor());
- return OUString::createFromAscii(ss.str().c_str());
+ return OUString::createFromAscii(ss.str());
}
OUString Color::AsRGBHEXString() const
{
std::stringstream ss;
ss << std::hex << std::uppercase << std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor());
- return OUString::createFromAscii(ss.str().c_str());
+ return OUString::createFromAscii(ss.str());
}
void Color::ApplyTintOrShade(sal_Int16 n100thPercent)
diff --git a/tools/source/generic/config.cxx b/tools/source/generic/config.cxx
index b2eb546c0ef7..cc5cce9c3b16 100644
--- a/tools/source/generic/config.cxx
+++ b/tools/source/generic/config.cxx
@@ -205,7 +205,6 @@ static void ImplMakeConfigList( ImplConfigData* pData,
sal_uInt64 i;
const sal_uInt8* pLine;
ImplKeyData* pPrevKey = nullptr;
- ImplKeyData* pKey;
ImplGroupData* pPrevGroup = nullptr;
ImplGroupData* pGroup = nullptr;
i = 0;
@@ -250,7 +249,6 @@ static void ImplMakeConfigList( ImplConfigData* pData,
pData->mpFirstGroup = pGroup;
pPrevGroup = pGroup;
pPrevKey = nullptr;
- pKey = nullptr;
// filter group names
pLine++;
@@ -292,7 +290,7 @@ static void ImplMakeConfigList( ImplConfigData* pData,
{
while ( pGroup->mnEmptyLines )
{
- pKey = new ImplKeyData;
+ ImplKeyData* pKey = new ImplKeyData;
pKey->mbIsComment = true;
pPrevKey->mpNext = pKey;
pPrevKey = pKey;
@@ -301,7 +299,7 @@ static void ImplMakeConfigList( ImplConfigData* pData,
}
// Generate new key
- pKey = new ImplKeyData;
+ ImplKeyData* pKey = new ImplKeyData;
pKey->mpNext = nullptr;
if ( pPrevKey )
pPrevKey->mpNext = pKey;
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index 93a92fb3a12a..7dfddf50a880 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -19,24 +19,22 @@
#include <tools/fract.hxx>
#include <tools/debug.hxx>
-#include <tools/stream.hxx>
+#include <o3tl/hash_combine.hxx>
#include <o3tl/safeint.hxx>
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <algorithm>
+#include <bit>
#include <cmath>
#include <numeric>
#include <boost/rational.hpp>
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
static boost::rational<sal_Int32> rational_FromDouble(double dVal);
static void rational_ReduceInaccurate(boost::rational<sal_Int32>& rRational, unsigned nSignificantBits);
-static int impl_NumberOfBits( sal_uInt32 nNum );
+// Find the number of bits required to represent this number
+static int impl_NumberOfBits(sal_uInt32 nNum) { return 32 - std::countl_zero(nNum); }
static boost::rational<sal_Int32> toRational(sal_Int32 n, sal_Int32 d)
{
@@ -49,24 +47,40 @@ static boost::rational<sal_Int32> toRational(sal_Int32 n, sal_Int32 d)
return boost::rational<sal_Int32>(n, d);
}
-// Initialized by setting nNum as nominator and nDen as denominator
-// Negative values in the denominator are invalid and cause the
-// inversion of both nominator and denominator signs
-// in order to return the correct value.
+static constexpr bool isOutOfRange(sal_Int64 nNum)
+{
+ return nNum < std::numeric_limits<sal_Int32>::min()
+ || nNum > std::numeric_limits<sal_Int32>::max();
+}
+
Fraction::Fraction( sal_Int64 nNum, sal_Int64 nDen ) : mnNumerator(nNum), mnDenominator(nDen)
{
- assert( nNum >= std::numeric_limits<sal_Int32>::min() );
- assert( nNum <= std::numeric_limits<sal_Int32>::max( ));
- assert( nDen >= std::numeric_limits<sal_Int32>::min() );
- assert( nDen <= std::numeric_limits<sal_Int32>::max( ));
- if ( nDen == 0 )
+ if ( isOutOfRange(nNum) || isOutOfRange(nDen) )
+ {
+ // tdf#143200
+ if (const auto gcd = std::gcd(nNum, nDen); gcd > 1)
+ {
+ nNum /= gcd;
+ nDen /= gcd;
+ }
+ SAL_WARN_IF(isOutOfRange(nNum) || isOutOfRange(nDen),
+ "tools.fraction", "values outside of range we can represent, doing reduction, which will reduce precision");
+ while (isOutOfRange(nNum) || isOutOfRange(nDen))
+ {
+ nNum /= 2;
+ nDen /= 2;
+ }
+ mnNumerator = nNum;
+ mnDenominator = nDen;
+ }
+ if ( mnDenominator == 0 )
{
mbValid = false;
SAL_WARN( "tools.fraction", "'Fraction(" << nNum << ",0)' invalid fraction created" );
return;
}
- if ((nDen == -1 && nNum == std::numeric_limits<sal_Int32>::min()) ||
- (nNum == -1 && nDen == std::numeric_limits<sal_Int32>::min()))
+ else if ((nDen == -1 && nNum == std::numeric_limits<sal_Int32>::min()) ||
+ (nNum == -1 && nDen == std::numeric_limits<sal_Int32>::min()))
{
mbValid = false;
SAL_WARN("tools.fraction", "'Fraction(" << nNum << "," << nDen << ")' invalid fraction created");
@@ -77,21 +91,9 @@ Fraction::Fraction( sal_Int64 nNum, sal_Int64 nDen ) : mnNumerator(nNum), mnDeno
/**
* only here to prevent passing of NaN
*/
-Fraction::Fraction( double nNum, double nDen ) : mnNumerator(sal_Int64(nNum)), mnDenominator(sal_Int64(nDen))
-{
- assert( !std::isnan(nNum) );
- assert( !std::isnan(nDen) );
- assert( nNum >= std::numeric_limits<sal_Int32>::min() );
- assert( nNum <= std::numeric_limits<sal_Int32>::max( ));
- assert( nDen >= std::numeric_limits<sal_Int32>::min() );
- assert( nDen <= std::numeric_limits<sal_Int32>::max( ));
- if ( nDen == 0 )
- {
- mbValid = false;
- SAL_WARN( "tools.fraction", "'Fraction(" << nNum << ",0)' invalid fraction created" );
- return;
- }
-}
+Fraction::Fraction( double nNum, double nDen )
+ : Fraction(sal_Int64(nNum), sal_Int64(nDen))
+{}
Fraction::Fraction( double dVal )
{
@@ -182,6 +184,9 @@ namespace
sal_Int32 gcd1 = std::gcd(i.numerator(), den);
sal_Int32 gcd2 = std::gcd(num, i.denominator());
+ if (!gcd1 || !gcd2)
+ return true;
+
bool fail = false;
fail |= o3tl::checked_multiply(i.numerator() / gcd1, num / gcd2, num);
fail |= o3tl::checked_multiply(i.denominator() / gcd2, den / gcd1, den);
@@ -399,22 +404,6 @@ static boost::rational<sal_Int32> rational_FromDouble(double dVal)
return boost::rational<sal_Int32>( sal_Int32(dVal), nDen );
}
-/**
- * Find the number of bits required to represent this number, using the CLZ intrinsic
- */
-static int impl_NumberOfBits( sal_uInt32 nNum )
-{
- if (nNum == 0)
- return 0;
-#ifdef _MSC_VER
- unsigned long r = 0;
- _BitScanReverse(&r, nNum);
- return r + 1;
-#else
- return 32 - __builtin_clz(nNum);
-#endif
-}
-
/** Inaccurate cancellation for a fraction.
Clip both nominator and denominator to said number of bits. If
@@ -471,4 +460,60 @@ static void rational_ReduceInaccurate(boost::rational<sal_Int32>& rRational, uns
rRational.assign( bNeg ? -nMul : nMul, nDiv );
}
+size_t Fraction::GetHashValue() const
+{
+ size_t hash = 0;
+ o3tl::hash_combine( hash, mnNumerator );
+ o3tl::hash_combine( hash, mnDenominator );
+ o3tl::hash_combine( hash, mbValid );
+ return hash;
+}
+
+Fraction Fraction::MakeFraction( tools::Long nN1, tools::Long nN2, tools::Long nD1, tools::Long nD2 )
+{
+ if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
+ {
+ SAL_WARN("tools.fraction", "Invalid parameter for ImplMakeFraction");
+ return Fraction( 1, 1 );
+ }
+
+ tools::Long i = 1;
+
+ if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
+ if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
+ if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
+ if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
+ // all positive; i sign
+
+ assert( nN1 >= std::numeric_limits<sal_Int32>::min() );
+ assert( nN1 <= std::numeric_limits<sal_Int32>::max( ));
+ assert( nD1 >= std::numeric_limits<sal_Int32>::min() );
+ assert( nD1 <= std::numeric_limits<sal_Int32>::max( ));
+ assert( nN2 >= std::numeric_limits<sal_Int32>::min() );
+ assert( nN2 <= std::numeric_limits<sal_Int32>::max( ));
+ assert( nD2 >= std::numeric_limits<sal_Int32>::min() );
+ assert( nD2 <= std::numeric_limits<sal_Int32>::max( ));
+
+ boost::rational<sal_Int32> a = toRational(i*nN1, nD1);
+ boost::rational<sal_Int32> b = toRational(nN2, nD2);
+ bool bFail = checked_multiply_by(a, b);
+
+ while ( bFail ) {
+ if ( nN1 > nN2 )
+ nN1 = (nN1 + 1) / 2;
+ else
+ nN2 = (nN2 + 1) / 2;
+ if ( nD1 > nD2 )
+ nD1 = (nD1 + 1) / 2;
+ else
+ nD2 = (nD2 + 1) / 2;
+
+ a = toRational(i*nN1, nD1);
+ b = toRational(nN2, nD2);
+ bFail = checked_multiply_by(a, b);
+ }
+
+ return Fraction(a.numerator(), a.denominator());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/generic/gen.cxx b/tools/source/generic/gen.cxx
index 1fe47071d4ce..012318c0218d 100644
--- a/tools/source/generic/gen.cxx
+++ b/tools/source/generic/gen.cxx
@@ -18,14 +18,13 @@
*/
#include <sal/config.h>
-#include <sal/log.hxx>
+#include <rtl/string.hxx>
#include <algorithm>
-#include <cassert>
-#include <sstream>
+#include <tuple>
+#include <o3tl/hash_combine.hxx>
#include <o3tl/safeint.hxx>
#include <tools/gen.hxx>
-#include <tools/stream.hxx>
OString Pair::toString() const
{
@@ -35,159 +34,152 @@ OString Pair::toString() const
return OString::number(A()) + ", " + OString::number(B());
}
-void tools::Rectangle::SetSize( const Size& rSize )
+size_t Pair::GetHashValue() const
{
- if ( rSize.Width() < 0 )
- nRight = nLeft + rSize.Width() +1;
- else if ( rSize.Width() > 0 )
- nRight = nLeft + rSize.Width() -1;
- else
- SetWidthEmpty();
-
- if ( rSize.Height() < 0 )
- nBottom = nTop + rSize.Height() +1;
- else if ( rSize.Height() > 0 )
- nBottom = nTop + rSize.Height() -1;
- else
- SetHeightEmpty();
+ size_t hash = 0;
+ o3tl::hash_combine( hash, mnA );
+ o3tl::hash_combine( hash, mnB );
+ return hash;
}
-void tools::Rectangle::SaturatingSetSize(const Size& rSize)
+void RectangleTemplateBase::SaturatingSetSize(const SizeTemplateBase& rSize)
{
if (rSize.Width() < 0)
- nRight = o3tl::saturating_add(nLeft, (rSize.Width() + 1));
+ mnRight = o3tl::saturating_add(mnLeft, (rSize.Width() + 1));
else if ( rSize.Width() > 0 )
- nRight = o3tl::saturating_add(nLeft, (rSize.Width() - 1));
+ mnRight = o3tl::saturating_add(mnLeft, (rSize.Width() - 1));
else
SetWidthEmpty();
if ( rSize.Height() < 0 )
- nBottom = o3tl::saturating_add(nTop, (rSize.Height() + 1));
+ mnBottom = o3tl::saturating_add(mnTop, (rSize.Height() + 1));
else if ( rSize.Height() > 0 )
- nBottom = o3tl::saturating_add(nTop, (rSize.Height() - 1));
+ mnBottom = o3tl::saturating_add(mnTop, (rSize.Height() - 1));
else
SetHeightEmpty();
}
-void tools::Rectangle::SaturatingSetPosX(tools::Long x)
+void RectangleTemplateBase::SaturatingSetPosX(tools::Long x)
{
if (!IsWidthEmpty())
- nRight = o3tl::saturating_add(nRight, x - nLeft);
- nLeft = x;
+ mnRight = o3tl::saturating_add(mnRight, x - mnLeft);
+ mnLeft = x;
}
-void tools::Rectangle::SaturatingSetPosY(tools::Long y)
+void RectangleTemplateBase::SaturatingSetPosY(tools::Long y)
{
if (!IsHeightEmpty())
- nBottom = o3tl::saturating_add(nBottom, y - nTop);
- nTop = y;
+ mnBottom = o3tl::saturating_add(mnBottom, y - mnTop);
+ mnTop = y;
}
-tools::Rectangle& tools::Rectangle::Union( const tools::Rectangle& rRect )
+void RectangleTemplateBase::Union( const RectangleTemplateBase& rRect )
{
if ( rRect.IsEmpty() )
- return *this;
+ return;
if ( IsEmpty() )
*this = rRect;
else
{
- std::tie(nLeft, nRight) = std::minmax({ nLeft, rRect.nLeft, nRight, rRect.nRight });
- std::tie(nTop, nBottom) = std::minmax({ nTop, rRect.nTop, nBottom, rRect.nBottom });
+ std::tie(mnLeft, mnRight) = std::minmax({ mnLeft, rRect.mnLeft, mnRight, rRect.mnRight });
+ std::tie(mnTop, mnBottom) = std::minmax({ mnTop, rRect.mnTop, mnBottom, rRect.mnBottom });
}
-
- return *this;
}
-tools::Rectangle& tools::Rectangle::Intersection( const tools::Rectangle& rRect )
+void RectangleTemplateBase::Intersection( const RectangleTemplateBase& rRect )
{
if ( IsEmpty() )
- return *this;
+ return;
if ( rRect.IsEmpty() )
{
*this = tools::Rectangle();
- return *this;
+ return;
}
- // Justify rectangle
- tools::Rectangle aTmpRect( rRect );
- Justify();
- aTmpRect.Justify();
+ // Normalize rectangle
+ RectangleTemplateBase aTmpRect( rRect );
+ Normalize();
+ aTmpRect.Normalize();
// Perform intersection
- nLeft = std::max( nLeft, aTmpRect.nLeft );
- nRight = std::min( nRight, aTmpRect.nRight );
- nTop = std::max( nTop, aTmpRect.nTop );
- nBottom= std::min( nBottom, aTmpRect.nBottom );
+ mnLeft = std::max( mnLeft, aTmpRect.mnLeft );
+ mnRight = std::min( mnRight, aTmpRect.mnRight );
+ mnTop = std::max( mnTop, aTmpRect.mnTop );
+ mnBottom= std::min( mnBottom, aTmpRect.mnBottom );
// Determine if intersection is empty
- if ( nRight < nLeft || nBottom < nTop )
+ if ( mnRight < mnLeft || mnBottom < mnTop )
*this = tools::Rectangle();
-
- return *this;
}
-void tools::Rectangle::Justify()
+void RectangleTemplateBase::Normalize()
{
- if ((nRight < nLeft) && (!IsWidthEmpty()))
+ if ((mnRight < mnLeft) && (!IsWidthEmpty()))
{
- std::swap(nLeft, nRight);
+ std::swap(mnLeft, mnRight);
}
- if ((nBottom < nTop) && (!IsHeightEmpty()))
+ if ((mnBottom < mnTop) && (!IsHeightEmpty()))
{
- std::swap(nBottom, nTop);
+ std::swap(mnBottom, mnTop);
}
}
-bool tools::Rectangle::Contains( const Point& rPoint ) const
+bool RectangleTemplateBase::Contains( const PointTemplateBase& rPoint ) const
{
if ( IsEmpty() )
return false;
- if ( nLeft <= nRight )
+ if ( mnLeft <= mnRight )
{
- if ( (rPoint.X() < nLeft) || (rPoint.X() > nRight) )
+ if ( (rPoint.X() < mnLeft) || (rPoint.X() > mnRight) )
return false;
}
else
{
- if ( (rPoint.X() > nLeft) || (rPoint.X() < nRight) )
+ if ( (rPoint.X() > mnLeft) || (rPoint.X() < mnRight) )
return false;
}
- if ( nTop <= nBottom )
+ if ( mnTop <= mnBottom )
{
- if ( (rPoint.Y() < nTop) || (rPoint.Y() > nBottom) )
+ if ( (rPoint.Y() < mnTop) || (rPoint.Y() > mnBottom) )
return false;
}
else
{
- if ( (rPoint.Y() > nTop) || (rPoint.Y() < nBottom) )
+ if ( (rPoint.Y() > mnTop) || (rPoint.Y() < mnBottom) )
return false;
}
return true;
}
-bool tools::Rectangle::Contains( const tools::Rectangle& rRect ) const
+bool RectangleTemplateBase::Contains( const RectangleTemplateBase& rRect ) const
{
- return Contains( rRect.TopLeft() ) && Contains( rRect.BottomRight() );
+ return Contains( PointTemplateBase{ rRect.Left(), rRect.Top() } )
+ && Contains( PointTemplateBase{ rRect.Right(), rRect.Bottom() } );
}
-bool tools::Rectangle::Overlaps( const tools::Rectangle& rRect ) const
+bool RectangleTemplateBase::Overlaps( const RectangleTemplateBase& rRect ) const
{
// If there's no intersection, they don't overlap
- return !GetIntersection( rRect ).IsEmpty();
+ RectangleTemplateBase aTmp(*this);
+ aTmp.Intersection(rRect);
+ return !aTmp.IsEmpty();
}
-OString tools::Rectangle::toString() const
+OString RectangleTemplateBase::toString() const
{
// Note that this is not just used for debugging output but the
// format is parsed by external code (passed in callbacks to
// LibreOfficeKit clients). So don't change.
- return OString::number(Left()) + ", " + OString::number(Top()) + ", " + OString::number(getWidth()) + ", " + OString::number(getHeight());
+ return OString::number(Left()) + ", "
+ + OString::number(Top()) + ", "
+ + OString::number(getOpenWidth()) + ", "
+ + OString::number(getOpenHeight());
}
-void tools::Rectangle::expand(tools::Long nExpandBy)
+void RectangleTemplateBase::expand(tools::Long nExpandBy)
{
AdjustLeft(-nExpandBy);
AdjustTop(-nExpandBy);
@@ -195,32 +187,32 @@ void tools::Rectangle::expand(tools::Long nExpandBy)
AdjustBottom(nExpandBy);
}
-void tools::Rectangle::shrink(tools::Long nShrinkBy)
+void RectangleTemplateBase::shrink(tools::Long nShrinkBy)
{
- nLeft += nShrinkBy;
- nTop += nShrinkBy;
+ mnLeft += nShrinkBy;
+ mnTop += nShrinkBy;
if (!IsWidthEmpty())
- nRight -= nShrinkBy;
+ mnRight -= nShrinkBy;
if (!IsHeightEmpty())
- nBottom -= nShrinkBy;
+ mnBottom -= nShrinkBy;
}
-tools::Long tools::Rectangle::AdjustRight(tools::Long nHorzMoveDelta)
+tools::Long RectangleTemplateBase::AdjustRight(tools::Long nHorzMoveDelta)
{
if (IsWidthEmpty())
- nRight = nLeft + nHorzMoveDelta - 1;
+ mnRight = mnLeft + nHorzMoveDelta - 1;
else
- nRight += nHorzMoveDelta;
- return nRight;
+ mnRight += nHorzMoveDelta;
+ return mnRight;
}
-tools::Long tools::Rectangle::AdjustBottom( tools::Long nVertMoveDelta )
+tools::Long RectangleTemplateBase::AdjustBottom( tools::Long nVertMoveDelta )
{
if (IsHeightEmpty())
- nBottom = nTop + nVertMoveDelta - 1;
+ mnBottom = mnTop + nVertMoveDelta - 1;
else
- nBottom += nVertMoveDelta;
- return nBottom;
+ mnBottom += nVertMoveDelta;
+ return mnBottom;
}
static_assert( std::is_trivially_copyable< Pair >::value );
diff --git a/tools/source/generic/line.cxx b/tools/source/generic/line.cxx
index 26465c5c85d6..328ae3e35e66 100644
--- a/tools/source/generic/line.cxx
+++ b/tools/source/generic/line.cxx
@@ -17,6 +17,9 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <basegfx/numeric/ftools.hxx>
#include <tools/line.hxx>
#include <tools/helpers.hxx>
@@ -37,8 +40,8 @@ bool Line::Intersection( const Line& rLine, Point& rIntersection ) const
if( Intersection( rLine, fX, fY ) )
{
- rIntersection.setX( FRound( fX ) );
- rIntersection.setY( FRound( fY ) );
+ rIntersection.setX(basegfx::fround<tools::Long>(fX));
+ rIntersection.setY(basegfx::fround<tools::Long>(fY));
bRet = true;
}
else
@@ -49,17 +52,17 @@ bool Line::Intersection( const Line& rLine, Point& rIntersection ) const
bool Line::Intersection( const tools::Line& rLine, double& rIntersectionX, double& rIntersectionY ) const
{
- const double fAx = maEnd.X() - maStart.X();
- const double fAy = maEnd.Y() - maStart.Y();
- const double fBx = rLine.maStart.X() - rLine.maEnd.X();
- const double fBy = rLine.maStart.Y() - rLine.maEnd.Y();
+ const double fAx = static_cast<double>(maEnd.X()) - maStart.X();
+ const double fAy = static_cast<double>(maEnd.Y()) - maStart.Y();
+ const double fBx = static_cast<double>(rLine.maStart.X()) - rLine.maEnd.X();
+ const double fBy = static_cast<double>(rLine.maStart.Y()) - rLine.maEnd.Y();
const double fDen = fAy * fBx - fAx * fBy;
bool bOk = false;
if( fDen != 0. )
{
- const double fCx = maStart.X() - rLine.maStart.X();
- const double fCy = maStart.Y() - rLine.maStart.Y();
+ const double fCx = static_cast<double>(maStart.X()) - rLine.maStart.X();
+ const double fCy = static_cast<double>(maStart.Y()) - rLine.maStart.Y();
const double fA = fBy * fCx - fBx * fCy;
const bool bGreater = ( fDen > 0. );
@@ -104,13 +107,13 @@ double Line::GetDistance( const double& rPtX, const double& rPtY ) const
if( maStart != maEnd )
{
- const double fDistX = maEnd.X() - maStart.X();
- const double fDistY = maEnd.Y() - maStart.Y();
- const double fACX = maStart.X() - rPtX;
- const double fACY = maStart.Y() - rPtY;
- const double fL2 = fDistX * fDistX + fDistY * fDistY;
- const double fR = ( fACY * -fDistY - fACX * fDistX ) / fL2;
- const double fS = ( fACY * fDistX - fACX * fDistY ) / fL2;
+ const double fDistX = static_cast<double>(maEnd.X()) - maStart.X();
+ const double fDistY = static_cast<double>(maEnd.Y()) - maStart.Y();
+ const double fACX = static_cast<double>(maStart.X()) - rPtX;
+ const double fACY = static_cast<double>(maStart.Y()) - rPtY;
+ const double fL2 = fDistX * fDistX + fDistY * fDistY;
+ const double fR = ( fACY * -fDistY - fACX * fDistX ) / fL2;
+ const double fS = ( fACY * fDistX - fACX * fDistY ) / fL2;
if( fR < 0.0 )
{
diff --git a/tools/source/generic/point.cxx b/tools/source/generic/point.cxx
index e9c3bd842a15..e71f60411a86 100644
--- a/tools/source/generic/point.cxx
+++ b/tools/source/generic/point.cxx
@@ -18,23 +18,22 @@
*/
#include <tools/gen.hxx>
-#include <basegfx/numeric/ftools.hxx>
-void Point::RotateAround( Point& rPoint,
+void PointTemplateBase::RotateAround( PointTemplateBase& rPoint,
Degree10 nOrientation ) const
{
- tools::Long nX = rPoint.X();
- tools::Long nY = rPoint.Y();
+ tools::Long nX = rPoint.mnA;
+ tools::Long nY = rPoint.mnB;
RotateAround(nX, nY, nOrientation);
- rPoint.setX(nX);
- rPoint.setY(nY);
+ rPoint.mnA = nX;
+ rPoint.mnB = nY;
}
-void Point::RotateAround( tools::Long& rX, tools::Long& rY,
+void PointTemplateBase::RotateAround( tools::Long& rX, tools::Long& rY,
Degree10 nOrientation ) const
{
- const tools::Long nOriginX = X();
- const tools::Long nOriginY = Y();
+ const tools::Long nOriginX = mnA;
+ const tools::Long nOriginY = mnB;
if ( (nOrientation >= 0_deg10) && !(nOrientation % 900_deg10) )
{
diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx
index 13d2df0e47ef..81419f7e70c3 100644
--- a/tools/source/generic/poly.cxx
+++ b/tools/source/generic/poly.cxx
@@ -38,20 +38,19 @@
#include <memory>
#include <vector>
-#include <iterator>
#include <algorithm>
-#include <cstdlib>
+#include <cassert>
#include <cstring>
#include <limits.h>
#include <cmath>
-#define EDGE_LEFT 1
-#define EDGE_TOP 2
-#define EDGE_RIGHT 4
-#define EDGE_BOTTOM 8
-#define EDGE_HORZ (EDGE_RIGHT | EDGE_LEFT)
-#define EDGE_VERT (EDGE_TOP | EDGE_BOTTOM)
-#define SMALL_DVALUE 0.0000001
+constexpr int EDGE_LEFT = 1;
+constexpr int EDGE_TOP = 2;
+constexpr int EDGE_RIGHT = 4;
+constexpr int EDGE_BOTTOM = 8;
+constexpr int EDGE_HORZ = EDGE_RIGHT | EDGE_LEFT;
+constexpr int EDGE_VERT = EDGE_TOP | EDGE_BOTTOM;
+constexpr double SMALL_DVALUE = 0.0000001;
#define FSQRT2 1.4142135623730950488016887242097
static double ImplGetParameter( const Point& rCenter, const Point& rPt, double fWR, double fHR )
@@ -122,7 +121,7 @@ ImplPolygon::ImplPolygon( const tools::Rectangle& rRect, sal_uInt32 nHorzRound,
if ( !rRect.IsEmpty() )
{
tools::Rectangle aRect( rRect );
- aRect.Justify(); // SJ: i9140
+ aRect.Normalize(); // SJ: i9140
nHorzRound = std::min( nHorzRound, static_cast<sal_uInt32>(std::abs( aRect.GetWidth() >> 1 )) );
nVertRound = std::min( nVertRound, static_cast<sal_uInt32>(std::abs( aRect.GetHeight() >> 1 )) );
@@ -179,10 +178,10 @@ ImplPolygon::ImplPolygon( const Point& rCenter, tools::Long nRadX, tools::Long n
const bool bOverflow = o3tl::checked_multiply(nRadX, nRadY, nRadXY);
if (!bOverflow)
{
- nPoints = static_cast<sal_uInt16>(MinMax(
+ nPoints = std::clamp(
( M_PI * ( 1.5 * ( nRadX + nRadY ) -
sqrt( static_cast<double>(std::abs(nRadXY)) ) ) ),
- 32, 256 ));
+ 32.0, 256.0 );
}
else
{
@@ -204,8 +203,8 @@ ImplPolygon::ImplPolygon( const Point& rCenter, tools::Long nRadX, tools::Long n
for( i=0, nAngle = 0.0; i < nPoints4; i++, nAngle += nAngleStep )
{
- tools::Long nX = FRound( nRadX * cos( nAngle ) );
- tools::Long nY = FRound( -nRadY * sin( nAngle ) );
+ tools::Long nX = basegfx::fround<tools::Long>(nRadX * cos(nAngle));
+ tools::Long nY = basegfx::fround<tools::Long>(nRadY * -sin(nAngle));
Point* pPt = &(mxPointAry[i]);
pPt->setX( nX + rCenter.X() );
@@ -225,30 +224,30 @@ ImplPolygon::ImplPolygon( const Point& rCenter, tools::Long nRadX, tools::Long n
mnPoints = 0;
}
-ImplPolygon::ImplPolygon( const tools::Rectangle& rBound, const Point& rStart, const Point& rEnd,
- PolyStyle eStyle )
+ImplPolygon::ImplPolygon(const tools::Rectangle& rBound, const Point& rStart, const Point& rEnd,
+ PolyStyle eStyle, const bool bClockWiseArcDirection)
{
const auto nWidth = rBound.GetWidth();
const auto nHeight = rBound.GetHeight();
- if( ( nWidth != 0 ) && ( nHeight != 0 ) )
+ if ((nWidth != 0) && (nHeight != 0))
{
- const Point aCenter( rBound.Center() );
+ const Point aCenter(rBound.Center());
// tdf#142268 Get Top Left corner of rectangle (the rectangle is not always correctly created)
const auto aBoundLeft = rBound.Left() < aCenter.X() ? rBound.Left() : rBound.Right();
const auto aBoundTop = rBound.Top() < aCenter.Y() ? rBound.Top() : rBound.Bottom();
const auto nRadX = o3tl::saturating_sub(aCenter.X(), aBoundLeft);
const auto nRadY = o3tl::saturating_sub(aCenter.Y(), aBoundTop);
- sal_uInt16 nPoints;
+ sal_uInt16 nPoints;
tools::Long nRadXY;
const bool bOverflow = o3tl::checked_multiply(nRadX, nRadY, nRadXY);
if (!bOverflow)
{
- nPoints = static_cast<sal_uInt16>(MinMax(
+ nPoints = std::clamp(
( M_PI * ( 1.5 * ( nRadX + nRadY ) -
sqrt( static_cast<double>(std::abs(nRadXY)) ) ) ),
- 32, 256 ));
+ 32.0, 256.0 );
}
else
{
@@ -270,17 +269,30 @@ ImplPolygon::ImplPolygon( const tools::Rectangle& rBound, const Point& rStart, c
double fStep;
sal_uInt16 nStart;
sal_uInt16 nEnd;
- // #i73608# If startPoint is equal to endPoint, then draw full circle instead of nothing (as Metafiles spec)
- if( fDiff <= 0. )
- fDiff += 2 * M_PI;
+
+ if (bClockWiseArcDirection == false)
+ {
+ // #i73608# If startPoint is equal to endPoint, then draw full circle instead of nothing (as Metafiles spec)
+ if (fDiff <= 0.)
+ fDiff += 2. * M_PI;
+ }
+ else
+ {
+ fDiff = (2. * M_PI) - fDiff;
+ if (fDiff > 2. * M_PI)
+ fDiff -= 2. * M_PI;
+ }
// Proportionally shrink number of points( fDiff / (2PI) );
- nPoints = std::max( static_cast<sal_uInt16>( ( fDiff / (2 * M_PI) ) * nPoints ), sal_uInt16(16) );
- fStep = fDiff / ( nPoints - 1 );
+ nPoints = std::max(static_cast<sal_uInt16>((fDiff / (2. * M_PI)) * nPoints), sal_uInt16(16));
+ fStep = fDiff / (nPoints - 1);
+ if (bClockWiseArcDirection == true)
+ fStep = -fStep;
- if( PolyStyle::Pie == eStyle )
+ if (PolyStyle::Pie == eStyle)
{
- const Point aCenter2( FRound( fCenterX ), FRound( fCenterY ) );
+ const Point aCenter2(basegfx::fround<tools::Long>(fCenterX),
+ basegfx::fround<tools::Long>(fCenterY));
nStart = 1;
nEnd = nPoints + 1;
@@ -299,8 +311,8 @@ ImplPolygon::ImplPolygon( const tools::Rectangle& rBound, const Point& rStart, c
{
Point& rPt = mxPointAry[nStart];
- rPt.setX( FRound( fCenterX + fRadX * cos( fStart ) ) );
- rPt.setY( FRound( fCenterY - fRadY * sin( fStart ) ) );
+ rPt.setX(basegfx::fround<tools::Long>(fCenterX + fRadX * cos(fStart)));
+ rPt.setY(basegfx::fround<tools::Long>(fCenterY - fRadY * sin(fStart)));
}
if( PolyStyle::Chord == eStyle )
@@ -344,8 +356,8 @@ ImplPolygon::ImplPolygon( const Point& rBezPt1, const Point& rCtrlPt1,
double fK12 = fK_1 * fK1_2;
double fK21 = fK_2 * fK1_1;
- rPt.setX( FRound( fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3 ) );
- rPt.setY( FRound( fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3 ) );
+ rPt.setX(basegfx::fround<tools::Long>(fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3));
+ rPt.setY(basegfx::fround<tools::Long>(fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3));
}
}
@@ -388,7 +400,9 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon)
for(sal_uInt32 a(0); a < nLoopCount; a++)
{
// add current point (always) and remember StartPointIndex for evtl. later corrections
- const Point aStartPoint(FRound(aBezier.getStartPoint().getX()), FRound(aBezier.getStartPoint().getY()));
+ const Point aStartPoint(
+ basegfx::fround<tools::Long>(aBezier.getStartPoint().getX()),
+ basegfx::fround<tools::Long>(aBezier.getStartPoint().getY()));
const sal_uInt32 nStartPointIndex(nArrayInsert);
mxPointAry[nStartPointIndex] = aStartPoint;
mxFlagAry[nStartPointIndex] = PolyFlags::Normal;
@@ -403,11 +417,13 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon)
if(aBezier.isBezier())
{
// if one is used, add always two control points due to the old schema
- mxPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointA().getX()), FRound(aBezier.getControlPointA().getY()));
+ mxPointAry[nArrayInsert] = Point(basegfx::fround<tools::Long>(aBezier.getControlPointA().getX()),
+ basegfx::fround<tools::Long>(aBezier.getControlPointA().getY()));
mxFlagAry[nArrayInsert] = PolyFlags::Control;
nArrayInsert++;
- mxPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointB().getX()), FRound(aBezier.getControlPointB().getY()));
+ mxPointAry[nArrayInsert] = Point(basegfx::fround<tools::Long>(aBezier.getControlPointB().getX()),
+ basegfx::fround<tools::Long>(aBezier.getControlPointB().getY()));
mxFlagAry[nArrayInsert] = PolyFlags::Control;
nArrayInsert++;
}
@@ -442,7 +458,8 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon)
{
// add last point as closing point
const basegfx::B2DPoint aClosingPoint(rPolygon.getB2DPoint(nB2DLocalCount - 1));
- const Point aEnd(FRound(aClosingPoint.getX()), FRound(aClosingPoint.getY()));
+ const Point aEnd(basegfx::fround<tools::Long>(aClosingPoint.getX()),
+ basegfx::fround<tools::Long>(aClosingPoint.getY()));
mxPointAry[nArrayInsert] = aEnd;
mxFlagAry[nArrayInsert] = PolyFlags::Normal;
nArrayInsert++;
@@ -475,7 +492,8 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon)
for(sal_uInt32 a(0); a < nB2DLocalCount; a++)
{
basegfx::B2DPoint aB2DPoint(rPolygon.getB2DPoint(a));
- Point aPoint(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
+ Point aPoint(basegfx::fround<tools::Long>(aB2DPoint.getX()),
+ basegfx::fround<tools::Long>(aB2DPoint.getY()));
mxPointAry[nIndex++] = aPoint;
}
@@ -903,8 +921,9 @@ Polygon::Polygon( const Point& rCenter, tools::Long nRadX, tools::Long nRadY )
{
}
-Polygon::Polygon( const tools::Rectangle& rBound, const Point& rStart, const Point& rEnd,
- PolyStyle eStyle ) : mpImplPolygon(ImplPolygon(rBound, rStart, rEnd, eStyle))
+Polygon::Polygon(const tools::Rectangle& rBound, const Point& rStart, const Point& rEnd,
+ PolyStyle eStyle, const bool bClockWiseArcDirection)
+ : mpImplPolygon(ImplPolygon(rBound, rStart, rEnd, eStyle, bClockWiseArcDirection))
{
}
@@ -1025,7 +1044,7 @@ double Polygon::CalcDistance( sal_uInt16 nP1, sal_uInt16 nP2 ) const
const double fDx = rP2.X() - rP1.X();
const double fDy = rP2.Y() - rP1.Y();
- return sqrt( fDx * fDx + fDy * fDy );
+ return std::hypot( fDx, fDy );
}
void Polygon::Optimize( PolyOptimizeFlags nOptimizeFlags )
@@ -1093,8 +1112,8 @@ void Polygon::Optimize( PolyOptimizeFlags nOptimizeFlags )
/** Recursively subdivide cubic bezier curve via deCasteljau.
- @param rPointIter
- Output iterator, where the subdivided polylines are written to.
+ @param rPoints
+ Output vector, where the subdivided polylines are written to.
@param d
Squared difference of curve to a straight line
@@ -1107,7 +1126,7 @@ void Polygon::Optimize( PolyOptimizeFlags nOptimizeFlags )
curve does not deviate more than one pixel from a straight line.
*/
-static void ImplAdaptiveSubdivide( ::std::back_insert_iterator< ::std::vector< Point > >& rPointIter,
+static void ImplAdaptiveSubdivide( std::vector<Point>& rPoints,
const double old_d2,
int recursionDepth,
const double d2,
@@ -1143,7 +1162,8 @@ static void ImplAdaptiveSubdivide( ::std::back_insert_iterator< ::std::vector< P
// stop if distance from line is guaranteed to be bounded by d
if( old_d2 > d2 &&
recursionDepth < maxRecursionDepth &&
- distance2 >= d2 )
+ distance2 >= d2 &&
+ rPoints.size() < SAL_MAX_UINT16 )
{
// deCasteljau bezier arc, split at t=0.5
// Foley/vanDam, p. 508
@@ -1159,15 +1179,15 @@ static void ImplAdaptiveSubdivide( ::std::back_insert_iterator< ::std::vector< P
// subdivide further
++recursionDepth;
- ImplAdaptiveSubdivide(rPointIter, distance2, recursionDepth, d2, L1x, L1y, L2x, L2y, L3x, L3y, L4x, L4y);
- ImplAdaptiveSubdivide(rPointIter, distance2, recursionDepth, d2, R1x, R1y, R2x, R2y, R3x, R3y, R4x, R4y);
+ ImplAdaptiveSubdivide(rPoints, distance2, recursionDepth, d2, L1x, L1y, L2x, L2y, L3x, L3y, L4x, L4y);
+ ImplAdaptiveSubdivide(rPoints, distance2, recursionDepth, d2, R1x, R1y, R2x, R2y, R3x, R3y, R4x, R4y);
}
else
{
// requested resolution reached.
// Add end points to output iterator.
// order is preserved, since this is so to say depth first traversal.
- *rPointIter++ = Point( FRound(P1x), FRound(P1y) );
+ rPoints.push_back(Point(basegfx::fround<tools::Long>(P1x), basegfx::fround<tools::Long>(P1y)));
}
}
@@ -1183,7 +1203,6 @@ void Polygon::AdaptiveSubdivide( Polygon& rResult, const double d ) const
sal_uInt16 nPts( GetSize() );
::std::vector< Point > aPoints;
aPoints.reserve( nPts );
- ::std::back_insert_iterator< ::std::vector< Point > > aPointIter( aPoints );
for(i=0; i<nPts;)
{
@@ -1197,7 +1216,7 @@ void Polygon::AdaptiveSubdivide( Polygon& rResult, const double d ) const
( PolyFlags::Control == mpImplPolygon->mxFlagAry[ i + 2 ] ) &&
( PolyFlags::Normal == P4 || PolyFlags::Smooth == P4 || PolyFlags::Symmetric == P4 ) )
{
- ImplAdaptiveSubdivide( aPointIter, d*d+1.0, 0, d*d,
+ ImplAdaptiveSubdivide( aPoints, d*d+1.0, 0, d*d,
mpImplPolygon->mxPointAry[ i ].X(), mpImplPolygon->mxPointAry[ i ].Y(),
mpImplPolygon->mxPointAry[ i+1 ].X(), mpImplPolygon->mxPointAry[ i+1 ].Y(),
mpImplPolygon->mxPointAry[ i+2 ].X(), mpImplPolygon->mxPointAry[ i+2 ].Y(),
@@ -1207,7 +1226,7 @@ void Polygon::AdaptiveSubdivide( Polygon& rResult, const double d ) const
}
}
- *aPointIter++ = mpImplPolygon->mxPointAry[ i++ ];
+ aPoints.push_back(mpImplPolygon->mxPointAry[i++]);
if (aPoints.size() >= SAL_MAX_UINT16)
{
@@ -1420,8 +1439,8 @@ void Polygon::Rotate( const Point& rCenter, double fSin, double fCos )
const tools::Long nX = rPt.X() - nCenterX;
const tools::Long nY = rPt.Y() - nCenterY;
- rPt.setX( FRound( fCos * nX + fSin * nY ) + nCenterX );
- rPt.setY( - FRound( fSin * nX - fCos * nY ) + nCenterY );
+ rPt.setX(basegfx::fround<tools::Long>(fCos * nX + fSin * nY + nCenterX));
+ rPt.setY(basegfx::fround<tools::Long>(-(fSin * nX - fCos * nY - nCenterY)));
}
}
@@ -1431,9 +1450,9 @@ void Polygon::Clip( const tools::Rectangle& rRect )
// Use PolyPolygon::Clip().
assert( !HasFlags());
- // #105251# Justify rect before edge filtering
+ // #105251# Normalize rect before edge filtering
tools::Rectangle aJustifiedRect( rRect );
- aJustifiedRect.Justify();
+ aJustifiedRect.Normalize();
sal_uInt16 nSourceSize = mpImplPolygon->mnPoints;
ImplPolygonPointFilter aPolygon( nSourceSize );
@@ -1567,7 +1586,7 @@ void Polygon::Insert( sal_uInt16 nPos, const tools::Polygon& rPoly )
Point& Polygon::operator[]( sal_uInt16 nPos )
{
- DBG_ASSERT( nPos < mpImplPolygon->mnPoints, "Polygon::[]: nPos >= nPoints" );
+ assert( nPos < mpImplPolygon->mnPoints );
return mpImplPolygon->mxPointAry[nPos];
}
@@ -1663,7 +1682,12 @@ void Polygon::ImplRead( SvStream& rIStream )
if ( bHasPolyFlags )
{
mpImplPolygon->mxFlagAry.reset(new PolyFlags[mpImplPolygon->mnPoints]);
- rIStream.ReadBytes(mpImplPolygon->mxFlagAry.get(), mpImplPolygon->mnPoints);
+ auto nRead = rIStream.ReadBytes(mpImplPolygon->mxFlagAry.get(), mpImplPolygon->mnPoints);
+ if (nRead != mpImplPolygon->mnPoints)
+ {
+ SAL_WARN("tools", "Short read");
+ memset(mpImplPolygon->mxFlagAry.get() + nRead, 0, mpImplPolygon->mnPoints - nRead);
+ }
}
}
diff --git a/tools/source/generic/poly2.cxx b/tools/source/generic/poly2.cxx
index c6d0a46032c8..a00f64f41b18 100644
--- a/tools/source/generic/poly2.cxx
+++ b/tools/source/generic/poly2.cxx
@@ -40,6 +40,10 @@ PolyPolygon::PolyPolygon( const tools::Polygon& rPoly )
: mpImplPolyPolygon( rPoly )
{
}
+PolyPolygon::PolyPolygon( const tools::Rectangle& rRect )
+ : mpImplPolyPolygon( tools::Polygon(rRect) )
+{
+}
PolyPolygon::PolyPolygon( const tools::PolyPolygon& rPolyPoly )
: mpImplPolyPolygon( rPolyPoly.mpImplPolyPolygon )
diff --git a/tools/source/inet/hostfilter.cxx b/tools/source/inet/hostfilter.cxx
new file mode 100644
index 000000000000..5bc63d42cfb7
--- /dev/null
+++ b/tools/source/inet/hostfilter.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <tools/hostfilter.hxx>
+#include <regex>
+
+static std::regex g_AllowedHostsRegex("");
+static bool g_AllowedHostsSet = false;
+
+void HostFilter::setAllowedHostsRegex(const char* sAllowedRegex)
+{
+ g_AllowedHostsSet = sAllowedRegex && sAllowedRegex[0] != '\0';
+ if (g_AllowedHostsSet)
+ g_AllowedHostsRegex = sAllowedRegex;
+}
+
+bool HostFilter::isForbidden(const OUString& rHost)
+{
+ if (!g_AllowedHostsSet)
+ return false;
+
+ return !std::regex_match(rHost.toUtf8().getStr(), g_AllowedHostsRegex);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tools/source/inet/inetmime.cxx b/tools/source/inet/inetmime.cxx
index f7265523b6e2..6694dc398669 100644
--- a/tools/source/inet/inetmime.cxx
+++ b/tools/source/inet/inetmime.cxx
@@ -27,6 +27,7 @@
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/tencinfo.h>
+#include <tools/debug.hxx>
#include <tools/inetmime.hxx>
#include <rtl/character.hxx>
@@ -131,30 +132,6 @@ std::unique_ptr<sal_Unicode[]> convertToUnicode(const char * pBegin,
return pBuffer;
}
-/** Put the UTF-16 encoding of a UTF-32 character into a buffer.
-
- @param pBuffer Points to a buffer, must not be null.
-
- @param nUTF32 A UTF-32 character, must be in the range 0..0x10FFFF.
-
- @return A pointer past the UTF-16 characters put into the buffer
- (i.e., pBuffer + 1 or pBuffer + 2).
- */
-sal_Unicode * putUTF32Character(sal_Unicode * pBuffer,
- sal_uInt32 nUTF32)
-{
- DBG_ASSERT(rtl::isUnicodeCodePoint(nUTF32), "putUTF32Character(): Bad char");
- if (nUTF32 < 0x10000)
- *pBuffer++ = sal_Unicode(nUTF32);
- else
- {
- nUTF32 -= 0x10000;
- *pBuffer++ = sal_Unicode(0xD800 | (nUTF32 >> 10));
- *pBuffer++ = sal_Unicode(0xDC00 | (nUTF32 & 0x3FF));
- }
- return pBuffer;
-}
-
void writeUTF8(OStringBuffer & rSink, sal_uInt32 nChar)
{
// See RFC 2279 for a discussion of UTF-8.
@@ -163,30 +140,34 @@ void writeUTF8(OStringBuffer & rSink, sal_uInt32 nChar)
if (nChar < 0x80)
rSink.append(char(nChar));
else if (nChar < 0x800)
- rSink.append(char(nChar >> 6 | 0xC0))
- .append(char((nChar & 0x3F) | 0x80));
+ rSink.append(OStringChar(char(nChar >> 6 | 0xC0))
+ + OStringChar(char((nChar & 0x3F) | 0x80)));
else if (nChar < 0x10000)
- rSink.append(char(nChar >> 12 | 0xE0))
- .append(char((nChar >> 6 & 0x3F) | 0x80))
- .append(char((nChar & 0x3F) | 0x80));
+ rSink.append(
+ OStringChar(char(nChar >> 12 | 0xE0))
+ + OStringChar(char((nChar >> 6 & 0x3F) | 0x80))
+ + OStringChar(char((nChar & 0x3F) | 0x80)));
else if (nChar < 0x200000)
- rSink.append(char(nChar >> 18 | 0xF0))
- .append(char((nChar >> 12 & 0x3F) | 0x80))
- .append(char((nChar >> 6 & 0x3F) | 0x80))
- .append(char((nChar & 0x3F) | 0x80));
+ rSink.append(
+ OStringChar(char(nChar >> 18 | 0xF0))
+ + OStringChar(char((nChar >> 12 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 6 & 0x3F) | 0x80))
+ + OStringChar(char((nChar & 0x3F) | 0x80)));
else if (nChar < 0x4000000)
- rSink.append(char(nChar >> 24 | 0xF8))
- .append(char((nChar >> 18 & 0x3F) | 0x80))
- .append(char((nChar >> 12 & 0x3F) | 0x80))
- .append(char((nChar >> 6 & 0x3F) | 0x80))
- .append(char((nChar & 0x3F) | 0x80));
+ rSink.append(
+ OStringChar(char(nChar >> 24 | 0xF8))
+ + OStringChar(char((nChar >> 18 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 12 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 6 & 0x3F) | 0x80))
+ + OStringChar(char((nChar & 0x3F) | 0x80)));
else
- rSink.append(char(nChar >> 30 | 0xFC))
- .append(char((nChar >> 24 & 0x3F) | 0x80))
- .append(char((nChar >> 18 & 0x3F) | 0x80))
- .append(char((nChar >> 12 & 0x3F) | 0x80))
- .append(char((nChar >> 6 & 0x3F) | 0x80))
- .append(char((nChar & 0x3F) | 0x80));
+ rSink.append(
+ OStringChar(char(nChar >> 30 | 0xFC))
+ + OStringChar(char((nChar >> 24 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 18 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 12 & 0x3F) | 0x80))
+ + OStringChar(char((nChar >> 6 & 0x3F) | 0x80))
+ + OStringChar(char((nChar & 0x3F) | 0x80)));
}
bool translateUTF8Char(const char *& rBegin,
@@ -1027,11 +1008,11 @@ bool INetMIME::scanUnsigned(const sal_Unicode *& rBegin,
// static
sal_Unicode const * INetMIME::scanContentType(
- OUString const & rStr, OUString * pType,
+ std::u16string_view rStr, OUString * pType,
OUString * pSubType, INetContentTypeParameterList * pParameters)
{
- sal_Unicode const * pBegin = rStr.getStr();
- sal_Unicode const * pEnd = pBegin + rStr.getLength();
+ sal_Unicode const * pBegin = rStr.data();
+ sal_Unicode const * pEnd = pBegin + rStr.size();
sal_Unicode const * p = skipLinearWhiteSpaceComment(pBegin, pEnd);
sal_Unicode const * pTypeBegin = p;
while (p != pEnd && isTokenChar(*p))
@@ -1290,10 +1271,11 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
bDone = true;
break;
}
- sText.append(rBody.subView(
- (pEncodedTextCopyBegin - pBegin),
- (q - 1 - pEncodedTextCopyBegin)));
- sText.append(char(nDigit1 << 4 | nDigit2));
+ sText.append(
+ rBody.subView(
+ (pEncodedTextCopyBegin - pBegin),
+ (q - 1 - pEncodedTextCopyBegin))
+ + OStringChar(char(nDigit1 << 4 | nDigit2)));
q += 2;
pEncodedTextCopyBegin = q;
break;
@@ -1310,10 +1292,11 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
break;
case '_':
- sText.append(rBody.subView(
- (pEncodedTextCopyBegin - pBegin),
- (q - 1 - pEncodedTextCopyBegin)));
- sText.append(' ');
+ sText.append(
+ rBody.subView(
+ (pEncodedTextCopyBegin - pBegin),
+ (q - 1 - pEncodedTextCopyBegin))
+ + OString::Concat(" "));
pEncodedTextCopyBegin = q;
break;
@@ -1386,9 +1369,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
if (translateUTF8Char(pUTF8End, pEnd, nCharacter))
{
appendISO88591(sDecoded, pCopyBegin, p - 1);
- sal_Unicode aUTF16Buf[2];
- sal_Int32 nUTF16Len = putUTF32Character(aUTF16Buf, nCharacter) - aUTF16Buf;
- sDecoded.append(aUTF16Buf, nUTF16Len);
+ sDecoded.appendUtf32(nCharacter);
p = pUTF8End;
pCopyBegin = p;
}
diff --git a/tools/source/inet/inetmsg.cxx b/tools/source/inet/inetmsg.cxx
index bb8a700d16f1..a5c6838176a1 100644
--- a/tools/source/inet/inetmsg.cxx
+++ b/tools/source/inet/inetmsg.cxx
@@ -22,6 +22,9 @@
#include <tools/inetmsg.hxx>
#include <comphelper/string.hxx>
#include <rtl/character.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/sprintf.hxx>
+#include <o3tl/string_view.hxx>
#include <map>
@@ -52,32 +55,32 @@ static const char *months[12] =
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
-static sal_uInt16 ParseNumber(const OString& rStr, sal_Int32& nIndex)
+static sal_uInt16 ParseNumber(std::string_view rStr, size_t& nIndex)
{
- sal_Int32 n = nIndex;
- while ((n < rStr.getLength())
+ size_t n = nIndex;
+ while ((n < rStr.size())
&& rtl::isAsciiDigit(static_cast<unsigned char>(rStr[n])))
n++;
- OString aNum(rStr.copy(nIndex, (n - nIndex)));
+ std::string_view aNum(rStr.substr(nIndex, (n - nIndex)));
nIndex = n;
- return static_cast<sal_uInt16>(aNum.toInt32());
+ return static_cast<sal_uInt16>(o3tl::toInt32(aNum));
}
-static sal_uInt16 ParseMonth(const OString& rStr, sal_Int32& nIndex)
+static sal_uInt16 ParseMonth(std::string_view rStr, size_t& nIndex)
{
- sal_Int32 n = nIndex;
- while ((n < rStr.getLength())
+ size_t n = nIndex;
+ while ((n < rStr.size())
&& rtl::isAsciiAlpha(static_cast<unsigned char>(rStr[n])))
n++;
- OString aMonth(rStr.copy(nIndex, 3));
+ std::string_view aMonth(rStr.substr(nIndex, 3));
nIndex = n;
sal_uInt16 i;
for (i = 0; i < 12; i++)
- if (aMonth.equalsIgnoreAsciiCase(months[i])) break;
+ if (o3tl::equalsIgnoreAsciiCase(aMonth, months[i])) break;
return (i + 1);
}
@@ -92,20 +95,20 @@ bool INetMIMEMessage::ParseDateField (
if (aDateField.indexOf(':') != -1)
{
// Some DateTime format.
- sal_Int32 nIndex = 0;
+ size_t nIndex = 0;
// Skip over <Wkd> or <Weekday>, leading and trailing space.
- while ((nIndex < aDateField.getLength()) &&
+ while ((nIndex < o3tl::make_unsigned(aDateField.getLength())) &&
(aDateField[nIndex] == ' '))
nIndex++;
while (
- (nIndex < aDateField.getLength()) &&
+ (nIndex < o3tl::make_unsigned(aDateField.getLength())) &&
(rtl::isAsciiAlpha (static_cast<unsigned char>(aDateField[nIndex])) ||
(aDateField[nIndex] == ',') ))
nIndex++;
- while ((nIndex < aDateField.getLength()) &&
+ while ((nIndex < o3tl::make_unsigned(aDateField.getLength())) &&
(aDateField[nIndex] == ' '))
nIndex++;
@@ -143,7 +146,7 @@ bool INetMIMEMessage::ParseDateField (
rDateTime.SetSec (ParseNumber (aDateField, nIndex)); nIndex++;
rDateTime.SetNanoSec (0);
- const char cPossiblePlusMinus = nIndex < aDateField.getLength() ? aDateField[nIndex] : 0;
+ const char cPossiblePlusMinus = nIndex < o3tl::make_unsigned(aDateField.getLength()) ? aDateField[nIndex] : 0;
if (cPossiblePlusMinus == '+' || cPossiblePlusMinus == '-')
{
// Offset from GMT: "(+|-)HHMM".
@@ -263,10 +266,10 @@ void INetMIMEMessage::EnableAttachMultipartFormDataChild()
tools::Time aCurTime( tools::Time::SYSTEM );
sal_uInt64 nThis = reinterpret_cast< sal_uIntPtr >( this ); // we can be on a 64bit architecture
nThis = ( ( nThis >> 32 ) ^ nThis ) & SAL_MAX_UINT32;
- sprintf (sTail, "%08X%08X",
+ o3tl::sprintf (sTail, "%08X%08X",
static_cast< unsigned int >(aCurTime.GetTime()),
static_cast< unsigned int >(nThis));
- m_aBoundary = "------------_4D48";
+ m_aBoundary = "------------_4D48"_ostr;
m_aBoundary += sTail;
// Set header fields.
diff --git a/tools/source/inet/inetstrm.cxx b/tools/source/inet/inetstrm.cxx
index 62889bae4733..f4a841da9331 100644
--- a/tools/source/inet/inetstrm.cxx
+++ b/tools/source/inet/inetstrm.cxx
@@ -22,7 +22,6 @@
#include <cassert>
#include <sal/types.h>
-#include <rtl/strbuf.hxx>
#include <tools/inetmsg.hxx>
#include <tools/inetstrm.hxx>
@@ -43,9 +42,9 @@ int INetMIMEMessageStream::GetHeaderLine(char* pData, sal_uInt32 nSize)
{
// NYI: Folding long lines.
maMsgBuffer.WriteOString( aHeader.GetName() );
- maMsgBuffer.WriteCharPtr( ": " );
+ maMsgBuffer.WriteOString( ": " );
maMsgBuffer.WriteOString( aHeader.GetValue() );
- maMsgBuffer.WriteCharPtr( "\r\n" );
+ maMsgBuffer.WriteOString( "\r\n" );
}
}
@@ -76,10 +75,7 @@ int INetMIMEMessageStream::GetBodyLine(char* pData, sal_uInt32 nSize)
if (pSourceMsg->GetDocumentLB())
{
- if (pMsgStrm == nullptr)
- pMsgStrm.reset(new SvStream (pSourceMsg->GetDocumentLB()));
-
- sal_uInt32 nRead = pMsgStrm->ReadBytes(pWBuf, (pWEnd - pWBuf));
+ sal_uInt32 nRead = pSourceMsg->GetDocumentLB()->ReadBytes(pWBuf, (pWEnd - pWBuf));
pWBuf += nRead;
}
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
index 1f3f8eb5a23a..739d2874875a 100644
--- a/tools/source/memtools/multisel.cxx
+++ b/tools/source/memtools/multisel.cxx
@@ -17,6 +17,11 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include <o3tl/string_view.hxx>
#include <tools/debug.hxx>
#include <tools/multisel.hxx>
@@ -29,20 +34,20 @@ void MultiSelection::ImplClear()
aSels.clear();
}
-sal_Int32 MultiSelection::ImplFindSubSelection( sal_Int32 nIndex ) const
+std::size_t MultiSelection::ImplFindSubSelection( sal_Int32 nIndex ) const
{
// iterate through the sub selections
- sal_Int32 n = 0;
+ std::size_t n = 0;
for ( ;
- n < sal_Int32(aSels.size()) && nIndex > aSels[ n ].Max();
+ n < aSels.size() && nIndex > aSels[ n ].Max();
++n ) {} /* empty loop */
return n;
}
-void MultiSelection::ImplMergeSubSelections( sal_Int32 nPos1, sal_Int32 nPos2 )
+void MultiSelection::ImplMergeSubSelections( sal_Int32 nPos1, std::size_t nPos2 )
{
// didn't a sub selection at nPos2 exist?
- if ( nPos2 >= sal_Int32(aSels.size()) )
+ if ( nPos2 >= aSels.size() )
return;
// did the sub selections touch each other?
@@ -141,12 +146,12 @@ bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
return false;
// find the virtual target position
- sal_Int32 nSubSelPos = ImplFindSubSelection( nIndex );
+ std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
if ( bSelect )
{
// is it included in the found sub selection?
- if ( nSubSelPos < sal_Int32(aSels.size()) && aSels[ nSubSelPos ].Contains( nIndex ) )
+ if ( nSubSelPos < aSels.size() && aSels[ nSubSelPos ].Contains( nIndex ) )
// already selected, nothing to do
return false;
@@ -164,7 +169,7 @@ bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
}
// is it at the beginning of the found sub selection
- else if ( nSubSelPos < sal_Int32(aSels.size())
+ else if ( nSubSelPos < aSels.size()
&& aSels[ nSubSelPos ].Min() == (nIndex+1)
)
// expand the found sub selection
@@ -172,7 +177,7 @@ bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
else
{
// create a new sub selection
- if ( nSubSelPos < sal_Int32(aSels.size()) ) {
+ if ( nSubSelPos < aSels.size() ) {
aSels.insert( aSels.begin() + nSubSelPos, Range( nIndex, nIndex ) );
} else {
aSels.push_back( Range( nIndex, nIndex ) );
@@ -184,7 +189,7 @@ bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
else
{
// is it excluded from the found sub selection?
- if ( nSubSelPos >= sal_Int32(aSels.size())
+ if ( nSubSelPos >= aSels.size()
|| !aSels[ nSubSelPos ].Contains( nIndex )
) {
// not selected, nothing to do
@@ -212,7 +217,7 @@ bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
else
{
// split the sub selection
- if ( nSubSelPos < sal_Int32(aSels.size()) ) {
+ if ( nSubSelPos < aSels.size() ) {
aSels.insert( aSels.begin() + nSubSelPos, Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
} else {
aSels.push_back( Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
@@ -302,23 +307,23 @@ void MultiSelection::Select( const Range& rIndexRange, bool bSelect )
bool MultiSelection::IsSelected( sal_Int32 nIndex ) const
{
// find the virtual target position
- sal_Int32 nSubSelPos = ImplFindSubSelection( nIndex );
+ std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
- return nSubSelPos < sal_Int32(aSels.size()) && aSels[ nSubSelPos ].Contains(nIndex);
+ return nSubSelPos < aSels.size() && aSels[ nSubSelPos ].Contains(nIndex);
}
void MultiSelection::Insert( sal_Int32 nIndex, sal_Int32 nCount )
{
// find the virtual target position
- sal_Int32 nSubSelPos = ImplFindSubSelection( nIndex );
+ std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
// did we need to shift the sub selections?
- if ( nSubSelPos < sal_Int32(aSels.size()) )
+ if ( nSubSelPos < aSels.size() )
{ // did we insert an unselected into an existing sub selection?
if ( aSels[ nSubSelPos ].Min() != nIndex
&& aSels[ nSubSelPos ].Contains(nIndex)
) { // split the sub selection
- if ( nSubSelPos < sal_Int32(aSels.size()) ) {
+ if ( nSubSelPos < aSels.size() ) {
aSels.insert( aSels.begin() + nSubSelPos, Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
} else {
aSels.push_back( Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
@@ -328,7 +333,7 @@ void MultiSelection::Insert( sal_Int32 nIndex, sal_Int32 nCount )
}
// shift the sub selections behind the inserting position
- for ( sal_Int32 nPos = nSubSelPos; nPos < sal_Int32(aSels.size()); ++nPos )
+ for ( std::size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
{
aSels[ nPos ].Min() += nCount;
aSels[ nPos ].Max() += nCount;
@@ -342,10 +347,10 @@ void MultiSelection::Insert( sal_Int32 nIndex, sal_Int32 nCount )
void MultiSelection::Remove( sal_Int32 nIndex )
{
// find the virtual target position
- sal_Int32 nSubSelPos = ImplFindSubSelection( nIndex );
+ std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
// did we remove from an existing sub selection?
- if ( nSubSelPos < sal_Int32(aSels.size())
+ if ( nSubSelPos < aSels.size()
&& aSels[ nSubSelPos ].Contains(nIndex)
) {
// does this sub selection only contain the index to be deleted
@@ -362,7 +367,7 @@ void MultiSelection::Remove( sal_Int32 nIndex )
}
// shift the sub selections behind the removed index
- for ( sal_Int32 nPos = nSubSelPos; nPos < sal_Int32(aSels.size()); ++nPos )
+ for ( std::size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
{
--( aSels[ nPos ].Min() );
--( aSels[ nPos ].Max() );
@@ -386,12 +391,12 @@ sal_Int32 MultiSelection::FirstSelected()
sal_Int32 MultiSelection::LastSelected()
{
- nCurSubSel = aSels.size() - 1;
bCurValid = !aSels.empty();
if ( !bCurValid )
return SFX_ENDOFSELECTION;
+ nCurSubSel = aSels.size() - 1;
nCurIndex = aSels[ nCurSubSel ].Max();
return nCurIndex;
}
@@ -406,7 +411,7 @@ sal_Int32 MultiSelection::NextSelected()
return ++nCurIndex;
// are there further sub selections?
- if ( ++nCurSubSel >= sal_Int32(aSels.size()) )
+ if ( ++nCurSubSel >= aSels.size() )
// we are at the end!
return SFX_ENDOFSELECTION;
@@ -468,7 +473,7 @@ void MultiSelection::SetTotalRange( const Range& rTotRange )
// StringRangeEnumerator
-StringRangeEnumerator::StringRangeEnumerator( const OUString& i_rInput,
+StringRangeEnumerator::StringRangeEnumerator( std::u16string_view i_rInput,
sal_Int32 i_nMinNumber,
sal_Int32 i_nMaxNumber,
sal_Int32 i_nLogicalOffset
@@ -566,26 +571,29 @@ void StringRangeEnumerator::insertJoinedRanges(
}
}
-bool StringRangeEnumerator::setRange( const OUString& i_rNewRange )
+bool StringRangeEnumerator::setRange( std::u16string_view aNewRange )
{
mnCount = 0;
maSequence.clear();
- const sal_Unicode* pInput = i_rNewRange.getStr();
+ auto pInput = aNewRange.begin();
+ auto pInputEnd = aNewRange.end();
OUStringBuffer aNumberBuf( 16 );
std::vector< sal_Int32 > aNumbers;
bool bSequence = false;
- while( *pInput )
+ while( pInput != pInputEnd )
{
- while( *pInput >= '0' && *pInput <= '9' )
+ while( pInput != pInputEnd && *pInput >= '0' && *pInput <= '9' )
aNumberBuf.append( *pInput++ );
if( !aNumberBuf.isEmpty() )
{
- sal_Int32 nNumber = aNumberBuf.makeStringAndClear().toInt32() + mnOffset;
+ sal_Int32 nNumber = o3tl::toInt32(aNumberBuf) + mnOffset;
+ aNumberBuf.setLength(0);
aNumbers.push_back( nNumber );
bSequence = false;
}
-
+ if (pInput == pInputEnd)
+ break;
if( *pInput == '-' )
{
bSequence = true;
@@ -607,11 +615,10 @@ bool StringRangeEnumerator::setRange( const OUString& i_rNewRange )
aNumbers.clear();
bSequence = false;
}
- else if( *pInput && *pInput != ' ' )
+ else if( *pInput != ' ' )
return false; // parse error
- if( *pInput )
- pInput++;
+ pInput++;
}
// insert last entries
if( bSequence && !aNumbers.empty() )
@@ -710,7 +717,7 @@ StringRangeEnumerator::Iterator StringRangeEnumerator::end( const o3tl::sorted_v
return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
}
-bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
+bool StringRangeEnumerator::getRangesFromString( std::u16string_view i_rPageRange,
std::vector< sal_Int32 >& o_rPageVector,
sal_Int32 i_nMinNumber,
sal_Int32 i_nMaxNumber,
diff --git a/tools/source/misc/extendapplicationenvironment.cxx b/tools/source/misc/extendapplicationenvironment.cxx
index ce2237a88c70..07f9779ccc26 100644
--- a/tools/source/misc/extendapplicationenvironment.cxx
+++ b/tools/source/misc/extendapplicationenvironment.cxx
@@ -38,7 +38,7 @@ namespace tools
{
void extendApplicationEnvironment()
{
-#if defined UNX
+#if defined UNX && !defined EMSCRIPTEN
// Try to set RLIMIT_NOFILE as large as possible (failure is harmless):
rlimit lim;
if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
diff --git a/tools/source/misc/fix16.cxx b/tools/source/misc/fix16.cxx
new file mode 100644
index 000000000000..5818d5c1e55f
--- /dev/null
+++ b/tools/source/misc/fix16.cxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * libfixmath is Copyright (c) 2011-2021 Flatmush <Flatmush@gmail.com>,
+ * Petteri Aimonen <Petteri.Aimonen@gmail.com>, & libfixmath AUTHORS
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <tools/fix16.hxx>
+
+#include <bit>
+
+const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */
+const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows */
+
+static inline uint32_t fix_abs(fix16_t in)
+{
+ if (in == fix16_minimum)
+ {
+ // minimum negative number has same representation as
+ // its absolute value in unsigned
+ return 0x80000000;
+ }
+ else
+ {
+ return (in >= 0) ? in : -in;
+ }
+}
+
+/* 64-bit implementation for fix16_mul. Fastest version for e.g. ARM Cortex M3.
+ * Performs a 32*32 -> 64bit multiplication. The middle 32 bits are the result,
+ * bottom 16 bits are used for rounding, and upper 16 bits are used for overflow
+ * detection.
+ */
+
+fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
+{
+ int64_t product = static_cast<int64_t>(inArg0) * inArg1;
+
+ // The upper 17 bits should all be the same (the sign).
+ uint32_t upper = (product >> 47);
+
+ if (product < 0)
+ {
+ if (~upper)
+ return fix16_overflow;
+
+ // This adjustment is required in order to round -1/2 correctly
+ product--;
+ }
+ else
+ {
+ if (upper)
+ return fix16_overflow;
+ }
+
+ fix16_t result = product >> 16;
+ result += (product & 0x8000) >> 15;
+
+ return result;
+}
+
+/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3.
+ * Performs 32-bit divisions repeatedly to reduce the remainder. For this to
+ * be efficient, the processor has to have 32-bit hardware division.
+ */
+fix16_t fix16_div(fix16_t a, fix16_t b)
+{
+ // This uses a hardware 32/32 bit division multiple times, until we have
+ // computed all the bits in (a<<17)/b. Usually this takes 1-3 iterations.
+
+ if (b == 0)
+ return fix16_minimum;
+
+ uint32_t remainder = fix_abs(a);
+ uint32_t divider = fix_abs(b);
+ uint64_t quotient = 0;
+ int bit_pos = 17;
+
+ // Kick-start the division a bit.
+ // This improves speed in the worst-case scenarios where N and D are large
+ // It gets a lower estimate for the result by N/(D >> 17 + 1).
+ if (divider & 0xFFF00000)
+ {
+ uint32_t shifted_div = (divider >> 17) + 1;
+ quotient = remainder / shifted_div;
+ uint64_t tmp = (quotient * static_cast<uint64_t>(divider)) >> 17;
+ remainder -= static_cast<uint32_t>(tmp);
+ }
+
+ // If the divider is divisible by 2^n, take advantage of it.
+ while (!(divider & 0xF) && bit_pos >= 4)
+ {
+ divider >>= 4;
+ bit_pos -= 4;
+ }
+
+ while (remainder && bit_pos >= 0)
+ {
+ // Shift remainder as much as we can without overflowing
+ int shift = std::countl_zero(remainder);
+ if (shift > bit_pos)
+ shift = bit_pos;
+ remainder <<= shift;
+ bit_pos -= shift;
+
+ uint32_t div = remainder / divider;
+ remainder = remainder % divider;
+ quotient += static_cast<uint64_t>(div) << bit_pos;
+
+ if (div & ~(0xFFFFFFFF >> bit_pos))
+ return fix16_overflow;
+
+ remainder <<= 1;
+ bit_pos--;
+ }
+
+ // Quotient is always positive so rounding is easy
+ quotient++;
+
+ fix16_t result = quotient >> 1;
+
+ // Figure out the sign of the result
+ if ((a ^ b) & 0x80000000)
+ {
+ if (result == fix16_minimum)
+ return fix16_overflow;
+
+ result = -result;
+ }
+
+ return result;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tools/source/misc/json_writer.cxx b/tools/source/misc/json_writer.cxx
index d6e34179f930..f5c262573418 100644
--- a/tools/source/misc/json_writer.cxx
+++ b/tools/source/misc/json_writer.cxx
@@ -8,8 +8,9 @@
*/
#include <tools/json_writer.hxx>
+#include <o3tl/string_view.hxx>
#include <stdio.h>
-#include <algorithm>
+#include <cstddef>
#include <cstring>
#include <rtl/math.hxx>
@@ -20,103 +21,77 @@ namespace tools
constexpr int DEFAULT_BUFFER_SIZE = 2048;
JsonWriter::JsonWriter()
- : mpBuffer(static_cast<char*>(malloc(DEFAULT_BUFFER_SIZE)))
- , mPos(mpBuffer)
+ : mpBuffer(rtl_string_alloc(DEFAULT_BUFFER_SIZE))
+ , mPos(mpBuffer->buffer)
, mSpaceAllocated(DEFAULT_BUFFER_SIZE)
, mStartNodeCount(0)
, mbFirstFieldInNode(true)
+ , mbClosed(false)
{
*mPos = '{';
++mPos;
*mPos = ' ';
++mPos;
+
+ addValidationMark();
}
JsonWriter::~JsonWriter()
{
- assert(!mpBuffer && "forgot to extract data?");
- free(mpBuffer);
+ assert(mbClosed && "forgot to extract data?");
+ rtl_string_release(mpBuffer);
}
-ScopedJsonWriterNode JsonWriter::startNode(const char* pNodeName)
+JsonWriter::ScopedJsonWriterNode<'}'> JsonWriter::startNode(std::string_view pNodeName)
{
- auto len = strlen(pNodeName);
- ensureSpace(len + 6);
-
- addCommaBeforeField();
+ putLiteral(pNodeName, "{ ");
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pNodeName, len);
- mPos += len;
- memcpy(mPos, "\": { ", 5);
- mPos += 5;
mStartNodeCount++;
mbFirstFieldInNode = true;
- return ScopedJsonWriterNode(*this);
+
+ return { *this };
}
-void JsonWriter::endNode()
+void JsonWriter::endNode(char closing)
{
assert(mStartNodeCount && "mismatched StartNode/EndNode somewhere");
--mStartNodeCount;
ensureSpace(1);
- *mPos = '}';
+ *mPos = closing;
++mPos;
mbFirstFieldInNode = false;
+
+ validate();
}
-ScopedJsonWriterArray JsonWriter::startArray(const char* pNodeName)
+JsonWriter::ScopedJsonWriterNode<']'> JsonWriter::startArray(std::string_view pNodeName)
{
- auto len = strlen(pNodeName);
- ensureSpace(len + 6);
+ putLiteral(pNodeName, "[ ");
- addCommaBeforeField();
-
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pNodeName, len);
- mPos += len;
- memcpy(mPos, "\": [ ", 5);
- mPos += 5;
mStartNodeCount++;
mbFirstFieldInNode = true;
- return ScopedJsonWriterArray(*this);
-}
-void JsonWriter::endArray()
-{
- assert(mStartNodeCount && "mismatched StartNode/EndNode somewhere");
- --mStartNodeCount;
- ensureSpace(1);
- *mPos = ']';
- ++mPos;
- mbFirstFieldInNode = false;
+ return { *this };
}
-ScopedJsonWriterStruct JsonWriter::startStruct()
+JsonWriter::ScopedJsonWriterNode<']'> JsonWriter::startAnonArray()
{
- ensureSpace(6);
-
- addCommaBeforeField();
+ putRaw("[ ");
- *mPos = '{';
- ++mPos;
- *mPos = ' ';
- ++mPos;
mStartNodeCount++;
mbFirstFieldInNode = true;
- return ScopedJsonWriterStruct(*this);
+
+ return { *this };
}
-void JsonWriter::endStruct()
+JsonWriter::ScopedJsonWriterNode<'}'> JsonWriter::startStruct()
{
- assert(mStartNodeCount && "mismatched StartNode/EndNode somewhere");
- --mStartNodeCount;
- ensureSpace(1);
- *mPos = '}';
- ++mPos;
- mbFirstFieldInNode = false;
+ putRaw("{ ");
+
+ mStartNodeCount++;
+ mbFirstFieldInNode = true;
+
+ return { *this };
}
static char getEscapementChar(char ch)
@@ -153,29 +128,30 @@ static bool writeEscapedSequence(sal_uInt32 ch, char*& pos)
*pos++ = '\\';
*pos++ = getEscapementChar(ch);
return true;
- // Special processing of U+2028 and U+2029, which are valid JSON, but invalid JavaScript
- // Write them in escaped '\u2028' or '\u2029' form
- case 0x2028:
- case 0x2029:
- *pos++ = '\\';
- *pos++ = 'u';
- *pos++ = '2';
- *pos++ = '0';
- *pos++ = '2';
- *pos++ = ch == 0x2028 ? '8' : '9';
- return true;
default:
+ if (ch <= 0x1f || ch == 0x2028 || ch == 0x2029)
+ {
+ // control characters, plus special processing of U+2028 and U+2029, which are valid
+ // JSON, but invalid JavaScript. Write them in escaped '\u2028' or '\u2029' form
+ int written = snprintf(pos, 7, "\\u%.4x", static_cast<unsigned int>(ch));
+ if (written > 0)
+ pos += written;
+ return true;
+ }
return false;
}
}
-void JsonWriter::writeEscapedOUString(const OUString& rPropVal)
+void JsonWriter::writeEscapedOUString(std::u16string_view rPropVal)
{
+ *mPos = '"';
+ ++mPos;
+
// Convert from UTF-16 to UTF-8 and perform escaping
- sal_Int32 i = 0;
- while (i < rPropVal.getLength())
+ std::size_t i = 0;
+ while (i < rPropVal.size())
{
- sal_uInt32 ch = rPropVal.iterateCodePoints(&i);
+ sal_uInt32 ch = o3tl::iterateCodePoints(rPropVal, &i);
if (writeEscapedSequence(ch, mPos))
continue;
if (ch <= 0x7F)
@@ -211,158 +187,91 @@ void JsonWriter::writeEscapedOUString(const OUString& rPropVal)
++mPos;
}
}
+
+ *mPos = '"';
+ ++mPos;
+
+ validate();
}
-void JsonWriter::put(const char* pPropName, const OUString& rPropVal)
+void JsonWriter::put(std::u16string_view pPropName, std::u16string_view rPropVal)
{
- auto nPropNameLength = strlen(pPropName);
+ auto nPropNameLength = pPropName.length();
// But values can be any UTF-8,
// if the string only contains of 0x2028, it will be expanded 6 times (see writeEscapedSequence)
- auto nWorstCasePropValLength = rPropVal.getLength() * 6;
+ auto nWorstCasePropValLength = rPropVal.size() * 6;
ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
addCommaBeforeField();
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pPropName, nPropNameLength);
- mPos += nPropNameLength;
- memcpy(mPos, "\": \"", 4);
- mPos += 4;
+ writeEscapedOUString(pPropName);
+
+ memcpy(mPos, ": ", 2);
+ mPos += 2;
writeEscapedOUString(rPropVal);
- *mPos = '"';
- ++mPos;
+ validate();
}
-void JsonWriter::put(const char* pPropName, std::string_view rPropVal)
+void JsonWriter::put(std::string_view pPropName, const OUString& rPropVal)
{
- // we assume property names are ascii
- auto nPropNameLength = strlen(pPropName);
- // escaping can double the length
- auto nWorstCasePropValLength = rPropVal.size() * 2;
- ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
+ // Values can be any UTF-8,
+ // if the string only contains of 0x2028, it will be expanded 6 times (see writeEscapedSequence)
+ auto nWorstCasePropValLength = rPropVal.getLength() * 6 + 2;
+ ensureSpaceAndWriteNameColon(pPropName, nWorstCasePropValLength);
- addCommaBeforeField();
+ writeEscapedOUString(rPropVal);
+}
+
+void JsonWriter::put(std::string_view pPropName, std::string_view rPropVal)
+{
+ // escaping can double the length, plus quotes
+ auto nWorstCasePropValLength = rPropVal.size() * 2 + 2;
+ ensureSpaceAndWriteNameColon(pPropName, nWorstCasePropValLength);
*mPos = '"';
++mPos;
- memcpy(mPos, pPropName, nPropNameLength);
- mPos += nPropNameLength;
- memcpy(mPos, "\": \"", 4);
- mPos += 4;
// copy and perform escaping
for (size_t i = 0; i < rPropVal.size(); ++i)
{
char ch = rPropVal[i];
- switch (ch)
+ if (ch == 0)
+ break;
+ // Special processing of U+2028 and U+2029
+ if (ch == '\xE2' && i + 2 < rPropVal.size() && rPropVal[i + 1] == '\x80'
+ && (rPropVal[i + 2] == '\xA8' || rPropVal[i + 2] == '\xA9'))
{
- case '\b':
- case '\t':
- case '\n':
- case '\f':
- case '\r':
- case '"':
- case '/':
- case '\\':
- writeEscapedSequence(ch, mPos);
- break;
- case '\xE2': // Special processing of U+2028 and U+2029
- if (i + 2 < rPropVal.size() && rPropVal[i + 1] == '\x80'
- && (rPropVal[i + 2] == '\xA8' || rPropVal[i + 2] == '\xA9'))
- {
- writeEscapedSequence(rPropVal[i + 2] == '\xA8' ? 0x2028 : 0x2029, mPos);
- i += 2;
- break;
- }
- [[fallthrough]];
- default:
- *mPos = ch;
- ++mPos;
- break;
+ writeEscapedSequence(rPropVal[i + 2] == '\xA8' ? 0x2028 : 0x2029, mPos);
+ i += 2;
+ }
+ else if (!writeEscapedSequence(static_cast<sal_uInt32>(ch), mPos))
+ {
+ *mPos = ch;
+ ++mPos;
}
}
*mPos = '"';
++mPos;
-}
-void JsonWriter::put(const char* pPropName, sal_Int64 nPropVal)
-{
- auto nPropNameLength = strlen(pPropName);
- auto nWorstCasePropValLength = 32;
- ensureSpace(nPropNameLength + nWorstCasePropValLength + 8);
-
- addCommaBeforeField();
-
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pPropName, nPropNameLength);
- mPos += nPropNameLength;
- memcpy(mPos, "\": ", 3);
- mPos += 3;
-
- mPos += sprintf(mPos, "%" SAL_PRIdINT64, nPropVal);
+ validate();
}
-void JsonWriter::put(const char* pPropName, double fPropVal)
+void JsonWriter::put(std::string_view pPropName, bool nPropVal)
{
- OString sPropVal = rtl::math::doubleToString(fPropVal, rtl_math_StringFormat_F, 12, '.');
- auto nPropNameLength = strlen(pPropName);
- ensureSpace(nPropNameLength + sPropVal.getLength() + 8);
-
- addCommaBeforeField();
-
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pPropName, nPropNameLength);
- mPos += nPropNameLength;
- memcpy(mPos, "\": ", 3);
- mPos += 3;
-
- memcpy(mPos, sPropVal.getStr(), sPropVal.getLength());
- mPos += sPropVal.getLength();
+ putLiteral(pPropName, nPropVal ? std::string_view("true") : std::string_view("false"));
}
-void JsonWriter::put(const char* pPropName, bool nPropVal)
+void JsonWriter::putSimpleValue(std::u16string_view rPropVal)
{
- auto nPropNameLength = strlen(pPropName);
- ensureSpace(nPropNameLength + 5 + 8);
-
- addCommaBeforeField();
-
- *mPos = '"';
- ++mPos;
- memcpy(mPos, pPropName, nPropNameLength);
- mPos += nPropNameLength;
- memcpy(mPos, "\": ", 3);
- mPos += 3;
-
- const char* pVal;
- if (nPropVal)
- pVal = "true";
- else
- pVal = "false";
- memcpy(mPos, pVal, strlen(pVal));
- mPos += strlen(pVal);
-}
-
-void JsonWriter::putSimpleValue(const OUString& rPropVal)
-{
- auto nWorstCasePropValLength = rPropVal.getLength() * 3;
+ auto nWorstCasePropValLength = rPropVal.size() * 6;
ensureSpace(nWorstCasePropValLength + 4);
addCommaBeforeField();
- *mPos = '"';
- ++mPos;
-
writeEscapedOUString(rPropVal);
-
- *mPos = '"';
- ++mPos;
}
void JsonWriter::putRaw(std::string_view rRawBuf)
@@ -373,6 +282,8 @@ void JsonWriter::putRaw(std::string_view rRawBuf)
memcpy(mPos, rRawBuf.data(), rRawBuf.size());
mPos += rRawBuf.size();
+
+ validate();
}
void JsonWriter::addCommaBeforeField()
@@ -390,54 +301,60 @@ void JsonWriter::addCommaBeforeField()
void JsonWriter::ensureSpace(int noMoreBytesRequired)
{
- assert(mpBuffer && "already extracted data");
- int currentUsed = mPos - mpBuffer;
+ assert(!mbClosed && "already extracted data");
+ int currentUsed = mPos - mpBuffer->buffer;
if (currentUsed + noMoreBytesRequired >= mSpaceAllocated)
{
auto newSize = (currentUsed + noMoreBytesRequired) * 2;
- mpBuffer = static_cast<char*>(realloc(mpBuffer, newSize));
- mPos = mpBuffer + currentUsed;
+ rtl_String* pNewBuffer = rtl_string_alloc(newSize);
+ memcpy(pNewBuffer->buffer, mpBuffer->buffer, currentUsed);
+ rtl_string_release(mpBuffer);
+ mpBuffer = pNewBuffer;
+ mPos = mpBuffer->buffer + currentUsed;
mSpaceAllocated = newSize;
+
+ addValidationMark();
}
}
-/** Hands ownership of the underlying storage buffer to the caller,
- * after this no more document modifications may be written. */
-std::pair<char*, int> JsonWriter::extractDataImpl()
+void JsonWriter::ensureSpaceAndWriteNameColon(std::string_view name, int valSize)
{
- assert(mStartNodeCount == 0 && "did not close all nodes");
- assert(mpBuffer && "data already extracted");
- ensureSpace(2);
- // add closing brace
- *mPos = '}';
+ // we assume property names are ascii
+ ensureSpace(name.size() + valSize + 6);
+
+ addCommaBeforeField();
+
+ *mPos = '"';
++mPos;
- // null-terminate
- *mPos = 0;
- const int sz = mPos - mpBuffer;
- mPos = nullptr;
- return { std::exchange(mpBuffer, nullptr), sz };
+ memcpy(mPos, name.data(), name.size());
+ mPos += name.size();
+ memcpy(mPos, "\": ", 3);
+ mPos += 3;
}
-OString JsonWriter::extractAsOString()
+void JsonWriter::putLiteral(std::string_view propName, std::string_view propValue)
{
- auto[pChar, sz] = extractDataImpl();
- OString ret(pChar, sz);
- free(pChar);
- return ret;
-}
+ ensureSpaceAndWriteNameColon(propName, propValue.size());
+ memcpy(mPos, propValue.data(), propValue.size());
+ mPos += propValue.size();
-std::string JsonWriter::extractAsStdString()
-{
- auto[pChar, sz] = extractDataImpl();
- std::string ret(pChar, sz);
- free(pChar);
- return ret;
+ validate();
}
-bool JsonWriter::isDataEquals(const std::string& s) const
+OString JsonWriter::finishAndGetAsOString()
{
- return s.length() == static_cast<size_t>(mPos - mpBuffer)
- && memcmp(s.data(), mpBuffer, s.length()) == 0;
+ assert(mStartNodeCount == 0 && "did not close all nodes");
+ assert(!mbClosed && "data already extracted");
+ ensureSpace(2);
+ // add closing brace
+ *mPos = '}';
+ ++mPos;
+ // null-terminate
+ *mPos = 0;
+ mbClosed = true;
+
+ mpBuffer->length = mPos - mpBuffer->buffer;
+ return mpBuffer;
}
} // namespace tools
diff --git a/tools/source/misc/pathutils.cxx b/tools/source/misc/pathutils.cxx
index 706740a320f9..30bdbde8f013 100644
--- a/tools/source/misc/pathutils.cxx
+++ b/tools/source/misc/pathutils.cxx
@@ -43,63 +43,40 @@ WCHAR * filename(WCHAR * path) {
}
}
-WCHAR * buildPath(
- WCHAR * path, WCHAR const * frontBegin, WCHAR const * frontEnd,
- WCHAR const * backBegin, std::size_t backLength)
+std::wstring buildPath(std::wstring_view front, std::wstring_view back)
{
// Remove leading ".." segments in the second path together with matching
// segments in the first path that are neither empty nor "." nor ".." nor
// end in ":" (which is not foolproof, as it can erroneously erase the start
// of a UNC path, but only if the input is bad data):
- while (backLength >= 2 && backBegin[0] == L'.' && backBegin[1] == L'.' &&
- (backLength == 2 || backBegin[2] == L'\\'))
+ while (back.starts_with(L"..") &&
+ (back.size() == 2 || back[2] == L'\\'))
{
- if (frontEnd - frontBegin < 2 || frontEnd[-1] != L'\\' ||
- frontEnd[-2] == L'\\' || frontEnd[-2] == L':' ||
- (frontEnd[-2] == L'.' &&
- (frontEnd - frontBegin < 3 || frontEnd[-3] == L'\\' ||
- (frontEnd[-3] == L'.' &&
- (frontEnd - frontBegin < 4 || frontEnd[-4] == L'\\')))))
+ if (front.size() < 2 || front.back() != L'\\' ||
+ front[front.size() - 2] == L'\\' || front[front.size() - 2] == L':' ||
+ (front[front.size() - 2] == L'.' &&
+ (front.size() < 3 || front[front.size() - 3] == L'\\' ||
+ (front[front.size() - 3] == L'.' &&
+ (front.size() < 4 || front[front.size() - 4] == L'\\')))))
{
break;
}
- WCHAR const * p = frontEnd - 1;
- while (p != frontBegin && p[-1] != L'\\') {
+ auto p = front.end() - 1;
+ while (p != front.begin() && p[-1] != L'\\') {
--p;
}
- if (p == frontBegin) {
+ if (p == front.begin()) {
break;
}
- frontEnd = p;
- if (backLength == 2) {
- backBegin += 2;
- backLength -= 2;
+ front.remove_suffix(front.end() - p);
+ if (back.size() == 2) {
+ back = {};
} else {
- backBegin += 3;
- backLength -= 3;
+ back.remove_prefix(3);
}
}
- if (backLength <
- o3tl::make_unsigned(MAX_PATH - (frontEnd - frontBegin)))
- {
- WCHAR * p;
- if (frontBegin == path) {
- p = const_cast< WCHAR * >(frontEnd);
- } else {
- p = path;
- while (frontBegin != frontEnd) {
- *p++ = *frontBegin++;
- }
- }
- for (; backLength > 0; --backLength) {
- *p++ = *backBegin++;
- }
- *p = L'\0';
- return p;
- } else {
- SetLastError(ERROR_FILENAME_EXCED_RANGE);
- return nullptr;
- }
+
+ return std::wstring(front) + std::wstring(back);
}
}
diff --git a/tools/source/ref/globname.cxx b/tools/source/ref/globname.cxx
index fda6fafab53c..4ae220659e3c 100644
--- a/tools/source/ref/globname.cxx
+++ b/tools/source/ref/globname.cxx
@@ -17,265 +17,127 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <stdio.h>
#include <string.h>
-#include <rtl/strbuf.hxx>
+#include <comphelper/mimeconfighelper.hxx>
+#include <o3tl/sprintf.hxx>
#include <rtl/character.hxx>
#include <tools/stream.hxx>
#include <tools/globname.hxx>
-// ImpSvGlobalName ------------------------------------------------------------
-ImpSvGlobalName::ImpSvGlobalName( const ImpSvGlobalName & rObj )
- : szData(rObj.szData)
-{
-}
-
-ImpSvGlobalName::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)
-{
- szData.Data1 = n1;
- szData.Data2 = n2;
- szData.Data3 = n3;
- szData.Data4[0] = b8;
- szData.Data4[1] = b9;
- szData.Data4[2] = b10;
- szData.Data4[3] = b11;
- szData.Data4[4] = b12;
- szData.Data4[5] = b13;
- szData.Data4[6] = b14;
- szData.Data4[7] = b15;
-}
-
-bool ImpSvGlobalName::operator == ( const ImpSvGlobalName & rObj ) const
-{
- return !memcmp( &szData, &rObj.szData, sizeof( szData ) );
-}
-
// SvGlobalName ----------------------------------------------------------------
-SvGlobalName::SvGlobalName()
-{
-}
-
-SvGlobalName::SvGlobalName( const SvGUID & rId ) :
- pImp( ImpSvGlobalName( rId ) )
-{
-}
-
-SvGlobalName::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 ) :
- pImp( ImpSvGlobalName(n1, n2, n3, b8, b9, b10, b11, b12, b13, b14, b15) )
-{
-}
SvGlobalName::SvGlobalName( const css::uno::Sequence < sal_Int8 >& aSeq )
{
// create SvGlobalName from a platform independent representation
- SvGUID aResult = {};
if ( aSeq.getLength() == 16 )
{
- aResult.Data1 = ( ( ( ( ( static_cast<sal_uInt8>(aSeq[0]) << 8 ) + static_cast<sal_uInt8>(aSeq[1]) ) << 8 ) + static_cast<sal_uInt8>(aSeq[2]) ) << 8 ) + static_cast<sal_uInt8>(aSeq[3]);
- aResult.Data2 = ( static_cast<sal_uInt8>(aSeq[4]) << 8 ) + static_cast<sal_uInt8>(aSeq[5]);
- aResult.Data3 = ( static_cast<sal_uInt8>(aSeq[6]) << 8 ) + static_cast<sal_uInt8>(aSeq[7]);
+ m_aData.Data1 = ( ( ( ( ( static_cast<sal_uInt8>(aSeq[0]) << 8 ) + static_cast<sal_uInt8>(aSeq[1]) ) << 8 ) + static_cast<sal_uInt8>(aSeq[2]) ) << 8 ) + static_cast<sal_uInt8>(aSeq[3]);
+ m_aData.Data2 = ( static_cast<sal_uInt8>(aSeq[4]) << 8 ) + static_cast<sal_uInt8>(aSeq[5]);
+ m_aData.Data3 = ( static_cast<sal_uInt8>(aSeq[6]) << 8 ) + static_cast<sal_uInt8>(aSeq[7]);
for( int nInd = 0; nInd < 8; nInd++ )
- aResult.Data4[nInd] = static_cast<sal_uInt8>(aSeq[nInd+8]);
+ m_aData.Data4[nInd] = static_cast<sal_uInt8>(aSeq[nInd+8]);
}
-
- pImp = ::o3tl::cow_wrapper< ImpSvGlobalName >(aResult);
-}
-
-SvGlobalName::~SvGlobalName()
-{
-}
-
-SvGlobalName & SvGlobalName::operator = ( const SvGlobalName & rObj )
-{
- pImp = rObj.pImp;
-
- return *this;
-}
-
-SvGlobalName & SvGlobalName::operator = ( SvGlobalName && rObj ) noexcept
-{
- pImp = std::move(rObj.pImp);
- return *this;
}
SvStream& WriteSvGlobalName( SvStream& rOStr, const SvGlobalName & rObj )
{
- rOStr.WriteUInt32( rObj.pImp->szData.Data1 );
- rOStr.WriteUInt16( rObj.pImp->szData.Data2 );
- rOStr.WriteUInt16( rObj.pImp->szData.Data3 );
- rOStr.WriteBytes( &rObj.pImp->szData.Data4, 8 );
+ rOStr.WriteUInt32( rObj.m_aData.Data1 );
+ rOStr.WriteUInt16( rObj.m_aData.Data2 );
+ rOStr.WriteUInt16( rObj.m_aData.Data3 );
+ rOStr.WriteBytes( &rObj.m_aData.Data4, 8 );
return rOStr;
}
SvStream& operator >> ( SvStream& rStr, SvGlobalName & rObj )
{
- // the non-const dereferencing operator
- // ensures pImp is unique
- rStr.ReadUInt32( rObj.pImp->szData.Data1 );
- rStr.ReadUInt16( rObj.pImp->szData.Data2 );
- rStr.ReadUInt16( rObj.pImp->szData.Data3 );
- rStr.ReadBytes( &rObj.pImp->szData.Data4, 8 );
+ rStr.ReadUInt32( rObj.m_aData.Data1 );
+ rStr.ReadUInt16( rObj.m_aData.Data2 );
+ rStr.ReadUInt16( rObj.m_aData.Data3 );
+ rStr.ReadBytes( &rObj.m_aData.Data4, 8 );
return rStr;
}
-
-bool SvGlobalName::operator < ( const SvGlobalName & rObj ) const
+void SvGlobalName::MakeFromMemory( void const * pData )
{
- if( pImp->szData.Data3 < rObj.pImp->szData.Data3 )
- return true;
- else if( pImp->szData.Data3 > rObj.pImp->szData.Data3 )
- return false;
-
- if( pImp->szData.Data2 < rObj.pImp->szData.Data2 )
- return true;
- else if( pImp->szData.Data2 > rObj.pImp->szData.Data2 )
- return false;
-
- return pImp->szData.Data1 < rObj.pImp->szData.Data1;
+ memcpy( &m_aData, pData, sizeof( m_aData ) );
}
-bool SvGlobalName::operator == ( const SvGlobalName & rObj ) const
+bool SvGlobalName::MakeId( std::u16string_view rIdStr )
{
- return pImp == rObj.pImp;
-}
+ const sal_Unicode *pStr = rIdStr.data();
+ if( rIdStr.size() != 36
+ || '-' != pStr[ 8 ] || '-' != pStr[ 13 ]
+ || '-' != pStr[ 18 ] || '-' != pStr[ 23 ] )
+ return false;
-void SvGlobalName::MakeFromMemory( void const * pData )
-{
- memcpy( &pImp->szData, pData, sizeof( pImp->szData ) );
-}
+ SvGUID aGuid = {};
+ auto asciiHexDigitToNumber = [](sal_Unicode c) -> sal_uInt8
+ {
+ if (rtl::isAsciiDigit(c))
+ return c - '0';
+ else
+ return rtl::toAsciiUpperCase(c) - 'A' + 10;
+ };
-bool SvGlobalName::MakeId( const OUString & rIdStr )
-{
- const sal_Unicode *pStr = rIdStr.getStr();
- if( rIdStr.getLength() == 36
- && '-' == pStr[ 8 ] && '-' == pStr[ 13 ]
- && '-' == pStr[ 18 ] && '-' == pStr[ 23 ] )
+ for( int i = 0; i < 8; i++ )
{
- sal_uInt32 nFirst = 0;
- int i = 0;
- for( i = 0; i < 8; i++ )
- {
- if( rtl::isAsciiHexDigit( *pStr ) )
- if( rtl::isAsciiDigit( *pStr ) )
- nFirst = nFirst * 16 + (*pStr - '0');
- else
- nFirst = nFirst * 16 + (rtl::toAsciiUpperCase( *pStr ) - 'A' + 10 );
- else
- return false;
- pStr++;
- }
+ if( !rtl::isAsciiHexDigit( *pStr ) )
+ return false;
+ aGuid.Data1 = aGuid.Data1 * 16 + asciiHexDigitToNumber( *pStr++ );
+ }
- sal_uInt16 nSec = 0;
- pStr++;
- for( i = 0; i < 4; i++ )
- {
- if( rtl::isAsciiHexDigit( *pStr ) )
- if( rtl::isAsciiDigit( *pStr ) )
- nSec = nSec * 16 + (*pStr - '0');
- else
- nSec = nSec * 16 + static_cast<sal_uInt16>(rtl::toAsciiUpperCase( *pStr ) - 'A' + 10 );
- else
- return false;
- pStr++;
- }
+ pStr++;
+ for( int i = 0; i < 4; i++ )
+ {
+ if( !rtl::isAsciiHexDigit( *pStr ) )
+ return false;
+ aGuid.Data2 = aGuid.Data2 * 16 + asciiHexDigitToNumber( *pStr++ );
+ }
- sal_uInt16 nThird = 0;
- pStr++;
- for( i = 0; i < 4; i++ )
- {
- if( rtl::isAsciiHexDigit( *pStr ) )
- if( rtl::isAsciiDigit( *pStr ) )
- nThird = nThird * 16 + (*pStr - '0');
- else
- nThird = nThird * 16 + static_cast<sal_uInt16>(rtl::toAsciiUpperCase( *pStr ) - 'A' + 10 );
- else
- return false;
- pStr++;
- }
+ pStr++;
+ for( int i = 0; i < 4; i++ )
+ {
+ if( !rtl::isAsciiHexDigit( *pStr ) )
+ return false;
+ aGuid.Data3 = aGuid.Data3 * 16 + asciiHexDigitToNumber( *pStr++ );
+ }
- sal_Int8 szRemain[ 8 ] = {};
- pStr++;
- for( i = 0; i < 16; i++ )
- {
- if( rtl::isAsciiHexDigit( *pStr ) )
- if( rtl::isAsciiDigit( *pStr ) )
- szRemain[i/2] = szRemain[i/2] * 16 + (*pStr - '0');
- else
- szRemain[i/2] = szRemain[i/2] * 16 + static_cast<sal_Int8>(rtl::toAsciiUpperCase( *pStr ) - 'A' + 10 );
- else
- return false;
+ pStr++;
+ for( int i = 0; i < 16; i++ )
+ {
+ if( !rtl::isAsciiHexDigit( *pStr ) )
+ return false;
+ aGuid.Data4[i/2] = aGuid.Data4[i/2] * 16 + asciiHexDigitToNumber( *pStr++ );
+ if( i == 3 )
pStr++;
- if( i == 3 )
- pStr++;
- }
-
- memcpy(&pImp->szData.Data1, &nFirst, sizeof(nFirst));
- memcpy(&pImp->szData.Data2, &nSec, sizeof(nSec));
- memcpy(&pImp->szData.Data3, &nThird, sizeof(nThird));
- memcpy(&pImp->szData.Data4, szRemain, 8);
- return true;
}
- return false;
+
+ m_aData = aGuid;
+ return true;
}
OUString SvGlobalName::GetHexName() const
{
- OStringBuffer aHexBuffer(36);
-
- char buf[ 10 ];
- sprintf( buf, "%8.8" SAL_PRIXUINT32, pImp->szData.Data1 );
- aHexBuffer.append(buf);
- aHexBuffer.append('-');
- sprintf( buf, "%4.4X", pImp->szData.Data2 );
- aHexBuffer.append(buf);
- aHexBuffer.append('-');
- sprintf( buf, "%4.4X", pImp->szData.Data3 );
- aHexBuffer.append(buf);
- aHexBuffer.append('-');
- for( int i = 0; i < 2; i++ )
- {
- sprintf( buf, "%2.2x", pImp->szData.Data4[ i ] );
- aHexBuffer.append(buf);
- }
- aHexBuffer.append('-');
- for( int i = 2; i < 8; i++ )
- {
- sprintf( buf, "%2.2x", pImp->szData.Data4[ i ] );
- aHexBuffer.append(buf);
- }
- return OStringToOUString(aHexBuffer.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+ char buf[ 37 ];
+ int n = o3tl::sprintf(buf,
+ "%8.8" SAL_PRIXUINT32 "-%4.4X-%4.4X-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
+ m_aData.Data1, m_aData.Data2, m_aData.Data3,
+ m_aData.Data4[0], m_aData.Data4[1], m_aData.Data4[2], m_aData.Data4[3],
+ m_aData.Data4[4], m_aData.Data4[5], m_aData.Data4[6], m_aData.Data4[7]);
+ assert(n == 36);
+ return OUString::createFromAscii(std::string_view(buf, n));
}
css::uno::Sequence < sal_Int8 > SvGlobalName::GetByteSequence() const
{
// platform independent representation of a "GlobalName"
// maybe transported remotely
- css::uno::Sequence< sal_Int8 > aResult{
- /* [ 0] */ static_cast<sal_Int8>(pImp->szData.Data1 >> 24),
- /* [ 1] */ static_cast<sal_Int8>((pImp->szData.Data1 << 8 ) >> 24),
- /* [ 2] */ static_cast<sal_Int8>((pImp->szData.Data1 << 16 ) >> 24),
- /* [ 3] */ static_cast<sal_Int8>((pImp->szData.Data1 << 24 ) >> 24),
- /* [ 4] */ static_cast<sal_Int8>(pImp->szData.Data2 >> 8),
- /* [ 5] */ static_cast<sal_Int8>((pImp->szData.Data2 << 8 ) >> 8),
- /* [ 6] */ static_cast<sal_Int8>(pImp->szData.Data3 >> 8),
- /* [ 7] */ static_cast<sal_Int8>((pImp->szData.Data3 << 8 ) >> 8),
- /* [ 8] */ static_cast<sal_Int8>(pImp->szData.Data4[ 0 ]),
- /* [ 9] */ static_cast<sal_Int8>(pImp->szData.Data4[ 1 ]),
- /* [10] */ static_cast<sal_Int8>(pImp->szData.Data4[ 2 ]),
- /* [11] */ static_cast<sal_Int8>(pImp->szData.Data4[ 3 ]),
- /* [12] */ static_cast<sal_Int8>(pImp->szData.Data4[ 4 ]),
- /* [13] */ static_cast<sal_Int8>(pImp->szData.Data4[ 5 ]),
- /* [14] */ static_cast<sal_Int8>(pImp->szData.Data4[ 6 ]),
- /* [15] */ static_cast<sal_Int8>(pImp->szData.Data4[ 7 ])
- };
-
- return aResult;
+ return comphelper::MimeConfigurationHelper::GetSequenceClassID(
+ m_aData.Data1, m_aData.Data2, m_aData.Data3,
+ m_aData.Data4[0], m_aData.Data4[1], m_aData.Data4[2], m_aData.Data4[3],
+ m_aData.Data4[4], m_aData.Data4[5], m_aData.Data4[6], m_aData.Data4[7]);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/reversemap/bestreversemap.cxx b/tools/source/reversemap/bestreversemap.cxx
index 02a81932b3f2..f124140c1918 100644
--- a/tools/source/reversemap/bestreversemap.cxx
+++ b/tools/source/reversemap/bestreversemap.cxx
@@ -11,6 +11,7 @@
#include <rtl/textcvt.h>
#include <cstdlib>
+#include <iterator>
#include <stdio.h>
namespace {
@@ -91,7 +92,7 @@ int main()
sal_Unicode c = 0;
while (c < 0xFFFF)
{
- for (size_t i = 0; i < SAL_N_ELEMENTS(aConverters); ++i)
+ for (size_t i = 0; i < std::size(aConverters); ++i)
aConverters[i].reset();
int nMostCapable = -1;
@@ -99,7 +100,7 @@ int main()
while(c < 0xFFFF)
{
bool bSomethingCapable = false;
- for (size_t i = 0; i < SAL_N_ELEMENTS(aConverters); ++i)
+ for (size_t i = 0; i < std::size(aConverters); ++i)
{
if (aConverters[i].isOK())
aConverters[i].checkSupports(c);
@@ -119,7 +120,7 @@ int main()
while(c < 0xFFFF)
{
bool bNothingCapable = true;
- for (size_t i = 0; i < SAL_N_ELEMENTS(aConverters); ++i)
+ for (size_t i = 0; i < std::size(aConverters); ++i)
{
aConverters[i].checkSupports(c);
if (aConverters[i].isOK())
diff --git a/tools/source/stream/GenericTypeSerializer.cxx b/tools/source/stream/GenericTypeSerializer.cxx
index 7bba06d97aba..3eefb008ea67 100644
--- a/tools/source/stream/GenericTypeSerializer.cxx
+++ b/tools/source/stream/GenericTypeSerializer.cxx
@@ -36,9 +36,9 @@ void GenericTypeSerializer::readColor(Color& rColor)
if (nColorNameID & COL_NAME_USER)
{
- sal_uInt16 nRed;
- sal_uInt16 nGreen;
- sal_uInt16 nBlue;
+ sal_uInt16 nRed(0);
+ sal_uInt16 nGreen(0);
+ sal_uInt16 nBlue(0);
mrStream.ReadUInt16(nRed);
mrStream.ReadUInt16(nGreen);
@@ -130,6 +130,18 @@ void GenericTypeSerializer::readSize(Size& rSize)
rSize.setWidth(nWidth);
rSize.setHeight(nHeight);
+
+ // sanitize negative size dimensions
+ if (rSize.Width() < 0)
+ {
+ SAL_WARN("tools", "negative width");
+ rSize.setWidth(0);
+ }
+ if (rSize.Height() < 0)
+ {
+ SAL_WARN("tools", "negative height");
+ rSize.setHeight(0);
+ }
}
void GenericTypeSerializer::writeSize(const Size& rSize)
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index d42cefdf63cf..d79a452cbade 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -26,12 +26,12 @@
#include <memory>
#include <string.h>
-#include <stdio.h>
#include <o3tl/safeint.hxx>
#include <osl/endian.h>
#include <osl/diagnose.h>
#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
#include <tools/long.hxx>
@@ -156,82 +156,43 @@ void SvStream::writeNumberWithoutSwap_(const void * pDataSrc, int nDataSize)
void SvLockBytes::close()
{
- if (m_bOwner)
- delete m_pStream;
- m_pStream = nullptr;
+ (void)this;
}
// virtual
-ErrCode SvLockBytes::ReadAt(sal_uInt64 const nPos, void * pBuffer, std::size_t nCount,
- std::size_t * pRead) const
+ErrCode SvLockBytes::ReadAt(sal_uInt64 const , void * , std::size_t ,
+ std::size_t * ) const
{
- if (!m_pStream)
- {
- OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
- return ERRCODE_NONE;
- }
-
- m_pStream->Seek(nPos);
- std::size_t nTheRead = m_pStream->ReadBytes(pBuffer, nCount);
- if (pRead)
- *pRead = nTheRead;
- return m_pStream->GetErrorCode();
+ OSL_FAIL("SvLockBytes::ReadAt(): Bad stream");
+ return ERRCODE_NONE;
}
// virtual
-ErrCode SvLockBytes::WriteAt(sal_uInt64 const nPos, const void * pBuffer, std::size_t nCount,
- std::size_t * pWritten)
+ErrCode SvLockBytes::WriteAt(sal_uInt64 const , const void * , std::size_t ,
+ std::size_t * )
{
- if (!m_pStream)
- {
- OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
- return ERRCODE_NONE;
- }
-
- m_pStream->Seek(nPos);
- std::size_t nTheWritten = m_pStream->WriteBytes(pBuffer, nCount);
- if (pWritten)
- *pWritten = nTheWritten;
- return m_pStream->GetErrorCode();
+ OSL_FAIL("SvLockBytes::WriteAt(): Bad stream");
+ return ERRCODE_NONE;
}
// virtual
ErrCode SvLockBytes::Flush() const
{
- if (!m_pStream)
- {
- OSL_FAIL("SvLockBytes::Flush(): Bad stream");
- return ERRCODE_NONE;
- }
-
- m_pStream->Flush();
- return m_pStream->GetErrorCode();
+ OSL_FAIL("SvLockBytes::Flush(): Bad stream");
+ return ERRCODE_NONE;
}
// virtual
-ErrCode SvLockBytes::SetSize(sal_uInt64 const nSize)
+ErrCode SvLockBytes::SetSize(sal_uInt64)
{
- if (!m_pStream)
- {
- OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
- return ERRCODE_NONE;
- }
-
- m_pStream->SetStreamSize(nSize);
- return m_pStream->GetErrorCode();
+ OSL_FAIL("SvLockBytes::SetSize(): Bad stream");
+ return ERRCODE_NONE;
}
-ErrCode SvLockBytes::Stat(SvLockBytesStat * pStat) const
+ErrCode SvLockBytes::Stat(SvLockBytesStat *) const
{
- if (!m_pStream)
- {
- OSL_FAIL("SvLockBytes::Stat(): Bad stream");
- return ERRCODE_NONE;
- }
-
- if (pStat)
- pStat->nSize = m_pStream->TellEnd();
+ OSL_FAIL("SvLockBytes::Stat(): Bad stream");
return ERRCODE_NONE;
}
@@ -332,12 +293,6 @@ SvStream::SvStream() :
SvStream::SvStream( SvLockBytes* pLockBytesP ) : SvStream()
{
m_xLockBytes = pLockBytesP;
- if( pLockBytesP ) {
- const SvStream* pStrm = pLockBytesP->GetStream();
- if( pStrm ) {
- SetError( pStrm->GetErrorCode() );
- }
- }
SetBufferSize( 256 );
}
@@ -355,20 +310,25 @@ void SvStream::ClearError()
void SvStream::SetError( ErrCode nErrorCode )
{
- if (m_nError == ERRCODE_NONE)
+ if (m_nError == ERRCODE_NONE || (m_nError.IsWarning() && nErrorCode.IsError()))
m_nError = nErrorCode;
}
void SvStream::SetEndian( SvStreamEndian nNewFormat )
{
- m_nEndian = nNewFormat;
- m_isSwap = false;
#ifdef OSL_BIGENDIAN
- if (m_nEndian == SvStreamEndian::LITTLE)
- m_isSwap = true;
+ m_isSwap = nNewFormat == SvStreamEndian::LITTLE;
+#else
+ m_isSwap = nNewFormat == SvStreamEndian::BIG;
+#endif
+}
+
+SvStreamEndian SvStream::GetEndian() const
+{
+#ifdef OSL_BIGENDIAN
+ return m_isSwap ? SvStreamEndian::LITTLE : SvStreamEndian::BIG;
#else
- if (m_nEndian == SvStreamEndian::BIG)
- m_isSwap = true;
+ return m_isSwap ? SvStreamEndian::BIG : SvStreamEndian::LITTLE;
#endif
}
@@ -378,7 +338,7 @@ void SvStream::SetBufferSize( sal_uInt16 nBufferSize )
bool bDontSeek = (m_pRWBuf == nullptr);
if (m_isDirty && m_isWritable) // due to Windows NT: Access denied
- Flush();
+ FlushBuffer();
if (m_nBufSize)
{
@@ -426,13 +386,21 @@ bool SvStream::ReadByteStringLine( OUString& rStr, rtl_TextEncoding eSrcCharSet,
bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
{
+ OStringBuffer aBuf(4096);
+ bool rv = ReadLine(aBuf, nMaxBytesToRead);
+ rStr = aBuf.makeStringAndClear();
+ return rv;
+}
+
+bool SvStream::ReadLine( OStringBuffer& aBuf, sal_Int32 nMaxBytesToRead )
+{
char buf[256+1];
bool bEnd = false;
sal_uInt64 nOldFilePos = Tell();
char c = 0;
std::size_t nTotalLen = 0;
- OStringBuffer aBuf(4096);
+ aBuf.setLength(0);
while( !bEnd && !GetError() ) // Don't test for EOF as we
// are reading block-wise!
{
@@ -443,7 +411,7 @@ bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
{
// Exit on first block-read error
m_isEof = true;
- rStr.clear();
+ aBuf.setLength(0);
return false;
}
else
@@ -494,7 +462,6 @@ bool SvStream::ReadLine( OString& rStr, sal_Int32 nMaxBytesToRead )
if ( bEnd )
m_isEof = false;
- rStr = aBuf.makeStringAndClear();
return bEnd;
}
@@ -635,9 +602,9 @@ OUString read_zeroTerminated_uInt8s_ToOUString(SvStream& rStream, rtl_TextEncodi
read_zeroTerminated_uInt8s_ToOString(rStream), eEnc);
}
-/** Attempt to write a prefixed sequence of nUnits 16bit units from an OUString,
+/** Attempt to write a sequence of nUnits 16bit units from an OUString,
returned value is number of bytes written */
-std::size_t write_uInt16s_FromOUString(SvStream& rStrm, std::u16string_view rStr,
+static std::size_t write_uInt16s_FromOUString(SvStream& rStrm, std::u16string_view rStr,
std::size_t nUnits)
{
DBG_ASSERT( sizeof(sal_Unicode) == sizeof(sal_uInt16), "write_uInt16s_FromOUString: swapping sizeof(sal_Unicode) not implemented" );
@@ -664,19 +631,22 @@ std::size_t write_uInt16s_FromOUString(SvStream& rStrm, std::u16string_view rStr
return nWritten;
}
-bool SvStream::WriteUnicodeOrByteText( std::u16string_view rStr, rtl_TextEncoding eDestCharSet )
+bool SvStream::WriteUnicodeOrByteText(std::u16string_view rStr, rtl_TextEncoding eDestCharSet, bool bZero)
{
if ( eDestCharSet == RTL_TEXTENCODING_UNICODE )
{
write_uInt16s_FromOUString(*this, rStr, rStr.size());
- return m_nError == ERRCODE_NONE;
+ if (bZero)
+ WriteUnicode(0);
}
else
{
OString aStr(OUStringToOString(rStr, eDestCharSet));
- write_uInt8s_FromOString(*this, aStr, aStr.getLength());
- return m_nError == ERRCODE_NONE;
+ WriteBytes(aStr.getStr(), aStr.getLength());
+ if (bZero)
+ WriteChar(0);
}
+ return m_nError == ERRCODE_NONE;
}
bool SvStream::WriteByteStringLine( std::u16string_view rStr, rtl_TextEncoding eDestCharSet )
@@ -705,10 +675,11 @@ bool SvStream::WriteUniOrByteChar( sal_Unicode ch, rtl_TextEncoding eDestCharSet
void SvStream::StartWritingUnicodeText()
{
+ m_isSwap = false; // Switch to no endian swapping
// BOM, Byte Order Mark, U+FEFF, see
// http://www.unicode.org/faq/utf_bom.html#BOM
// Upon read: 0xfeff(-257) => no swap; 0xfffe(-2) => swap
- writeNumberWithoutSwap(sal_uInt16(0xfeff)); // write native format
+ WriteUInt16(0xfeff);
}
void SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
@@ -718,52 +689,54 @@ void SvStream::StartReadingUnicodeText( rtl_TextEncoding eReadBomCharSet )
eReadBomCharSet == RTL_TEXTENCODING_UTF8))
return; // nothing to read
- bool bTryUtf8 = false;
- sal_uInt16 nFlag(0);
- sal_sSize nBack = sizeof(nFlag);
- ReadUInt16( nFlag );
+ const sal_uInt64 nOldPos = Tell();
+ bool bGetBack = true;
+ unsigned char nFlag(0);
+ ReadUChar( nFlag );
switch ( nFlag )
{
- case 0xfeff :
- // native UTF-16
+ case 0xfe: // UTF-16BE?
if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
- nBack = 0;
+ {
+ ReadUChar(nFlag);
+ if (nFlag == 0xff)
+ {
+ SetEndian(SvStreamEndian::BIG);
+ bGetBack = false;
+ }
+ }
break;
- case 0xfffe :
- // swapped UTF-16
+ case 0xff: // UTF-16LE?
if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
eReadBomCharSet == RTL_TEXTENCODING_UNICODE)
{
- SetEndian( m_nEndian == SvStreamEndian::BIG ? SvStreamEndian::LITTLE : SvStreamEndian::BIG );
- nBack = 0;
+ ReadUChar(nFlag);
+ if (nFlag == 0xfe)
+ {
+ SetEndian(SvStreamEndian::LITTLE);
+ bGetBack = false;
+ }
}
break;
- case 0xefbb :
- if (m_nEndian == SvStreamEndian::BIG &&
- (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
- eReadBomCharSet == RTL_TEXTENCODING_UTF8))
- bTryUtf8 = true;
- break;
- case 0xbbef :
- if (m_nEndian == SvStreamEndian::LITTLE &&
- (eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
- eReadBomCharSet == RTL_TEXTENCODING_UTF8))
- bTryUtf8 = true;
+ case 0xef: // UTF-8?
+ if ( eReadBomCharSet == RTL_TEXTENCODING_DONTKNOW ||
+ eReadBomCharSet == RTL_TEXTENCODING_UTF8)
+ {
+ ReadUChar(nFlag);
+ if (nFlag == 0xbb)
+ {
+ ReadUChar(nFlag);
+ if (nFlag == 0xbf)
+ bGetBack = false; // it is UTF-8
+ }
+ }
break;
default:
; // nothing
}
- if (bTryUtf8)
- {
- unsigned char nChar(0);
- nBack += sizeof(nChar);
- ReadUChar( nChar );
- if (nChar == 0xbf)
- nBack = 0; // it is UTF-8
- }
- if (nBack)
- SeekRel( -nBack ); // no BOM, pure data
+ if (bGetBack)
+ Seek(nOldPos); // no BOM, pure data
}
sal_uInt64 SvStream::SeekRel(sal_Int64 const nPos)
@@ -1014,27 +987,13 @@ SvStream& SvStream::WriteFloat( float v )
return *this;
}
-SvStream& SvStream::WriteDouble ( const double& r )
+SvStream& SvStream::WriteDouble ( double v )
{
#if defined UNX
if (m_isSwap)
- {
- double nHelp = r;
- SwapDouble(nHelp);
- writeNumberWithoutSwap(nHelp);
- return *this;
- }
- else
+ SwapDouble(v);
#endif
- {
- writeNumberWithoutSwap(r);
- }
- return *this;
-}
-
-SvStream& SvStream::WriteCharPtr( const char* pBuf )
-{
- WriteBytes( pBuf, strlen(pBuf) );
+ writeNumberWithoutSwap(v);
return *this;
}
@@ -1344,22 +1303,6 @@ void SvStream::RefreshBuffer()
m_isIoRead = m_isIoWrite = false;
}
-SvStream& SvStream::WriteInt32AsString(sal_Int32 nInt32)
-{
- char buffer[12];
- std::size_t nLen = sprintf(buffer, "%" SAL_PRIdINT32, nInt32);
- WriteBytes(buffer, nLen);
- return *this;
-}
-
-SvStream& SvStream::WriteUInt32AsString(sal_uInt32 nUInt32)
-{
- char buffer[11];
- std::size_t nLen = sprintf(buffer, "%" SAL_PRIuUINT32, nUInt32);
- WriteBytes(buffer, nLen);
- return *this;
-}
-
#define CRYPT_BUFSIZE 1024
/// Encrypt and write
@@ -1544,7 +1487,7 @@ SvMemoryStream::~SvMemoryStream()
if( bOwnsData )
FreeMemory();
else
- Flush();
+ FlushBuffer();
}
}
@@ -1752,7 +1695,7 @@ void SvMemoryStream::FreeMemory()
void* SvMemoryStream::SwitchBuffer()
{
- Flush();
+ FlushBuffer();
if( !bOwnsData )
return nullptr;
Seek( STREAM_SEEK_TO_BEGIN );
@@ -1785,7 +1728,16 @@ void SvMemoryStream::SetSize(sal_uInt64 const nNewSize)
ReAllocateMemory( nDiff );
}
-//Create an OString of nLen bytes from rStream
+void SvMemoryStream::MakeReadOnly()
+{
+ FlushBuffer();
+ m_isWritable = false;
+ nResize = 0;
+ SetBufferSize( 0 );
+}
+
+// Create an OString of nLen bytes from rStream
+// coverity[ +taint_sanitize ]
OString read_uInt8s_ToOString(SvStream& rStrm, std::size_t nLen)
{
rtl_String *pStr = nullptr;
@@ -1816,7 +1768,8 @@ OString read_uInt8s_ToOString(SvStream& rStrm, std::size_t nLen)
return pStr ? OString(pStr, SAL_NO_ACQUIRE) : OString();
}
-//Create an OUString of nLen sal_Unicode code units from rStream
+// Create an OUString of nLen sal_Unicode code units from rStream
+// coverity[ +taint_sanitize ]
OUString read_uInt16s_ToOUString(SvStream& rStrm, std::size_t nLen)
{
rtl_uString *pStr = nullptr;
@@ -1848,7 +1801,8 @@ OUString read_uInt16s_ToOUString(SvStream& rStrm, std::size_t nLen)
}
}
- //take ownership of buffer and return, otherwise return empty string
+ // take ownership of buffer and return, otherwise return empty string
+ // coverity[tainted_data] - unhelpful untrusted loop bound
return pStr ? OUString(pStr, SAL_NO_ACQUIRE) : OUString();
}
@@ -1989,7 +1943,7 @@ std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream& rStrm,
if (rStrm.good())
{
nWritten += sizeof(sal_uInt16);
- nWritten += write_uInt8s_FromOString(rStrm, rStr, nUnits);
+ nWritten += rStrm.WriteBytes(rStr.data(), nUnits);
}
return nWritten;
}
diff --git a/tools/source/stream/strmunx.cxx b/tools/source/stream/strmunx.cxx
index 853389266ac3..881d7a28c0af 100644
--- a/tools/source/stream/strmunx.cxx
+++ b/tools/source/stream/strmunx.cxx
@@ -24,7 +24,7 @@
#include <tools/stream.hxx>
#include <map>
-#include <osl/mutex.hxx>
+#include <mutex>
#include <osl/thread.h>
#include <sal/log.hxx>
@@ -37,9 +37,9 @@ using namespace osl;
namespace {
-osl::Mutex& LockMutex()
+std::mutex& LockMutex()
{
- static osl::Mutex SINGLETON;
+ static std::mutex SINGLETON;
return SINGLETON;
}
@@ -63,7 +63,7 @@ bool lockFile( const SvFileStream* pStream )
if( aStatus.getFileType() == osl::FileStatus::Directory )
return true;
- osl::MutexGuard aGuard( LockMutex() );
+ std::unique_lock aGuard( LockMutex() );
for( const auto& [rLockStream, rLockItem] : gLocks )
{
if( aItem.isIdenticalTo( rLockItem ) )
@@ -86,22 +86,12 @@ bool lockFile( const SvFileStream* pStream )
void unlockFile( SvFileStream const * pStream )
{
- osl::MutexGuard aGuard( LockMutex() );
+ std::unique_lock aGuard( LockMutex() );
gLocks.erase(pStream);
}
}
-// StreamData ------------------------------------------------------------------
-
-class StreamData
-{
-public:
- oslFileHandle rHandle;
-
- StreamData() : rHandle( nullptr ) { }
-};
-
static ErrCode GetSvError( int nErrno )
{
static struct { int nErr; ErrCode sv; } const errArr[] =
@@ -111,7 +101,7 @@ static ErrCode GetSvError( int nErrno )
{ EBADF, SVSTREAM_INVALID_HANDLE },
#if defined(NETBSD) || \
defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
- defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
+ defined(__FreeBSD_kernel__) || defined(DRAGONFLY) || \
defined(IOS) || defined(HAIKU)
{ EDEADLK, SVSTREAM_LOCKING_VIOLATION },
#else
@@ -198,8 +188,6 @@ SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nOpenMode )
{
bIsOpen = false;
m_isWritable = false;
- mbDontFlushOnClose = false;
- pInstanceData.reset(new StreamData);
SetBufferSize( 1024 );
// convert URL to SystemPath, if necessary
@@ -216,8 +204,6 @@ SvFileStream::SvFileStream()
{
bIsOpen = false;
m_isWritable = false;
- mbDontFlushOnClose = false;
- pInstanceData.reset(new StreamData);
SetBufferSize( 1024 );
}
@@ -233,7 +219,7 @@ std::size_t SvFileStream::GetData( void* pData, std::size_t nSize )
sal_uInt64 nRead = 0;
if ( IsOpen() )
{
- oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,static_cast<sal_uInt64>(nSize),&nRead);
+ oslFileError rc = osl_readFile(mxFileHandle,pData,static_cast<sal_uInt64>(nSize),&nRead);
if ( rc != osl_File_E_None )
{
SetError( ::GetSvError( rc ));
@@ -250,7 +236,7 @@ std::size_t SvFileStream::PutData( const void* pData, std::size_t nSize )
sal_uInt64 nWrite = 0;
if ( IsOpen() )
{
- oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,static_cast<sal_uInt64>(nSize),&nWrite);
+ oslFileError rc = osl_writeFile(mxFileHandle,pData,static_cast<sal_uInt64>(nSize),&nWrite);
if ( rc != osl_File_E_None )
{
SetError( ::GetSvError( rc ) );
@@ -271,9 +257,9 @@ sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
oslFileError rc;
sal_uInt64 nNewPos;
if ( nPos != STREAM_SEEK_TO_END )
- rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
+ rc = osl_setFilePos( mxFileHandle, osl_Pos_Absolut, nPos );
else
- rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
+ rc = osl_setFilePos( mxFileHandle, osl_Pos_End, 0 );
if ( rc != osl_File_E_None )
{
@@ -282,7 +268,7 @@ sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
}
if ( nPos != STREAM_SEEK_TO_END )
return nPos;
- osl_getFilePos( pInstanceData->rHandle, &nNewPos );
+ osl_getFilePos( mxFileHandle, &nNewPos );
return nNewPos;
}
SetError( SVSTREAM_GENERALERROR );
@@ -291,7 +277,7 @@ sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
void SvFileStream::FlushData()
{
- auto rc = osl_syncFile(pInstanceData->rHandle);
+ auto rc = osl_syncFile(mxFileHandle);
if (rc != osl_File_E_None)
SetError( ::GetSvError( rc ));
}
@@ -335,10 +321,7 @@ bool SvFileStream::LockFile()
if( !lockFile( this ) )
{
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "InternalLock on %s failed\n",
- OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr() );
-#endif
+ SAL_WARN("tools.stream", "InternalLock on " << aFilename << "failed");
return false;
}
@@ -374,14 +357,20 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
// FIXME: we really need to switch to a pure URL model ...
if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
aFileURL = aFilename;
- bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
- aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
- // SvFileStream can't open a directory
- if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
+ // don't both stat()ing a temporary file, unnecessary
+ bool bStatValid = true;
+ if (!(nOpenMode & StreamMode::TEMPORARY))
{
- SetError( ::GetSvError( EISDIR ) );
- return;
+ bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
+ aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
+
+ // SvFileStream can't open a directory
+ if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
+ {
+ SetError( ::GetSvError( EISDIR ) );
+ return;
+ }
}
if ( !( nOpenMode & StreamMode::WRITE ) )
@@ -411,14 +400,9 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
{
File::copy( aStatus.getLinkTargetURL(), aFileURL );
-#if OSL_DEBUG_LEVEL > 0
- fprintf( stderr,
- "Removing link and replacing with file contents (%s) -> (%s).\n",
- OUStringToOString( aStatus.getLinkTargetURL(),
- RTL_TEXTENCODING_UTF8).getStr(),
- OUStringToOString( aFileURL,
- RTL_TEXTENCODING_UTF8).getStr() );
-#endif
+ SAL_INFO("tools.stream",
+ "Removing link and replacing with file contents (" <<
+ aStatus.getLinkTargetURL() << ") -> (" << aFileURL << ").");
}
}
}
@@ -436,7 +420,7 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
}
if ( rc == osl_File_E_None )
{
- pInstanceData->rHandle = nHandleTmp;
+ mxFileHandle = nHandleTmp;
bIsOpen = true;
if ( uFlags & osl_File_OpenFlag_Write )
m_isWritable = true;
@@ -446,7 +430,7 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
osl_closeFile( nHandleTmp );
bIsOpen = false;
m_isWritable = false;
- pInstanceData->rHandle = nullptr;
+ mxFileHandle = nullptr;
}
}
else
@@ -460,10 +444,9 @@ void SvFileStream::Close()
if ( IsOpen() )
{
SAL_INFO("tools", "Closing " << aFilename);
- if ( !mbDontFlushOnClose )
- Flush();
- osl_closeFile( pInstanceData->rHandle );
- pInstanceData->rHandle = nullptr;
+ FlushBuffer();
+ osl_closeFile( mxFileHandle );
+ mxFileHandle = nullptr;
}
bIsOpen = false;
@@ -482,7 +465,7 @@ void SvFileStream::SetSize (sal_uInt64 const nSize)
{
if (IsOpen())
{
- oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
+ oslFileError rc = osl_setFileSize( mxFileHandle, nSize );
if (rc != osl_File_E_None )
{
SetError ( ::GetSvError( rc ));
diff --git a/tools/source/stream/strmwnt.cxx b/tools/source/stream/strmwnt.cxx
index c91628b55091..d7d3a73ed2ce 100644
--- a/tools/source/stream/strmwnt.cxx
+++ b/tools/source/stream/strmwnt.cxx
@@ -36,16 +36,6 @@
#include <osl/file.hxx>
using namespace osl;
-class StreamData
-{
-public:
- HANDLE hFile;
-
- StreamData() : hFile(nullptr)
- {
- }
-};
-
static ErrCode GetSvError( DWORD nWntError )
{
static struct { DWORD wnt; ErrCode sv; } errArr[] =
@@ -107,8 +97,6 @@ SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nMode )
bIsOpen = false;
nLockCounter = 0;
m_isWritable = false;
- mbDontFlushOnClose = false;
- pInstanceData.reset( new StreamData );
SetBufferSize( 8192 );
// convert URL to SystemPath, if necessary
@@ -124,8 +112,6 @@ SvFileStream::SvFileStream()
bIsOpen = false;
nLockCounter = 0;
m_isWritable = false;
- mbDontFlushOnClose = false;
- pInstanceData.reset( new StreamData );
SetBufferSize( 8192 );
}
@@ -141,7 +127,7 @@ std::size_t SvFileStream::GetData( void* pData, std::size_t nSize )
DWORD nCount = 0;
if( IsOpen() )
{
- bool bResult = ReadFile(pInstanceData->hFile,pData,nSize,&nCount,nullptr);
+ bool bResult = ReadFile(mxFileHandle,pData,nSize,&nCount,nullptr);
if( !bResult )
{
std::size_t nTestError = GetLastError();
@@ -156,7 +142,7 @@ std::size_t SvFileStream::PutData( const void* pData, std::size_t nSize )
DWORD nCount = 0;
if( IsOpen() )
{
- if(!WriteFile(pInstanceData->hFile,pData,nSize,&nCount,nullptr))
+ if(!WriteFile(mxFileHandle,pData,nSize,&nCount,nullptr))
SetError(::GetSvError( GetLastError() ) );
}
return nCount;
@@ -166,31 +152,36 @@ sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
{
// check if a truncated STREAM_SEEK_TO_END was passed
assert(nPos != SAL_MAX_UINT32);
- DWORD nNewPos = 0;
+ LARGE_INTEGER nNewPos, nActPos;
+ nNewPos.QuadPart = 0;
+ nActPos.QuadPart = nPos;
+ bool result = false;
if( IsOpen() )
{
if( nPos != STREAM_SEEK_TO_END )
- // 64-Bit files are not supported
- nNewPos=SetFilePointer(pInstanceData->hFile,nPos,nullptr,FILE_BEGIN);
+ {
+ result = SetFilePointerEx(mxFileHandle, nActPos, &nNewPos, FILE_BEGIN);
+ }
else
- nNewPos=SetFilePointer(pInstanceData->hFile,0L,nullptr,FILE_END);
-
- if( nNewPos == 0xFFFFFFFF )
{
- SetError(::GetSvError( GetLastError() ) );
- nNewPos = 0;
+ result = SetFilePointerEx(mxFileHandle, nNewPos, &nNewPos, FILE_END);
+ }
+ if (!result)
+ {
+ SetError(::GetSvError(GetLastError()));
+ return 0;
}
}
else
SetError( SVSTREAM_GENERALERROR );
- return static_cast<sal_uInt64>(nNewPos);
+ return static_cast<sal_uInt64>(nNewPos.QuadPart);
}
void SvFileStream::FlushData()
{
if( IsOpen() )
{
- if( !FlushFileBuffers(pInstanceData->hFile) )
+ if( !FlushFileBuffers(mxFileHandle) )
SetError(::GetSvError(GetLastError()));
}
}
@@ -202,7 +193,7 @@ bool SvFileStream::LockFile()
{
if( IsOpen() )
{
- bRetVal = ::LockFile(pInstanceData->hFile,0L,0L,LONG_MAX,0L );
+ bRetVal = ::LockFile(mxFileHandle,0L,0L,LONG_MAX,0L );
if( bRetVal )
{
nLockCounter = 1;
@@ -227,7 +218,7 @@ void SvFileStream::UnlockFile()
{
if( IsOpen() )
{
- if( ::UnlockFile(pInstanceData->hFile,0L,0L,LONG_MAX,0L ) )
+ if( ::UnlockFile(mxFileHandle,0L,0L,LONG_MAX,0L ) )
{
nLockCounter = 0;
}
@@ -306,8 +297,10 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nMode )
if ( nMode & StreamMode::TEMPORARY )
nAttributes |= FILE_ATTRIBUTE_TEMPORARY;
+ if ( nMode & StreamMode::DELETE_ON_CLOSE )
+ nAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
- pInstanceData->hFile = CreateFileW(
+ mxFileHandle = CreateFileW(
o3tl::toW(aFilename.getStr()),
nAccessMode,
nShareMode,
@@ -317,7 +310,7 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nMode )
nullptr
);
- if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && (
+ if( mxFileHandle!=INVALID_HANDLE_VALUE && (
// Did Create Always overwrite a file?
GetLastError() == ERROR_ALREADY_EXISTS ||
// Did Create Always open a new file?
@@ -329,7 +322,7 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nMode )
}
// Otherwise, determine if we're allowed to read
- if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) &&
+ if( (mxFileHandle==INVALID_HANDLE_VALUE) &&
(nAccessMode & GENERIC_WRITE))
{
ErrCode nErr = ::GetSvError( GetLastError() );
@@ -341,7 +334,7 @@ void SvFileStream::Open( const OUString& rFilename, StreamMode nMode )
// if Openaction is CREATE_ALWAYS
nOpenAction = OPEN_EXISTING;
SetLastError( ERROR_SUCCESS );
- pInstanceData->hFile = CreateFileW(
+ mxFileHandle = CreateFileW(
o3tl::toW(aFilename.getStr()),
GENERIC_READ,
nShareMode,
@@ -379,9 +372,8 @@ void SvFileStream::Close()
nLockCounter = 1;
UnlockFile();
}
- if ( !mbDontFlushOnClose )
- Flush();
- CloseHandle( pInstanceData->hFile );
+ FlushBuffer();
+ CloseHandle( mxFileHandle );
}
bIsOpen = false;
nLockCounter= 0;
@@ -402,7 +394,7 @@ void SvFileStream::SetSize(sal_uInt64 const nSize)
if( IsOpen() )
{
bool bError = false;
- HANDLE hFile = pInstanceData->hFile;
+ HANDLE hFile = mxFileHandle;
DWORD const nOld = SetFilePointer( hFile, 0L, nullptr, FILE_CURRENT );
if( nOld != 0xffffffff )
{
diff --git a/tools/source/xml/XmlWalker.cxx b/tools/source/xml/XmlWalker.cxx
index c0e8a2abef48..f486cef36b34 100644
--- a/tools/source/xml/XmlWalker.cxx
+++ b/tools/source/xml/XmlWalker.cxx
@@ -59,14 +59,17 @@ bool XmlWalker::open(SvStream* pStream)
return true;
}
-OString XmlWalker::name() { return reinterpret_cast<const char*>(mpImpl->mpCurrent->name); }
+std::string_view XmlWalker::name()
+{
+ return reinterpret_cast<const char*>(mpImpl->mpCurrent->name);
+}
-OString XmlWalker::namespaceHref()
+std::string_view XmlWalker::namespaceHref()
{
return reinterpret_cast<const char*>(mpImpl->mpCurrent->ns->href);
}
-OString XmlWalker::namespacePrefix()
+std::string_view XmlWalker::namespacePrefix()
{
return reinterpret_cast<const char*>(mpImpl->mpCurrent->ns->prefix);
}
diff --git a/tools/source/xml/XmlWriter.cxx b/tools/source/xml/XmlWriter.cxx
index 726b63966045..afc6dd9b73be 100644
--- a/tools/source/xml/XmlWriter.cxx
+++ b/tools/source/xml/XmlWriter.cxx
@@ -29,6 +29,15 @@ int funcCloseCallback(void* pContext)
return 0; // 0 or -1 in case of error
}
+template <typename T>
+requires(sizeof(T) == sizeof(char)) void attributeBase64_impl(xmlTextWriterPtr writer,
+ const char* name, const T* value,
+ int size)
+{
+ (void)xmlTextWriterStartAttribute(writer, BAD_CAST(name));
+ (void)xmlTextWriterWriteBase64(writer, reinterpret_cast<const char*>(value), 0, size);
+ (void)xmlTextWriterEndAttribute(writer);
+}
} // end anonymous namespace
struct XmlWriterImpl
@@ -82,76 +91,61 @@ void XmlWriter::endDocument()
void XmlWriter::startElement(const OString& sPrefix, const OString& sName,
const OString& sNamespaceUri)
{
- xmlChar* xmlName = xmlCharStrdup(sName.getStr());
+ xmlChar* xmlName = BAD_CAST(sName.getStr());
xmlChar* xmlPrefix = nullptr;
xmlChar* xmlNamespaceUri = nullptr;
if (!sPrefix.isEmpty())
- xmlPrefix = xmlCharStrdup(sPrefix.getStr());
+ xmlPrefix = BAD_CAST(sPrefix.getStr());
if (!sNamespaceUri.isEmpty())
- xmlNamespaceUri = xmlCharStrdup(sNamespaceUri.getStr());
+ xmlNamespaceUri = BAD_CAST(sNamespaceUri.getStr());
(void)xmlTextWriterStartElementNS(mpImpl->mpWriter, xmlPrefix, xmlName, xmlNamespaceUri);
-
- xmlFree(xmlName);
- if (!sPrefix.isEmpty())
- xmlFree(xmlPrefix);
- if (!sNamespaceUri.isEmpty())
- xmlFree(xmlNamespaceUri);
}
-void XmlWriter::startElement(const OString& sName)
+void XmlWriter::startElement(const char* pName)
{
- xmlChar* xmlName = xmlCharStrdup(sName.getStr());
+ xmlChar* xmlName = BAD_CAST(pName);
(void)xmlTextWriterStartElement(mpImpl->mpWriter, xmlName);
- xmlFree(xmlName);
}
void XmlWriter::endElement() { (void)xmlTextWriterEndElement(mpImpl->mpWriter); }
-void XmlWriter::attributeBase64(const OString& rsName, std::vector<sal_uInt8> const& rValueInBytes)
+void XmlWriter::attributeBase64(const char* pName, std::vector<sal_uInt8> const& rValueInBytes)
{
- std::vector<char> aSignedBytes(rValueInBytes.begin(), rValueInBytes.end());
- attributeBase64(rsName, aSignedBytes);
+ attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size());
}
-void XmlWriter::attributeBase64(const OString& rsName, std::vector<char> const& rValueInBytes)
+void XmlWriter::attributeBase64(const char* pName, std::vector<char> const& rValueInBytes)
{
- xmlChar* xmlName = xmlCharStrdup(rsName.getStr());
- (void)xmlTextWriterStartAttribute(mpImpl->mpWriter, xmlName);
- (void)xmlTextWriterWriteBase64(mpImpl->mpWriter, rValueInBytes.data(), 0, rValueInBytes.size());
- (void)xmlTextWriterEndAttribute(mpImpl->mpWriter);
- xmlFree(xmlName);
+ attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size());
}
-void XmlWriter::attribute(const OString& name, const OString& value)
+void XmlWriter::attribute(const char* name, const OString& value)
{
- xmlChar* xmlName = xmlCharStrdup(name.getStr());
- xmlChar* xmlValue = xmlCharStrdup(value.getStr());
+ xmlChar* xmlName = BAD_CAST(name);
+ xmlChar* xmlValue = BAD_CAST(value.getStr());
(void)xmlTextWriterWriteAttribute(mpImpl->mpWriter, xmlName, xmlValue);
- xmlFree(xmlValue);
- xmlFree(xmlName);
}
-void XmlWriter::attribute(const OString& name, std::u16string_view value)
+void XmlWriter::attribute(const char* name, std::u16string_view value)
{
- attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr());
+ attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8));
}
-void XmlWriter::attribute(const OString& name, const sal_Int32 aNumber)
+void XmlWriter::attribute(const char* name, const sal_Int64 aNumber)
{
- attribute(name, OUString::number(aNumber));
+ attribute(name, OString::number(aNumber));
}
-void XmlWriter::attributeDouble(const OString& name, const double aNumber)
+void XmlWriter::attributeDouble(const char* name, const double aNumber)
{
- attribute(name, OUString::number(aNumber));
+ attribute(name, OString::number(aNumber));
}
void XmlWriter::content(const OString& sValue)
{
- xmlChar* xmlValue = xmlCharStrdup(sValue.getStr());
+ xmlChar* xmlValue = BAD_CAST(sValue.getStr());
(void)xmlTextWriterWriteString(mpImpl->mpWriter, xmlValue);
- xmlFree(xmlValue);
}
void XmlWriter::content(std::u16string_view sValue)
@@ -159,7 +153,7 @@ void XmlWriter::content(std::u16string_view sValue)
content(OUStringToOString(sValue, RTL_TEXTENCODING_UTF8));
}
-void XmlWriter::element(const OString& sName)
+void XmlWriter::element(const char* sName)
{
startElement(sName);
endElement();
diff --git a/tools/source/zcodec/zcodec.cxx b/tools/source/zcodec/zcodec.cxx
index 97a03a463021..c925ecde8a2d 100644
--- a/tools/source/zcodec/zcodec.cxx
+++ b/tools/source/zcodec/zcodec.cxx
@@ -29,14 +29,15 @@
#include <tools/long.hxx>
/* gzip flag byte */
-// GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
-#define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
-
-const int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */
+// GZ_ASCII_FLAG = 0x01; /* bit 0 set: file probably ascii text */
+constexpr sal_uInt8 GZ_HEAD_CRC = 0x02; /* bit 1 set: header CRC present */
+constexpr sal_uInt8 GZ_EXTRA_FIELD = 0x04; /* bit 2 set: extra field present */
+constexpr sal_uInt8 GZ_ORIG_NAME = 0x08; /* bit 3 set: original file name present */
+constexpr sal_uInt8 GZ_COMMENT = 0x10; /* bit 4 set: file comment present */
+constexpr sal_uInt8 GZ_RESERVED = 0xE0; /* bits 5..7: reserved */
+constexpr sal_uInt16 GZ_MAGIC_BYTES_LE = 0x8B1F; /* gzip magic bytes, little endian */
+constexpr sal_uInt8 GZ_DEFLATE = 0x08;
+constexpr sal_uInt8 GZ_FS_UNKNOWN = 0xFF;
ZCodec::ZCodec( size_t nInBufSize, size_t nOutBufSize )
: meState(STATE_INIT)
@@ -46,6 +47,9 @@ ZCodec::ZCodec( size_t nInBufSize, size_t nOutBufSize )
, mnInToRead(0)
, mpOStm(nullptr)
, mnOutBufSize(nOutBufSize)
+ , mnUncompressedSize(0)
+ , mnInBufCRC32(0)
+ , mnLastModifiedTime(0)
, mnCompressLevel(0)
, mbGzLib(false)
{
@@ -58,6 +62,16 @@ ZCodec::~ZCodec()
delete pStream;
}
+bool ZCodec::IsZCompressed( SvStream& rIStm )
+{
+ sal_uInt64 nCurPos = rIStm.Tell();
+ rIStm.Seek( 0 );
+ sal_uInt16 nFirstTwoBytes = 0;
+ rIStm.ReadUInt16( nFirstTwoBytes );
+ rIStm.Seek( nCurPos );
+ return nFirstTwoBytes == GZ_MAGIC_BYTES_LE;
+}
+
void ZCodec::BeginCompression( int nCompressLevel, bool gzLib )
{
assert(meState == STATE_INIT);
@@ -99,6 +113,25 @@ tools::Long ZCodec::EndCompression()
retvalue = pStream->total_in;
deflateEnd( pStream );
+ if ( mbGzLib )
+ {
+ // metadata must be set to compress as gz format
+ assert(!msFilename.isEmpty());
+ // overwrite zlib checksum
+ mpOStm->Seek(STREAM_SEEK_TO_END);
+ mpOStm->SeekRel(-4);
+ mpOStm->WriteUInt32( mnInBufCRC32 ); // Uncompressed buffer CRC32
+ mpOStm->WriteUInt32( mnUncompressedSize ); // Uncompressed size mod 2^32
+ mpOStm->Seek( 0 );
+ mpOStm->WriteUInt16( GZ_MAGIC_BYTES_LE ) // Magic bytes
+ .WriteUInt8( GZ_DEFLATE ) // Compression algorithm
+ .WriteUInt8( GZ_ORIG_NAME ) // Filename
+ .WriteUInt32( mnLastModifiedTime ) // Modification time
+ .WriteUInt8( 0 ) // Extra flags
+ .WriteUInt8( GZ_FS_UNKNOWN ) // Operating system
+ .WriteBytes( msFilename.pData->buffer, msFilename.pData->length );
+ mpOStm->WriteUInt8( 0 ); // null terminate the filename string
+ }
}
else
{
@@ -112,10 +145,20 @@ tools::Long ZCodec::EndCompression()
return mbStatus ? retvalue : -1;
}
+void ZCodec::SetCompressionMetadata( const OString& sFilename, sal_uInt32 nLastModifiedTime, sal_uInt32 nInBufCRC32 )
+{
+ assert( mbGzLib );
+ msFilename = sFilename;
+ mnLastModifiedTime = nLastModifiedTime;
+ mnInBufCRC32 = nInBufCRC32;
+}
+
void ZCodec::Compress( SvStream& rIStm, SvStream& rOStm )
{
assert(meState == STATE_INIT);
mpOStm = &rOStm;
+ rIStm.Seek(0);
+ mnUncompressedSize = rIStm.TellEnd();
InitCompress();
mpInBuf.reset(new sal_uInt8[ mnInBufSize ]);
auto pStream = static_cast<z_stream*>(mpsC_Stream);
@@ -255,6 +298,14 @@ void ZCodec::ImplWriteBack()
void ZCodec::InitCompress()
{
assert(meState == STATE_INIT);
+ if (mbGzLib)
+ {
+ // Seek just enough so that the zlib header is overwritten after compression
+ // with the gz header
+ // 10 header bytes + filename length + null terminator - 2 bytes for
+ // zlib header that gets overwritten
+ mpOStm->Seek(10 + msFilename.getLength() + 1 - 2);
+ }
meState = STATE_COMPRESS;
auto pStream = static_cast<z_stream*>(mpsC_Stream);
mbStatus = deflateInit2_(
@@ -272,12 +323,11 @@ void ZCodec::InitDecompress(SvStream & inStream)
if ( mbStatus && mbGzLib )
{
sal_uInt8 j, nMethod, nFlags;
- for (int i : gz_magic) // gz - magic number
- {
- inStream.ReadUChar( j );
- if ( j != i )
- mbStatus = false;
- }
+ sal_uInt16 nFirstTwoBytes;
+ inStream.Seek( 0 );
+ inStream.ReadUInt16( nFirstTwoBytes );
+ if ( nFirstTwoBytes != GZ_MAGIC_BYTES_LE )
+ mbStatus = false;
inStream.ReadUChar( nMethod );
inStream.ReadUChar( nFlags );
if ( nMethod != Z_DEFLATED )