tdate_parse.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2007, Cameron Rich
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. * * Neither the name of the axTLS project nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  26. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <sys/types.h>
  31. #include <ctype.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <time.h>
  36. #include "axhttp.h"
  37. struct day_mon_map
  38. {
  39. const char* s;
  40. uint8_t l;
  41. };
  42. static struct day_mon_map wday_tab[] =
  43. {
  44. { "Sun", 0 }, { "Mon", 1 }, { "Tue", 2 }, { "Wed", 3 },
  45. { "Thu", 4 }, { "Fri", 5 }, { "Sat", 6 },
  46. };
  47. static struct day_mon_map mon_tab[] =
  48. {
  49. { "Jan", 0 }, { "Feb", 1 }, { "Mar", 2 }, { "Apr", 3 },
  50. { "May", 4 }, { "Jun", 5 }, { "Jul", 6 }, { "Aug", 7 },
  51. { "Sep", 8 }, { "Oct", 9 }, { "Nov", 10 }, { "Dec", 11 },
  52. };
  53. static int day_mon_map_compare(const char *v1, const char *v2)
  54. {
  55. return strcmp(((struct day_mon_map*)v1)->s, ((struct day_mon_map*)v2)->s);
  56. }
  57. void tdate_init(void)
  58. {
  59. qsort(wday_tab, sizeof(wday_tab)/sizeof(struct day_mon_map),
  60. sizeof(struct day_mon_map),
  61. (int (*)(const void *, const void *))day_mon_map_compare);
  62. qsort(mon_tab, sizeof(mon_tab)/sizeof(struct day_mon_map),
  63. sizeof(struct day_mon_map),
  64. (int (*)(const void *, const void *))day_mon_map_compare);
  65. }
  66. static int8_t day_mon_map_search(const char* str,
  67. const struct day_mon_map* tab, int n)
  68. {
  69. struct day_mon_map *search = bsearch(&str, tab, n,
  70. sizeof(struct day_mon_map),
  71. (int (*)(const void *, const void *))day_mon_map_compare);
  72. return search ? search->l : -1;
  73. }
  74. time_t tdate_parse(const char* str)
  75. {
  76. struct tm tm;
  77. char str_mon[4], str_wday[4];
  78. int tm_sec, tm_min, tm_hour, tm_mday, tm_year;
  79. /* Initialize. */
  80. memset(&tm, 0, sizeof(struct tm));
  81. /* wdy, DD mth YY HH:MM:SS GMT */
  82. if ((sscanf(str, "%3[a-zA-Z], %d %3[a-zA-Z] %d %d:%d:%d GMT",
  83. str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
  84. &tm_sec) == 7) ||
  85. /* wdy mth DD HH:MM:SS YY */
  86. (sscanf(str, "%3[a-zA-Z] %3[a-zA-Z] %d %d:%d:%d %d",
  87. str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
  88. &tm_year) == 7))
  89. {
  90. int8_t tm_wday = day_mon_map_search(str_wday, wday_tab,
  91. sizeof(wday_tab)/sizeof(struct day_mon_map));
  92. int8_t tm_mon = day_mon_map_search(str_mon, mon_tab,
  93. sizeof(mon_tab)/sizeof(struct day_mon_map));
  94. if (tm_wday < 0 || tm_mon < 0)
  95. return -1;
  96. tm.tm_wday = tm_wday;
  97. tm.tm_mon = tm_mon;
  98. tm.tm_mday = tm_mday;
  99. tm.tm_hour = tm_hour;
  100. tm.tm_min = tm_min;
  101. tm.tm_sec = tm_sec;
  102. tm.tm_year = tm_year - 1900;
  103. return mktime(&tm);
  104. }
  105. return -1; /* error */
  106. }