1/*
2 * Copyright 2010 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Christophe Huriaux, c.huriaux@gmail.com
7 */
8
9#include <HttpTime.h>
10
11#include <new>
12
13#include <cstdio>
14
15
16#define PRINT(x) printf x
17
18
19static const char* 	kRfc1123Format			= "%a, %d %b %Y %H:%M:%S GMT";
20static const char* 	kCookieFormat			= "%a, %d-%b-%Y %H:%M:%S GMT";
21static const char* 	kRfc1036Format			= "%A, %d-%b-%y %H:%M:%S GMT";
22static const char* 	kAscTimeFormat			= "%a %d %b %H:%M:%S %Y";
23static const uint16	kTimetToStringMaxLength	= 128;
24
25using namespace BPrivate;
26
27
28BHttpTime::BHttpTime()
29	:
30	fDate(0),
31	fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED)
32{
33}
34
35
36BHttpTime::BHttpTime(time_t date)
37	:
38	fDate(date),
39	fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED)
40{
41}
42
43
44BHttpTime::BHttpTime(const BString& dateString)
45	:
46	fDateString(dateString),
47	fDate(0),
48	fDateFormat(B_HTTP_TIME_FORMAT_PREFERRED)
49{
50}
51
52
53// #pragma mark Date modification
54
55
56void
57BHttpTime::SetString(const BString& string)
58{
59	fDateString = string;
60}
61
62
63void
64BHttpTime::SetDate(time_t date)
65{
66	fDate = date;
67}
68
69
70// #pragma mark Date conversion
71
72
73time_t
74BHttpTime::Parse()
75{
76	struct tm expireTime;
77
78	if (fDateString.Length() < 4)
79		return 0;
80
81	if (fDateString[3] == ',') {
82		if (strptime(fDateString.String(), kRfc1123Format, &expireTime)
83				== NULL) {
84			strptime(fDateString.String(), kCookieFormat, &expireTime);
85			fDateFormat = B_HTTP_TIME_FORMAT_COOKIE;
86		} else
87			fDateFormat = B_HTTP_TIME_FORMAT_RFC1123;
88	} else if (fDateString[3] == ' ') {
89		strptime(fDateString.String(), kRfc1036Format, &expireTime);
90		fDateFormat = B_HTTP_TIME_FORMAT_RFC1036;
91	} else {
92		strptime(fDateString.String(), kAscTimeFormat, &expireTime);
93		fDateFormat = B_HTTP_TIME_FORMAT_ASCTIME;
94	}
95
96//	return timegm(&expireTime);
97// TODO: The above was used initially. See http://en.wikipedia.org/wiki/Time.h
98// stippi: I don't know how Christophe had this code compiling initially,
99// since Haiku does not appear to implement timegm().
100return mktime(&expireTime);
101}
102
103
104BString
105BHttpTime::ToString(int8 format)
106{
107	BString expirationFinal;
108	struct tm* expirationTm = localtime(&fDate);
109	char expirationString[kTimetToStringMaxLength + 1];
110	size_t strLength;
111
112	switch ((format == B_HTTP_TIME_FORMAT_PARSED)?fDateFormat:format) {
113		default:
114		case B_HTTP_TIME_FORMAT_RFC1123:
115			strLength = strftime(expirationString, kTimetToStringMaxLength,
116				kRfc1123Format, expirationTm);
117			break;
118
119		case B_HTTP_TIME_FORMAT_RFC1036:
120			strLength = strftime(expirationString, kTimetToStringMaxLength,
121				kRfc1036Format, expirationTm);
122			break;
123
124		case B_HTTP_TIME_FORMAT_ASCTIME:
125			strLength = strftime(expirationString, kTimetToStringMaxLength,
126				kAscTimeFormat, expirationTm);
127			break;
128	}
129
130	expirationFinal.SetTo(expirationString, strLength);
131	return expirationFinal;
132}
133