"Fossies" - the Fresh Open Source Software Archive

Member "ffe-0.3.9/src/endian.c" (25 May 2008, 4214 Bytes) of package /linux/privat/ffe-0.3.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "endian.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *    ffe - flat file extractor
    3  *
    4  *    Copyright (C) 2008 Timo Savinen
    5  *    This file is part of ffe.
    6  * 
    7  *    ffe is free software; you can redistribute it and/or modify
    8  *    it under the terms of the GNU General Public License as published by
    9  *    the Free Software Foundation; either version 2 of the License, or
   10  *    (at your option) any later version.
   11  *
   12  *    ffe is distributed in the hope that it will be useful,
   13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  *    GNU General Public License for more details.
   16  *
   17  *    You should have received a copy of the GNU General Public License
   18  *    along with ffe; if not, write to the Free Software
   19  *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   20  *
   21  */
   22 
   23 /* $Id: endian.c,v 1.11 2008-05-25 15:23:58 timo Exp $ */
   24 
   25 #include "ffe.h"
   26 #ifdef HAVE_CONFIG_H
   27 #include <config.h>
   28 #endif
   29 #ifdef HAVE_STRING_H
   30 #include <string.h>
   31 #endif
   32 
   33 #define LONG_INT 0x0a0b0c0d
   34 
   35 uint8_t be[4]={0x0a,0x0b,0x0c,0x0d};
   36 uint8_t le[4]={0x0d,0x0c,0x0b,0x0a};
   37 uint8_t pe[4]={0x0b,0x0a,0x0d,0x0c};
   38 
   39 size_t target_size = 16;
   40 uint8_t *target = NULL;
   41 
   42 int 
   43 check_system_endianess()
   44 {
   45     uint32_t l = LONG_INT;
   46 
   47     if(target == NULL) target = xmalloc(target_size); // conversion buffer is reserved with malloc in order to ensure proper aligment
   48 
   49     if(memcmp(&l,be,4) == 0) return F_BIG_ENDIAN;
   50     if(memcmp(&l,le,4) == 0) return F_LITTLE_ENDIAN;
   51     if(memcmp(&l,pe,4) == 0)
   52     {
   53         fprintf(stderr,"Pdp endianess is not supported");
   54     }
   55     return F_UNKNOWN_ENDIAN;
   56 }
   57 
   58 /* Endian change functions, s = source 
   59    returns pointer to aligned and converted number
   60 */
   61 
   62 inline uint8_t *
   63 betole_16(uint8_t *s)
   64 {
   65     target[0] = s[1];
   66     target[1] = s[0];
   67     return target;
   68 }
   69 
   70 inline uint8_t *
   71 letobe_16(uint8_t *s)
   72 {
   73     return betole_16(s);
   74 }
   75 
   76 inline uint8_t *
   77 betole_32(uint8_t *s)
   78 {
   79     target[0] = s[3];
   80     target[1] = s[2];
   81     target[2] = s[1];
   82     target[3] = s[0];
   83     return target;
   84 }
   85 
   86 inline uint8_t *
   87 letobe_32(uint8_t *s)
   88 {
   89     return betole_32(s);
   90 }
   91 
   92 inline uint8_t *
   93 betole_64(uint8_t *s)
   94 {
   95     target[0] = s[7];
   96     target[1] = s[6];
   97     target[2] = s[5];
   98     target[3] = s[4];
   99     target[4] = s[3];
  100     target[5] = s[2];
  101     target[6] = s[1];
  102     target[7] = s[0];
  103     return target;
  104 }
  105 
  106 inline uint8_t *
  107 letobe_64(uint8_t *s)
  108 {
  109     return betole_64(s);
  110 }
  111 
  112 inline uint8_t *
  113 betole_128(uint8_t *s)
  114 {
  115     target[0] = s[15];
  116     target[1] = s[14];
  117     target[2] = s[13];
  118     target[3] = s[12];
  119     target[4] = s[11];
  120     target[5] = s[10];
  121     target[6] = s[9];
  122     target[7] = s[8];
  123     target[8] = s[7];
  124     target[9] = s[6];
  125     target[10] = s[5];
  126     target[11] = s[4];
  127     target[12] = s[3];
  128     target[13] = s[2];
  129     target[14] = s[1];
  130     target[15] = s[0];
  131     return target;
  132 }
  133 
  134 
  135 inline uint8_t *
  136 letobe_128(uint8_t *s)
  137 {
  138     return betole_128(s);
  139 }
  140 
  141 uint8_t *
  142 endian_and_align(uint8_t *s,int t_endian, int s_endian, int bytes)
  143 {
  144     if(t_endian == s_endian || bytes < 2)
  145     {
  146         if(bytes > target_size)
  147         {
  148             while(bytes > target_size) target_size = target_size * 2;
  149             target = xrealloc(target,target_size);
  150         }
  151         memcpy(target,s,bytes);
  152         return target;
  153     }
  154 
  155     if(t_endian == F_BIG_ENDIAN && s_endian == F_LITTLE_ENDIAN && bytes == 2) return letobe_16(s);
  156     if(t_endian == F_LITTLE_ENDIAN && s_endian == F_BIG_ENDIAN && bytes == 2) return betole_16(s);
  157     if(t_endian == F_BIG_ENDIAN && s_endian == F_LITTLE_ENDIAN && bytes == 4) return letobe_32(s);
  158     if(t_endian == F_LITTLE_ENDIAN && s_endian == F_BIG_ENDIAN && bytes == 4) return betole_32(s);
  159     if(t_endian == F_BIG_ENDIAN && s_endian == F_LITTLE_ENDIAN && bytes == 8) return letobe_64(s);
  160     if(t_endian == F_LITTLE_ENDIAN && s_endian == F_BIG_ENDIAN && bytes == 8) return betole_64(s);
  161     if(t_endian == F_BIG_ENDIAN && s_endian == F_LITTLE_ENDIAN && bytes == 16) return letobe_128(s);
  162     if(t_endian == F_LITTLE_ENDIAN && s_endian == F_BIG_ENDIAN && bytes == 16) return betole_128(s);
  163     fprintf(stderr,"%d %d %d\n",s_endian,t_endian,bytes);
  164     panic("Internal endian error",NULL,NULL);
  165     return NULL;
  166 }
  167