@@ -107,6 +107,37 @@ float float16to32(float16_s f16) {
107
107
return f32 .v ;
108
108
}
109
109
110
+ #pragma pack(4)
111
+ typedef union {
112
+ u16 num ;
113
+ struct {
114
+ u32 day : 5 ;
115
+ u32 month : 4 ;
116
+ u32 year : 7 ;
117
+ } date ;
118
+ } ms_date ;
119
+
120
+ typedef union {
121
+ u16 num ;
122
+ struct {
123
+ u32 second : 5 ;
124
+ u32 minute : 6 ;
125
+ u32 hour : 5 ;
126
+ } time ;
127
+ } ms_time ;
128
+
129
+ typedef union {
130
+ u32 num ;
131
+ struct {
132
+ u32 second : 5 ;
133
+ u32 minute : 6 ;
134
+ u32 hour : 5 ;
135
+ u32 day : 5 ;
136
+ u32 month : 4 ;
137
+ u32 year : 7 ;
138
+ } val ;
139
+ } ms_datetime ;
140
+ #pragma pack()
110
141
111
142
#define ASSERT_SI_RANGE (v , n ) if (VAL_INT64(v) < (- (i64)n) || VAL_INT64(v) > (i64)n) Trap1(RE_OUT_OF_RANGE, v);
112
143
#define ASSERT_UI_RANGE (v , n ) if (VAL_INT32(v) > n) Trap1(RE_OUT_OF_RANGE, v);
@@ -204,8 +235,13 @@ static REBCNT EncodedU32_Size(u32 value) {
204
235
REBCNT n , count , index , tail , tail_new ;
205
236
i32 i , len ;
206
237
u64 u ;
238
+ i64 si ;
207
239
u32 ulong ;
208
240
241
+ ms_datetime * msdt = NULL ;
242
+ ms_date * msd = NULL ;
243
+ ms_time * mst = NULL ;
244
+
209
245
REBVAL * value , * next ;
210
246
REBVAL * data ;
211
247
REBSER * blk = NULL ; //used to store results of the read action
@@ -472,6 +508,24 @@ static REBCNT EncodedU32_Size(u32 value) {
472
508
value -- ; //there is no argument so no next
473
509
count += 4 ;
474
510
break ;
511
+
512
+ case SYM_MSDOS_DATE :
513
+ if (!IS_DATE (next )) goto error ; // only date allowed
514
+ //continue..
515
+ case SYM_MSDOS_TIME :
516
+ if (IS_DATE (next ) || IS_TIME (next )) {
517
+ count += 2 ;
518
+ continue ;
519
+ }
520
+ goto error ;
521
+
522
+ case SYM_MSDOS_DATETIME :
523
+ if (IS_DATE (next ) || IS_TIME (next )) {
524
+ count += 4 ;
525
+ continue ;
526
+ }
527
+ goto error ;
528
+
475
529
case SYM_RANDOM_BYTES :
476
530
if (IS_INTEGER (next )) {
477
531
count += VAL_INT32 (next );
@@ -751,6 +805,52 @@ static REBCNT EncodedU32_Size(u32 value) {
751
805
cp [0 ] = bp [3 ]; cp [1 ] = bp [2 ]; cp [2 ] = bp [1 ]; cp [3 ] = bp [0 ];
752
806
#endif
753
807
break ;
808
+
809
+ case SYM_MSDOS_DATE :
810
+ msd = (ms_date * )cp ;
811
+ msd -> date .year = VAL_YEAR (next ) - 1980 ;
812
+ msd -> date .month = VAL_MONTH (next );
813
+ msd -> date .day = VAL_DAY (next );
814
+ n = 2 ;
815
+ break ;
816
+
817
+ case SYM_MSDOS_TIME :
818
+ if (VAL_TIME (next ) == NO_TIME ) {
819
+ cp [0 ] = 0 ;
820
+ cp [1 ] = 0 ;
821
+ } else {
822
+ mst = (ms_time * )cp ;
823
+ si = VAL_TIME (next ) / SEC_SEC ;
824
+ mst -> time .hour = (u32 )(si / 3600 );
825
+ si -= 3600 * (i64 )mst -> time .hour ;
826
+ mst -> time .minute = (u32 )(si / 60 );
827
+ si -= 60 * (i64 )mst -> time .minute ;
828
+ mst -> time .second = (u32 )si / 2 ; // this format has only 2 sec resolution!
829
+ }
830
+ n = 2 ;
831
+ break ;
832
+
833
+ case SYM_MSDOS_DATETIME :
834
+ msdt = (ms_datetime * )cp ;
835
+ msdt -> val .year = VAL_YEAR (next ) - 1980 ;
836
+ msdt -> val .month = VAL_MONTH (next );
837
+ msdt -> val .day = VAL_DAY (next );
838
+ if (VAL_TIME (next ) == NO_TIME ) {
839
+ msdt -> val .hour = 0 ;
840
+ msdt -> val .minute = 0 ;
841
+ msdt -> val .second = 0 ;
842
+ }
843
+ else {
844
+ si = VAL_TIME (next ) / SEC_SEC ;
845
+ msdt -> val .hour = (u32 )(si / 3600 );
846
+ si -= 3600 * (i64 )msdt -> val .hour ;
847
+ msdt -> val .minute = (u32 )(si / 60 );
848
+ si -= 60 * (i64 )msdt -> val .minute ;
849
+ msdt -> val .second = (u32 )si / 2 ; // this format has only 2 sec resolution!
850
+ }
851
+ n = 4 ;
852
+ break ;
853
+
754
854
case SYM_RANDOM_BYTES :
755
855
if (IS_INTEGER (next )) {
756
856
n = (REBCNT )VAL_INT32 (next );
@@ -1269,6 +1369,45 @@ static REBCNT EncodedU32_Size(u32 value) {
1269
1369
VAL_SET (temp , REB_DECIMAL );
1270
1370
VAL_DECIMAL (temp ) = ((float )i / 65536.0f );
1271
1371
break ;
1372
+ case SYM_MSDOS_DATETIME :
1373
+ n = 4 ;
1374
+ ASSERT_READ_SIZE (value , cp , ep , n );
1375
+ msdt -> num = ((u32 )cp [0 ] << 0 ) |
1376
+ ((u32 )cp [1 ] << 8 ) |
1377
+ ((u32 )cp [2 ] << 16 ) |
1378
+ ((u32 )cp [3 ] << 24 ) ;
1379
+ VAL_SET (temp , REB_DATE );
1380
+ VAL_YEAR (temp ) = msdt -> val .year + 1980 ;
1381
+ VAL_MONTH (temp ) = msdt -> val .month ;
1382
+ VAL_DAY (temp ) = msdt -> val .day ;
1383
+ VAL_ZONE (temp ) = 0 ;
1384
+ VAL_TIME (temp ) = TIME_SEC (msdt -> val .second * 2
1385
+ + msdt -> val .minute * 60
1386
+ + msdt -> val .hour * 3600 );
1387
+ break ;
1388
+ case SYM_MSDOS_DATE :
1389
+ n = 2 ;
1390
+ ASSERT_READ_SIZE (value , cp , ep , n );
1391
+ msd -> num = ((u16 )cp [0 ] << 0 ) |
1392
+ ((u16 )cp [1 ] << 8 ) ;
1393
+ CLEARS (temp );
1394
+ VAL_SET (temp , REB_DATE );
1395
+ VAL_YEAR (temp ) = msd -> date .year + 1980 ;
1396
+ VAL_MONTH (temp ) = msd -> date .month ;
1397
+ VAL_DAY (temp ) = msd -> date .day ;
1398
+ VAL_TIME (temp ) = NO_TIME ;
1399
+ break ;
1400
+ case SYM_MSDOS_TIME :
1401
+ n = 2 ;
1402
+ ASSERT_READ_SIZE (value , cp , ep , n );
1403
+ mst -> num = ((u16 )cp [0 ] << 0 ) |
1404
+ ((u16 )cp [1 ] << 8 ) ;
1405
+ CLEARS (temp );
1406
+ VAL_SET (temp , REB_TIME );
1407
+ VAL_TIME (temp ) = TIME_SEC (mst -> time .second * 2 // this format has only 2 sec resolution!
1408
+ + mst -> time .minute * 60
1409
+ + mst -> time .hour * 3600 );
1410
+ break ;
1272
1411
1273
1412
default :
1274
1413
Trap1 (RE_INVALID_SPEC , value );
0 commit comments