00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <libheraia.h>
00025
00026 static gboolean bissextile_year(guint32 year);
00027 static void calc_which_month_day(date_and_time_t *mydate, guint32 day, guint tab_ns_months[12]);
00028 static void which_month_day(date_and_time_t *mydate, guint32 day, gboolean bi);
00029 static guint32 remove_days_from_first_january(guint32 base_year, guint8 base_month, guint8 base_day);
00030 static void which_year_month_day(date_and_time_t *mydate, guint32 days, guint32 base_year, guint base_month, guint8 base_day);
00031 static void make_date_and_time(date_and_time_t *mydate, guchar *data, guint8 len, guint64 nbticks, guint32 base_year, guint base_month, guint8 base_day);
00032 static void transform_bcd_to_human(gchar *bcd, guint8 part, guint8 part_number);
00033
00040 gchar *decode_8bits_signed(guchar *data)
00041 {
00042 gint8 total = 0;
00043
00044 if (data == NULL)
00045 {
00046 return NULL;
00047 }
00048 else
00049 {
00050 memcpy(&total, data, sizeof (guchar));
00051 return g_strdup_printf("%d", total);
00052 }
00053 }
00054
00055
00062 gchar *decode_8bits_unsigned(guchar *data)
00063 {
00064 guint8 total = 0;
00065
00066 if (data == NULL)
00067 {
00068 return NULL;
00069 }
00070 else
00071 {
00072 memcpy(&total, data, sizeof (guchar));
00073 return g_strdup_printf("%u", total);
00074 }
00075 }
00076
00077
00078
00085 gchar *decode_16bits_signed(guchar *data)
00086 {
00087 gint16 total = 0;
00088
00089 if (data == NULL)
00090 {
00091 return NULL;
00092 }
00093 else
00094 {
00095 memcpy(&total, data, 2 * sizeof (guchar));
00096 return g_strdup_printf("%d", total);
00097 }
00098 }
00099
00100
00107 gchar *decode_16bits_unsigned(guchar *data)
00108 {
00109 guint16 total = 0;
00110
00111 if (data == NULL)
00112 {
00113 return NULL;
00114 }
00115 else
00116 {
00117 memcpy(&total, data, 2 * sizeof (guchar));
00118 return g_strdup_printf("%u", total);
00119 }
00120 }
00121
00122
00129 gchar *decode_32bits_signed(guchar *data)
00130 {
00131 gint32 total = 0;
00132
00133 if (data == NULL)
00134 {
00135 return NULL;
00136 }
00137 else
00138 {
00139 memcpy(&total, data, 4 * sizeof (guchar));
00140 return g_strdup_printf("%d", total);
00141 }
00142 }
00143
00144
00151 gchar *decode_32bits_unsigned(guchar *data)
00152 {
00153 guint32 total = 0;
00154
00155 if (data == NULL)
00156 {
00157 return NULL;
00158 }
00159 else
00160 {
00161 memcpy(&total, data, 4 * sizeof (guchar));
00162 return g_strdup_printf("%u", total);
00163 }
00164 }
00165
00172 gchar *decode_64bits_signed(guchar *data)
00173 {
00174 gint64 total = 0;
00175
00176 if (data == NULL)
00177 {
00178 return NULL;
00179 }
00180 else
00181 {
00182 memcpy(&total, data, 8 * sizeof (guchar));
00183 return g_strdup_printf("%lld", total);
00184 }
00185 }
00186
00187
00194 gchar *decode_64bits_unsigned(guchar *data)
00195 {
00196 guint64 total = 0;
00197
00198 if (data == NULL)
00199 {
00200 return NULL;
00201 }
00202 else
00203 {
00204 memcpy(&total, data, 8 * sizeof (guchar));
00205 return g_strdup_printf("%llu", total);
00206 }
00207 }
00208
00209
00213 static gboolean bissextile_year(guint32 year)
00214 {
00215
00216 if ((year % 4) == 0)
00217 {
00218 if ((year % 100) == 0)
00219 {
00220 if ((year % 400) == 0)
00221 {
00222 return TRUE;
00223 }
00224 else
00225 {
00226 return FALSE;
00227 }
00228 }
00229 else
00230 {
00231 return TRUE;
00232 }
00233 }
00234 else
00235 {
00236 return FALSE;
00237 }
00238 }
00239
00244 static void calc_which_month_day(date_and_time_t *mydate, guint32 day, guint tab_ns_months[12])
00245 {
00246 gushort i = 0;
00247
00248 while (i<12 && day > tab_ns_months[i])
00249 {
00250 i++;
00251 }
00252
00253 mydate->month = i + 1;
00254
00255 if (i == 0)
00256 {
00257 mydate->day = 1 + day;
00258 }
00259 else
00260 {
00261 mydate->day = (1 + day) - tab_ns_months[i-1];
00262 }
00263 }
00264
00268 static void which_month_day(date_and_time_t *mydate, guint32 day, gboolean bi)
00269 {
00270
00271 if (bi == TRUE)
00272 {
00273 if (day <= 366)
00274 {
00275 guint tab_ns_months[12] = { 31, 60, 91, 121, 152, 182,
00276 213, 244, 274, 305, 335, 366 } ;
00277 calc_which_month_day(mydate, day, tab_ns_months);
00278 }
00279 else
00280 {
00281 mydate->day = 0;
00282 mydate->month = 0;
00283 }
00284 }
00285 else
00286 {
00287 if (day <= 365)
00288 {
00289 guint tab_ns_months[12] = { 31, 59, 90, 120, 151, 181,
00290 212, 243, 273, 304, 334, 365 };
00291 calc_which_month_day(mydate, day, tab_ns_months);
00292 }
00293 else
00294 {
00295 mydate->day = 0;
00296 mydate->month = 0;
00297 }
00298 }
00299 }
00300
00305 static guint32 remove_days_from_first_january(guint32 base_year, guint8 base_month, guint8 base_day)
00306 {
00307 guint tab_ns_months[11];
00308
00309 if (base_day > 0 && base_day < 32)
00310 {
00311 base_day -= 1;
00312 }
00313 else
00314 {
00315 return 0;
00316 }
00317
00318 tab_ns_months[0] = 31;
00319 if (bissextile_year(base_year))
00320 {
00321 tab_ns_months[1] = 60;
00322 tab_ns_months[2] = 91;
00323 tab_ns_months[3] = 121;
00324 tab_ns_months[4] = 152;
00325 tab_ns_months[5] = 182;
00326 tab_ns_months[6] = 213;
00327 tab_ns_months[7] = 244;
00328 tab_ns_months[8] = 274;
00329 tab_ns_months[9] = 305;
00330 tab_ns_months[10] = 335;
00331 }
00332 else
00333 {
00334 tab_ns_months[1] = 59;
00335 tab_ns_months[2] = 90;
00336 tab_ns_months[3] = 120;
00337 tab_ns_months[4] = 151;
00338 tab_ns_months[5] = 181;
00339 tab_ns_months[6] = 212;
00340 tab_ns_months[7] = 243;
00341 tab_ns_months[8] = 273;
00342 tab_ns_months[9] = 304;
00343 tab_ns_months[10] = 334;
00344 }
00345
00346 if (base_month > 1 && base_month < 13)
00347 {
00348 return (tab_ns_months[base_month-2] + base_day);
00349 }
00350 else if (base_month == 1)
00351 {
00352 return base_day;
00353 }
00354 else
00355 {
00356 return 0;
00357 }
00358 }
00359
00360
00361
00374 static void which_year_month_day (date_and_time_t *mydate, guint32 days, guint32 base_year, guint base_month, guint8 base_day)
00375 {
00376 guint32 modulus = 0;
00377 guint32 reste = 0;
00378 guint32 nbdays = 0;
00379
00380 days -= remove_days_from_first_january(base_year, base_month, base_day);
00381
00382 if (days > 146100)
00383 {
00384 modulus = days / 146100;
00385 mydate->year = modulus * 400;
00386 reste = modulus * 3;
00387 days = days % 146100;
00388 }
00389
00390 modulus = days / 1461;
00391 mydate->year += modulus * 4;
00392 reste += (modulus*4) / 100;
00393 reste += days % 1461;
00394
00395 mydate->year += base_year;
00396 if (bissextile_year(mydate->year))
00397 nbdays = 366;
00398 else
00399 nbdays = 365;
00400
00401 while (reste > nbdays)
00402 {
00403 reste -= nbdays;
00404 mydate->year += 1;
00405 if (bissextile_year(mydate->year))
00406 nbdays = 366;
00407 else
00408 nbdays = 365;
00409 }
00410
00411 which_month_day(mydate, reste, bissextile_year(mydate->year));
00412 }
00413
00414
00422 static gchar *date_printf(date_and_time_t *mydate)
00423 {
00424 return g_strdup_printf("%02u/%02u/%04u - %02u:%02u:%02u", mydate->day, mydate->month, mydate->year, mydate->hour, mydate->minutes, mydate->seconds);
00425 }
00426
00427
00435 gchar *decode_dos_date(guchar *data, date_and_time_t *mydate)
00436 {
00437
00438 if (data == NULL)
00439 {
00440 return NULL;
00441 }
00442 else
00443 {
00444 mydate->year = (data[3] >> 1) + 1980;
00445 mydate->month = ((data[3] & 0x01) << 3) + (data[2] >> 5);
00446 mydate->day = data[2] & 0x1F;
00447 mydate->hour = (data[1] & 0xF8) >> 3;
00448 mydate->minutes = ((data[1] & 0x07) << 3) + ((data[0] & 0xE0) >> 5);
00449 mydate->seconds = (data[0] & 0x1F) << 1;
00450
00451 return date_printf(mydate);
00452 }
00453 }
00454
00455
00467 static void make_date_and_time(date_and_time_t *mydate, guchar *data, guint8 len, guint64 nbticks, guint32 base_year, guint base_month, guint8 base_day)
00468 {
00469 guint64 total = 0;
00470 guint32 days = 0;
00471
00472 memcpy(&total, data, len * sizeof (guchar));
00473
00474 total = (total / nbticks);
00475 days = (guint32) (total / 86400); ;
00476
00477 which_year_month_day(mydate, days, base_year, base_month, base_day);
00478
00479 mydate->hour = ((total % 86400) / 3600);
00480 mydate->minutes = ((total % 3600) / 60);
00481 mydate->seconds = (total % 60);
00482 }
00483
00484
00492 gchar *decode_filetime_date(guchar *data, date_and_time_t *mydate)
00493 {
00494 if (data == NULL)
00495 {
00496 return NULL;
00497 }
00498 else
00499 {
00500 make_date_and_time(mydate, data, 8, 10000000, 1601, 1, 1);
00501 return date_printf(mydate);
00502 }
00503 }
00504
00505
00513 gchar *decode_C_date(guchar *data, date_and_time_t *mydate)
00514 {
00515 if (data == NULL)
00516 {
00517 return NULL;
00518 }
00519 else
00520 {
00521 make_date_and_time(mydate, data, 4, 1, 1970, 1, 1);
00522 return date_printf(mydate);
00523 }
00524 }
00525
00533 gchar *decode_HFS_date(guchar *data, date_and_time_t *mydate)
00534 {
00535 if (data == NULL)
00536 {
00537 return NULL;
00538 }
00539 else
00540 {
00541 make_date_and_time(mydate, data, 4, 1, 1904, 1, 1);
00542 return date_printf(mydate);
00543 }
00544 }
00545
00546
00547
00552 gchar *decode_to_bits(guchar *data)
00553 {
00554
00555 if (data == NULL)
00556 {
00557 return NULL;
00558 }
00559 else
00560 {
00561 return g_strdup_printf("%1u%1u%1u%1u%1u%1u%1u%1u",
00562 (data[0] & 0x80) > 0 ? 1 : 0,
00563 (data[0] & 0x40) > 0 ? 1 : 0,
00564 (data[0] & 0x20) > 0 ? 1 : 0,
00565 (data[0] & 0x10) > 0 ? 1 : 0,
00566 (data[0] & 0x08) > 0 ? 1 : 0,
00567 (data[0] & 0x04) > 0 ? 1 : 0,
00568 (data[0] & 0x02) > 0 ? 1 : 0,
00569 (data[0] & 0x01));
00570 }
00571 }
00572
00573
00580 static void transform_bcd_to_human(gchar *bcd, guint8 part, guint8 part_number)
00581 {
00582 switch (part)
00583 {
00584 case 0 :
00585 bcd[part_number] = '0';
00586 break;
00587 case 1 :
00588 bcd[part_number] = '1';
00589 break;
00590 case 2 :
00591 bcd[part_number] = '2';
00592 break;
00593 case 3 :
00594 bcd[part_number] = '3';
00595 break;
00596 case 4 :
00597 bcd[part_number] = '4';
00598 break;
00599 case 5 :
00600 bcd[part_number] = '5';
00601 break;
00602 case 6 :
00603 bcd[part_number] = '6';
00604 break;
00605 case 7 :
00606 bcd[part_number] = '7';
00607 break;
00608 case 8 :
00609 bcd[part_number] = '8';
00610 break;
00611 case 9 :
00612 bcd[part_number] = '9';
00613 break;
00614 case 10 :
00615 bcd[part_number] = '*';
00616 break;
00617 case 11 :
00618 bcd[part_number] = '#';
00619 break;
00620 case 12 :
00621 bcd[part_number] = 'a';
00622 break;
00623 case 13 :
00624 bcd[part_number] = 'b';
00625 break;
00626 case 14 :
00627 bcd[part_number] = 'c';
00628 break;
00629 case 15 :
00630 bcd[part_number] = ' ';
00631 break;
00632 default :
00633 bcd[part_number] = '?';
00634 break;
00635 }
00636 }
00637
00638
00644 gchar *decode_packed_BCD(guchar *data)
00645 {
00646 guint8 total = 0;
00647 gchar *bcd = NULL;
00648
00649 if (data == NULL)
00650 {
00651 return NULL;
00652 }
00653 else
00654 {
00655 memcpy(&total, data, sizeof(guchar));
00656 bcd = (gchar *) g_malloc0(3 * sizeof(gchar));
00657 transform_bcd_to_human(bcd, (total & 0x0F), 0);
00658 transform_bcd_to_human(bcd, ((total & 0xF0)>>4), 1);
00659 bcd[2] = '\0';
00660
00661 return bcd;
00662 }
00663 }
00664
00665
00666
00667
00687 gboolean swap_bytes(guchar *to_swap, guint first, guint last)
00688 {
00689 guchar aux;
00690
00691 if (first >= last)
00692 {
00693 return TRUE;
00694 }
00695 else
00696 {
00697 aux = to_swap[first];
00698 to_swap[first] = to_swap[last];
00699 to_swap[last] = aux;
00700 return swap_bytes(to_swap, ++first, --last);
00701 }
00702 }
00703
00708 void reverse_byte_order(guchar *to_reverse)
00709 {
00710 guint8 car = (guint8) to_reverse[0];
00711 guint8 aux = 0;
00712
00713 aux = ((car & 0x80) >> 7);
00714 aux += ((car & 0x40) >> 5);
00715 aux += ((car & 0x20) >> 3);
00716 aux += ((car & 0x10) >> 1);
00717 aux += ((car & 0x08) << 1);
00718 aux += ((car & 0x04) << 3);
00719 aux += ((car & 0x02) << 5);
00720 aux += ((car & 0x01) << 7);
00721
00722 to_reverse[0] = (guchar) aux;
00723 }