summaryrefslogtreecommitdiff
path: root/sax/source
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-04-20 09:14:08 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-04-20 10:38:02 +0200
commit8e4453c2117b6c3bb15be6b949a0a8a43df66647 (patch)
tree73cf2208d992c5406777be3edc4efe5fc28963ce /sax/source
parent2ddf33f78fbc4ce0f49752e4adb9357c1fb69833 (diff)
use more FastAttributeIter::toView
Change-Id: I8a8ad5456fea349a45fca0aa468313cb04aa02f5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133198 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sax/source')
-rw-r--r--sax/source/tools/converter.cxx165
1 files changed, 163 insertions, 2 deletions
diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx
index 6b6301bac0ff..b882ac076cd9 100644
--- a/sax/source/tools/converter.cxx
+++ b/sax/source/tools/converter.cxx
@@ -1216,8 +1216,9 @@ readUnsignedNumberMaxDigits(int maxDigits,
return bOverflow ? R_OVERFLOW : R_SUCCESS;
}
+template<typename V>
static bool
-readDurationT(std::u16string_view rString, size_t & io_rnPos)
+readDurationT(V rString, size_t & io_rnPos)
{
if ((io_rnPos < rString.size()) &&
(rString[io_rnPos] == 'T' || rString[io_rnPos] == 't'))
@@ -1228,8 +1229,9 @@ readDurationT(std::u16string_view rString, size_t & io_rnPos)
return false;
}
+template<typename V>
static bool
-readDurationComponent(std::u16string_view rString,
+readDurationComponent(V rString,
size_t & io_rnPos, sal_Int32 & io_rnTemp, bool & io_rbTimePart,
sal_Int32 & o_rnTarget, const sal_Unicode cLower, const sal_Unicode cUpper)
{
@@ -1418,6 +1420,165 @@ bool Converter::convertDuration(util::Duration& rDuration,
return bSuccess;
}
+/** convert ISO8601 "duration" string to util::Duration */
+bool Converter::convertDuration(util::Duration& rDuration,
+ std::string_view rString)
+{
+ std::string_view string = trim(rString);
+ size_t nPos(0);
+
+ bool bIsNegativeDuration(false);
+ if (!string.empty() && ('-' == string[0]))
+ {
+ bIsNegativeDuration = true;
+ ++nPos;
+ }
+
+ if (nPos < string.size()
+ && string[nPos] != 'P' && string[nPos] != 'p') // duration must start with "P"
+ {
+ return false;
+ }
+
+ ++nPos;
+
+ /// last read number; -1 == no valid number! always reset after using!
+ sal_Int32 nTemp(-1);
+ bool bTimePart(false); // have we read 'T'?
+ bool bSuccess(false);
+ sal_Int32 nYears(0);
+ sal_Int32 nMonths(0);
+ sal_Int32 nDays(0);
+ sal_Int32 nHours(0);
+ sal_Int32 nMinutes(0);
+ sal_Int32 nSeconds(0);
+ sal_Int32 nNanoSeconds(0);
+
+ bTimePart = readDurationT(string, nPos);
+ bSuccess = (R_SUCCESS == readUnsignedNumber(string, nPos, nTemp));
+
+ if (!bTimePart && bSuccess)
+ {
+ bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
+ nYears, 'y', 'Y');
+ }
+
+ if (!bTimePart && bSuccess)
+ {
+ bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
+ nMonths, 'm', 'M');
+ }
+
+ if (!bTimePart && bSuccess)
+ {
+ bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
+ nDays, 'd', 'D');
+ }
+
+ if (bTimePart)
+ {
+ if (-1 == nTemp) // a 'T' must be followed by a component
+ {
+ bSuccess = false;
+ }
+
+ if (bSuccess)
+ {
+ bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
+ nHours, 'h', 'H');
+ }
+
+ if (bSuccess)
+ {
+ bSuccess = readDurationComponent(string, nPos, nTemp, bTimePart,
+ nMinutes, 'm', 'M');
+ }
+
+ // eeek! seconds are icky.
+ if ((nPos < string.size()) && bSuccess)
+ {
+ if (string[nPos] == '.' ||
+ string[nPos] == ',')
+ {
+ ++nPos;
+ if (-1 != nTemp)
+ {
+ nSeconds = nTemp;
+ nTemp = -1;
+ const sal_Int32 nStart(nPos);
+ bSuccess = readUnsignedNumberMaxDigits(9, string, nPos, nTemp) == R_SUCCESS;
+ if ((nPos < string.size()) && bSuccess)
+ {
+ if (-1 != nTemp)
+ {
+ nNanoSeconds = nTemp;
+ sal_Int32 nDigits = nPos - nStart;
+ assert(nDigits >= 0);
+ for (; nDigits < 9; ++nDigits)
+ {
+ nNanoSeconds *= 10;
+ }
+ nTemp=-1;
+ if ('S' == string[nPos] || 's' == string[nPos])
+ {
+ ++nPos;
+ }
+ else
+ {
+ bSuccess = false;
+ }
+ }
+ else
+ {
+ bSuccess = false;
+ }
+ }
+ }
+ else
+ {
+ bSuccess = false;
+ }
+ }
+ else if ('S' == string[nPos] || 's' == string[nPos])
+ {
+ ++nPos;
+ if (-1 != nTemp)
+ {
+ nSeconds = nTemp;
+ nTemp = -1;
+ }
+ else
+ {
+ bSuccess = false;
+ }
+ }
+ }
+ }
+
+ if (nPos != string.size()) // string not processed completely?
+ {
+ bSuccess = false;
+ }
+
+ if (nTemp != -1) // unprocessed number?
+ {
+ bSuccess = false;
+ }
+
+ if (bSuccess)
+ {
+ rDuration.Negative = bIsNegativeDuration;
+ rDuration.Years = static_cast<sal_Int16>(nYears);
+ rDuration.Months = static_cast<sal_Int16>(nMonths);
+ rDuration.Days = static_cast<sal_Int16>(nDays);
+ rDuration.Hours = static_cast<sal_Int16>(nHours);
+ rDuration.Minutes = static_cast<sal_Int16>(nMinutes);
+ rDuration.Seconds = static_cast<sal_Int16>(nSeconds);
+ rDuration.NanoSeconds = nNanoSeconds;
+ }
+
+ return bSuccess;
+}
static void
lcl_AppendTimezone(OUStringBuffer & i_rBuffer, int const nOffset)