Thread: how to read binary date big endian (BE) in LE machine?

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    7

    how to read binary date big endian (BE) in LE machine?

    Hello maybe it is a neubie question but i have problems reading the real values coming from a binary BE archive in a LE machine (Intel based).
    One of the structures to read is:

    struct s{ //60 bytes
    char a[6];
    char b[6];
    char c[6];
    char d[6];
    char e[6];
    char f[6];
    char g[4];
    struct X x_;
    struct X xr_;
    char h[10];
    }s_;

    i use to obtain the original values:

    a= (((uint64_t)(s_.s.a[0]) << 56
    | (uint64_t)(s_.s.a[1]) << 48
    | (uint64_t)(s_.s.a[2]) << 40
    | (uint64_t)(s_.s.a[3]) << 32
    | (uint64_t)(s_.s.a[4]) << 24
    | (uint64_t)(s_.s.a[5]) << 16) >> 16);

    i use this for all the fields, is that correct? if not, what kind of displacement i must use or where i can find good info about that topic?
    Thank you

  2. #2
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    A char doesn't have "endianness". You need a multi-byte numeric data type to be affected by endianness. Is your array of chars really a multi-byte numeric field? In which case you need to change your structure.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    Excuseme, what do u mean with multibyte numeric field?

  4. #4
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    e.g. typically an int will be 4 bytes. Say you have the decimal value 16909060 stored in an integer. If you were to print out the 4 bytes of that integer in hex, (not the number itself)

    on a big endian machine it would be 04030201
    on a little endian machine it would be 01020304

    Thus you have an endianness problem.

    If you have 4 characters, the machine will store them in the same order regardless of endianness because they aren't a numeric field and aren't treated as such.

    So "ABCD" is stored (in hex) typically as 41424344 on both a little endian and a big endian machine.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    ah ok, no, the values that i must obtain go from -1.e10 to +1.e10, not characters itselfs, they are numbers but are defined as chars

    the binary coded value: integer from 0 to 2 elev (48) - 1

    thanks!

  6. #6
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    If they are numbers, why have you defined them as chars?

    Define them as the correct number types, then we can work on converting them from BE->LE.
    You need to know what type of number it is before you can convert it!

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    i defined as chars just because i need a longitude of 6 bytes for this field. Is there an equivalent representing an integer?
    thanks

  8. #8
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    Are you allowing fractional values for each longitude field (degrees, minutes, seconds) or only integers?

    Code:
    typedef struct LONGITUDE
    {
        short degrees;          /* Where +ve is east, -ve is west */
        unsigned char minutes;  /* 0 - 59 */
        unsigned char seconds;  /* 0 - 59 */
    } LONGITUDE;
    Or

    Code:
    typedef struct LONGITUDE 
    {
        short degrees;            /* Where +ve is east, -ve is west */
        unsigned char minutes;    /* 0.0 - 59 */
        double seconds;           /* 0.0 - 59.99.. */
    } LONGITUDE;
    Or something like that ...
    but not raw chars!
    Last edited by SKeane; 10-09-2006 at 06:43 AM.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    -My values have sign, so i can not define them as unsigned, is that ok? so then, how can i define them if i must obtain a value of 1.e10 to +1.e10 (coded with 6 bytes)?
    Thanks

  10. #10
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    Longitude doesn't have a sign in the minutes or seconds field.

    Do you mean each field can have a value of -1.e10 to +1.e10, or the whole longitude (expressed as a float/double) can have a value of -1.e10 to +1.e10? Because it really can't!

    The range would be -180 to +180 if held as a float/double or

    degrees -180 to +180
    minutes 0 to 59
    seconds 0 to 59

    If broken down into fields.

    Do you really mean longitude?

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    no no sorry, by longitude i mean that the fields are 6 bytes long. Not longitude as u understood (well understood, it s my fault) , that was an error of translation of my spanish sorry.

  12. #12
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    No un problema.

    Is the number a 6-byte integer, in which case you could use LONGLONG (on windows) for 64 bits, or long long on Unix.

    Is the number floating -point, in which case use double.

  13. #13
    Registered User
    Join Date
    Oct 2006
    Posts
    7
    i don t really know. The only thing i have are those specs:

    the Size : 6 bytes
    Value : from -1.0e10m to 1e10m
    Binary coded value : integer from 0 to pow (2,48)-1

    From the values i guess it will be a floating one, but i work in linux environment and the value ot was generated with a BE machine? So, is double correct?

  14. #14
    Registered User SKeane's Avatar
    Join Date
    Sep 2006
    Location
    England
    Posts
    234
    You could store it in a 64-bit integer (as it appears to be a 48-bit integer)

    Here's how I've seen it done in the past on a Windows box.

    Code:
    UINT uint32_to_le(UINT arg)
    {
    	UINT res;
    
    	res =  ((arg >> 24) & 0xFF) +
    		  (((arg >> 16) & 0xFF) <<  8) +
    		  (((arg >>  8) & 0xFF) << 16)+
    		  ( (arg        & 0xFF) << 24);
    
    	return(res);
    }
    
    ULONGLONG uint64_to_le(ULONGLONG arg)
    {
        ULONGLONG res;
        UINT lhs, rhs;
    
    	lhs = (UINT)((arg & (LONGLONG)0xFFFFFFFF00000000) >> 32);
    	rhs = (UINT)(arg & (LONGLONG)0x00000000FFFFFFFF);
    
    	res = ((ULONGLONG)uint32_to_le(rhs) << 32) + (ULONGLONG)uint32_to_le(lhs);
    
        return(res);
    }
    Last edited by SKeane; 10-09-2006 at 09:11 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to read the date & time of a file?
    By megablue in forum C Programming
    Replies: 5
    Last Post: 11-03-2003, 11:58 PM
  2. Binary files read newline (help)
    By Perimeter in forum C++ Programming
    Replies: 2
    Last Post: 02-13-2003, 08:08 AM
  3. Replies: 10
    Last Post: 06-12-2002, 03:15 PM
  4. Read a binary file
    By Sue Paterniti in forum C Programming
    Replies: 8
    Last Post: 04-29-2002, 02:36 AM
  5. read records fron file into a binary tree
    By Kirsten in forum C Programming
    Replies: 1
    Last Post: 04-23-2002, 02:48 PM