1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2007-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
8 *
9 * File DTPTNGEN.H
10 *
11 *******************************************************************************
12 */
13 
14 #ifndef __DTPTNGEN_IMPL_H__
15 #define __DTPTNGEN_IMPL_H__
16 
17 #include "unicode/udatpg.h"
18 #include "uvector.h"
19 
20 // TODO(claireho): Split off Builder class.
21 // TODO(claireho): If splitting off Builder class: As subclass or independent?
22 
23 #define MAX_PATTERN_ENTRIES 52
24 #define MAX_CLDR_FIELD_LEN  60
25 #define MAX_DT_TOKEN        50
26 #define MAX_RESOURCE_FIELD  12
27 #define MAX_AVAILABLE_FORMATS  12
28 #define NONE          0
29 #define EXTRA_FIELD   0x10000
30 #define MISSING_FIELD  0x1000
31 #define MAX_STRING_ENUMERATION  200
32 #define SINGLE_QUOTE      ((UChar)0x0027)
33 #define FORWARDSLASH      ((UChar)0x002F)
34 #define BACKSLASH         ((UChar)0x005C)
35 #define SPACE             ((UChar)0x0020)
36 #define QUOTATION_MARK    ((UChar)0x0022)
37 #define ASTERISK          ((UChar)0x002A)
38 #define PLUSSITN          ((UChar)0x002B)
39 #define COMMA             ((UChar)0x002C)
40 #define HYPHEN            ((UChar)0x002D)
41 #define DOT               ((UChar)0x002E)
42 #define COLON             ((UChar)0x003A)
43 #define CAP_A             ((UChar)0x0041)
44 #define CAP_B             ((UChar)0x0042)
45 #define CAP_C             ((UChar)0x0043)
46 #define CAP_D             ((UChar)0x0044)
47 #define CAP_E             ((UChar)0x0045)
48 #define CAP_F             ((UChar)0x0046)
49 #define CAP_G             ((UChar)0x0047)
50 #define CAP_H             ((UChar)0x0048)
51 #define CAP_J             ((UChar)0x004A)
52 #define CAP_K             ((UChar)0x004B)
53 #define CAP_L             ((UChar)0x004C)
54 #define CAP_M             ((UChar)0x004D)
55 #define CAP_O             ((UChar)0x004F)
56 #define CAP_Q             ((UChar)0x0051)
57 #define CAP_S             ((UChar)0x0053)
58 #define CAP_T             ((UChar)0x0054)
59 #define CAP_U             ((UChar)0x0055)
60 #define CAP_V             ((UChar)0x0056)
61 #define CAP_W             ((UChar)0x0057)
62 #define CAP_X             ((UChar)0x0058)
63 #define CAP_Y             ((UChar)0x0059)
64 #define CAP_Z             ((UChar)0x005A)
65 #define LOWLINE           ((UChar)0x005F)
66 #define LOW_A             ((UChar)0x0061)
67 #define LOW_B             ((UChar)0x0062)
68 #define LOW_C             ((UChar)0x0063)
69 #define LOW_D             ((UChar)0x0064)
70 #define LOW_E             ((UChar)0x0065)
71 #define LOW_F             ((UChar)0x0066)
72 #define LOW_G             ((UChar)0x0067)
73 #define LOW_H             ((UChar)0x0068)
74 #define LOW_I             ((UChar)0x0069)
75 #define LOW_J             ((UChar)0x006A)
76 #define LOW_K             ((UChar)0x006B)
77 #define LOW_L             ((UChar)0x006C)
78 #define LOW_M             ((UChar)0x006D)
79 #define LOW_N             ((UChar)0x006E)
80 #define LOW_O             ((UChar)0x006F)
81 #define LOW_P             ((UChar)0x0070)
82 #define LOW_Q             ((UChar)0x0071)
83 #define LOW_R             ((UChar)0x0072)
84 #define LOW_S             ((UChar)0x0073)
85 #define LOW_T             ((UChar)0x0074)
86 #define LOW_U             ((UChar)0x0075)
87 #define LOW_V             ((UChar)0x0076)
88 #define LOW_W             ((UChar)0x0077)
89 #define LOW_X             ((UChar)0x0078)
90 #define LOW_Y             ((UChar)0x0079)
91 #define LOW_Z             ((UChar)0x007A)
92 #define DT_SHORT          -0x102
93 #define DT_LONG           -0x103
94 #define DT_NUMERIC         0x100
95 #define DT_NARROW         -0x101
96 #define DT_DELTA           0x10
97 
98 U_NAMESPACE_BEGIN
99 
100 const int32_t UDATPG_FRACTIONAL_MASK = 1<<UDATPG_FRACTIONAL_SECOND_FIELD;
101 const int32_t UDATPG_SECOND_AND_FRACTIONAL_MASK = (1<<UDATPG_SECOND_FIELD) | (1<<UDATPG_FRACTIONAL_SECOND_FIELD);
102 
103 typedef enum dtStrEnum {
104     DT_BASESKELETON,
105     DT_SKELETON,
106     DT_PATTERN
107 }dtStrEnum;
108 
109 typedef struct dtTypeElem {
110     UChar                  patternChar;
111     UDateTimePatternField  field;
112     int16_t                type;
113     int16_t                minLen;
114     int16_t                weight;
115 }dtTypeElem;
116 
117 // A compact storage mechanism for skeleton field strings.  Several dozen of these will be created
118 // for a typical DateTimePatternGenerator instance.
119 class SkeletonFields : public UMemory {
120 public:
121     SkeletonFields();
122     void clear();
123     void copyFrom(const SkeletonFields& other);
124     void clearField(int32_t field);
125     UChar getFieldChar(int32_t field) const;
126     int32_t getFieldLength(int32_t field) const;
127     void populate(int32_t field, const UnicodeString& value);
128     void populate(int32_t field, UChar repeatChar, int32_t repeatCount);
129     UBool isFieldEmpty(int32_t field) const;
130     UnicodeString& appendTo(UnicodeString& string) const;
131     UnicodeString& appendFieldTo(int32_t field, UnicodeString& string) const;
132     UChar getFirstChar() const;
133     inline UBool operator==(const SkeletonFields& other) const;
134     inline UBool operator!=(const SkeletonFields& other) const;
135 
136 private:
137     int8_t chars[UDATPG_FIELD_COUNT];
138     int8_t lengths[UDATPG_FIELD_COUNT];
139 };
140 
141 inline UBool SkeletonFields::operator==(const SkeletonFields& other) const {
142     return (uprv_memcmp(chars, other.chars, sizeof(chars)) == 0
143         && uprv_memcmp(lengths, other.lengths, sizeof(lengths)) == 0);
144 }
145 
146 inline UBool SkeletonFields::operator!=(const SkeletonFields& other) const {
147     return (! operator==(other));
148 }
149 
150 class PtnSkeleton : public UMemory {
151 public:
152     int32_t type[UDATPG_FIELD_COUNT];
153     SkeletonFields original;
154     SkeletonFields baseOriginal;
155 
156     PtnSkeleton();
157     PtnSkeleton(const PtnSkeleton& other);
158     void copyFrom(const PtnSkeleton& other);
159     void clear();
160     UBool equals(const PtnSkeleton& other) const;
161     UnicodeString getSkeleton() const;
162     UnicodeString getBaseSkeleton() const;
163     UChar getFirstChar() const;
164 
165     // TODO: Why is this virtual, as well as the other destructors in this file? We don't want
166     // vtables when we don't use class objects polymorphically.
167     virtual ~PtnSkeleton();
168 };
169 
170 
171 class PtnElem : public UMemory {
172 public:
173     UnicodeString basePattern;
174     PtnSkeleton   *skeleton;
175     UnicodeString pattern;
176     UBool         skeletonWasSpecified; // if specified in availableFormats, not derived
177     PtnElem       *next;
178 
179     PtnElem(const UnicodeString &basePattern, const UnicodeString &pattern);
180     virtual ~PtnElem();
181 
182 };
183 
184 class FormatParser : public UMemory {
185 public:
186     UnicodeString items[MAX_DT_TOKEN];
187     int32_t  itemNumber;
188 
189     FormatParser();
190     virtual ~FormatParser();
191     void set(const UnicodeString& patternString);
192     void getQuoteLiteral(UnicodeString& quote, int32_t *itemIndex);
193     UBool isPatternSeparator(UnicodeString& field);
194     static UBool isQuoteLiteral(const UnicodeString& s);
getCanonicalIndex(const UnicodeString & s)195     static int32_t getCanonicalIndex(const UnicodeString& s) { return getCanonicalIndex(s, TRUE); }
196     static int32_t getCanonicalIndex(const UnicodeString& s, UBool strict);
197 
198 private:
199    typedef enum TokenStatus {
200        START,
201        ADD_TOKEN,
202        SYNTAX_ERROR,
203        DONE
204    } ToeknStatus;
205 
206    TokenStatus status;
207    virtual TokenStatus setTokens(const UnicodeString& pattern, int32_t startPos, int32_t *len);
208 };
209 
210 class DistanceInfo : public UMemory {
211 public:
212     int32_t missingFieldMask;
213     int32_t extraFieldMask;
214 
DistanceInfo()215     DistanceInfo() {}
216     virtual ~DistanceInfo();
clear()217     void clear() { missingFieldMask = extraFieldMask = 0; }
218     void setTo(DistanceInfo& other);
addMissing(int32_t field)219     void addMissing(int32_t field) { missingFieldMask |= (1<<field); }
addExtra(int32_t field)220     void addExtra(int32_t field) { extraFieldMask |= (1<<field); }
221 };
222 
223 class DateTimeMatcher: public UMemory {
224 public:
225     PtnSkeleton skeleton;
226 
227     void getBasePattern(UnicodeString& basePattern);
228     UnicodeString getPattern();
229     void set(const UnicodeString& pattern, FormatParser* fp);
230     void set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton& skeleton);
231     void copyFrom(const PtnSkeleton& skeleton);
232     void copyFrom();
233     PtnSkeleton* getSkeletonPtr();
234     UBool equals(const DateTimeMatcher* other) const;
235     int32_t getDistance(const DateTimeMatcher& other, int32_t includeMask, DistanceInfo& distanceInfo);
236     DateTimeMatcher();
237     DateTimeMatcher(const DateTimeMatcher& other);
238     virtual ~DateTimeMatcher();
239     int32_t getFieldMask();
240 };
241 
242 class PatternMap : public UMemory {
243 public:
244     PtnElem *boot[MAX_PATTERN_ENTRIES];
245     PatternMap();
246     virtual  ~PatternMap();
247     void  add(const UnicodeString& basePattern, const PtnSkeleton& skeleton, const UnicodeString& value, UBool skeletonWasSpecified, UErrorCode& status);
248     const UnicodeString* getPatternFromBasePattern(UnicodeString& basePattern, UBool& skeletonWasSpecified);
249     const UnicodeString* getPatternFromSkeleton(PtnSkeleton& skeleton, const PtnSkeleton** specifiedSkeletonPtr = 0);
250     void copyFrom(const PatternMap& other, UErrorCode& status);
251     PtnElem* getHeader(UChar baseChar);
252     UBool equals(const PatternMap& other);
253 private:
254     UBool isDupAllowed;
255     PtnElem*  getDuplicateElem(const UnicodeString &basePattern, const PtnSkeleton& skeleton, PtnElem *baseElem);
256 }; // end  PatternMap
257 
258 class PatternMapIterator : public UMemory {
259 public:
260     PatternMapIterator();
261     virtual ~PatternMapIterator();
262     void set(PatternMap& patternMap);
263     PtnSkeleton* getSkeleton();
264     UBool hasNext();
265     DateTimeMatcher& next();
266 private:
267     int32_t bootIndex;
268     PtnElem *nodePtr;
269     DateTimeMatcher *matcher;
270     PatternMap *patternMap;
271 };
272 
273 class DTSkeletonEnumeration : public StringEnumeration {
274 public:
275     DTSkeletonEnumeration(PatternMap &patternMap, dtStrEnum type, UErrorCode& status);
276     virtual ~DTSkeletonEnumeration();
277     static UClassID U_EXPORT2 getStaticClassID(void);
278     virtual UClassID getDynamicClassID(void) const;
279     virtual const UnicodeString* snext(UErrorCode& status);
280     virtual void reset(UErrorCode& status);
281     virtual int32_t count(UErrorCode& status) const;
282 private:
283     int32_t pos;
284     UBool isCanonicalItem(const UnicodeString& item);
285     UVector *fSkeletons;
286 };
287 
288 class DTRedundantEnumeration : public StringEnumeration {
289 public:
290     DTRedundantEnumeration();
291     virtual ~DTRedundantEnumeration();
292     static UClassID U_EXPORT2 getStaticClassID(void);
293     virtual UClassID getDynamicClassID(void) const;
294     virtual const UnicodeString* snext(UErrorCode& status);
295     virtual void reset(UErrorCode& status);
296     virtual int32_t count(UErrorCode& status) const;
297     void add(const UnicodeString &pattern, UErrorCode& status);
298 private:
299     int32_t pos;
300     UBool isCanonicalItem(const UnicodeString& item);
301     UVector *fPatterns;
302 };
303 
304 U_NAMESPACE_END
305 
306 #endif
307