Thread: Complex struct organization (network/packet-related)

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    40

    Complex struct organization (network/packet-related)

    Quick little structure organization problem. Basically revolves around how do you define a set of structures with optimal memory layout for networking purposes; set as in, dynamic fields in a struct.

    Constructing a transaction structure which holds a header and optional TLV (Type/Length/Value (networking term)) structs. Though, say, there are 6 different TLV structs and they are only to be included if necessary. So, how do I create a dynamic transaction struct that holds different combinations of TLVs that are contiguous in memory?

    The following is an example if I want to include all the TLVs.

    **NOTE: tlv_artist has a array ptr field. So when malloc'ing the transaction structure I'd do a "sizeof(transaction_t) + artist_name_length)", then memcpy into artist_name[0] so that the memory is all contiguous (no pointers to more data, etc...).

    **Also note that tlv_artist is at the bottom of the transaction struct. This is so that you can properly index after malloc'ing. Otherwise, you couldn't index to fields defined below tlv_artist.

    Code:
    typedef struct tlv_song_size_ {
        int type;
        int length;
        int song_size;
    } tlv_song_size_t;
    
    typedef struct tlv_song_len_ {
        int type;
        int length;
        int song_length;
    } tlv_song_len_t;
    
    typedef struct tlv_artist {
        int type;
        int length;
        char artist_name[0];
    } tlv_artist_t;
    
    typedef struct header_ {
        int version;
        int blah;
    } header_t;
    
    typedef struct transaction_ {
        header_t header;
        tlv_song_size;
        tlv_song_len;
        tlv_artist_t artist;
    } transaction_t;
    Note this works fine. Though, what if I don't need to include a tlv_song_size? What if I don't want to include a tlv_song_len? I could always malloc that structure and fill it, but the memory wouldn't be contiguous then...

    So how do I avoid defining multiple transaction structures that holds different combinations of header + TLVs?

    I sincerely thank you for your advice.

  2. #2
    Registered User
    Join Date
    Jul 2008
    Posts
    133
    Did you try realloc()? Idea would be to allocate buffer (to hold header initialy), see what needs to be added, realloc() buffer (increase it's size), append data, repeat as necessary, send...
    Last edited by rasta_freak; 08-15-2008 at 06:39 PM.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    40
    Looks like I'll have to end up with that implementation. Wish C allowed dynamic structures like described above.

  4. #4
    Registered User
    Join Date
    Jul 2008
    Posts
    133
    Quote Originally Posted by brooksbp View Post
    Looks like I'll have to end up with that implementation. Wish C allowed dynamic structures like described above.
    But it's easy to make a function that will do that (append structure) if (and it seems so) every struct has type/size info, so it's enough to pass just a pointer to function and it will detect struct easily (no explicit type/size info required to pass along).

    EDIT: you can also go fancy and use va_args to handle all stuff in one call
    Last edited by rasta_freak; 08-16-2008 at 09:25 PM.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Would a union help?

  6. #6
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    A union has a fixed size and would not help. A buffer with realloc would be the best solution IMO

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Well it would make it a little smaller. Instead of having those 3 structs (tlv_song_size, tlv_song_len, tlv_artist_t artist) in the transaction_t struct you'd have a union of structs which should take up as much space as whichever one of those structs is largest.
    Obviously in some cases there would be some wasted space, but it might be easier and less error prone in the long run.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting from C to C++
    By Taka in forum C++ Programming
    Replies: 5
    Last Post: 04-08-2009, 02:16 AM
  2. linked list question
    By brb9412 in forum C Programming
    Replies: 16
    Last Post: 01-04-2009, 04:05 PM
  3. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  4. Looking for a way to store listbox data
    By Welder in forum C Programming
    Replies: 20
    Last Post: 11-01-2007, 11:48 PM
  5. Problem from texbook
    By Unregistered in forum C++ Programming
    Replies: 5
    Last Post: 07-26-2002, 04:55 AM