xref: /aoo41x/main/svl/source/numbers/zforfind.hxx (revision 39a19a47)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _ZFORFIND_HXX
25 #define _ZFORFIND_HXX
26 
27 #include <tools/string.hxx>
28 
29 class Date;
30 class SvNumberformat;
31 class SvNumberFormatter;
32 
33 #define SV_MAX_ANZ_INPUT_STRINGS  20    // max count of substrings in input scanner
34 
35 class ImpSvNumberInputScan
36 {
37 public:
38     ImpSvNumberInputScan( SvNumberFormatter* pFormatter );
39     ~ImpSvNumberInputScan();
40 
41 /*!*/   void ChangeIntl();                      // MUST be called if language changes
42 
43     /// set reference date for offset calculation
44     void ChangeNullDate(
45             const sal_uInt16 nDay,
46             const sal_uInt16 nMonth,
47             const sal_uInt16 nYear );
48 
49     /// convert input string to number
50     sal_Bool IsNumberFormat(
51             const String& rString,              /// input string
52             short& F_Type,                      /// format type (in + out)
53             double& fOutNumber,                 /// value determined (out)
54             const SvNumberformat* pFormat = NULL    /// optional a number format to which compare against
55             );
56 
57     /// after IsNumberFormat: get decimal position
GetDecPos() const58     short   GetDecPos() const { return nDecPos; }
59     /// after IsNumberFormat: get count of numeric substrings in input string
GetAnzNums() const60     sal_uInt16  GetAnzNums() const { return nAnzNums; }
61 
62     /// set threshold of two-digit year input
SetYear2000(sal_uInt16 nVal)63     void    SetYear2000( sal_uInt16 nVal ) { nYear2000 = nVal; }
64     /// get threshold of two-digit year input
GetYear2000() const65     sal_uInt16  GetYear2000() const { return nYear2000; }
66 
67 private:
68     SvNumberFormatter*  pFormatter;
69     String* pUpperMonthText;                    // Array of month names, uppercase
70     String* pUpperAbbrevMonthText;              // Array of month names, abbreviated, uppercase
71     String* pUpperDayText;                      // Array of day of week names, uppercase
72     String* pUpperAbbrevDayText;                // Array of day of week names, abbreviated, uppercase
73     String  aUpperCurrSymbol;                   // Currency symbol, uppercase
74     sal_Bool    bTextInitialized;                   // Whether days and months are initialized
75     Date* pNullDate;                            // 30Dec1899
76                                                 // Variables for provisional results:
77     String sStrArray[SV_MAX_ANZ_INPUT_STRINGS]; // Array of scanned substrings
78     sal_Bool   IsNum[SV_MAX_ANZ_INPUT_STRINGS];     // Whether a substring is numeric
79     sal_uInt16 nNums[SV_MAX_ANZ_INPUT_STRINGS];     // Sequence of offsets to numeric strings
80     sal_uInt16 nAnzStrings;                         // Total count of scanned substrings
81     sal_uInt16 nAnzNums;                            // Count of numeric substrings
82     sal_Bool   bDecSepInDateSeps;                   // True <=> DecSep in {.,-,/,DateSep}
83     sal_uInt8   nMatchedAllStrings;                  // Scan...String() matched all substrings,
84                                                 // bit mask of nMatched... constants
85 
86     static const sal_uInt8 nMatchedEndString;        // 0x01
87     static const sal_uInt8 nMatchedMidString;        // 0x02
88     static const sal_uInt8 nMatchedStartString;      // 0x04
89     static const sal_uInt8 nMatchedVirgin;           // 0x08
90     static const sal_uInt8 nMatchedUsedAsReturn;     // 0x10
91 
92     int    nSign;                               // Sign of number
93     short  nMonth;                              // Month (1..x) if date
94                                                 // negative => short format
95     short  nMonthPos;                           // 1 = front, 2 = middle
96                                                 // 3 = end
97     sal_uInt16 nTimePos;                            // Index of first time separator (+1)
98     short  nDecPos;                             // Index of substring containing "," (+1)
99     short  nNegCheck;                           // '( )' for negative
100     short  nESign;                              // Sign of exponent
101     short  nAmPm;                               // +1 AM, -1 PM, 0 if none
102     short  nLogical;                            // -1 => False, 1 => True
103     sal_uInt16 nThousand;                           // Count of group (AKA thousand) separators
104     sal_uInt16 nPosThousandString;                  // Position of concatenaded 000,000,000 string
105     short  eScannedType;                        // Scanned type
106     short  eSetType;                            // Preset Type
107 
108     sal_uInt16 nStringScanNumFor;                   // Fixed strings recognized in
109                                                 // pFormat->NumFor[nNumForStringScan]
110     short  nStringScanSign;                     // Sign resulting of FixString
111     sal_uInt16 nYear2000;                           // Two-digit threshold
112                                                 // Year as 20xx
113                                                 // default 18
114                                                 // number <= nYear2000 => 20xx
115                                                 // number >  nYear2000 => 19xx
116     sal_uInt16  nTimezonePos;                       // Index of timezone separator (+1)
117     sal_uInt8    nMayBeIso8601;                      // 0:=dontknowyet, 1:=yes, 2:=no
118 
119 #ifdef _ZFORFIND_CXX        // methods private to implementation
120     void Reset();                               // Reset all variables before start of analysis
121 
122     void InitText();                            // Init of months and days of week
123 
124     // Convert string to double.
125     // Only simple unsigned floating point values without any error detection,
126     // decimal separator has to be '.'
127     // If bForceFraction==sal_True the string is taken to be the fractional part
128     // of 0.1234 without the leading 0. (thus being just "1234").
129     double StringToDouble(
130             const String& rStr,
131             sal_Bool bForceFraction = sal_False );
132 
133     sal_Bool NextNumberStringSymbol(                // Next number/string symbol
134             const sal_Unicode*& pStr,
135             String& rSymbol );
136 
137     sal_Bool SkipThousands(                         // Concatenate ,000,23 blocks
138             const sal_Unicode*& pStr,           // in input to 000123
139             String& rSymbol );
140 
141     void NumberStringDivision(                  // Divide numbers/strings into
142             const String& rString );            // arrays and variables above.
143                                                 // Leading blanks and blanks
144                                                 // after numbers are thrown away
145 
146 
147                                                 // optimized substring versions
148 
StringContains(const String & rWhat,const String & rString,xub_StrLen nPos)149     static inline sal_Bool StringContains(          // Whether rString contains rWhat at nPos
150             const String& rWhat,
151             const String& rString,
152             xub_StrLen nPos )
153                 {   // mostly used with one character
154                     if ( rWhat.GetChar(0) != rString.GetChar(nPos) )
155                         return sal_False;
156                     return StringContainsImpl( rWhat, rString, nPos );
157                 }
StringPtrContains(const String & rWhat,const sal_Unicode * pString,xub_StrLen nPos)158     static inline sal_Bool StringPtrContains(       // Whether pString contains rWhat at nPos
159             const String& rWhat,
160             const sal_Unicode* pString,
161             xub_StrLen nPos )                   // nPos MUST be a valid offset from pString
162                 {   // mostly used with one character
163                     if ( rWhat.GetChar(0) != *(pString+nPos) )
164                         return sal_False;
165                     return StringPtrContainsImpl( rWhat, pString, nPos );
166                 }
167     static sal_Bool StringContainsImpl(             //! DO NOT use directly
168             const String& rWhat,
169             const String& rString,
170             xub_StrLen nPos );
171     static sal_Bool StringPtrContainsImpl(          //! DO NOT use directly
172             const String& rWhat,
173             const sal_Unicode* pString,
174             xub_StrLen nPos );
175 
176 
177     static inline sal_Bool SkipChar(                // Skip a special character
178             sal_Unicode c,
179             const String& rString,
180             xub_StrLen& nPos );
181     static inline void SkipBlanks(              // Skip blank
182             const String& rString,
183             xub_StrLen& nPos );
184     static inline sal_Bool SkipString(              // Jump over rWhat in rString at nPos
185             const String& rWhat,
186             const String& rString,
187             xub_StrLen& nPos );
188 
189     inline sal_Bool GetThousandSep(                 // Recognizes exactly ,111 as group separator
190             const String& rString,
191             xub_StrLen& nPos,
192             sal_uInt16 nStringPos );
193     short GetLogical(                           // Get boolean value
194             const String& rString );
195     short GetMonth(                             // Get month and advance string position
196             const String& rString,
197             xub_StrLen& nPos );
198     int GetDayOfWeek(                           // Get day of week and advance string position
199             const String& rString,
200             xub_StrLen& nPos );
201     sal_Bool GetCurrency(                           // Get currency symbol and advance string position
202             const String& rString,
203             xub_StrLen& nPos,
204             const SvNumberformat* pFormat = NULL ); // optional number format to match against
205     sal_Bool GetTimeAmPm(                           // Get symbol AM or PM and advance string position
206             const String& rString,
207             xub_StrLen& nPos );
208     inline sal_Bool GetDecSep(                      // Get decimal separator and advance string position
209             const String& rString,
210             xub_StrLen& nPos );
211     inline sal_Bool GetTime100SecSep(               // Get hundredth seconds separator and advance string position
212             const String& rString,
213             xub_StrLen& nPos );
214     int GetSign(                                // Get sign  and advance string position
215             const String& rString,              // Including special case '('
216             xub_StrLen& nPos );
217     short GetESign(                             // Get sign of exponent and advance string position
218             const String& rString,
219             xub_StrLen& nPos );
220 
221     inline sal_Bool GetNextNumber(                  // Get next number as array offset
222             sal_uInt16& i,
223             sal_uInt16& j );
224 
225     void GetTimeRef(                            // Converts time -> double (only decimals)
226             double& fOutNumber,                 // result as double
227             sal_uInt16 nIndex,                      // Index of hour in input
228             sal_uInt16 nAnz );                      // Count of time substrings in input
229     sal_uInt16 ImplGetDay  ( sal_uInt16 nIndex );       // Day input, 0 if no match
230     sal_uInt16 ImplGetMonth( sal_uInt16 nIndex );       // Month input, zero based return, NumberOfMonths if no match
231     sal_uInt16 ImplGetYear ( sal_uInt16 nIndex );       // Year input, 0 if no match
232     sal_Bool GetDateRef(                            // Conversion of date to number
233             double& fDays,                      // OUT: days diff to null date
234             sal_uInt16& nCounter,                   // Count of date substrings
235             const SvNumberformat* pFormat = NULL ); // optional number format to match against
236 
237     sal_Bool ScanStartString(                       // Analyze start of string
238             const String& rString,
239             const SvNumberformat* pFormat = NULL );
240     sal_Bool ScanMidString(                         // Analyze middle substring
241             const String& rString,
242             sal_uInt16 nStringPos,
243             const SvNumberformat* pFormat = NULL );
244     sal_Bool ScanEndString(                         // Analyze end of string
245             const String& rString,
246             const SvNumberformat* pFormat = NULL );
247 
248     // Whether input may be a ISO 8601 date format, yyyy-mm-dd...
249     // checks if at least 3 numbers and first number>31
250     bool MayBeIso8601();
251 
252     // Compare rString to substring of array indexed by nString
253     // nString == 0xFFFF => last substring
254     sal_Bool ScanStringNumFor(
255             const String& rString,
256             xub_StrLen nPos,
257             const SvNumberformat* pFormat,
258             sal_uInt16 nString,
259             sal_Bool bDontDetectNegation = sal_False );
260 
261     // if nMatchedAllStrings set nMatchedUsedAsReturn and return sal_True,
262     // else do nothing and return sal_False
263     sal_Bool MatchedReturn();
264 
265     //! Be sure that the string to be analyzed is already converted to upper
266     //! case and if it contained native humber digits that they are already
267     //! converted to ASCII.
268     sal_Bool IsNumberFormatMain(                    // Main anlyzing function
269             const String& rString,
270             double& fOutNumber,                 // return value if string is numeric
271             const SvNumberformat* pFormat = NULL    // optional number format to match against
272             );
273 
274     static inline sal_Bool MyIsdigit( sal_Unicode c );
275 
276     // native number transliteration if necessary
277     void TransformInput( String& rString );
278 
279 #endif  // _ZFORFIND_CXX
280 };
281 
282 
283 
284 #endif  // _ZFORFIND_HXX
285