1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: zforfind.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <tools/string.hxx>
38 class SvNumberFormatter
;
40 #define SV_MAX_ANZ_INPUT_STRINGS 20 // max count of substrings in input scanner
42 class ImpSvNumberInputScan
45 ImpSvNumberInputScan( SvNumberFormatter
* pFormatter
);
46 ~ImpSvNumberInputScan();
48 /*!*/ void ChangeIntl(); // MUST be called if language changes
50 /// set reference date for offset calculation
56 /// convert input string to number
58 const String
& rString
, /// input string
59 short& F_Type
, /// format type (in + out)
60 double& fOutNumber
, /// value determined (out)
61 const SvNumberformat
* pFormat
= NULL
/// optional a number format to which compare against
64 /// after IsNumberFormat: get decimal position
65 short GetDecPos() const { return nDecPos
; }
66 /// after IsNumberFormat: get count of numeric substrings in input string
67 USHORT
GetAnzNums() const { return nAnzNums
; }
69 /// set threshold of two-digit year input
70 void SetYear2000( USHORT nVal
) { nYear2000
= nVal
; }
71 /// get threshold of two-digit year input
72 USHORT
GetYear2000() const { return nYear2000
; }
75 SvNumberFormatter
* pFormatter
;
76 String
* pUpperMonthText
; // Array of month names, uppercase
77 String
* pUpperAbbrevMonthText
; // Array of month names, abbreviated, uppercase
78 String
* pUpperDayText
; // Array of day of week names, uppercase
79 String
* pUpperAbbrevDayText
; // Array of day of week names, abbreviated, uppercase
80 String aUpperCurrSymbol
; // Currency symbol, uppercase
81 BOOL bTextInitialized
; // Whether days and months are initialized
82 Date
* pNullDate
; // 30Dec1899
83 // Variables for provisional results:
84 String sStrArray
[SV_MAX_ANZ_INPUT_STRINGS
]; // Array of scanned substrings
85 BOOL IsNum
[SV_MAX_ANZ_INPUT_STRINGS
]; // Whether a substring is numeric
86 USHORT nNums
[SV_MAX_ANZ_INPUT_STRINGS
]; // Sequence of offsets to numeric strings
87 USHORT nAnzStrings
; // Total count of scanned substrings
88 USHORT nAnzNums
; // Count of numeric substrings
89 BOOL bDecSepInDateSeps
; // True <=> DecSep in {.,-,/,DateSep}
90 BYTE nMatchedAllStrings
; // Scan...String() matched all substrings,
91 // bit mask of nMatched... constants
93 static const BYTE nMatchedEndString
; // 0x01
94 static const BYTE nMatchedMidString
; // 0x02
95 static const BYTE nMatchedStartString
; // 0x04
96 static const BYTE nMatchedVirgin
; // 0x08
97 static const BYTE nMatchedUsedAsReturn
; // 0x10
99 int nSign
; // Sign of number
100 short nMonth
; // Month (1..x) if date
101 // negative => short format
102 short nMonthPos
; // 1 = front, 2 = middle
104 USHORT nTimePos
; // Index of first time separator (+1)
105 short nDecPos
; // Index of substring containing "," (+1)
106 short nNegCheck
; // '( )' for negative
107 short nESign
; // Sign of exponent
108 short nAmPm
; // +1 AM, -1 PM, 0 if none
109 short nLogical
; // -1 => False, 1 => True
110 USHORT nThousand
; // Count of group (AKA thousand) separators
111 USHORT nPosThousandString
; // Position of concatenaded 000,000,000 string
112 short eScannedType
; // Scanned type
113 short eSetType
; // Preset Type
115 USHORT nStringScanNumFor
; // Fixed strings recognized in
116 // pFormat->NumFor[nNumForStringScan]
117 short nStringScanSign
; // Sign resulting of FixString
118 USHORT nYear2000
; // Two-digit threshold
121 // number <= nYear2000 => 20xx
122 // number > nYear2000 => 19xx
123 USHORT nTimezonePos
; // Index of timezone separator (+1)
124 BYTE nMayBeIso8601
; // 0:=dontknowyet, 1:=yes, 2:=no
126 #ifdef _ZFORFIND_CXX // methods private to implementation
127 void Reset(); // Reset all variables before start of analysis
129 void InitText(); // Init of months and days of week
131 // Convert string to double.
132 // Only simple unsigned floating point values without any error detection,
133 // decimal separator has to be '.'
134 // If bForceFraction==TRUE the string is taken to be the fractional part
135 // of 0.1234 without the leading 0. (thus being just "1234").
136 double StringToDouble(
138 BOOL bForceFraction
= FALSE
);
140 BOOL
NextNumberStringSymbol( // Next number/string symbol
141 const sal_Unicode
*& pStr
,
144 BOOL
SkipThousands( // Concatenate ,000,23 blocks
145 const sal_Unicode
*& pStr
, // in input to 000123
148 void NumberStringDivision( // Divide numbers/strings into
149 const String
& rString
); // arrays and variables above.
150 // Leading blanks and blanks
151 // after numbers are thrown away
154 // optimized substring versions
156 static inline BOOL
StringContains( // Whether rString contains rWhat at nPos
158 const String
& rString
,
160 { // mostly used with one character
161 if ( rWhat
.GetChar(0) != rString
.GetChar(nPos
) )
163 return StringContainsImpl( rWhat
, rString
, nPos
);
165 static inline BOOL
StringPtrContains( // Whether pString contains rWhat at nPos
167 const sal_Unicode
* pString
,
168 xub_StrLen nPos
) // nPos MUST be a valid offset from pString
169 { // mostly used with one character
170 if ( rWhat
.GetChar(0) != *(pString
+nPos
) )
172 return StringPtrContainsImpl( rWhat
, pString
, nPos
);
174 static BOOL
StringContainsImpl( //! DO NOT use directly
176 const String
& rString
,
178 static BOOL
StringPtrContainsImpl( //! DO NOT use directly
180 const sal_Unicode
* pString
,
184 static inline BOOL
SkipChar( // Skip a special character
186 const String
& rString
,
188 static inline void SkipBlanks( // Skip blank
189 const String
& rString
,
191 static inline BOOL
SkipString( // Jump over rWhat in rString at nPos
193 const String
& rString
,
196 inline BOOL
GetThousandSep( // Recognizes exactly ,111 as group separator
197 const String
& rString
,
200 short GetLogical( // Get boolean value
201 const String
& rString
);
202 short GetMonth( // Get month and advance string position
203 const String
& rString
,
205 int GetDayOfWeek( // Get day of week and advance string position
206 const String
& rString
,
208 BOOL
GetCurrency( // Get currency symbol and advance string position
209 const String
& rString
,
211 const SvNumberformat
* pFormat
= NULL
); // optional number format to match against
212 BOOL
GetTimeAmPm( // Get symbol AM or PM and advance string position
213 const String
& rString
,
215 inline BOOL
GetDecSep( // Get decimal separator and advance string position
216 const String
& rString
,
218 inline BOOL
GetTime100SecSep( // Get hundredth seconds separator and advance string position
219 const String
& rString
,
221 int GetSign( // Get sign and advance string position
222 const String
& rString
, // Including special case '('
224 short GetESign( // Get sign of exponent and advance string position
225 const String
& rString
,
228 inline BOOL
GetNextNumber( // Get next number as array offset
232 void GetTimeRef( // Converts time -> double (only decimals)
233 double& fOutNumber
, // result as double
234 USHORT nIndex
, // Index of hour in input
235 USHORT nAnz
); // Count of time substrings in input
236 USHORT
ImplGetDay ( USHORT nIndex
); // Day input, 0 if no match
237 USHORT
ImplGetMonth( USHORT nIndex
); // Month input, zero based return, NumberOfMonths if no match
238 USHORT
ImplGetYear ( USHORT nIndex
); // Year input, 0 if no match
239 BOOL
GetDateRef( // Conversion of date to number
240 double& fDays
, // OUT: days diff to null date
241 USHORT
& nCounter
, // Count of date substrings
242 const SvNumberformat
* pFormat
= NULL
); // optional number format to match against
244 BOOL
ScanStartString( // Analyze start of string
245 const String
& rString
,
246 const SvNumberformat
* pFormat
= NULL
);
247 BOOL
ScanMidString( // Analyze middle substring
248 const String
& rString
,
250 const SvNumberformat
* pFormat
= NULL
);
251 BOOL
ScanEndString( // Analyze end of string
252 const String
& rString
,
253 const SvNumberformat
* pFormat
= NULL
);
255 // Whether input may be a ISO 8601 date format, yyyy-mm-dd...
256 // checks if at least 3 numbers and first number>31
259 // Compare rString to substring of array indexed by nString
260 // nString == 0xFFFF => last substring
261 BOOL
ScanStringNumFor(
262 const String
& rString
,
264 const SvNumberformat
* pFormat
,
266 BOOL bDontDetectNegation
= FALSE
);
268 // if nMatchedAllStrings set nMatchedUsedAsReturn and return TRUE,
269 // else do nothing and return FALSE
270 BOOL
MatchedReturn();
272 //! Be sure that the string to be analyzed is already converted to upper
273 //! case and if it contained native humber digits that they are already
274 //! converted to ASCII.
275 BOOL
IsNumberFormatMain( // Main anlyzing function
276 const String
& rString
,
277 double& fOutNumber
, // return value if string is numeric
278 const SvNumberformat
* pFormat
= NULL
// optional number format to match against
281 static inline BOOL
MyIsdigit( sal_Unicode c
);
283 // native number transliteration if necessary
284 void TransformInput( String
& rString
);
286 #endif // _ZFORFIND_CXX
291 #endif // _ZFORFIND_HXX