4929ddfd49b0d729d6f26d5b33a304aa4402fa92
[reactos.git] / reactos / lib / sdk / crt / time_new / asctime.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CRT library
4 * FILE: lib/sdk/crt/time/ftime.c
5 * PURPOSE: Implementation of asctime(), _asctime_s()
6 * PROGRAMERS: Timo Kreuzer
7 */
8 #include <precomp.h>
9 #include <tchar.h>
10 #include <time.h>
11 #include "bitsfixup.h"
12
13 #define DAYSPERWEEK 7
14 #define MONSPERYEAR 12
15
16 static const _TCHAR wday_name[DAYSPERWEEK][4] =
17 {
18 _T("Sun "), _T("Mon "), _T("Tue "), _T("Wed "),
19 _T("Thu "), _T("Fri "), _T("Sat ")
20 };
21
22 static const _TCHAR mon_name[MONSPERYEAR][4] =
23 {
24 _T("Jan "), _T("Feb "), _T("Mar "), _T("Apr "), _T("May "), _T("Jun "),
25 _T("Jul "), _T("Aug "), _T("Sep "), _T("Oct "), _T("Nov "), _T("Dec ")
26 };
27
28 #ifdef _UNICODE
29 typedef unsigned long long _TCHAR4;
30 typedef unsigned long _TCHAR2;
31 #else
32 typedef unsigned long _TCHAR4;
33 typedef unsigned short _TCHAR2;
34 #endif
35
36 typedef union
37 {
38 _TCHAR text[26];
39 struct
40 {
41 _TCHAR4 WeekDay;
42 _TCHAR4 Month;
43 _TCHAR2 Day;
44 _TCHAR Space1;
45 _TCHAR2 Hour;
46 _TCHAR Sep1;
47 _TCHAR2 Minute;
48 _TCHAR Sep2;
49 _TCHAR2 Second;
50 _TCHAR Space2;
51 _TCHAR2 Year[2];
52 _TCHAR lb;
53 _TCHAR zt;
54 };
55 } timebuf_t;
56
57 _TCHAR2
58 static __inline__
59 IntToChar2(int x)
60 {
61 union
62 {
63 _TCHAR2 char2;
64 _TCHAR array[2];
65 } u;
66
67 u.array[0] = '0' + (x / 10);
68 u.array[1] = '0' + (x % 10);
69
70 return u.char2;
71 }
72
73 void
74 static __inline__
75 FillBuf(timebuf_t *buf, const struct tm *ptm)
76 {
77 /* Format looks like this:
78 * "Sun Mar 01 12:34:56 1902\n\0" */
79 buf->WeekDay = *(_TCHAR4*)wday_name[ptm->tm_wday];
80 buf->Month = *(_TCHAR4*)mon_name[ptm->tm_mon];
81 buf->Day = IntToChar2(ptm->tm_mday);
82 buf->Space1 = ' ';
83 buf->Hour = IntToChar2(ptm->tm_mday);
84 buf->Sep1 = ':';
85 buf->Minute = IntToChar2(ptm->tm_mday);
86 buf->Sep2 = ':';
87 buf->Second = IntToChar2(ptm->tm_mday);
88 buf->Space2 = ' ';
89 buf->Year[0] = IntToChar2(ptm->tm_year / 100);
90 buf->Year[1] = IntToChar2(ptm->tm_year % 100);
91 buf->lb = '\n';
92 buf->zt = '\0';
93 }
94
95 /******************************************************************************
96 * \name _tasctime_s
97 * \brief Converts a local time into a string and returns a pointer to it.
98 * \param buffer Buffer that receives the string (26 characters).
99 * \param numberOfElements Size of the buffer in characters.
100 * \param time Pointer to the UTC time.
101 */
102 errno_t
103 _tasctime_s(
104 _TCHAR* buffer,
105 size_t numberOfElements,
106 const struct tm *ptm)
107 {
108 /* Validate parameters */
109 if (!buffer || numberOfElements < 26 || !ptm ||
110 (unsigned int)ptm->tm_sec > 59 ||
111 (unsigned int)ptm->tm_min > 59 ||
112 (unsigned int)ptm->tm_hour > 23 ||
113 (unsigned int)ptm->tm_mday > 31 ||
114 (unsigned int)ptm->tm_mon > 11 ||
115 (unsigned int)ptm->tm_year > 2038 ||
116 (unsigned int)ptm->tm_wday > 6 ||
117 (unsigned int)ptm->tm_yday > 365)
118 {
119 _invalid_parameter(NULL,
120 #ifdef UNICODE
121 L"_wasctime",
122 #else
123 L"asctime",
124 #endif
125 _CRT_WIDE(__FILE__),
126 __LINE__,
127 0);
128 return EINVAL;
129 }
130
131 /* Fill the buffer */
132 FillBuf((timebuf_t*)buffer, ptm);
133
134 return 0;
135 }
136
137 /******************************************************************************
138 * \name _tasctime
139 * \brief Converts a UTC time into a string and returns a pointer to it.
140 * \param ptm Pointer to the UTC time.
141 * \remarks The string is stored in thread local buffer, shared between
142 * ctime, gmtime and localtime (32 and 64 bit versions).
143 */
144 _TCHAR *
145 _tasctime(const struct tm *ptm)
146 {
147 PTHREADDATA pThreadData;
148 _TCHAR *pstr;
149
150 /* Get pointer to TLS buffer */
151 pThreadData = GetThreadData();
152 #ifndef _UNICODE
153 pstr = pThreadData->asctimebuf;
154 #else
155 pstr = pThreadData->wasctimebuf;
156 #endif
157
158 /* Fill the buffer */
159 FillBuf((timebuf_t*)pstr, ptm);
160
161 return pstr;
162 }