LTP GCOV extension - code coverage report
Current view: directory - trunk/src - decode.c
Test: coverage.info
Date: 2008-08-24 Instrumented lines: 236
Code covered: 67.8 % Executed lines: 160

       1                 : /* -*- Mode: C; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
       2                 : /*
       3                 :   decode.c
       4                 :   heraia - an hexadecimal file editor and analyser based on ghex
       5                 :  
       6                 :   (C) Copyright 2005 - 2007 Olivier Delhomme
       7                 :   e-mail : heraia@delhomme.org
       8                 :   URL    : http://heraia.tuxfamily.org
       9                 :  
      10                 :   This program is free software; you can redistribute it and/or modify
      11                 :   it under the terms of the GNU General Public License as published by
      12                 :   the Free Software Foundation; either version 2, or  (at your option) 
      13                 :   any later version.
      14                 :  
      15                 :   This program is distributed in the hope that it will be useful,
      16                 :   but WITHOUT ANY WARRANTY;  without even the implied warranty of
      17                 :   MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the
      18                 :   GNU General Public License for more details.
      19                 :  
      20                 :   You should have received a copy of the GNU General Public License
      21                 :   along with this program; if not, write to the Free Software
      22                 :   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
      23                 : */
      24                 : 
      25                 : #include "heraia_types.h"
      26                 : 
      27                 : static gboolean bissextile_year(guint32 year);
      28                 : static void calc_which_month_day(date_and_time_t *mydate, guint32 day, guint tab_ns_months[12]);
      29                 : static void which_month_day(date_and_time_t *mydate, guint32 day, gboolean bi);
      30                 : static guint32 remove_days_from_first_january(guint32 base_year, guint8 base_month, guint8 base_day);
      31                 : static void which_year_month_day(date_and_time_t *mydate, guint32 days, guint32 base_year, guint base_month, guint8 base_day);
      32                 : 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);
      33                 : static void transform_bcd_to_human(gchar *bcd, guint8 part, guint8 part_number);
      34                 : 
      35                 : /**
      36                 :  *  Says whether a year is a leap one or not
      37                 :  */
      38                 : static gboolean bissextile_year(guint32 year)
      39              17 : {
      40                 : 
      41              17 :         if ((year % 4) == 0)
      42                 :                 {
      43               3 :                         if ((year % 100) == 0)
      44                 :                                 {
      45               0 :                                         if ((year % 400) == 0)
      46                 :                                                 {
      47               0 :                                                         return TRUE;
      48                 :                                                 }
      49                 :                                         else
      50                 :                                                 {
      51               0 :                                                         return FALSE;
      52                 :                                                 }
      53                 :                                 }
      54                 :                         else
      55                 :                                 {
      56               3 :                                         return TRUE;
      57                 :                                 }
      58                 :                 }
      59                 :         else
      60                 :                 {
      61              14 :                         return FALSE;
      62                 :                 }
      63                 : }
      64                 : 
      65                 : /**
      66                 :  *  Says, from a number of days (eg 154), which month it is (eg  may)
      67                 :  *  and which day in the corresponding month (eg 2 (leap year) or 3)
      68                 :  */
      69                 : static void calc_which_month_day(date_and_time_t *mydate, guint32 day, guint tab_ns_months[12])
      70                 : {
      71               3 :         gushort i = 0;
      72                 : 
      73              36 :         while (i<12 && day > tab_ns_months[i])
      74                 :                 {
      75              33 :                         i++;
      76                 :                 }
      77                 : 
      78               3 :         mydate->month = i + 1;
      79                 : 
      80               3 :         if (i == 0)
      81                 :                 {
      82               0 :                         mydate->day = 1 + day;
      83                 :                 }
      84                 :         else
      85                 :                 {
      86               3 :                         mydate->day = (1 + day) - tab_ns_months[i-1];
      87                 :                 }
      88                 : }
      89                 : 
      90                 : /**
      91                 :  *  Front end function for the calc_which_month_day function !
      92                 :  */
      93                 : static void which_month_day(date_and_time_t *mydate, guint32 day, gboolean bi)
      94                 : {
      95                 : 
      96               3 :         if (bi == TRUE)
      97                 :                 {
      98               0 :                         if (day <= 366)
      99                 :                                 {                
     100                 :                                         guint tab_ns_months[12] = { 31, 60, 91, 121, 152, 182, 
     101               0 :                                                                                                                  213, 244, 274, 305, 335, 366 } ;
     102                 :                                         calc_which_month_day(mydate, day, tab_ns_months);
     103                 :                                 }
     104                 :                         else
     105                 :                                 {
     106               0 :                                         mydate->day = 0;
     107               0 :                                         mydate->month = 0;
     108                 :                                 }
     109                 :                 }
     110                 :         else
     111                 :                 {
     112               3 :                         if (day <= 365)
     113                 :                                 {
     114                 :                                         guint tab_ns_months[12] = { 31, 59, 90, 120, 151, 181, 
     115               3 :                                                                                                                  212, 243, 273, 304, 334, 365 };
     116                 :                                         calc_which_month_day(mydate, day, tab_ns_months);
     117                 :                                 }
     118                 :                         else
     119                 :                                 {
     120               0 :                                         mydate->day = 0;
     121               0 :                                         mydate->month = 0;
     122                 :                                 }
     123                 :                 }
     124                 : }
     125                 : 
     126                 : /**
     127                 :  *  Returns the number of days since 01/01/base_year
     128                 :  *  eg 15/02/base_year --> 31 + 15 = 46
     129                 :  */
     130                 : static guint32 remove_days_from_first_january(guint32 base_year, guint8 base_month, guint8 base_day)
     131                 : { 
     132                 :         guint tab_ns_months[11];
     133                 :   
     134               3 :         if (base_day > 0 && base_day < 32)
     135                 :                 {
     136               3 :                         base_day -= 1;
     137                 :                 }
     138                 :         else
     139                 :                 {
     140               0 :                         return 0;  /* Obviously something might be wrong if we fall here */
     141                 :                 }
     142                 : 
     143               3 :         tab_ns_months[0] = 31;
     144               3 :         if (bissextile_year(base_year))
     145                 :                 {
     146               1 :                         tab_ns_months[1] = 60;
     147               1 :                         tab_ns_months[2] = 91;
     148               1 :                         tab_ns_months[3] = 121;
     149               1 :                         tab_ns_months[4] = 152;
     150               1 :                         tab_ns_months[5] = 182;
     151               1 :                         tab_ns_months[6] = 213;
     152               1 :                         tab_ns_months[7] = 244;
     153               1 :                         tab_ns_months[8] = 274;
     154               1 :                         tab_ns_months[9] = 305;
     155               1 :                         tab_ns_months[10] = 335;
     156                 :                 }
     157                 :         else
     158                 :                 {
     159               2 :                         tab_ns_months[1] = 59;
     160               2 :                         tab_ns_months[2] = 90;
     161               2 :                         tab_ns_months[3] = 120;
     162               2 :                         tab_ns_months[4] = 151;
     163               2 :                         tab_ns_months[5] = 181;
     164               2 :                         tab_ns_months[6] = 212;
     165               2 :                         tab_ns_months[7] = 243;
     166               2 :                         tab_ns_months[8] = 273;
     167               2 :                         tab_ns_months[9] = 304;
     168               2 :                         tab_ns_months[10] = 334;
     169                 :                 }
     170                 : 
     171               3 :         if (base_month > 1 && base_month < 13)
     172                 :                 {
     173               0 :                         return (tab_ns_months[base_month-2] + base_day);
     174                 :                 }
     175               3 :         else if (base_month == 1)
     176                 :                 {
     177               3 :                         return base_day;
     178                 :                 }
     179                 :         else
     180                 :                 {
     181               0 :                         return 0;
     182                 :                 }
     183                 : }
     184                 : 
     185                 : 
     186                 : 
     187                 : /**
     188                 :  * About date calculation : Leap years are periods of 4 years except
     189                 :  * the years that we can divide by 100 and not 400.
     190                 :  * So we can distinguish 2 periods : one of 400 years and one of 4 years.
     191                 :  *  - we have 100 bissextiles years in a period of 400 years this means that
     192                 :  *    every 400 years we have exactly 146100 days.
     193                 :  *  - we have 1 bissextile year every 4 years : this means that we have exactly
     194                 :  *    1461 days every 4 years.
     195                 :  *  As we can calculate _exactly_ the number of days in a filetime or C_date
     196                 :  *  format, we could calculate _exactly_ the number of periods of 400 years and
     197                 :  *  then the number of periods of 4 years.
     198                 : */
     199                 : static void which_year_month_day (date_and_time_t *mydate, guint32 days, guint32 base_year, guint base_month, guint8 base_day)
     200               3 : {
     201               3 :         guint32 modulus = 0;
     202               3 :         guint32 reste = 0;
     203               3 :         guint32 nbdays = 0;
     204                 :         
     205               6 :         days -= remove_days_from_first_january(base_year, base_month, base_day);
     206                 : 
     207               3 :         if (days > 146100)
     208                 :                 {
     209               1 :                         modulus = days / 146100;        
     210               1 :                         mydate->year = modulus * 400;
     211               1 :                         reste = modulus * 3;     /* To add centuries in the 400 years modulus */
     212               1 :                         days = days % 146100;
     213                 :                 }
     214                 : 
     215               3 :         modulus = days / 1461;
     216               3 :         mydate->year += modulus * 4;
     217               3 :         reste += (modulus*4) / 100;    /* To add centuries */
     218               3 :         reste += days % 1461;
     219                 : 
     220               3 :         mydate->year += base_year;
     221               3 :         if (bissextile_year(mydate->year))
     222               1 :                 nbdays = 366;
     223                 :         else
     224               2 :                 nbdays = 365;
     225                 : 
     226              11 :         while (reste > nbdays)
     227                 :                 {
     228               8 :                         reste -= nbdays; 
     229               8 :                         mydate->year += 1;
     230               8 :                         if (bissextile_year(mydate->year))
     231               1 :                                 nbdays = 366;
     232                 :                         else
     233               7 :                                 nbdays = 365;
     234                 :                 }
     235                 :  
     236               3 :         which_month_day(mydate, reste, bissextile_year(mydate->year));
     237               3 : }
     238                 : 
     239                 : 
     240                 : /**
     241                 :  *  Return a gchar* that contains the date and time
     242                 :  *  encoded from the values contained in the date_and_time_t structure
     243                 :  *  it may be freed when no longer needed
     244                 :  *  We do not use any of the g_date_strftime or strftime function
     245                 :  *  because interpreted dates are not always valid !
     246                 :  */
     247                 : static gchar *date_printf(date_and_time_t *mydate)
     248                 : {
     249               4 :         return g_strdup_printf("%02u/%02u/%04u - %02u:%02u:%02u", mydate->day, mydate->month, mydate->year, mydate->hour, mydate->minutes, mydate->seconds);
     250                 : }
     251                 : 
     252                 : 
     253                 : /**
     254                 :  *  general purpose of this function is to take a 4 byte data stream
     255                 :  *  and convert it as if it is a dos date. If it is not, the result
     256                 :  *  may be funny !
     257                 :  *  data : 4 guchars
     258                 :  *  returns a gchar* that may be freed when no longer needed 
     259                 : */
     260                 : gchar *decode_dos_date(guchar *data, date_and_time_t *mydate)
     261               1 : {
     262                 : 
     263               1 :         if (data == NULL) 
     264                 :                 {
     265               0 :                         return NULL;
     266                 :                 }
     267                 :         else
     268                 :                 {
     269               1 :                         mydate->year = (data[3] >> 1) + 1980;
     270               1 :                         mydate->month = ((data[3] & 0x01) << 3) + (data[2] >> 5);
     271               1 :                         mydate->day = data[2] & 0x1F;
     272               1 :                         mydate->hour = (data[1] & 0xF8) >> 3;
     273               1 :                         mydate->minutes = ((data[1] & 0x07) << 3) + ((data[0] & 0xE0) >> 5);
     274               1 :                         mydate->seconds = (data[0] & 0x1F) << 1;
     275                 : 
     276               1 :                         return date_printf(mydate);
     277                 :                 }
     278                 : }
     279                 : 
     280                 : 
     281                 : /**
     282                 :  *  Reads the data from the stream (specified length !! <= 64 bits )
     283                 :  *   . date_and_time_t *mydate : the resulting date
     284                 :  *   . guchar *data : the stream
     285                 :  *   . guint8 len : length of the stream in bytes ( must be <= 64 bits)
     286                 :  *   . guint64 nbticks : number of ticks per seconds (1, 1000, ...)
     287                 :  *   . guint32 base_year : Epoch year (1970, 1904, ...)
     288                 :  *   . guint8 base_month : Epoch month (january, ...)
     289                 :  *   . guint8 base_day : Epoch day (01, 15, ...)
     290                 :  *  populates the date_and_time_t structure
     291                 : */
     292                 : 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)
     293               3 : {
     294               3 :         guint64 total = 0;
     295               3 :         guint32 days = 0;
     296                 :   
     297               3 :         memcpy(&total, data, len * sizeof (guchar));
     298                 : 
     299               3 :         total = (total / nbticks);         /* 1 seconds represents nbticks */
     300               3 :         days = (guint32) (total / 86400);  /* 86400 seconds a day          */;
     301                 : 
     302               3 :         which_year_month_day(mydate, days, base_year, base_month, base_day);
     303                 : 
     304               3 :         mydate->hour = ((total % 86400) / 3600);  /* 3600 seconds is one hour out of one day */
     305               3 :         mydate->minutes = ((total % 3600) / 60);  /* 60 seconds is one minute out of one hour */
     306               3 :         mydate->seconds = (total % 60);
     307               3 : }
     308                 : 
     309                 : 
     310                 : /**
     311                 :  *  general purpose of this function is to take a 8 byte data stream
     312                 :  *  and convert it as if it is a filetime date. If it is not, the result
     313                 :  *  may be funny ! Counting 100th of nanoseconds from 01/01/1601
     314                 :  *  data : 8 guchars
     315                 :  *  returns a gchar* that may be freed when no longer needed 
     316                 : */
     317                 : gchar *decode_filetime_date(guchar *data, date_and_time_t *mydate)
     318               1 : {
     319               1 :         if (data == NULL)
     320                 :                 {
     321               0 :                         return NULL;
     322                 :                 }
     323                 :         else
     324                 :                 {
     325               1 :                         make_date_and_time(mydate, data, 8, 10000000, 1601, 1, 1);
     326               1 :                         return date_printf(mydate);
     327                 :                 }
     328                 : }
     329                 : 
     330                 : 
     331                 : /**
     332                 :  *  general purpose of this function is to take a 4 byte data stream
     333                 :  *  and convert it as if it is a C date. If it is not, the result may 
     334                 :  *  be funny ! Counting seconds from 01/01/1970
     335                 :  *  data : 4 guchars
     336                 :  *  returns a gchar* that may be freed when no longer needed 
     337                 : */
     338                 : gchar *decode_C_date(guchar *data, date_and_time_t *mydate)
     339               1 : { 
     340               1 :         if (data == NULL)
     341                 :                 {
     342               0 :                         return NULL;
     343                 :                 }
     344                 :         else
     345                 :                 {
     346               1 :                         make_date_and_time(mydate, data, 4, 1, 1970, 1, 1);
     347               1 :                         return date_printf(mydate);
     348                 :                 }
     349                 : }
     350                 : 
     351                 : /**
     352                 :  *  general purpose of this function is to take a 4 byte data stream
     353                 :  *  and convert it as if it is a HFS date. If it is not, the result may 
     354                 :  *  be funny ! Counting seconds 01/01/1904
     355                 :  *  data : 4 guchars
     356                 :  *  returns a gchar* that may be freed when no longer needed 
     357                 : */
     358                 : gchar *decode_HFS_date(guchar *data, date_and_time_t *mydate)
     359               1 : {
     360               1 :         if (data == NULL)
     361                 :                 {
     362               0 :                         return NULL;
     363                 :                 }
     364                 :         else
     365                 :                 {
     366               1 :                         make_date_and_time(mydate, data, 4, 1, 1904, 1, 1);
     367               1 :                         return date_printf(mydate);
     368                 :                 }
     369                 : }
     370                 : 
     371                 : 
     372                 : 
     373                 : /**
     374                 :  *  decodes the stream represented by *data (one byte) to a
     375                 :  *  string containing eight 0 or 1 (Little Endian style)
     376                 :  */
     377                 : gchar *decode_to_bits(guchar *data)
     378               1 : {
     379                 : 
     380               1 :         if (data == NULL)
     381                 :                 {
     382               0 :                         return NULL;
     383                 :                 }
     384                 :         else
     385                 :                 {
     386               1 :                         return g_strdup_printf("%1u%1u%1u%1u%1u%1u%1u%1u",
     387                 :                                                                                   (data[0] & 0x80) > 0 ? 1 : 0, 
     388                 :                                                                                   (data[0] & 0x40) > 0 ? 1 : 0,
     389                 :                                                                                   (data[0] & 0x20) > 0 ? 1 : 0, 
     390                 :                                                                                   (data[0] & 0x10) > 0 ? 1 : 0,
     391                 :                                                                                   (data[0] & 0x08) > 0 ? 1 : 0, 
     392                 :                                                                                   (data[0] & 0x04) > 0 ? 1 : 0,
     393                 :                                                                                   (data[0] & 0x02) > 0 ? 1 : 0, 
     394                 :                                                                                   (data[0] & 0x01));
     395                 :                 }
     396                 : }
     397                 : 
     398                 : 
     399                 : /**
     400                 :  *  transcribes the bcd number "part" into a 
     401                 :  *  gchar * human readable string
     402                 :  *  Coding style is from ETSI GSM 04.08 ETS 300557 p387
     403                 :  *  TODO : give choice of coding style (eg for numbers >=10)
     404                 :  */
     405                 : static void transform_bcd_to_human(gchar *bcd, guint8 part, guint8 part_number)
     406               2 : {
     407               2 :         switch (part)
     408                 :                 {
     409                 :                 case 0 :
     410               0 :                         bcd[part_number] = '0';
     411               0 :                         break;
     412                 :                 case 1 :
     413               0 :                         bcd[part_number] = '1';
     414               0 :                         break;
     415                 :                 case 2 :
     416               1 :                         bcd[part_number] = '2';
     417               1 :                         break;
     418                 :                 case 3 :
     419               0 :                         bcd[part_number] = '3';
     420               0 :                         break;
     421                 :                 case 4 :
     422               0 :                         bcd[part_number] = '4';
     423               0 :                         break;
     424                 :                 case 5 :
     425               0 :                         bcd[part_number] = '5';
     426               0 :                         break;
     427                 :                 case 6 :
     428               0 :                         bcd[part_number] = '6';
     429               0 :                         break;
     430                 :                 case 7 :
     431               0 :                         bcd[part_number] = '7';
     432               0 :                         break;
     433                 :                 case 8 :
     434               0 :                         bcd[part_number] = '8';
     435               0 :                         break;
     436                 :                 case 9 :
     437               0 :                         bcd[part_number] = '9';
     438               0 :                         break;
     439                 :                 case 10 :
     440               0 :                         bcd[part_number] = '*';
     441               0 :                         break;
     442                 :                 case 11 :
     443               0 :                         bcd[part_number] = '#';
     444               0 :                         break;
     445                 :                 case 12 :
     446               0 :                         bcd[part_number] = 'a';
     447               0 :                         break;
     448                 :                 case 13 :
     449               0 :                         bcd[part_number] = 'b';
     450               0 :                         break;
     451                 :                 case 14 :
     452               0 :                         bcd[part_number] = 'c';
     453               0 :                         break;
     454                 :                 case 15 :
     455               1 :                         bcd[part_number] = ' ';  /* Endmark */
     456               1 :                         break;
     457                 :                 default :
     458               0 :                         bcd[part_number] = '?';  /* This default case should never happen */
     459                 :                         break;
     460                 :                 }
     461               2 : }
     462                 : 
     463                 : 
     464                 : /**
     465                 :  *  Decode one byte as a Packed BCD (Binary Coded Decimal)
     466                 :  *  and return a gchar* that me be freed when no longer 
     467                 :  *  needed
     468                 :  */
     469                 : gchar *decode_packed_BCD(guchar *data)
     470               1 : {
     471               1 :         guint8 total = 0;
     472               1 :         gchar *bcd = NULL;
     473                 : 
     474               1 :         if (data == NULL)
     475                 :                 {
     476               0 :                         return NULL;
     477                 :                 }
     478                 :         else
     479                 :                 {
     480               1 :                         memcpy(&total, data, sizeof(guchar));
     481               1 :                         bcd = (gchar *) g_malloc0(3 * sizeof(gchar));
     482               1 :                         transform_bcd_to_human(bcd, (total & 0x0F), 0);
     483               1 :                         transform_bcd_to_human(bcd, ((total & 0xF0)>>4), 1);
     484               1 :                         bcd[2] = '\0';
     485                 : 
     486               1 :                         return bcd;
     487                 :                 }
     488                 : }
     489                 : 
     490                 : 
     491                 : /**
     492                 :  *  general purpose of this function is to take a 1 byte data stream
     493                 :  *  and convert it as if it is an 8 bits signed number
     494                 :  *  data : 1 guchar
     495                 :  *  returns a gchar* that may be freed when no longer needed 
     496                 :  */
     497                 : gchar *decode_8bits_signed(guchar *data)
     498               1 : {
     499               1 :         gint8 total = 0;
     500                 : 
     501               1 :         if (data == NULL)
     502                 :                 {
     503               0 :                         return NULL;
     504                 :                 }
     505                 :         else
     506                 :                 {
     507               1 :                         memcpy(&total, data, sizeof (guchar));
     508               1 :                         return g_strdup_printf("%d", total);
     509                 :                 }
     510                 : }
     511                 : 
     512                 : 
     513                 : /**
     514                 :  *  general purpose of this function is to take a 1 byte data stream
     515                 :  *  and convert it as if it is an 8 bits unsigned number
     516                 :  *  data : 1 guchar
     517                 :  *  returns a gchar* that may be freed when no longer needed
     518                 : */
     519                 : gchar *decode_8bits_unsigned(guchar *data)
     520               1 : {
     521               1 :         guint8 total = 0;
     522                 : 
     523               1 :         if (data == NULL)
     524                 :                 {
     525               0 :                         return NULL;
     526                 :                 }
     527                 :         else
     528                 :                 {
     529               1 :                         memcpy(&total, data, sizeof (guchar));
     530               1 :                         return g_strdup_printf("%u", total);
     531                 :                 }
     532                 : }
     533                 : 
     534                 : 
     535                 : /**
     536                 :  *  general purpose of this function is to take a 2 byte data stream
     537                 :  *  and convert it as if it is a 16 bits signed number
     538                 :  *  data : 2 guchars
     539                 :  *  returns a gchar* that may be freed when no longer needed
     540                 :  */
     541                 : gchar *decode_16bits_signed(guchar *data)
     542               1 : {
     543               1 :         gint16 total = 0;
     544                 : 
     545               1 :         if (data == NULL)
     546                 :                 {
     547               0 :                         return NULL;
     548                 :                 }
     549                 :         else
     550                 :                 {
     551               1 :                         memcpy(&total, data, 2 * sizeof (guchar));
     552               1 :                         return g_strdup_printf("%d", total);
     553                 :                 }
     554                 : }
     555                 : 
     556                 : 
     557                 : /**
     558                 :  *  general purpose of this function is to take a 2 byte data stream
     559                 :  *  and convert it as if it is a 16 bits unsigned number
     560                 :  *  data : 2 guchars
     561                 :  *  returns a gchar* that may be freed when no longer needed
     562                 :  */
     563                 : gchar *decode_16bits_unsigned(guchar *data)
     564               1 : {
     565               1 :         guint16 total = 0;
     566                 : 
     567               1 :         if (data == NULL)
     568                 :                 {
     569               0 :                         return NULL;
     570                 :                 }
     571                 :         else
     572                 :                 {
     573               1 :                         memcpy(&total, data, 2 * sizeof (guchar));
     574               1 :                         return g_strdup_printf("%u", total);
     575                 :                 }
     576                 : }
     577                 : 
     578                 : 
     579                 : /**
     580                 :  *  general purpose of this function is to take a 4 byte data stream
     581                 :  *  and convert it as if it is a 32 bits signed number
     582                 :  *  data : 4 guchars
     583                 :  *  returns a gchar* that may be freed when no longer needed
     584                 : */
     585                 : gchar *decode_32bits_signed(guchar *data)
     586               1 : {
     587               1 :         gint32 total = 0;
     588                 : 
     589               1 :         if (data == NULL)
     590                 :                 {
     591               0 :                         return NULL;
     592                 :                 }
     593                 :         else
     594                 :                 {
     595               1 :                         memcpy(&total, data, 4 * sizeof (guchar));
     596               1 :                         return g_strdup_printf("%d", total);
     597                 :                 }
     598                 : }
     599                 : 
     600                 : 
     601                 : /**
     602                 :  *  general purpose of this function is to take a 4 byte data stream
     603                 :  *  and convert it as if it is a 32 bits unsigned number
     604                 :  *  data : 4 guchars
     605                 :  *  returns a gchar* that may be freed when no longer needed
     606                 : */
     607                 : gchar *decode_32bits_unsigned(guchar *data)
     608               1 : {
     609               1 :         guint32 total = 0;
     610                 : 
     611               1 :         if (data == NULL)
     612                 :                 {
     613               0 :                         return NULL;
     614                 :                 }
     615                 :         else
     616                 :                 {
     617               1 :                         memcpy(&total, data, 4 * sizeof (guchar));
     618               1 :                         return g_strdup_printf("%u", total);
     619                 :                 }
     620                 : }
     621                 : 
     622                 : /**
     623                 :  *  general purpose of this function is to take a 8 byte data stream
     624                 :  *  and convert it as if it is a 64 bits signed number
     625                 :  *  data : 8 guchars
     626                 :  *  returns a gchar* that may be freed when no longer needed
     627                 : */
     628                 : gchar *decode_64bits_signed(guchar *data)
     629               1 : {
     630               1 :         gint64 total = 0;
     631                 : 
     632               1 :         if (data == NULL)
     633                 :                 {
     634               0 :                         return NULL;
     635                 :                 }
     636                 :         else
     637                 :                 {
     638               1 :                         memcpy(&total, data, 8 * sizeof (guchar));
     639               1 :                         return g_strdup_printf("%lld", total);
     640                 :                 }
     641                 : }
     642                 : 
     643                 : 
     644                 : /**
     645                 :  *  general purpose of this function is to take a 8 byte data stream
     646                 :  *  and convert it as if it is a 64 bits unsigned number
     647                 :  *  data : 8 guchars
     648                 :  *  returns a gchar* that may be freed when no longer needed
     649                 : */
     650                 : gchar *decode_64bits_unsigned(guchar *data)
     651               1 : {
     652               1 :         guint64 total = 0;
     653                 : 
     654               1 :         if (data == NULL)
     655                 :                 {
     656               0 :                         return NULL;
     657                 :                 }
     658                 :         else
     659                 :                 {
     660               1 :                         memcpy(&total, data, 8 * sizeof (guchar));
     661               1 :                         return g_strdup_printf("%llu", total);
     662                 :                 }
     663                 : }
     664                 : 
     665                 : 
     666                 : /**
     667                 :  *  Swap bytes from the buffer to_swap
     668                 :  *  recursive function !!
     669                 :  *  call with first = 0 and last = last byte of buffer to swap
     670                 :  */
     671                 : gboolean swap_bytes(guchar *to_swap, guint first, guint last)
     672               0 : {
     673                 :         guchar aux;
     674                 : 
     675               0 :         if (first >= last)
     676                 :                 {
     677               0 :                         return TRUE;
     678                 :                 }
     679                 :         else
     680                 :                 {
     681               0 :                         aux = to_swap[first];
     682               0 :                         to_swap[first] = to_swap[last];
     683               0 :                         to_swap[last] = aux;
     684               0 :                         return swap_bytes(to_swap, ++first, --last);
     685                 :                 }
     686                 : }
     687                 : 
     688                 : /**
     689                 :  *  Reverse the byte order LSB -> MSB in MSB -> LSB
     690                 :  *  12345678 in 87654321
     691                 :  */
     692                 : void reverse_byte_order(guchar *to_reverse)
     693               0 : {
     694               0 :         guint8 car = (guint8) to_reverse[0];
     695               0 :         guint8 aux = 0;
     696                 : 
     697               0 :         aux = ((car & 0x80) >> 7);
     698               0 :         aux += ((car & 0x40) >> 5);
     699               0 :         aux += ((car & 0x20) >> 3);
     700               0 :         aux += ((car & 0x10) >> 1);
     701               0 :         aux += ((car & 0x08) << 1);
     702               0 :         aux += ((car & 0x04) << 3);
     703               0 :         aux += ((car & 0x02) << 5);
     704               0 :         aux += ((car & 0x01) << 7);
     705                 : 
     706               0 :         to_reverse[0] = (guchar) aux;
     707               0 : }

Generated by: LTP GCOV extension version 1.6