DCL 4.1
Loading...
Searching...
No Matches
IFXTypes.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <sqlhdr.h>
4#include <sqliapi.h>
5
6#include <stdio.h>
7#include <string.h>
8
9#include <dcl/Object.h>
10#if __DCL_HAVE_ALLOC_DEBUG
11#undef __DCL_ALLOC_LEVEL
12#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
13#endif
14
15#include <dcl/SQLCore.h>
16
17#include "IFXTypes_.h"
18
19#ifdef __DCL_DEBUG
20#undef __THIS_FILE__
21static const wchar_t __THIS_FILE__[] = __T("dcl/sql/IFXTypes.cpp");
22#endif
23
24__DCL_BEGIN_NAMESPACE
25
26size_t __get_dec_strlen(const dec_t* p)
27{
28 // assert(p->dec_pos != -1);
29 // assert(p->dec_ndgts >= 0);
30 __DCL_ASSERT(p->dec_pos != -1);
31 __DCL_ASSERT(p->dec_ndgts >= 0);
32
33 if (p->dec_ndgts == 0)
34 return 1; // "0"
35
36 size_t n = p->dec_pos == 0 ? 1 : 0;
37
38 int __n = p->dec_exp - p->dec_ndgts;
39 if (__n < 0)
40 {
41 // 소숫점 아래 포함
42
43 if (p->dec_exp > 0)
44 {
45 // 소숫점 위 포함
46 // 소숫점 아래와 소숫점 위 모두 포함
47
48 n += p->dec_ndgts * 2;
49
50 // 첫번째가 10보다 작으면
51 if (p->dec_dgts[0] < 10)
52 n--;
53
54 // 소숫점아래 마지막이 0이면
55 if ((p->dec_dgts[p->dec_ndgts - 1] % 10) == 0)
56 n--;
57
58 n++; // 소숫점
59 }
60 else
61 {
62 // 소숫점 아래만 있음
63 n += 2; // "0."
64 n += (-__n) * 2;
65
66 // 소숫점아래 마지막이 0이면
67 if ((p->dec_dgts[p->dec_ndgts - 1] % 10) == 0)
68 n--;
69 }
70 }
71 else
72 {
73 // 소숫점을 포함하지 않음
74
75 if (__n > 0)
76 n += (p->dec_ndgts + __n) * 2;
77 else
78 n += p->dec_ndgts * 2;
79
80 // 첫번째가 10보다 작으면
81 if (p->dec_dgts[0] < 10)
82 n--;
83
84 // dectoasc 에서 소숫점 없는 수는 ".0"을 추가함
85 n += 2;
86 }
87
88 return n;
89}
90
91// __GET_UNIT_VALUE
92// 첫번째이면 첫번째 길이만큼, 나머지는 1바이트(0~99) 값
93#define __GET_UNIT_VALUE(TU_VAR, TU_NAME, TU_EXP) \
94 if (_s->in_dec.dec_exp >= TU_EXP) \
95 { \
96 if (TU_START(_s->in_qual) == TU_NAME) \
97 { \
98 int n = _s->in_dec.dec_exp - (TU_EXP - 1); \
99 while(n-- > 0) \
100 { \
101 TU_VAR *= 100; \
102 if (ndgts > 0) \
103 { \
104 TU_VAR += *p++; \
105 ndgts--; \
106 } \
107 } \
108 } \
109 else \
110 { \
111 TU_VAR += *p++; \
112 ndgts--; \
113 } \
114 } \
115 if (TU_END(_s->in_qual) == TU_NAME || ndgts == 0) \
116 break;
117
118void __decode_intrvl(const intrvl_t* _s, SQL::Interval* _r)
119{
120 __DCL_ASSERT(_s->in_dec.dec_pos >= 0);
121
122 int nYears, nMonths, nDays, nHours, nMins, nSecs, nFSecs;
123 nYears = nMonths = nDays = nHours = nMins = nSecs = nFSecs = 0;
124
125 const char* p = _s->in_dec.dec_dgts;
126 int ndgts = _s->in_dec.dec_ndgts;
127
128 switch(TU_START(_s->in_qual))
129 {
130 case TU_YEAR :
131 __GET_UNIT_VALUE(nYears, TU_YEAR, 6)
132 case TU_MONTH :
133 __GET_UNIT_VALUE(nMonths, TU_MONTH, 5)
134 case TU_DAY :
135 __GET_UNIT_VALUE(nDays, TU_DAY, 4)
136 case TU_HOUR :
137 __GET_UNIT_VALUE(nHours, TU_HOUR, 3)
138 case TU_MINUTE :
139 __GET_UNIT_VALUE(nMins, TU_MINUTE, 2)
140 case TU_SECOND :
141 __GET_UNIT_VALUE(nSecs, TU_SECOND, 1)
142 case TU_FRAC :
143 // TU_F1, TU_F2
144 if (_s->in_dec.dec_exp >= 0)
145 {
146 nFSecs += *p++ * 10000;
147 ndgts--;
148 }
149 if (ndgts == 0)
150 break;
151 // TU_F3, TU_F4
152 if (_s->in_dec.dec_exp >= -1)
153 {
154 nFSecs += *p * 100;
155 ndgts--;
156 }
157 if (ndgts == 0)
158 break;
159 // TU_F5
160 if (_s->in_dec.dec_exp >= -2)
161 nFSecs += *p;
162 }
163
164#define MIN_PER_DAY 1440
165#define SEC_PER_DAY 86400
166#define SEC_PER_HOUR 3600
167
168 switch(TU_START(_s->in_qual))
169 {
170 case TU_YEAR :
171 break;
172 case TU_MONTH :
173 nYears = nMonths / 12;
174 nMonths = nMonths % 12;
175 break;
176 case TU_DAY :
177 break;
178 case TU_HOUR :
179 nDays = nHours / 24;
180 nHours = nHours % 24;
181 break;
182 case TU_MINUTE :
183 nDays = nMins / MIN_PER_DAY;
184 nHours = (nMins % MIN_PER_DAY) / 60;
185 nMins = nMins % 60;
186 break;
187 case TU_SECOND :
188 nDays = nSecs / SEC_PER_DAY;
189 nHours = (nSecs % SEC_PER_DAY) / SEC_PER_HOUR;
190 nMins = (nSecs % SEC_PER_HOUR) / 60;
191 nSecs = nSecs % 60;
192 break;
193 case TU_FRAC :
194 break;
195 default :
196 __DCL_ASSERT(false);
197 }
198
199 if (_s->in_dec.dec_pos == 1)
200 {
201 _r->years = nYears;
202 _r->months = nMonths;
203 _r->days = nDays;
204 _r->hours = nHours;
205 _r->mins = nMins;
206 _r->secs = nSecs;
207 _r->fracs = nFSecs * 1000;
208 }
209 else
210 {
211 _r->years = -nYears;
212 _r->months = -nMonths;
213 _r->days = -nDays;
214 _r->hours = -nHours;
215 _r->mins = -nMins;
216 _r->secs = -nSecs;
217 _r->fracs = -(nFSecs * 1000);
218 }
219}
220
221void __decode_dtime(const dtime_t* _s, SQL::TimeStamp* _r)
222{
223 // assert(0 <= _s->dt_dec.dec_exp && _s->dt_dec.dec_exp <= 7)
224 // assert(_s->dt_dec.dec_ndgts > 0)
225 __DCL_ASSERT(0 <= _s->dt_dec.dec_exp && _s->dt_dec.dec_exp <= 7);
226 __DCL_ASSERT(_s->dt_dec.dec_ndgts > 0);
227
228 int nYear, nMonth, nDay, nHour, nMin, nSec, nFSec;
229 nYear = nMonth = nDay = nHour = nMin = nSec = nFSec = 0;
230
231 const char* p = _s->dt_dec.dec_dgts;
232 int ndgts = _s->dt_dec.dec_ndgts;
233 switch(TU_START(_s->dt_qual))
234 {
235 case TU_YEAR :
236 if (_s->dt_dec.dec_exp >= 7)
237 {
238 nYear = (*p++) * 100;
239 if (--ndgts == 0)
240 break;
241 }
242 if (_s->dt_dec.dec_exp >= 6)
243 {
244 nYear += (*p++);
245 if (--ndgts == 0)
246 break;
247 }
248 case TU_MONTH :
249 if (_s->dt_dec.dec_exp >= 5)
250 {
251 nMonth = *p++;
252 if (--ndgts == 0)
253 break;
254 }
255 case TU_DAY :
256 if (_s->dt_dec.dec_exp >= 4)
257 {
258 nDay = *p++;
259 if (--ndgts == 0)
260 break;
261 }
262 case TU_HOUR :
263 if (_s->dt_dec.dec_exp >= 3)
264 {
265 nHour = *p++;
266 if (--ndgts == 0)
267 break;
268 }
269 case TU_MINUTE :
270 if (_s->dt_dec.dec_exp >= 2)
271 {
272 nMin = *p++;
273 if (--ndgts == 0)
274 break;
275 }
276 case TU_SECOND :
277 if (_s->dt_dec.dec_exp >= 1)
278 {
279 nSec = *p++;
280 if (--ndgts == 0)
281 break;
282 }
283 case TU_FRAC :
284 // TU_F1, TU_F2
285 if (_s->dt_dec.dec_exp >= 0)
286 {
287 nFSec = *p++ * 10000;
288 if (--ndgts == 0)
289 break;
290 }
291 // TU_F3, TU_F4
292 if (_s->dt_dec.dec_exp >= -1)
293 {
294 nFSec += *p * 100;
295 if (--ndgts == 0)
296 break;
297 }
298 // TU_F5
299 if (_s->dt_dec.dec_exp >= -2)
300 nFSec += *p;
301 }
302
303 _r->year = nYear;
304 _r->month = nMonth;
305 _r->day = nDay;
306 _r->hour = nHour;
307 _r->min = nMin;
308 _r->sec = nSec;
309 _r->frac = nFSec * 1000;
310 _r->tzoff = INT16_MIN;
311}
312
313void __decode_dtime(const dtime_t* _s, SQL::Date* _r)
314{
316 __decode_dtime(_s, &t);
317 _r->year = t.year;
318 _r->month = t.month;
319 _r->day = t.day;
320}
321
322void __decode_dtime(const dtime_t* _s, SQL::Time* _r)
323{
325 __decode_dtime(_s, &t);
326 _r->hour = t.hour;
327 _r->min = t.min;
328 _r->sec = t.sec;
329 _r->frac = t.frac;
330 _r->tzoff = INT16_MIN;
331}
332
333#if __DCL_WINDOWS
334#define snprintf _snprintf
335#endif
336
337int __encode_dtime(const SQL::TimeStamp* _s, dtime_t* _r)
338{
339 char sz[40]; // YYYY-MM-DD HH:MM:SS.FFF 23
340 int n = snprintf(
341 sz,
342 sizeof(sz),
343 "%04d-%02u-%02u %02u:%02u:%02u.%05u",
344 _s->year, _s->month, _s->day,
345 _s->hour, _s->min, _s->sec, _s->frac / 10000
346 );
347
348 // -1263 A field in a datetime or interval value
349 // is out of range or incorrect.
350 if (n < 0)
351 return -1263;
352 else
353 sz[n] = '\0';
354
355 _r->dt_qual = TU_DTENCODE(TU_YEAR, TU_F5);
356 return dtcvasc(sz, _r);
357}
358
359int __encode_dtime(const SQL::Date* _s, dtime_t* _r)
360{
361 char sz[30]; // YYYY-MM-DD 10
362 int n = snprintf(
363 sz,
364 sizeof(sz),
365 "%04d-%02d-%02d",
366 _s->year, _s->month, _s->day
367 );
368 if (n < 0)
369 return -1263;
370 else
371 sz[n] = '\0';
372
373 _r->dt_qual = TU_DTENCODE(TU_YEAR, TU_DAY);
374 return dtcvasc(sz, _r);
375}
376
377int __encode_dtime(const SQL::Time* _s, dtime_t* _r)
378{
379 char sz[30]; // HH:MM:SS.FFF 12
380 int n = snprintf(
381 sz,
382 sizeof(sz),
383 "%02u:%02u:%02u.%05u",
384 _s->hour, _s->min, _s->sec, _s->frac / 10000
385 );
386 if (n < 0)
387 return -1263;
388 else
389 sz[n] = '\0';
390
391 _r->dt_qual = TU_DTENCODE(TU_HOUR, TU_F5);
392 return dtcvasc(sz, _r);
393}
394
395inline int __ABS(int n)
396{
397 return n < 0 ? -n : n;
398}
399
401 const SQL::Interval* _s,
402 SQL::DataType _dataType,
403 intrvl_t* _r
404 )
405{
406 if (_dataType == SQL::typeIntervalYm)
407 {
408 int fn = 1;
409 int d = 10;
410 for( ; _s->years / d; fn++)
411 d *= 10;
412
413 const char* fmt = "%d-%d";
414 if (_s->years < 0 || _s->months < 0)
415 fmt = "-%d-%d";
416
417 char sz[30]; // YYYYYYYYY-MM
418 int n = snprintf(
419 sz,
420 sizeof(sz),
421 fmt,
422 __ABS(_s->years),
423 __ABS(_s->months)
424 );
425 if (n < 0)
426 return -1263;
427 else
428 sz[n] = '\0';
429
430 _r->in_qual = TU_IENCODE(fn, TU_YEAR, TU_MONTH);
431 return incvasc(sz, _r);
432 }
433 else
434 {
435 __DCL_ASSERT(_dataType == SQL::typeIntervalDs);
436
437 int fn = 1; // FIRST LENGTH
438 int d = 10;
439 for( ; _s->days / d; fn++)
440 d *= 10;
441
442 const char* fmt = "%d %02d:%02d:%02d.%05d";
443 if (_s->days < 0 || _s->hours < 0 || _s->mins < 0
444 || _s->secs < 0 || _s->fracs < 0)
445 fmt = "-%d %02d:%02d:%02d.%05d";
446
447 char sz[40]; // DDDDDDDDDD HH:MM:SS.FFF + sign = 24
448 int n = snprintf(
449 sz,
450 sizeof(sz),
451 fmt,
452 __ABS(_s->days),
453 __ABS(_s->hours),
454 __ABS(_s->mins),
455 __ABS(_s->secs),
456 __ABS(_s->fracs / 10000)
457 );
458 if (n < 0)
459 return -1263;
460 else
461 sz[n] = '\0';
462
463 _r->in_qual = TU_IENCODE(fn, TU_DAY, TU_F5);
464 return incvasc(sz, _r);
465 }
466}
467
468__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define INT16_MIN
Definition Config.h:312
#define SEC_PER_HOUR
Definition DateTime.cpp:391
#define SEC_PER_DAY
Definition DateTime.cpp:389
void __decode_dtime(const dtime_t *_s, SQL::TimeStamp *_r)
Definition IFXTypes.cpp:221
__DCL_BEGIN_NAMESPACE size_t __get_dec_strlen(const dec_t *p)
Definition IFXTypes.cpp:26
void __decode_intrvl(const intrvl_t *_s, SQL::Interval *_r)
Definition IFXTypes.cpp:118
int __encode_dtime(const SQL::TimeStamp *_s, dtime_t *_r)
Definition IFXTypes.cpp:337
#define __GET_UNIT_VALUE(TU_VAR, TU_NAME, TU_EXP)
Definition IFXTypes.cpp:93
int __encode_intrvl(const SQL::Interval *_s, SQL::DataType _dataType, intrvl_t *_r)
Definition IFXTypes.cpp:400
#define MIN_PER_DAY
#define __ABS(n)
Definition MyParam.cpp:143
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define __T(str)
Definition Object.h:44
_r
Definition SQLField.cpp:261
void CharsetConvertException *size_t n
Definition SQLField.cpp:254
DataType
Definition SQLCore.h:62
@ typeIntervalDs
Definition SQLCore.h:75
@ typeIntervalYm
Definition SQLCore.h:74
int16_t year
Definition SQLCore.h:97
uint8_t month
Definition SQLCore.h:98
uint8_t day
Definition SQLCore.h:99
int32_t years
Definition SQLCore.h:127
int32_t days
Definition SQLCore.h:129
int8_t hours
Definition SQLCore.h:130
int8_t mins
Definition SQLCore.h:131
int32_t fracs
Definition SQLCore.h:133
int8_t months
Definition SQLCore.h:128
int8_t secs
Definition SQLCore.h:132
uint8_t hour
Definition SQLCore.h:104
uint8_t sec
Definition SQLCore.h:106
uint32_t frac
Definition SQLCore.h:107
uint8_t min
Definition SQLCore.h:105
uint32_t frac
Definition SQLCore.h:119
uint8_t min
Definition SQLCore.h:117
uint8_t sec
Definition SQLCore.h:118
uint8_t hour
Definition SQLCore.h:116
uint8_t day
Definition SQLCore.h:115
int16_t year
Definition SQLCore.h:113
uint8_t month
Definition SQLCore.h:114