aceaf2237e333e6a8bddde93ecde3809d2114874
[shibboleth/cpp-xmltooling.git] / xmltooling / util / DateTime.h
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * @file DateTime.h\r
19  * \r
20  * Manipulation of XML date/time data. \r
21  */\r
22 \r
23 #ifndef _XML_DATETIME_H\r
24 #define _XML_DATETIME_H\r
25 \r
26 #include <xmltooling/base.h>\r
27 \r
28 #if defined (_MSC_VER)\r
29     #pragma warning( push )\r
30     #pragma warning( disable : 4244 )\r
31 #endif\r
32 \r
33 #include <xercesc/util/XMLDateTime.hpp>\r
34 \r
35 #if defined (_MSC_VER)\r
36     #pragma warning( pop )\r
37 #endif\r
38 \r
39 namespace xmltooling\r
40 {\r
41     /**\r
42      * Class for manipulating XML date/time information.\r
43      * \r
44      * This is mostly copied from Xerces-C, but they haven't produced a usable date/time\r
45      * class, so we had to incorporate a version of it for now. It can't be inherited\r
46      * since the fields needed are private.\r
47      */\r
48     class XMLTOOL_API DateTime\r
49     {\r
50     public:\r
51         /// @cond OFF\r
52         DateTime();\r
53         DateTime(const XMLCh* const);\r
54         DateTime(time_t epoch);\r
55         DateTime(const DateTime&);\r
56         DateTime& operator=(const DateTime&);\r
57         ~DateTime();\r
58     \r
59         inline void setBuffer(const XMLCh* const);\r
60     \r
61         const XMLCh* getRawData() const;\r
62         const XMLCh* getFormattedString() const;\r
63         int getSign() const;\r
64     \r
65         XMLCh* getDateTimeCanonicalRepresentation() const;\r
66         XMLCh* getTimeCanonicalRepresentation() const;\r
67     \r
68         void parseDateTime();\r
69         void parseDate();\r
70         void parseTime();\r
71         void parseDay();\r
72         void parseMonth();\r
73         void parseYear();\r
74         void parseMonthDay();\r
75         void parseYearMonth();\r
76         void parseDuration();\r
77     \r
78         static int compare(const DateTime* const, const DateTime* const);\r
79         static int compare(const DateTime* const, const DateTime* const, bool);\r
80         static int compareOrder(const DateTime* const, const DateTime* const);                                    \r
81     \r
82         int getYear() const {return fValue[CentYear];}\r
83         int getMonth() const {return fValue[Month];}\r
84         int getDay() const {return fValue[Day];}\r
85         int getHour() const {return fValue[Hour];}\r
86         int getMinute() const {return fValue[Minute];}\r
87         int getSecond() const {return fValue[Second];}\r
88         time_t getEpoch() const;\r
89     \r
90         /// @endcond\r
91     private:\r
92         enum valueIndex {\r
93             CentYear   = 0,\r
94             Month      ,\r
95             Day        ,\r
96             Hour       ,\r
97             Minute     ,\r
98             Second     ,\r
99             MiliSecond ,  //not to be used directly\r
100             utc        ,\r
101             TOTAL_SIZE\r
102         };\r
103     \r
104         enum utcType {\r
105             UTC_UNKNOWN = 0,\r
106             UTC_STD        ,          // set in parse() or normalize()\r
107             UTC_POS        ,          // set in parse()\r
108             UTC_NEG                   // set in parse()\r
109         };\r
110     \r
111         enum timezoneIndex {\r
112             hh = 0,\r
113             mm ,\r
114             TIMEZONE_ARRAYSIZE\r
115         };\r
116     \r
117         static int compareResult(int, int, bool);\r
118         static void addDuration(DateTime* pDuration, const DateTime* const pBaseDate, int index);\r
119         static int compareResult(const DateTime* const, const DateTime* const, bool, int);\r
120         static inline int getRetVal(int, int);\r
121     \r
122         inline void reset();\r
123         //inline void assertBuffer() const;\r
124         inline void copy(const DateTime&);\r
125         \r
126         inline void initParser();\r
127         inline bool isNormalized() const;\r
128     \r
129         void getDate();\r
130         void getTime();\r
131         void getYearMonth();\r
132         void getTimeZone(const int);\r
133         void parseTimeZone();\r
134     \r
135         int findUTCSign(const int start);\r
136         int indexOf(const int start, const int end, const XMLCh ch) const;\r
137         int parseInt(const int start, const int end) const;\r
138         int parseIntYear(const int end) const;\r
139         double parseMiliSecond(const int start, const int end) const;\r
140     \r
141         void validateDateTime() const;\r
142         void normalize();\r
143         void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;\r
144         int  fillYearString(XMLCh*& ptr, valueIndex ind) const;\r
145         void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;\r
146     \r
147         bool operator==(const DateTime& toCompare) const;\r
148     \r
149         static const int DATETIMES[][TOTAL_SIZE];\r
150         int fValue[TOTAL_SIZE];\r
151         int fTimeZone[TIMEZONE_ARRAYSIZE];\r
152         int fStart;\r
153         int fEnd;\r
154         int fBufferMaxLen;\r
155         XMLCh* fBuffer;\r
156     \r
157         double fMiliSecond;\r
158         bool fHasTime;\r
159     };\r
160 \r
161     inline void DateTime::setBuffer(const XMLCh* const aString)\r
162     {\r
163         reset();\r
164         fEnd = XMLString::stringLen(aString);\r
165         if (fEnd > 0) {\r
166             if (fEnd > fBufferMaxLen) {\r
167                 delete[] fBuffer;\r
168                 fBufferMaxLen = fEnd + 8;\r
169                 fBuffer = new XMLCh[fBufferMaxLen+1];\r
170             }\r
171             memcpy(fBuffer, aString, (fEnd+1) * sizeof(XMLCh));\r
172         }\r
173     }\r
174     \r
175     inline void DateTime::reset()\r
176     {\r
177         for ( int i=0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
178             fValue[i] = 0;\r
179     \r
180         fMiliSecond   = 0;\r
181         fHasTime      = false;\r
182         fTimeZone[hh] = fTimeZone[mm] = 0;\r
183         fStart = fEnd = 0;\r
184     \r
185         if (fBuffer)\r
186             *fBuffer = 0;\r
187     }\r
188     \r
189     inline void DateTime::copy(const DateTime& rhs)\r
190     {\r
191         for ( int i = 0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
192             fValue[i] = rhs.fValue[i];\r
193     \r
194         fMiliSecond   = rhs.fMiliSecond;\r
195         fHasTime      = rhs.fHasTime;\r
196         fTimeZone[hh] = rhs.fTimeZone[hh];\r
197         fTimeZone[mm] = rhs.fTimeZone[mm];\r
198         fStart = rhs.fStart;\r
199         fEnd   = rhs.fEnd;\r
200     \r
201         if (fEnd > 0) {\r
202             if (fEnd > fBufferMaxLen) {\r
203                 delete[] fBuffer;\r
204                 fBufferMaxLen = rhs.fBufferMaxLen;\r
205                 fBuffer = new XMLCh[fBufferMaxLen+1];\r
206             }\r
207             memcpy(fBuffer, rhs.fBuffer, (fEnd+1) * sizeof(XMLCh));\r
208         }\r
209     }\r
210     \r
211     inline void DateTime::initParser()\r
212     {\r
213         fStart = 0;   // to ensure scan from the very first beginning\r
214                       // in case the pointer is updated accidentally by someone else.\r
215     }\r
216     \r
217     inline bool DateTime::isNormalized() const\r
218     {\r
219         return (fValue[XMLDateTime::utc] == XMLDateTime::UTC_STD ? true : false);\r
220     }\r
221     \r
222     inline int DateTime::getRetVal(int c1, int c2)\r
223     {\r
224         if ((c1 == XMLDateTime::LESS_THAN && c2 == XMLDateTime::GREATER_THAN) ||\r
225             (c1 == XMLDateTime::GREATER_THAN && c2 == XMLDateTime::LESS_THAN))\r
226             return XMLDateTime::INDETERMINATE;\r
227     \r
228         return (c1 != XMLDateTime::INDETERMINATE) ? c1 : c2;\r
229     }\r
230 \r
231 }\r
232 \r
233 #endif\r