63
63
#include <dmalloc.h>
64
64
#endif
65
65
66
- TDS_RCSID (var , "$Id: convert.c,v 1.212 2011/08/08 12:32:07 freddy77 Exp $" );
66
+ TDS_RCSID (var , "$Id: convert.c,v 1.213 2011/08/08 12:33:18 freddy77 Exp $" );
67
67
68
68
typedef unsigned short utf16_t ;
69
69
@@ -486,6 +486,10 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
486
486
break ;
487
487
case SYBDATETIME :
488
488
case SYBDATETIME4 :
489
+ case SYBMSTIME :
490
+ case SYBMSDATE :
491
+ case SYBMSDATETIME2 :
492
+ case SYBMSDATETIMEOFFSET :
489
493
/* FIXME not null terminated */
490
494
return string_to_datetime (src , desttype , cr );
491
495
break ;
@@ -1240,38 +1244,101 @@ tds_convert_money(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
1240
1244
}
1241
1245
1242
1246
static TDS_INT
1243
- tds_convert_datetime (const TDSCONTEXT * tds_ctx , int srctype , const TDS_CHAR * src , int desttype , CONV_RESULT * cr )
1247
+ tds_convert_datetimeall (const TDSCONTEXT * tds_ctx , int srctype , const TDS_DATETIMEALL * dta , int desttype , CONV_RESULT * cr )
1244
1248
{
1249
+ char whole_date_string [64 ];
1250
+ TDSDATEREC when ;
1251
+
1252
+ switch (desttype ) {
1253
+ case TDS_CONVERT_CHAR :
1254
+ case CASE_ALL_CHAR :
1255
+ memset (& when , 0 , sizeof (when ));
1245
1256
1246
- TDS_INT dt_days , dt_time ;
1257
+ tds_datecrack (srctype , dta , & when );
1258
+ tds_strftime (whole_date_string , sizeof (whole_date_string ), tds_ctx -> locale -> date_fmt , & when ,
1259
+ dta -> time_prec );
1260
+
1261
+ return string_to_result (whole_date_string , cr );
1262
+ case CASE_ALL_BINARY :
1263
+ /* TODO */
1264
+ break ;
1265
+ case SYBDATETIME :
1266
+ /* TODO check overflow */
1267
+ cr -> dt .dtdays = dta -> date ;
1268
+ cr -> dt .dttime = dta -> time * 3u / 100000u ;
1269
+ return sizeof (TDS_DATETIME );
1270
+ case SYBDATETIME4 :
1271
+ /* TODO check overflow */
1272
+ cr -> dt4 .days = dta -> date ;
1273
+ cr -> dt4 .minutes = dta -> time / (60u * 10000000u );
1274
+ return sizeof (TDS_DATETIME4 );
1275
+ case SYBMSDATETIMEOFFSET :
1276
+ case SYBMSDATE :
1277
+ case SYBMSTIME :
1278
+ case SYBMSDATETIME2 :
1279
+ cr -> dta = * dta ;
1280
+ return sizeof (TDS_DATETIMEALL );
1281
+ /* conversions not allowed */
1282
+ case SYBUNIQUE :
1283
+ case SYBBIT :
1284
+ case SYBBITN :
1285
+ case SYBINT1 :
1286
+ case SYBINT2 :
1287
+ case SYBINT4 :
1288
+ case SYBINT8 :
1289
+ case SYBMONEY4 :
1290
+ case SYBMONEY :
1291
+ case SYBNUMERIC :
1292
+ case SYBDECIMAL :
1293
+ default :
1294
+ break ;
1295
+ }
1296
+ return TDS_CONVERT_NOAVAIL ;
1297
+ }
1247
1298
1248
- char whole_date_string [30 ];
1299
+ static TDS_INT
1300
+ tds_convert_datetime (const TDSCONTEXT * tds_ctx , int srctype , const TDS_DATETIME * dt , int desttype , CONV_RESULT * cr )
1301
+ {
1302
+ char whole_date_string [64 ];
1249
1303
TDSDATEREC when ;
1250
1304
1251
1305
switch (desttype ) {
1252
1306
case TDS_CONVERT_CHAR :
1253
1307
case CASE_ALL_CHAR :
1254
1308
memset (& when , 0 , sizeof (when ));
1255
1309
1256
- tds_datecrack (SYBDATETIME , src , & when );
1310
+ tds_datecrack (SYBDATETIME , dt , & when );
1257
1311
tds_strftime (whole_date_string , sizeof (whole_date_string ), tds_ctx -> locale -> date_fmt , & when , 3 );
1258
1312
1259
1313
return string_to_result (whole_date_string , cr );
1260
- break ;
1261
1314
case CASE_ALL_BINARY :
1262
- return binary_to_result (src , sizeof (TDS_DATETIME ), cr );
1263
- break ;
1315
+ return binary_to_result (dt , sizeof (TDS_DATETIME ), cr );
1264
1316
case SYBDATETIME :
1265
- memcpy ( & cr -> dt , src , sizeof ( TDS_DATETIME )) ;
1317
+ cr -> dt = * dt ;
1266
1318
return sizeof (TDS_DATETIME );
1267
- break ;
1268
1319
case SYBDATETIME4 :
1269
- memcpy (& dt_days , src , 4 );
1270
- memcpy (& dt_time , src + 4 , 4 );
1271
- cr -> dt4 .days = dt_days ;
1272
- cr -> dt4 .minutes = (dt_time / 300 ) / 60 ;
1320
+ cr -> dt4 .days = dt -> dtdays ;
1321
+ cr -> dt4 .minutes = (dt -> dttime / 300 ) / 60 ;
1273
1322
return sizeof (TDS_DATETIME4 );
1274
- break ;
1323
+ case SYBMSDATETIMEOFFSET :
1324
+ case SYBMSDATE :
1325
+ case SYBMSTIME :
1326
+ case SYBMSDATETIME2 :
1327
+ memset (& cr -> dta , 0 , sizeof (cr -> dta ));
1328
+ /* FIXME must be 0 if came from DATETIME4 */
1329
+ cr -> dta .time_prec = 3 ;
1330
+ if (desttype == SYBMSDATETIMEOFFSET )
1331
+ cr -> dta .has_offset = 1 ;
1332
+ if (desttype != SYBMSDATE ) {
1333
+ cr -> dta .has_time = 1 ;
1334
+ cr -> dta .time_prec = 3 ;
1335
+ cr -> dta .time = ((TDS_UINT8 ) dt -> dttime ) * 100000u / 3u ;
1336
+ }
1337
+ if (desttype != SYBMSTIME ) {
1338
+ cr -> dta .has_date = 1 ;
1339
+ cr -> dta .date = dt -> dtdays ;
1340
+ }
1341
+ return sizeof (TDS_DATETIMEALL );
1275
1342
/* conversions not allowed */
1276
1343
case SYBUNIQUE :
1277
1344
case SYBBIT :
@@ -1291,26 +1358,24 @@ tds_convert_datetime(const TDSCONTEXT * tds_ctx, int srctype, const TDS_CHAR * s
1291
1358
}
1292
1359
1293
1360
static TDS_INT
1294
- tds_convert_datetime4 (const TDSCONTEXT * tds_ctx , int srctype , const TDS_CHAR * src , int desttype , CONV_RESULT * cr )
1361
+ tds_convert_datetime4 (const TDSCONTEXT * tds_ctx , int srctype , const TDS_DATETIME4 * dt4 , int desttype , CONV_RESULT * cr )
1295
1362
{
1296
1363
TDS_DATETIME dt ;
1297
1364
1298
- #define DT4 ((TDS_DATETIME4*) src)
1299
1365
switch (desttype ) {
1300
1366
case CASE_ALL_BINARY :
1301
- return binary_to_result (src , sizeof (TDS_DATETIME4 ), cr );
1367
+ return binary_to_result (dt4 , sizeof (TDS_DATETIME4 ), cr );
1302
1368
case SYBDATETIME4 :
1303
- cr -> dt4 = * DT4 ;
1369
+ cr -> dt4 = * dt4 ;
1304
1370
return sizeof (TDS_DATETIME4 );
1305
1371
default :
1306
1372
break ;
1307
1373
}
1308
1374
1309
1375
/* convert to DATETIME and use tds_convert_datetime */
1310
- dt .dtdays = DT4 -> days ;
1311
- dt .dttime = DT4 -> minutes * (60u * 300u );
1312
- #undef DT4
1313
- return tds_convert_datetime (tds_ctx , SYBDATETIME , (TDS_CHAR * ) & dt , desttype , cr );
1376
+ dt .dtdays = dt4 -> days ;
1377
+ dt .dttime = dt4 -> minutes * (60u * 300u );
1378
+ return tds_convert_datetime (tds_ctx , SYBDATETIME , & dt , desttype , cr );
1314
1379
}
1315
1380
1316
1381
static TDS_INT
@@ -1567,7 +1632,6 @@ TDS_INT
1567
1632
tds_convert (const TDSCONTEXT * tds_ctx , int srctype , const TDS_CHAR * src , TDS_UINT srclen , int desttype , CONV_RESULT * cr )
1568
1633
{
1569
1634
TDS_INT length = 0 ;
1570
- TDS_DATETIME dt ;
1571
1635
1572
1636
assert (srclen >= 0 && srclen <= 2147483647u );
1573
1637
@@ -1618,20 +1682,13 @@ tds_convert(const TDSCONTEXT * tds_ctx, int srctype, const TDS_CHAR * src, TDS_U
1618
1682
case SYBMSDATE :
1619
1683
case SYBMSDATETIME2 :
1620
1684
case SYBMSDATETIMEOFFSET :
1621
- #define dta ((TDS_DATETIMEALL *) (src))
1622
- memset (& dt , 0 , sizeof (dt ));
1623
- if (dta -> has_time )
1624
- dt .dttime = (dta -> time * 300u + 150u ) / 10000000lu ;
1625
- if (dta -> has_date )
1626
- dt .dtdays = dta -> date ;
1627
- length = tds_convert_datetime (tds_ctx , SYBDATETIME , (const TDS_CHAR * ) & dt , desttype , cr );
1628
- break ;
1629
- #undef dta
1685
+ length = tds_convert_datetimeall (tds_ctx , srctype , (const TDS_DATETIMEALL * ) src , desttype , cr );
1686
+ break ;
1630
1687
case SYBDATETIME :
1631
- length = tds_convert_datetime (tds_ctx , srctype , src , desttype , cr );
1688
+ length = tds_convert_datetime (tds_ctx , srctype , ( const TDS_DATETIME * ) src , desttype , cr );
1632
1689
break ;
1633
1690
case SYBDATETIME4 :
1634
- length = tds_convert_datetime4 (tds_ctx , srctype , src , desttype , cr );
1691
+ length = tds_convert_datetime4 (tds_ctx , srctype , ( const TDS_DATETIME4 * ) src , desttype , cr );
1635
1692
break ;
1636
1693
case SYBLONGBINARY :
1637
1694
case CASE_ALL_BINARY :
@@ -1895,13 +1952,22 @@ string_to_datetime(const char *instr, int desttype, CONV_RESULT * cr)
1895
1952
dt_time = (t .tm_hour * 60 + t .tm_min ) * 60 + t .tm_sec ;
1896
1953
cr -> dt .dttime = dt_time * 300 + (t .tm_ns / 1000000u * 300 + 150 ) / 1000 ;
1897
1954
return sizeof (TDS_DATETIME );
1898
- } else {
1899
- /* SYBDATETIME4 */
1955
+ }
1956
+ if ( desttype == SYBDATETIME4 ) {
1900
1957
cr -> dt4 .days = dt_days ;
1901
1958
cr -> dt4 .minutes = t .tm_hour * 60 + t .tm_min ;
1902
1959
return sizeof (TDS_DATETIME4 );
1903
1960
}
1904
1961
1962
+ cr -> dta .has_offset = 0 ;
1963
+ cr -> dta .offset = 0 ;
1964
+ cr -> dta .has_date = 1 ;
1965
+ cr -> dta .date = dt_days ;
1966
+ cr -> dta .has_time = 1 ;
1967
+ cr -> dta .time_prec = 7 ; /* TODO correct value */
1968
+ dt_time = (t .tm_hour * 60 + t .tm_min ) * 60 + t .tm_sec ;
1969
+ cr -> dta .time = dt_time * 10000000u + t .tm_ns / 100u ;
1970
+ return sizeof (TDS_DATETIMEALL );
1905
1971
}
1906
1972
1907
1973
static int
@@ -2896,28 +2962,39 @@ day weekday week date
2896
2962
TDSRET
2897
2963
tds_datecrack (TDS_INT datetype , const void * di , TDSDATEREC * dr )
2898
2964
{
2899
-
2900
- const TDS_DATETIME * dt ;
2901
- const TDS_DATETIME4 * dt4 ;
2902
-
2903
2965
int dt_days ;
2904
2966
unsigned int dt_time ;
2905
2967
2906
- int years , months , days , ydays , wday , hours , mins , secs , ms ;
2968
+ int years , months , days , ydays , wday , hours , mins , secs , dms ;
2907
2969
int l , n , i , j ;
2908
2970
2909
- if (datetype == SYBDATETIME ) {
2910
- dt = (const TDS_DATETIME * ) di ;
2971
+ if (datetype == SYBMSDATE || datetype == SYBMSTIME
2972
+ || datetype == SYBMSDATETIME2 || datetype == SYBMSDATETIMEOFFSET ) {
2973
+ const TDS_DATETIMEALL * dta = (const TDS_DATETIMEALL * ) di ;
2974
+ dt_days = (datetype == SYBMSTIME ) ? 0 : dta -> date ;
2975
+ if (datetype == SYBMSTIME ) {
2976
+ dms = 0 ;
2977
+ secs = 0 ;
2978
+ dt_time = 0 ;
2979
+ } else {
2980
+ dms = dta -> time % 10000000u ;
2981
+ dt_time = dta -> time / 10000000u ;
2982
+ secs = dt_time % 60 ;
2983
+ dt_time = dt_time / 60 ;
2984
+ dt_days = dta -> date ;
2985
+ }
2986
+ } else if (datetype == SYBDATETIME ) {
2987
+ const TDS_DATETIME * dt = (const TDS_DATETIME * ) di ;
2911
2988
dt_time = dt -> dttime ;
2912
- ms = ((dt_time % 300 ) * 1000 + 150 ) / 300 ;
2989
+ dms = ((dt_time % 300 ) * 1000 + 150 ) / 300 * 10000u ;
2913
2990
dt_time = dt_time / 300 ;
2914
2991
secs = dt_time % 60 ;
2915
2992
dt_time = dt_time / 60 ;
2916
2993
dt_days = dt -> dtdays ;
2917
2994
} else if (datetype == SYBDATETIME4 ) {
2918
- dt4 = (const TDS_DATETIME4 * ) di ;
2995
+ const TDS_DATETIME4 * dt4 = (const TDS_DATETIME4 * ) di ;
2919
2996
secs = 0 ;
2920
- ms = 0 ;
2997
+ dms = 0 ;
2921
2998
dt_days = dt4 -> days ;
2922
2999
dt_time = dt4 -> minutes ;
2923
3000
} else
@@ -2956,7 +3033,7 @@ tds_datecrack(TDS_INT datetype, const void *di, TDSDATEREC * dr)
2956
3033
dr -> hour = hours ;
2957
3034
dr -> minute = mins ;
2958
3035
dr -> second = secs ;
2959
- dr -> decimicrosecond = ms * 10000u ;
3036
+ dr -> decimicrosecond = dms ;
2960
3037
return TDS_SUCCESS ;
2961
3038
}
2962
3039
0 commit comments