/[resiprocate]/branches/b-directory-reorg/sip/resiprocate/DateCategory.cxx
ViewVC logotype

Contents of /branches/b-directory-reorg/sip/resiprocate/DateCategory.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5271 - (show annotations) (download)
Thu Aug 18 23:43:07 2005 UTC (14 years, 3 months ago) by jason
File size: 14434 byte(s)
new directory reorg proposal
1 #if defined(HAVE_CONFIG_H)
2 #include "resiprocate/config.hxx"
3 #endif
4
5 #include <time.h>
6
7 #include "resiprocate/DateCategory.hxx"
8 #include "resiprocate/Transport.hxx"
9 #include "resiprocate/os/Data.hxx"
10 #include "resiprocate/os/DnsUtil.hxx"
11 #include "resiprocate/os/Logger.hxx"
12 #include "resiprocate/os/ParseBuffer.hxx"
13 #include "resiprocate/os/Socket.hxx"
14 #include "resiprocate/os/WinLeakCheck.hxx"
15
16 using namespace resip;
17 using namespace std;
18
19 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
20
21 //====================
22 // Date
23 //====================
24
25 Data resip::DayOfWeekData[] =
26 {
27 "Sun",
28 "Mon",
29 "Tue",
30 "Wed",
31 "Thu",
32 "Fri",
33 "Sat"
34 };
35
36 Data resip::MonthData[] =
37 {
38 "Jan",
39 "Feb",
40 "Mar",
41 "Apr",
42 "May",
43 "Jun",
44 "Jul",
45 "Aug",
46 "Sep",
47 "Oct",
48 "Nov",
49 "Dec"
50 };
51
52
53 DateCategory::DateCategory()
54 : ParserCategory(),
55 mDayOfWeek(Sun),
56 mDayOfMonth(),
57 mMonth(Jan),
58 mYear(0),
59 mHour(0),
60 mMin(0),
61 mSec(0)
62 {
63 time_t now;
64 time(&now);
65 if (now == ((time_t)-1))
66 {
67 int e = getErrno();
68 DebugLog (<< "Failed to get time: " << strerror(e));
69 Transport::error(e);
70 return;
71 }
72
73 struct tm gmt;
74 #if defined(WIN32) || defined(__sun)
75 struct tm *gmtp = gmtime(&now);
76 if (gmtp == 0)
77 {
78 int e = getErrno();
79 DebugLog (<< "Failed to convert to gmt: " << strerror(e));
80 Transport::error(e);
81 return;
82 }
83 memcpy(&gmt,gmtp,sizeof(gmt));
84 #else
85 if (gmtime_r(&now, &gmt) == 0)
86 {
87 int e = getErrno();
88 DebugLog (<< "Failed to convert to gmt: " << strerror(e));
89 Transport::error(e);
90 return;
91 }
92 #endif
93
94 mDayOfWeek = static_cast<DayOfWeek>(gmt.tm_wday);
95 mDayOfMonth = gmt.tm_mday;
96 mMonth = static_cast<Month>(gmt.tm_mon);
97 mYear = gmt.tm_year + 1900;
98 mHour = gmt.tm_hour;
99 mMin = gmt.tm_min;
100 mSec = gmt.tm_sec;
101 DebugLog (<< "Set date: day=" << mDayOfWeek
102 << " month=" << mMonth
103 << " year=" << mYear
104 << " " << mHour << ":" << mMin << ":" << mSec);
105 }
106
107 DateCategory::DateCategory(HeaderFieldValue* hfv, Headers::Type type)
108 : ParserCategory(hfv, type),
109 mDayOfWeek(Sun),
110 mDayOfMonth(),
111 mMonth(Jan),
112 mYear(0),
113 mHour(0),
114 mMin(0),
115 mSec(0)
116 {}
117
118 DateCategory::DateCategory(const DateCategory& rhs)
119 {
120 *this = rhs;
121 }
122
123 DateCategory&
124 DateCategory::operator=(const DateCategory& rhs)
125 {
126 if (this != &rhs)
127 {
128 ParserCategory::operator=(rhs);
129 mDayOfWeek = rhs.mDayOfWeek;
130 mDayOfMonth = rhs.mDayOfMonth;
131 mMonth = rhs.mMonth;
132 mYear = rhs.mYear;
133 mHour = rhs.mHour;
134 mMin = rhs.mMin;
135 mSec = rhs.mSec;
136 }
137 return *this;
138 }
139
140 /* ANSI-C code produced by gperf version 2.7.2 */
141 /* Command-line: gperf -L ANSI-C -t -k '*' dayofweek.gperf */
142 struct days { char name[32]; DayOfWeek day; };
143
144 #ifdef __GNUC__
145 __inline
146 #else
147 #ifdef __cplusplus
148 inline
149 #endif
150 #endif
151 static unsigned int
152 dayofweek_hash (register const char *str, register unsigned int len)
153 {
154 static unsigned char asso_values[] =
155 {
156 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
157 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
158 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
159 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
160 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
161 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
162 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
163 1, 13, 13, 13, 13, 13, 13, 5, 13, 13,
164 13, 13, 13, 2, 0, 13, 13, 7, 13, 13,
165 13, 13, 13, 13, 13, 13, 13, 7, 13, 13,
166 0, 0, 13, 13, 4, 0, 13, 13, 13, 13,
167 0, 0, 13, 13, 0, 13, 0, 0, 13, 13,
168 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
169 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
170 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
171 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
172 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
173 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
174 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
175 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
176 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
177 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
178 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
179 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
180 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
181 13, 13, 13, 13, 13, 13
182 };
183 register int hval = len;
184
185 switch (hval)
186 {
187 default:
188 case 3:
189 hval += asso_values[(unsigned char)str[2]];
190 case 2:
191 hval += asso_values[(unsigned char)str[1]];
192 case 1:
193 hval += asso_values[(unsigned char)str[0]];
194 break;
195 }
196 return hval;
197 }
198
199 #ifdef __GNUC__
200 __inline
201 #endif
202 struct days *
203 in_dayofweek_word_set (register const char *str, register unsigned int len)
204 {
205 static const unsigned int MIN_WORD_LENGTH = 3;
206 static const unsigned int MAX_WORD_LENGTH = 3;
207 static const int MAX_HASH_VALUE = 12;
208
209 static struct days wordlist[] =
210 {
211 {""}, {""}, {""},
212 {"Tue", Tue},
213 {"Fri", Fri},
214 {"Sun", Sun},
215 {""},
216 {"Thu", Thu},
217 {"Mon", Mon},
218 {""},
219 {"Wed", Wed},
220 {""},
221 {"Sat", Sat}
222 };
223
224 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
225 {
226 register int key = dayofweek_hash (str, len);
227
228 if (key <= MAX_HASH_VALUE && key >= 0)
229 {
230 register const char *s = wordlist[key].name;
231
232 if (*str == *s && !strcmp (str + 1, s + 1))
233 return &wordlist[key];
234 }
235 }
236 return 0;
237 }
238
239 DayOfWeek
240 DateCategory::DayOfWeekFromData(const Data& dow)
241 {
242 static const unsigned int MIN_WORD_LENGTH = 3;
243 static const unsigned int MAX_WORD_LENGTH = 3;
244 static const int MAX_HASH_VALUE = 12;
245
246 register const char *str = dow.data();
247 register Data::size_type len = dow.size();
248
249 static struct days wordlist[] =
250 {
251 {""}, {""}, {""},
252 {"Tue", Tue},
253 {"Fri", Fri},
254 {"Sun", Sun},
255 {""},
256 {"Thu", Thu},
257 {"Mon", Mon},
258 {""},
259 {"Wed", Wed},
260 {""},
261 {"Sat", Sat}
262 };
263
264 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
265 {
266 register int key = dayofweek_hash (str, len);
267
268 if (key <= MAX_HASH_VALUE && key >= 0)
269 {
270 register const char *s = wordlist[key].name;
271
272 if (*str == *s && !strncmp (str+1, s+1, len-1))
273 {
274 return wordlist[key].day;
275 }
276 }
277 }
278 return Sun;
279 }
280
281 /* ANSI-C code produced by gperf version 2.7.2 */
282 /* Command-line: gperf -L ANSI-C -t -k '*' month.gperf */
283 struct months { char name[32]; Month type; };
284
285 /* maximum key range = 31, duplicates = 0 */
286
287 #ifdef __GNUC__
288 __inline
289 #else
290 #ifdef __cplusplus
291 inline
292 #endif
293 #endif
294 static unsigned int
295 month_hash (register const char *str, register unsigned int len)
296 {
297 static unsigned char asso_values[] =
298 {
299 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
300 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
301 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
302 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
303 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
304 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
305 34, 34, 34, 34, 34, 15, 34, 34, 8, 34,
306 5, 34, 34, 34, 0, 34, 34, 10, 3, 14,
307 34, 34, 34, 9, 34, 34, 34, 34, 34, 34,
308 34, 34, 34, 34, 34, 34, 34, 10, 0, 0,
309 34, 0, 34, 10, 34, 34, 34, 34, 4, 34,
310 0, 0, 0, 34, 0, 34, 0, 0, 0, 34,
311 34, 10, 34, 34, 34, 34, 34, 34, 34, 34,
312 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
313 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
314 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
315 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
316 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
317 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
318 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
319 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
320 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
321 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
322 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
323 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
324 34, 34, 34, 34, 34, 34
325 };
326 register int hval = len;
327
328 switch (hval)
329 {
330 default:
331 case 3:
332 hval += asso_values[(unsigned char)str[2]];
333 case 2:
334 hval += asso_values[(unsigned char)str[1]];
335 case 1:
336 hval += asso_values[(unsigned char)str[0]];
337 break;
338 }
339 return hval;
340 }
341
342 Month
343 DateCategory::MonthFromData(const Data& mon)
344 {
345 static const unsigned int MIN_WORD_LENGTH = 3;
346 static const unsigned int MAX_WORD_LENGTH = 3;
347 static const int MAX_HASH_VALUE = 33;
348
349 register const char *str = mon.data();
350 register Data::size_type len = mon.size();
351
352 static struct months wordlist[] =
353 {
354 {""}, {""}, {""},
355 {"Jun", Jun},
356 {""}, {""},
357 {"Nov", Nov},
358 {"Jul", Jul},
359 {"Feb", Feb},
360 {""}, {""},
361 {"Dec", Dec},
362 {"Sep", Sep},
363 {"Jan", Jan},
364 {""}, {""}, {""},
365 {"Oct", Oct},
366 {"Apr", Apr},
367 {""}, {""}, {""}, {""},
368 {"Mar", Mar},
369 {""}, {""}, {""}, {""},
370 {"Aug", Aug},
371 {""}, {""}, {""}, {""},
372 {"May", May}
373 };
374
375 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
376 {
377 register int key = month_hash (str, len);
378
379 if (key <= MAX_HASH_VALUE && key >= 0)
380 {
381 register const char *s = wordlist[key].name;
382
383 if (*str == *s && !strncmp (str + 1, s + 1, mon.size()-1))
384 return wordlist[key].type;
385 }
386 }
387 return Jan;
388 }
389
390 const DayOfWeek&
391 DateCategory::dayOfWeek() const
392 {
393 checkParsed();
394 return mDayOfWeek;
395 }
396
397 int&
398 DateCategory::dayOfMonth()
399 {
400 checkParsed();
401 return mDayOfMonth;
402 }
403
404 int
405 DateCategory::dayOfMonth() const
406 {
407 checkParsed();
408 return mDayOfMonth;
409 }
410
411 Month&
412 DateCategory::month()
413 {
414 checkParsed();
415 return mMonth;
416 }
417
418 Month
419 DateCategory::month() const
420 {
421 checkParsed();
422 return mMonth;
423 }
424
425 int&
426 DateCategory::year()
427 {
428 checkParsed();
429 return mYear;
430 }
431
432 int
433 DateCategory::year() const
434 {
435 checkParsed();
436 return mYear;
437 }
438
439 int&
440 DateCategory::hour()
441 {
442 checkParsed();
443 return mHour;
444 }
445
446 int
447 DateCategory::hour() const
448 {
449 checkParsed();
450 return mHour;
451 }
452
453 int&
454 DateCategory::minute()
455 {
456 checkParsed();
457 return mMin;
458 }
459
460 int
461 DateCategory::minute() const
462 {
463 checkParsed();
464 return mMin;
465 }
466
467 int&
468 DateCategory::second()
469 {
470 checkParsed();
471 return mSec;
472 }
473
474 int
475 DateCategory::second() const
476 {
477 checkParsed();
478 return mSec;
479 }
480
481 void
482 DateCategory::parse(ParseBuffer& pb)
483 {
484 // Mon, 04 Nov 2002 17:34:15 GMT
485
486 const char* anchor = pb.skipWhitespace();
487
488 pb.skipToChar(Symbols::COMMA[0]);
489 Data dayOfWeek;
490 pb.data(dayOfWeek, anchor);
491 mDayOfWeek = DateCategory::DayOfWeekFromData(dayOfWeek);
492
493 pb.skipChar(Symbols::COMMA[0]);
494
495 pb.skipWhitespace();
496
497 mDayOfMonth = pb.integer();
498
499 anchor = pb.skipWhitespace();
500 pb.skipNonWhitespace();
501
502 Data month;
503 pb.data(month, anchor);
504 mMonth = DateCategory::MonthFromData(month);
505
506 pb.skipWhitespace();
507 mYear = pb.integer();
508
509 pb.skipWhitespace();
510
511 mHour = pb.integer();
512 pb.skipChar(Symbols::COLON[0]);
513 mMin = pb.integer();
514 pb.skipChar(Symbols::COLON[0]);
515 mSec = pb.integer();
516
517 pb.skipWhitespace();
518 pb.skipChar('G');
519 pb.skipChar('M');
520 pb.skipChar('T');
521
522 pb.skipWhitespace();
523 pb.assertEof();
524 }
525
526 ParserCategory*
527 DateCategory::clone() const
528 {
529 return new DateCategory(*this);
530 }
531
532 static void pad2(const int x, std::ostream& str)
533 {
534 if (x < 10)
535 {
536 str << Symbols::ZERO[0];
537 }
538 str << x;
539 }
540
541 std::ostream&
542 DateCategory::encodeParsed(std::ostream& str) const
543 {
544 str << DayOfWeekData[mDayOfWeek] // Mon
545 << Symbols::COMMA[0] << Symbols::SPACE[0];
546
547 pad2(mDayOfMonth, str); // 04
548
549 str << Symbols::SPACE[0]
550 << MonthData[mMonth] << Symbols::SPACE[0] // Nov
551 << mYear << Symbols::SPACE[0]; // 2002
552
553 pad2(mHour, str);
554 str << Symbols::COLON[0];
555 pad2(mMin, str);
556 str << Symbols::COLON[0];
557 pad2(mSec, str);
558 str << " GMT";
559
560 return str;
561 }
562
563
564 /* ====================================================================
565 * The Vovida Software License, Version 1.0
566 *
567 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
568 *
569 * Redistribution and use in source and binary forms, with or without
570 * modification, are permitted provided that the following conditions
571 * are met:
572 *
573 * 1. Redistributions of source code must retain the above copyright
574 * notice, this list of conditions and the following disclaimer.
575 *
576 * 2. Redistributions in binary form must reproduce the above copyright
577 * notice, this list of conditions and the following disclaimer in
578 * the documentation and/or other materials provided with the
579 * distribution.
580 *
581 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
582 * and "Vovida Open Communication Application Library (VOCAL)" must
583 * not be used to endorse or promote products derived from this
584 * software without prior written permission. For written
585 * permission, please contact vocal@vovida.org.
586 *
587 * 4. Products derived from this software may not be called "VOCAL", nor
588 * may "VOCAL" appear in their name, without prior written
589 * permission of Vovida Networks, Inc.
590 *
591 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
592 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
593 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
594 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
595 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
596 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
597 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
598 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
599 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
600 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
601 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
602 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
603 * DAMAGE.
604 *
605 * ====================================================================
606 *
607 * This software consists of voluntary contributions made by Vovida
608 * Networks, Inc. and many individuals on behalf of Vovida Networks,
609 * Inc. For more information on Vovida Networks, Inc., please see
610 * <http://www.vovida.org/>.
611 *
612 */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27