Struct with dynamic sized array member

Discussion in 'C++' started by joe, Aug 30, 2011.

  1. joe

    joe Guest

    An external interface is sending over the wire basically a variable
    sized struct, similar to:

    struct ExternalMessage
    {
    int m_numberOfOranges;
    int m_numberOfApples;
    Apple m_foo[=m_numberOfApples];
    Orange m_orange[=m_numberOfOrange];
    };

    Having to access this struct which is of unknown size until it is
    received is not straightforward.

    I was considering trying to use templates to pre-create every possible
    struct layout and use the accessors that way.

    Something like:

    class VarLenBase {};

    template<int NUM_ORANGE,int NUM_APPLE>
    struct VarLenMsg : public VarLenBase
    {
    int m_numberOfOranges;
    int m_numberOfApples;
    Apple m_foo[NUM_APPLE];
    Orange m_orange[NUM_ORANGE];

    // then accessors such as:
    Orange getOrange(int index) { return m_orange[index]; }
    // would just work without counting bytes and hopping
    };

    To pre-create them, i need some sort of mapping of the known params to
    the concrete struct that matches:
    std::map<std::pair<int,int>, VarLenBase*> ;

    But I'm strugglnig how to then use this information to cast the
    received buffer as the type that I now know it is.

    Is there a better way (probably yes). using std::vectors is not the
    answer since i am not in control of the sender, and it has to be sent
    over a network anyway.
    Thanks,
    JC
     
    joe, Aug 30, 2011
    #1
    1. Advertising

  2. joe

    Goran Guest

    On Aug 30, 7:08 pm, joe <> wrote:
    > An external interface is sending over the wire basically a variable
    > sized struct, similar to:
    >
    > struct ExternalMessage
    > {
    >   int m_numberOfOranges;
    >   int m_numberOfApples;
    >   Apple m_foo[=m_numberOfApples];
    >   Orange m_orange[=m_numberOfOrange];
    >
    > };
    >
    > Having to access this struct which is of unknown size until it is
    > received is not straightforward.
    >
    > I was considering trying to use templates to pre-create every possible
    > struct layout and use the accessors that way.
    >
    > Something like:
    >
    > class VarLenBase  {};


    class VarLenBase
    {
    int m_numberOfOranges;
    int m_numberOfApples;
    };

    would probably serve you better.

    But...

    > template<int NUM_ORANGE,int NUM_APPLE>
    > struct VarLenMsg : public VarLenBase
    > {
    >   int m_numberOfOranges;
    >   int m_numberOfApples;
    >   Apple m_foo[NUM_APPLE];
    >   Orange m_orange[NUM_ORANGE];
    >
    >   // then accessors such as:
    >   Orange getOrange(int index)  { return m_orange[index]; }
    >   // would just work without counting bytes and hopping
    >
    > };
    >
    > To pre-create them, i need some sort of mapping of the known params to
    > the concrete struct that matches:
    >   std::map<std::pair<int,int>, VarLenBase*> ;
    >
    > But I'm strugglnig how to then use this information to cast the
    > received buffer as the type that I now know it is.
    >
    > Is there a better way (probably yes).  using std::vectors is not the
    > answer since i am not in control of the sender, and it has to be sent
    > over a network anyway.
    > Thanks,


    Even if you got your idea to work, as soon as wire-representation of
    Apple and Orange isn't fixed size, it wouldn't work again. In other
    words, the total number of "type" combination is massive for any but
    the "smallest" cases.

    I'd advise not to do that. Ever. Separate wire-(disk?) representation
    from actual data you'd use in code. Only try to match the two in
    lowest-level code dedicated to creation of non-wire data
    representation. Do use, however, "internal" representation, for wire-
    reading/writing purposes only; you still need to observe bit-count and
    endiannes issues that Paavo mentions. For example "base" with counts
    only is reasonable IMO. After that, go back to reading off to another
    type of a buffer (Apples).

    e.g.

    // Internal. Matches wire-representation, sizes, layout, and endiannes
    included.
    // Platform-specific.
    struct sizes
    {
    int capples, coranges; // "c" meant "count.
    };

    struct data
    {
    std::vector<apple> apples;
    std::vector<oranges> oranges;
    };

    template<typename T>
    read(stream& s, T* first, size_t count)
    {
    s.read(first, count * sizeof(*first));
    }

    template<typename T>
    read(stream& s, vector<T>& v)
    {
    read(&v[0], v.size());
    }

    data read(stream& str)
    {
    sizes s;
    str.read(&s, sizeof s);
    data result;
    result.apples.resize(s.capples);
    read(s, result.apples);
    result.oranges.resize(s.coranges);
    read(s, result.oranges);
    }

    Goran.
     
    Goran, Aug 31, 2011
    #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. thechaosengine

    Oddly sized sized password textbox

    thechaosengine, Sep 15, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    590
    David Hearn
    Sep 15, 2005
  2. Michael B Allen

    Variable Sized Struct Members?

    Michael B Allen, Sep 26, 2004, in forum: C Programming
    Replies:
    2
    Views:
    254
    Derrick Coetzee
    Sep 26, 2004
  3. Daniel T.

    Dynamic sized array?

    Daniel T., Oct 17, 2006, in forum: C++
    Replies:
    4
    Views:
    326
    Sumit Rajan
    Oct 17, 2006
  4. MartinBroadhurst

    List as a dynamic array of increasing-sized arrays

    MartinBroadhurst, Oct 21, 2010, in forum: C Programming
    Replies:
    13
    Views:
    1,080
    MartinBroadhurst
    Nov 3, 2010
  5. Tuan  Bui
    Replies:
    14
    Views:
    479
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page