2 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
5 #include <asn_internal.h>
7 #include <GeneralizedTime.h>
11 #include "/usr/include/time.h"
14 #endif /* __CYGWIN__ */
16 #ifndef __ASN_INTERNAL_TEST_MODE__
19 * UTCTime basic type description.
21 static ber_tlv_tag_t asn_DEF_UTCTime_tags
[] = {
22 (ASN_TAG_CLASS_UNIVERSAL
| (23 << 2)), /* [UNIVERSAL 23] IMPLICIT ...*/
23 (ASN_TAG_CLASS_UNIVERSAL
| (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/
24 (ASN_TAG_CLASS_UNIVERSAL
| (4 << 2)) /* ... OCTET STRING */
26 static asn_per_constraints_t asn_DEF_UTCTime_constraints
= {
27 { APC_CONSTRAINED
, 7, 7, 0x20, 0x7e }, /* Value */
28 { APC_SEMI_CONSTRAINED
, -1, -1, 0, 0 }, /* Size */
31 asn_TYPE_descriptor_t asn_DEF_UTCTime
= {
37 OCTET_STRING_decode_ber
, /* Implemented in terms of OCTET STRING */
38 OCTET_STRING_encode_der
, /* Implemented in terms of OCTET STRING */
39 OCTET_STRING_decode_xer_utf8
,
41 OCTET_STRING_decode_uper
,
42 OCTET_STRING_encode_uper
,
43 0, /* Use generic outmost tag fetcher */
45 sizeof(asn_DEF_UTCTime_tags
)
46 / sizeof(asn_DEF_UTCTime_tags
[0]) - 2,
48 sizeof(asn_DEF_UTCTime_tags
)
49 / sizeof(asn_DEF_UTCTime_tags
[0]),
50 &asn_DEF_UTCTime_constraints
,
51 0, 0, /* No members */
55 #endif /* __ASN_INTERNAL_TEST_MODE__ */
58 * Check that the time looks like the time.
61 UTCTime_constraint(asn_TYPE_descriptor_t
*td
, const void *sptr
,
62 asn_app_constraint_failed_f
*ctfailcb
, void *app_key
) {
63 const UTCTime_t
*st
= (const UTCTime_t
*)sptr
;
66 errno
= EPERM
; /* Just an unlikely error code */
67 tloc
= asn_UT2time(st
, 0, 0);
68 if(tloc
== -1 && errno
!= EPERM
) {
69 _ASN_CTFAIL(app_key
, td
, sptr
,
70 "%s: Invalid time format: %s (%s:%d)",
71 td
->name
, strerror(errno
), __FILE__
, __LINE__
);
78 #ifndef __ASN_INTERNAL_TEST_MODE__
81 UTCTime_encode_xer(asn_TYPE_descriptor_t
*td
, void *sptr
,
82 int ilevel
, enum xer_encoder_flags_e flags
,
83 asn_app_consume_bytes_f
*cb
, void *app_key
) {
85 if(flags
& XER_F_CANONICAL
) {
91 if(asn_UT2time((UTCTime_t
*)sptr
, &tm
, 1) == -1
95 /* Fractions are not allowed in UTCTime */
96 ut
= asn_time2GT(0, 0, 1);
97 if(!ut
) _ASN_ENCODE_FAILED
;
99 rv
= OCTET_STRING_encode_xer_utf8(td
, sptr
, ilevel
, flags
,
101 OCTET_STRING_free(&asn_DEF_UTCTime
, ut
, 0);
104 return OCTET_STRING_encode_xer_utf8(td
, sptr
, ilevel
, flags
,
109 #endif /* __ASN_INTERNAL_TEST_MODE__ */
112 UTCTime_print(asn_TYPE_descriptor_t
*td
, const void *sptr
, int ilevel
,
113 asn_app_consume_bytes_f
*cb
, void *app_key
) {
114 const UTCTime_t
*st
= (const UTCTime_t
*)sptr
;
116 (void)td
; /* Unused argument */
117 (void)ilevel
; /* Unused argument */
125 if(asn_UT2time(st
, &tm
, 1) == -1 && errno
!= EPERM
)
126 return (cb("<bad-value>", 11, app_key
) < 0) ? -1 : 0;
128 ret
= snprintf(buf
, sizeof(buf
),
129 "%04d-%02d-%02d %02d:%02d:%02d (GMT)",
130 tm
.tm_year
+ 1900, tm
.tm_mon
+ 1, tm
.tm_mday
,
131 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
132 assert(ret
> 0 && ret
< (int)sizeof(buf
));
133 return (cb(buf
, ret
, app_key
) < 0) ? -1 : 0;
135 return (cb("<absent>", 8, app_key
) < 0) ? -1 : 0;
140 asn_UT2time(const UTCTime_t
*st
, struct tm
*_tm
, int as_gmt
) {
141 char buf
[24]; /* "AAMMJJhhmmss+hhmm" + cushion */
142 GeneralizedTime_t gt
;
145 || st
->size
< 11 || st
->size
>= ((int)sizeof(buf
) - 2)) {
150 gt
.buf
= (unsigned char *)buf
;
151 gt
.size
= st
->size
+ 2;
152 memcpy(gt
.buf
+ 2, st
->buf
, st
->size
);
153 if(st
->buf
[0] > 0x35) {
163 return asn_GT2time(>
, _tm
, as_gmt
);
167 asn_time2UT(UTCTime_t
*opt_ut
, const struct tm
*tm
, int force_gmt
) {
168 GeneralizedTime_t
*gt
= (GeneralizedTime_t
*)opt_ut
;
170 gt
= asn_time2GT(gt
, tm
, force_gmt
);
171 if(gt
== 0) return 0;
173 assert(gt
->size
>= 2);
175 memmove(gt
->buf
, gt
->buf
+ 2, gt
->size
+ 1);
177 return (UTCTime_t
*)gt
;