diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-04-20 09:14:08 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-04-20 10:38:02 +0200 |
commit | 8e4453c2117b6c3bb15be6b949a0a8a43df66647 (patch) | |
tree | 73cf2208d992c5406777be3edc4efe5fc28963ce /sax | |
parent | 2ddf33f78fbc4ce0f49752e4adb9357c1fb69833 (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')
-rw-r--r-- | sax/source/tools/converter.cxx | 165 |
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) |