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
98U_NAMESPACE_BEGIN
99
100const int32_t UDATPG_FRACTIONAL_MASK = 1<<UDATPG_FRACTIONAL_SECOND_FIELD;
101const int32_t UDATPG_SECOND_AND_FRACTIONAL_MASK = (1<<UDATPG_SECOND_FIELD) | (1<<UDATPG_FRACTIONAL_SECOND_FIELD);
102
103typedef enum dtStrEnum {
104    DT_BASESKELETON,
105    DT_SKELETON,
106    DT_PATTERN
107}dtStrEnum;
108
109typedef 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.
119class SkeletonFields : public UMemory {
120public:
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
136private:
137    int8_t chars[UDATPG_FIELD_COUNT];
138    int8_t lengths[UDATPG_FIELD_COUNT];
139};
140
141inline 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
146inline UBool SkeletonFields::operator!=(const SkeletonFields& other) const {
147    return (! operator==(other));
148}
149
150class PtnSkeleton : public UMemory {
151public:
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
171class PtnElem : public UMemory {
172public:
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
184class FormatParser : public UMemory {
185public:
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);
195    static int32_t getCanonicalIndex(const UnicodeString& s) { return getCanonicalIndex(s, TRUE); }
196    static int32_t getCanonicalIndex(const UnicodeString& s, UBool strict);
197
198private:
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
210class DistanceInfo : public UMemory {
211public:
212    int32_t missingFieldMask;
213    int32_t extraFieldMask;
214
215    DistanceInfo() {}
216    virtual ~DistanceInfo();
217    void clear() { missingFieldMask = extraFieldMask = 0; }
218    void setTo(DistanceInfo& other);
219    void addMissing(int32_t field) { missingFieldMask |= (1<<field); }
220    void addExtra(int32_t field) { extraFieldMask |= (1<<field); }
221};
222
223class DateTimeMatcher: public UMemory {
224public:
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
242class PatternMap : public UMemory {
243public:
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);
253private:
254    UBool isDupAllowed;
255    PtnElem*  getDuplicateElem(const UnicodeString &basePattern, const PtnSkeleton& skeleton, PtnElem *baseElem);
256}; // end  PatternMap
257
258class PatternMapIterator : public UMemory {
259public:
260    PatternMapIterator();
261    virtual ~PatternMapIterator();
262    void set(PatternMap& patternMap);
263    PtnSkeleton* getSkeleton();
264    UBool hasNext();
265    DateTimeMatcher& next();
266private:
267    int32_t bootIndex;
268    PtnElem *nodePtr;
269    DateTimeMatcher *matcher;
270    PatternMap *patternMap;
271};
272
273class DTSkeletonEnumeration : public StringEnumeration {
274public:
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;
282private:
283    int32_t pos;
284    UBool isCanonicalItem(const UnicodeString& item);
285    UVector *fSkeletons;
286};
287
288class DTRedundantEnumeration : public StringEnumeration {
289public:
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);
298private:
299    int32_t pos;
300    UBool isCanonicalItem(const UnicodeString& item);
301    UVector *fPatterns;
302};
303
304U_NAMESPACE_END
305
306#endif
307