| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #ifndef _ZFORFIND_HXX |
| #define _ZFORFIND_HXX |
| |
| #include <tools/string.hxx> |
| |
| class Date; |
| class SvNumberformat; |
| class SvNumberFormatter; |
| |
| #define SV_MAX_ANZ_INPUT_STRINGS 20 // max count of substrings in input scanner |
| |
| class ImpSvNumberInputScan |
| { |
| public: |
| ImpSvNumberInputScan( SvNumberFormatter* pFormatter ); |
| ~ImpSvNumberInputScan(); |
| |
| /*!*/ void ChangeIntl(); // MUST be called if language changes |
| |
| /// set reference date for offset calculation |
| void ChangeNullDate( |
| const sal_uInt16 nDay, |
| const sal_uInt16 nMonth, |
| const sal_uInt16 nYear ); |
| |
| /// convert input string to number |
| sal_Bool IsNumberFormat( |
| const String& rString, /// input string |
| short& F_Type, /// format type (in + out) |
| double& fOutNumber, /// value determined (out) |
| const SvNumberformat* pFormat = NULL /// optional a number format to which compare against |
| ); |
| |
| /// after IsNumberFormat: get decimal position |
| short GetDecPos() const { return nDecPos; } |
| /// after IsNumberFormat: get count of numeric substrings in input string |
| sal_uInt16 GetAnzNums() const { return nAnzNums; } |
| |
| /// set threshold of two-digit year input |
| void SetYear2000( sal_uInt16 nVal ) { nYear2000 = nVal; } |
| /// get threshold of two-digit year input |
| sal_uInt16 GetYear2000() const { return nYear2000; } |
| |
| private: |
| SvNumberFormatter* pFormatter; |
| String* pUpperMonthText; // Array of month names, uppercase |
| String* pUpperAbbrevMonthText; // Array of month names, abbreviated, uppercase |
| String* pUpperDayText; // Array of day of week names, uppercase |
| String* pUpperAbbrevDayText; // Array of day of week names, abbreviated, uppercase |
| String aUpperCurrSymbol; // Currency symbol, uppercase |
| sal_Bool bTextInitialized; // Whether days and months are initialized |
| Date* pNullDate; // 30Dec1899 |
| // Variables for provisional results: |
| String sStrArray[SV_MAX_ANZ_INPUT_STRINGS]; // Array of scanned substrings |
| sal_Bool IsNum[SV_MAX_ANZ_INPUT_STRINGS]; // Whether a substring is numeric |
| sal_uInt16 nNums[SV_MAX_ANZ_INPUT_STRINGS]; // Sequence of offsets to numeric strings |
| sal_uInt16 nAnzStrings; // Total count of scanned substrings |
| sal_uInt16 nAnzNums; // Count of numeric substrings |
| sal_Bool bDecSepInDateSeps; // True <=> DecSep in {.,-,/,DateSep} |
| sal_uInt8 nMatchedAllStrings; // Scan...String() matched all substrings, |
| // bit mask of nMatched... constants |
| |
| static const sal_uInt8 nMatchedEndString; // 0x01 |
| static const sal_uInt8 nMatchedMidString; // 0x02 |
| static const sal_uInt8 nMatchedStartString; // 0x04 |
| static const sal_uInt8 nMatchedVirgin; // 0x08 |
| static const sal_uInt8 nMatchedUsedAsReturn; // 0x10 |
| |
| int nSign; // Sign of number |
| short nMonth; // Month (1..x) if date |
| // negative => short format |
| short nMonthPos; // 1 = front, 2 = middle |
| // 3 = end |
| sal_uInt16 nTimePos; // Index of first time separator (+1) |
| short nDecPos; // Index of substring containing "," (+1) |
| short nNegCheck; // '( )' for negative |
| short nESign; // Sign of exponent |
| short nAmPm; // +1 AM, -1 PM, 0 if none |
| short nLogical; // -1 => False, 1 => True |
| sal_uInt16 nThousand; // Count of group (AKA thousand) separators |
| sal_uInt16 nPosThousandString; // Position of concatenaded 000,000,000 string |
| short eScannedType; // Scanned type |
| short eSetType; // Preset Type |
| |
| sal_uInt16 nStringScanNumFor; // Fixed strings recognized in |
| // pFormat->NumFor[nNumForStringScan] |
| short nStringScanSign; // Sign resulting of FixString |
| sal_uInt16 nYear2000; // Two-digit threshold |
| // Year as 20xx |
| // default 18 |
| // number <= nYear2000 => 20xx |
| // number > nYear2000 => 19xx |
| sal_uInt16 nTimezonePos; // Index of timezone separator (+1) |
| sal_uInt8 nMayBeIso8601; // 0:=dontknowyet, 1:=yes, 2:=no |
| |
| #ifdef _ZFORFIND_CXX // methods private to implementation |
| void Reset(); // Reset all variables before start of analysis |
| |
| void InitText(); // Init of months and days of week |
| |
| // Convert string to double. |
| // Only simple unsigned floating point values without any error detection, |
| // decimal separator has to be '.' |
| // If bForceFraction==sal_True the string is taken to be the fractional part |
| // of 0.1234 without the leading 0. (thus being just "1234"). |
| double StringToDouble( |
| const String& rStr, |
| sal_Bool bForceFraction = sal_False ); |
| |
| sal_Bool NextNumberStringSymbol( // Next number/string symbol |
| const sal_Unicode*& pStr, |
| String& rSymbol ); |
| |
| sal_Bool SkipThousands( // Concatenate ,000,23 blocks |
| const sal_Unicode*& pStr, // in input to 000123 |
| String& rSymbol ); |
| |
| void NumberStringDivision( // Divide numbers/strings into |
| const String& rString ); // arrays and variables above. |
| // Leading blanks and blanks |
| // after numbers are thrown away |
| |
| |
| // optimized substring versions |
| |
| static inline sal_Bool StringContains( // Whether rString contains rWhat at nPos |
| const String& rWhat, |
| const String& rString, |
| xub_StrLen nPos ) |
| { // mostly used with one character |
| if ( rWhat.GetChar(0) != rString.GetChar(nPos) ) |
| return sal_False; |
| return StringContainsImpl( rWhat, rString, nPos ); |
| } |
| static inline sal_Bool StringPtrContains( // Whether pString contains rWhat at nPos |
| const String& rWhat, |
| const sal_Unicode* pString, |
| xub_StrLen nPos ) // nPos MUST be a valid offset from pString |
| { // mostly used with one character |
| if ( rWhat.GetChar(0) != *(pString+nPos) ) |
| return sal_False; |
| return StringPtrContainsImpl( rWhat, pString, nPos ); |
| } |
| static sal_Bool StringContainsImpl( //! DO NOT use directly |
| const String& rWhat, |
| const String& rString, |
| xub_StrLen nPos ); |
| static sal_Bool StringPtrContainsImpl( //! DO NOT use directly |
| const String& rWhat, |
| const sal_Unicode* pString, |
| xub_StrLen nPos ); |
| |
| |
| static inline sal_Bool SkipChar( // Skip a special character |
| sal_Unicode c, |
| const String& rString, |
| xub_StrLen& nPos ); |
| static inline void SkipBlanks( // Skip blank |
| const String& rString, |
| xub_StrLen& nPos ); |
| static inline sal_Bool SkipString( // Jump over rWhat in rString at nPos |
| const String& rWhat, |
| const String& rString, |
| xub_StrLen& nPos ); |
| |
| inline sal_Bool GetThousandSep( // Recognizes exactly ,111 as group separator |
| const String& rString, |
| xub_StrLen& nPos, |
| sal_uInt16 nStringPos ); |
| short GetLogical( // Get boolean value |
| const String& rString ); |
| short GetMonth( // Get month and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| int GetDayOfWeek( // Get day of week and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| sal_Bool GetCurrency( // Get currency symbol and advance string position |
| const String& rString, |
| xub_StrLen& nPos, |
| const SvNumberformat* pFormat = NULL ); // optional number format to match against |
| sal_Bool GetTimeAmPm( // Get symbol AM or PM and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| inline sal_Bool GetDecSep( // Get decimal separator and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| inline sal_Bool GetTime100SecSep( // Get hundredth seconds separator and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| int GetSign( // Get sign and advance string position |
| const String& rString, // Including special case '(' |
| xub_StrLen& nPos ); |
| short GetESign( // Get sign of exponent and advance string position |
| const String& rString, |
| xub_StrLen& nPos ); |
| |
| inline sal_Bool GetNextNumber( // Get next number as array offset |
| sal_uInt16& i, |
| sal_uInt16& j ); |
| |
| void GetTimeRef( // Converts time -> double (only decimals) |
| double& fOutNumber, // result as double |
| sal_uInt16 nIndex, // Index of hour in input |
| sal_uInt16 nAnz ); // Count of time substrings in input |
| sal_uInt16 ImplGetDay ( sal_uInt16 nIndex ); // Day input, 0 if no match |
| sal_uInt16 ImplGetMonth( sal_uInt16 nIndex ); // Month input, zero based return, NumberOfMonths if no match |
| sal_uInt16 ImplGetYear ( sal_uInt16 nIndex ); // Year input, 0 if no match |
| sal_Bool GetDateRef( // Conversion of date to number |
| double& fDays, // OUT: days diff to null date |
| sal_uInt16& nCounter, // Count of date substrings |
| const SvNumberformat* pFormat = NULL ); // optional number format to match against |
| |
| sal_Bool ScanStartString( // Analyze start of string |
| const String& rString, |
| const SvNumberformat* pFormat = NULL ); |
| sal_Bool ScanMidString( // Analyze middle substring |
| const String& rString, |
| sal_uInt16 nStringPos, |
| const SvNumberformat* pFormat = NULL ); |
| sal_Bool ScanEndString( // Analyze end of string |
| const String& rString, |
| const SvNumberformat* pFormat = NULL ); |
| |
| // Whether input may be a ISO 8601 date format, yyyy-mm-dd... |
| // checks if at least 3 numbers and first number>31 |
| bool MayBeIso8601(); |
| |
| // Compare rString to substring of array indexed by nString |
| // nString == 0xFFFF => last substring |
| sal_Bool ScanStringNumFor( |
| const String& rString, |
| xub_StrLen nPos, |
| const SvNumberformat* pFormat, |
| sal_uInt16 nString, |
| sal_Bool bDontDetectNegation = sal_False ); |
| |
| // if nMatchedAllStrings set nMatchedUsedAsReturn and return sal_True, |
| // else do nothing and return sal_False |
| sal_Bool MatchedReturn(); |
| |
| //! Be sure that the string to be analyzed is already converted to upper |
| //! case and if it contained native humber digits that they are already |
| //! converted to ASCII. |
| sal_Bool IsNumberFormatMain( // Main anlyzing function |
| const String& rString, |
| double& fOutNumber, // return value if string is numeric |
| const SvNumberformat* pFormat = NULL // optional number format to match against |
| ); |
| |
| static inline sal_Bool MyIsdigit( sal_Unicode c ); |
| |
| // native number transliteration if necessary |
| void TransformInput( String& rString ); |
| |
| #endif // _ZFORFIND_CXX |
| }; |
| |
| |
| |
| #endif // _ZFORFIND_HXX |