2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // Manage the Tower of Babel of CSSM dates and times
22 #include <Security/cssmdates.h>
27 // A (private) PODwrapper for CFGregorianDate
29 struct Gregorian
: public PodWrapper
<Gregorian
, CFGregorianDate
> {
32 Gregorian(int y
, int m
, int d
, int h
= 0, int min
= 0, double sec
= 0)
34 year
= y
; month
= m
; day
= d
;
35 hour
= h
; minute
= min
; second
= sec
;
38 Gregorian(CFAbsoluteTime ref
)
39 { static_cast<CFGregorianDate
&>(*this) = CFAbsoluteTimeGetGregorianDate(ref
, NULL
); }
41 operator CFAbsoluteTime () const
42 { return CFGregorianDateGetAbsoluteTime(*this, NULL
); }
47 // The CssmDate PODwrapper
49 CssmDate::CssmDate(const char *y
, const char *m
, const char *d
)
51 assign(years(), 4, y
);
52 assign(months(), 2, m
);
56 CssmDate::CssmDate(int y
, int m
, int d
)
58 // internal format is "yyyymmdd" (no null termination)
60 if (8 != snprintf(str
, 9, "%4.4d%2.2d%2.2d", y
, m
, d
))
61 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
65 int CssmDate::year() const
66 { return atoi(string(years(), 4).c_str()); }
68 int CssmDate::month() const
69 { return atoi(string(months(), 2).c_str()); }
71 int CssmDate::day() const
72 { return atoi(string(days(), 2).c_str()); }
75 void CssmDate::assign(char *dest
, int width
, const char *src
)
77 // pick last width characters of src at most
78 int len
= strlen(src
);
80 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
81 memset(dest
, '0', width
- len
);
82 memcpy(dest
+ width
- len
, src
, len
);
87 // CssmUniformDate core functions
92 // Uniform conversions with CFDateRef
94 CssmUniformDate::CssmUniformDate(CFDateRef ref
)
96 mTime
= CFDateGetAbsoluteTime(ref
);
99 CssmUniformDate::operator CFDateRef() const
101 return CFDateCreate(NULL
, mTime
);
106 // Uniform conversions with CssmDates
108 CssmUniformDate::CssmUniformDate(const CssmDate
&date
)
110 mTime
= CFGregorianDateGetAbsoluteTime(Gregorian(date
.year(), date
.month(), date
.day()),
114 CssmUniformDate::operator CssmDate () const
116 Gregorian
greg(mTime
);
117 return CssmDate(greg
.year
, greg
.month
, greg
.day
);
122 // Uniform conversions with CssmData (1999-06-30_15:05:39 form)
124 CssmUniformDate::CssmUniformDate(const CSSM_DATA
&inData
)
126 const CssmData
&data
= CssmData::overlay(inData
);
127 if (data
.length() != 19)
128 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
129 setFromString(reinterpret_cast<const char *>(inData
.Data
), "%ld-%d-%d_%d:%d:%lf", 19);
132 void CssmUniformDate::convertTo(CssmOwnedData
&data
) const
134 Gregorian
greg(mTime
);
136 if (19 != snprintf(str
, 20, "%4.4d-%2.2d-%2.2d_%2.2d:%2.2d:%2.2d",
137 int(greg
.year
), greg
.month
, greg
.day
, greg
.hour
, greg
.minute
, int(greg
.second
)))
138 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
139 data
= CssmData(str
, 19);
144 // Uniform conversions with CSSM_TIMESTRING (19990630150539 form)
146 CssmUniformDate::CssmUniformDate(const char *src
)
148 setFromString(src
, "%4ld%2d%2d%2d%2d%2lf", 14);
151 void CssmUniformDate::convertTo(char *dst
, size_t length
) const
154 CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL
);
155 Gregorian
greg(mTime
);
157 if (14 != snprintf(str
, 15, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
158 int(greg
.year
), greg
.month
, greg
.day
, greg
.hour
, greg
.minute
, int(greg
.second
)))
159 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
160 memcpy(dst
, str
, length
== 14 ? 14 : 15); // null terminate if there's room
165 // Generalized parse-from-string setup
167 void CssmUniformDate::setFromString(const char *src
, const char *format
, size_t fieldWidth
)
169 // use a stack buffer
171 assert(fieldWidth
< sizeof(str
));
173 // make a copy with proper null terminator
174 memcpy(str
, src
, fieldWidth
);
175 str
[fieldWidth
] = '\0';
177 // parse (with limited checks for bad field formats)
179 int month
, day
, hour
, minute
;
181 if (6 != sscanf(str
, format
,
182 &year
, &month
, &day
, &hour
, &minute
, &second
))
183 CssmError::throwMe(CSSM_ERRCODE_UNKNOWN_FORMAT
);
186 mTime
= Gregorian(year
, month
, day
, hour
, minute
, second
);