Data structure problems.

Discussion in 'C++' started by tony.fountaine@gmail.com, Dec 6, 2005.

  1. Guest

    I am working on a project to read a Bosch Measurement Data File (MDF).
    The file contains a number of blocks that can be read from the file
    using a baisc structure.

    For example the ID BLOCK is as follows,

    (Data Type) (Number of Elements) (Description)
    CHAR 8 File identifier,
    CHAR 8 Format identifier,
    CHAR 8 Program identifier,
    UINT16 1 Byte order
    UINT16 1 Floating-point
    UINT16 1 Version number
    UINT16 1 Reserved
    CHAR 2 Reserved
    CHAR 30 Reserved

    The measured data is described with a channel group as follows (Link is
    a file offset pointer)

    CHAR 2 Block type identifier, always "CG"
    UINT16 1 Block size of this block in bytes (entire CGBLOCK)
    LINK 1 Pointer to next data Channel group block (CGBLOCK) (NIL
    allowed)
    LINK 1 Pointer to first channel block (CNBLOCK) (NIL allowed)
    LINK 1 Pointer to channel group comment text (TXBLOCK) (NIL allowed)
    UINT16 1 Record ID
    UINT16 1 Number of channels
    UINT16 1 Data record size in bytes (without the record ID), i.e. data
    size of the channel group for each sample
    UINT32 1 Number of records

    This channel group above, defines how big the data record size is and
    how many records are contained. The data record can consist of many
    channels that are described as follows

    CHAR 2 Block type identifier, always "CN"
    UINT16 1 Block size of this block in bytes (entire CNBLOCK)
    LINK 1 Pointer to next channel block (CNBLOCK) of this channel group
    (NIL allowed)
    LINK 1 Pointer to the conversion formula (CCBLOCK) of this signal
    (NIL allowed).
    LINK 1 Reserved
    LINK 1 Reserved
    LINK 1 Pointer to the channel comment (TXBLOCK) of this signal (NIL
    allowed)
    UINT16 1 Channel type 0 = data channel, 1 = time channel for all
    signals of this group (in each channel group, exactly one
    channel must be defined as time channel)
    CHAR 32 Signal name, i.e. the first 32 characters of the ASAM-MCD
    unique name
    CHAR 128 Signal description
    UINT16 1 Number of the first bits [0..n] (bit position within a byte:
    bit 0 is the least significant bit, bit 7 is the most significant bit)
    UINT16 1 Number of bits
    UINT16 1 Signal data type
    0 = unsigned integer
    1 = signed integer (two's complement)
    2,3 = IEEE 754 floating-point format
    7 = String (NULL terminated)
    8 = Byte Array
    BOOL 1 Value range - known implementation value
    REAL 1 Value range - minimum implementation value
    REAL 1 Value range - maximum implementation value
    REAL 1 Rate in which the variable was sampled. Unit
    LINK 1 Pointer to the ASAM-MCD unique name (TXBLOCK) (NIL allowed)
    LINK 1 Pointer to TXBLOCK that contains the signal's display
    identifier (default: NIL; NIL allowed)
    UINT16 1 Byte offset of the signal in the data record in addition to
    bit offset (default value: 0) note: this fields shall only be used if
    the CGBLOCK record size and the actual offset
    is larger than 8192 Bytes to ensure compatibility; it enables to write
    data blocks larger than 8kBytes

    Since I cannot determine in advance what the number of channels are and
    the data format of each channel what is the best way to create the data
    structure in memory. I thought of reading in the raw data to a char
    array. Dynamically allocate arrays for each channel. Then casting the
    char array to the proper data type for each channel and fill the
    arrays. Somehow I believe there must be an easier way to do this. Any
    suggestions?
     
    , Dec 6, 2005
    #1
    1. Advertising

  2. wrote:
    > I am working on a project to read a Bosch Measurement Data File (MDF).
    > The file contains a number of blocks that can be read from the file
    > using a baisc structure.
    >
    > For example the ID BLOCK is as follows,
    >
    > (Data Type) (Number of Elements) (Description)
    > CHAR 8 File identifier,
    > CHAR 8 Format identifier,
    > CHAR 8 Program identifier,
    > UINT16 1 Byte order
    > UINT16 1 Floating-point
    > UINT16 1 Version number
    > UINT16 1 Reserved
    > CHAR 2 Reserved
    > CHAR 30 Reserved


    First step - create a struct.

    typedef char MDF_CHAR8[8];
    typedef char MDF_CHAR2[2];
    typedef char MDF_CHAR30[30];

    struct MDF_UNIT16
    {
    char m_data[2];

    operator unsigned () const
    {
    // endian conversion magic here
    };
    };

    struct ID_BLOCK
    {
    MDF_CHAR8 m_file_identifier;
    MDF_CHAR8 m_format_identifier;
    MDF_CHAR8 m_program_identifier;

    MDF_UINT16 m_byte_order;
    MDF_UINT16 m_floating_point;
    MDF_UINT16 m_version_number;
    MDF_UNIT16 m_reserved_1;
    MDF_CHAR2 m_reserved_2;
    MDF_CHAR30 m_reserved_3;
    };

    Do this for the rest of the "BLOCKS".

    Then you can do simpler operations - like:

    const ID_BLOCK * idblock = reinterpret_cast<const ID_BLOCK *>( data );

    std::cout << idblock->m_version_number;

    There is more stuff like this you can do.

    >
    > The measured data is described with a channel group as follows (Link is
    > a file offset pointer)
    >
    > CHAR 2 Block type identifier, always "CG"
    > UINT16 1 Block size of this block in bytes (entire CGBLOCK)
    > LINK 1 Pointer to next data Channel group block (CGBLOCK) (NIL
    > allowed)
    > LINK 1 Pointer to first channel block (CNBLOCK) (NIL allowed)
    > LINK 1 Pointer to channel group comment text (TXBLOCK) (NIL allowed)
    > UINT16 1 Record ID
    > UINT16 1 Number of channels
    > UINT16 1 Data record size in bytes (without the record ID), i.e. data
    > size of the channel group for each sample
    > UINT32 1 Number of records
    >
    > This channel group above, defines how big the data record size is and
    > how many records are contained. The data record can consist of many
    > channels that are described as follows
    >
    > CHAR 2 Block type identifier, always "CN"
    > UINT16 1 Block size of this block in bytes (entire CNBLOCK)
    > LINK 1 Pointer to next channel block (CNBLOCK) of this channel group
    > (NIL allowed)
    > LINK 1 Pointer to the conversion formula (CCBLOCK) of this signal
    > (NIL allowed).
    > LINK 1 Reserved
    > LINK 1 Reserved
    > LINK 1 Pointer to the channel comment (TXBLOCK) of this signal (NIL
    > allowed)
    > UINT16 1 Channel type 0 = data channel, 1 = time channel for all
    > signals of this group (in each channel group, exactly one
    > channel must be defined as time channel)
    > CHAR 32 Signal name, i.e. the first 32 characters of the ASAM-MCD
    > unique name
    > CHAR 128 Signal description
    > UINT16 1 Number of the first bits [0..n] (bit position within a byte:
    > bit 0 is the least significant bit, bit 7 is the most significant bit)
    > UINT16 1 Number of bits
    > UINT16 1 Signal data type
    > 0 = unsigned integer
    > 1 = signed integer (two's complement)
    > 2,3 = IEEE 754 floating-point format
    > 7 = String (NULL terminated)
    > 8 = Byte Array
    > BOOL 1 Value range - known implementation value
    > REAL 1 Value range - minimum implementation value
    > REAL 1 Value range - maximum implementation value
    > REAL 1 Rate in which the variable was sampled. Unit
    > LINK 1 Pointer to the ASAM-MCD unique name (TXBLOCK) (NIL allowed)
    > LINK 1 Pointer to TXBLOCK that contains the signal's display
    > identifier (default: NIL; NIL allowed)
    > UINT16 1 Byte offset of the signal in the data record in addition to
    > bit offset (default value: 0) note: this fields shall only be used if
    > the CGBLOCK record size and the actual offset
    > is larger than 8192 Bytes to ensure compatibility; it enables to write
    > data blocks larger than 8kBytes
    >
    > Since I cannot determine in advance what the number of channels are and
    > the data format of each channel what is the best way to create the data
    > structure in memory.


    I have no idea. What is a channel ?

    > ... I thought of reading in the raw data to a char
    > array. Dynamically allocate arrays for each channel. Then casting the
    > char array to the proper data type for each channel and fill the
    > arrays.


    Somthing like that would work.

    > ... Somehow I believe there must be an easier way to do this. Any
    > suggestions?


    No, parsing binary data is non trivial.
     
    Gianni Mariani, Dec 6, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Excluded_Middle

    Pointers to structure and array of structure.

    Excluded_Middle, Oct 24, 2004, in forum: C Programming
    Replies:
    4
    Views:
    757
    Martin Ambuhl
    Oct 26, 2004
  2. Leo Nunez
    Replies:
    3
    Views:
    1,229
    Neil Kurzman
    Feb 9, 2005
  3. Replies:
    2
    Views:
    609
  4. Replies:
    9
    Views:
    25,316
    Lal Bahadur Singh
    Nov 11, 2011
  5. A
    Replies:
    27
    Views:
    1,601
    Jorgen Grahn
    Apr 17, 2011
Loading...

Share This Page