1 <!-- ##### SECTION Title ##### -->
4 <!-- ##### SECTION Short_Description ##### -->
7 <!-- ##### SECTION Long_Description ##### -->
8 <para>In order to allow GRAS to send data over the network (or simply to
9 dupplicate it in SG), you have to describe the structure of data attached
10 with each message. This mecanism is stolen from NWS message passing
13 <para>For each message, you have to declare a structure representing the
14 data to send as payload with the message.</para>
17 <title>Sending (or receiving) simple structures</title>
18 <para>Let's imagin you want to declare a <command>STORE_STATE</command>
19 message, which will send some data to the memory server for inclusion in
20 the database. Here is the structure we want to send:</para>
24 char id[STATE_NAME_SIZE];
32 <para>And here is the structure description GRAS needs to be able to send
33 this over the network:</para>
36 const static DataDescriptor stateDescriptor[] =
37 {SIMPLE_MEMBER(CHAR_TYPE, STATE_NAME_SIZE, offsetof(struct state, id)),
38 SIMPLE_MEMBER(INT_TYPE, 1, offsetof(struct state, rec_size)),
39 SIMPLE_MEMBER(INT_TYPE, 1, offsetof(struct state, rec_count)),
40 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(struct state, seq_no)),
41 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(struct state, time_out))};
44 <para>Contrary to what one could think when you first see it, it's pretty
45 easy. A structure descriptor is a list of descriptions, describing each
46 field of the structure. For example, for the first field, you say that
47 the base type is <command>CHAR_TYPE</command>, that there is
48 <command>STATE_NAME_SIZE</command> element of this type and that it's
49 position in the structure is computed by <command>offsetof(struct state,
50 id)</command>. This leads to two remarks:</para>
54 <para>it's impossible to send dynamic sized strings that way. It's a
55 known limitation, but I think we can live with it.</para>
58 <para>Yes, the <command>offsetof(struct state, id)</command>
59 construction is C ANSI and is portable.</para>
65 <title>Sending (or receiving) complex structure</title>
66 <para>How to send non-flat structures, do you ask? It's not harder. Let's
67 imagin you want to send the following structure:</para>
71 unsigned long address;
76 char name[MAX_CLIQUE_NAME_SIZE];
79 char skill[MAX_SKILL_SIZE];
80 char options[MAX_OPTIONS_SIZE];
83 CliqueMember members[MAX_MEMBERS];
89 <para>As you can see, this structure contains an array of another user
90 defined structure. To be able to send <command>struct Clique</command>,
91 you have to describe each structures that way:</para>
94 static const DataDescriptor cliqueMemberDescriptor[] =
95 {SIMPLE_MEMBER(UNSIGNED_LONG_TYPE, 1, offsetof(CliqueMember, address)),
96 SIMPLE_MEMBER(UNSIGNED_LONG_TYPE, 1, offsetof(CliqueMember, port))};
98 static const DataDescriptor cliqueDescriptor[] =
99 {SIMPLE_MEMBER(CHAR_TYPE, MAX_CLIQUE_NAME_SIZE, offsetof(Clique, name)),
100 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(Clique, whenGenerated)),
101 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(Clique, instance)),
102 SIMPLE_MEMBER(CHAR_TYPE, MAX_SKILL_SIZE, offsetof(Clique, skill)),
103 SIMPLE_MEMBER(CHAR_TYPE, MAX_OPTIONS_SIZE, offsetof(Clique, options)),
104 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(Clique, period)),
105 SIMPLE_MEMBER(DOUBLE_TYPE, 1, offsetof(Clique, timeOut)),
106 {STRUCT_TYPE, MAX_MEMBERS, offsetof(Clique, members),
107 (DataDescriptor *)&cliqueMemberDescriptor, cliqueMemberDescriptorLength,
108 PAD_BYTES(CliqueMember, port, unsigned long, 1)},
109 SIMPLE_MEMBER(UNSIGNED_INT_TYPE, 1, offsetof(Clique, count)),
110 SIMPLE_MEMBER(UNSIGNED_INT_TYPE, 1, offsetof(Clique, leader))};
113 <para>So, even if less natural, it is possible to send structures
114 containing structures with these tools.</para>
116 <para>You can see that it's not only impossible to send dynamic-sized
117 strings, it impossible to send dynamic-sized arrays. Here,
118 <command>MAX_MEMBERS</command> is the maximum of members a clique can
119 contain. In NWS, this value is defined to 100. <warning><para>I'm not
120 sure, but I think that all the 100 values are sent each time, even if
121 there is only 3 non-null members. Yes, that's
122 bad.</para></warning></para>
124 <warning><para>The DataDescriptor_t MUST be const. Malloc'ing them and
125 then casting them on argument passing IS NOT OK. This is because we get
126 the number of elements in the array with the sizeof(dd)/sizeof(dd[0]).
130 <!-- ##### SECTION See_Also ##### -->
135 <!-- ##### ENUM DataTypes ##### -->
148 @UNSIGNED_SHORT_TYPE:
151 <!-- ##### MACRO SIMPLE_DATA ##### -->
160 <!-- ##### MACRO SIMPLE_MEMBER ##### -->
170 <!-- ##### MACRO PAD_BYTES ##### -->