License / Documentation home / Help and feedback |
The MIT binary data object can be used to transmit arbitrary structures from server to server, among other things. In this set of tools, we provide a facility for automatically encoding and decoding these structures. We provide an example of this facility in the context of the binary data example.
See the page on compiling and accessing these utilities.
typedef void *(*MGal_BinaryDataEncoder)(void
*obj, int *size)
typedef void *(*MGal_BinaryDataDecoder)(void
*data, int size)
void MGal_AddBinaryDataType(int
data_type, MGal_BinaryDataEncoder encoder, MGal_BinaryDataDecoder
decoder)
This function associates the encoder and decoder functions
with the data_type. The encoder takes an arbitrary structure and returns
something that will be treated as an array of bytes of length size.
The decoder takes an array of bytes of length size and returns an
arbitrary structure. The programmer defines the encoder and decoder; typically,
the types are declared in _GalSS_init_server:
/* The Test2 type is elided here; see example */
typedef struct __TestStruct1 {
int first;
int last;
char *msg;
} TestStruct1;
static void *encode_test_struct1(void *data, int *len)
{
char *encode_buf;
TestStruct1 *s = (TestStruct1 *) data;
encode_buf = (char *) malloc(sizeof(char) * (strlen(s->msg)
+ 64));
sprintf(encode_buf, "%d %d %s", s->first, s->last, s->msg);
*len = strlen(encode_buf);
return (void *) encode_buf;
}
static void *decode_test_struct1(void *data, int len)
{
TestStruct1 *s = (TestStruct1 *) malloc(sizeof(TestStruct1));
int where;
sscanf(data, "%d %d %n", &(s->first), &(s->last),
&where);
s->msg = (char *) malloc(sizeof(char) * (1 + (len - where)));
strncpy(s->msg, data + where, len - where);
s->msg[1 + (len - where)] = '\0';
return (void *) s;
}
void *_GalSS_init_server(GalIO_ServerStruct *s, int argc, char **argv)
{
MGal_AddBinaryDataType(TEST1_DT, encode_test_struct1, decode_test_struct1);
return (void *) NULL;
}
Gal_Object MGal_OpaqueObject(void
*obj, int data_type)
Given an object whose encoder and decoder have been associated with data_type,
return an object suitable for use as a value of a frame key. This function
constructs a frame which contains the data_type and the binary encoding of
the object:
{c __opaque__void *MGal_GetOpaque(Gal_Frame fr, char *key, int *data_type)
:type <datatype>
:data <binary_encoding>}
void *MGal_GetOpaqueWarn(Gal_Frame
fr, char *key, int data_type)
Like MGal_GetOpaque, but in addition returns NULL if the element found is
not of the required data_type.
In the example provided, the reinitialize dispatch function creates an object and dispatches it to the Hub, which returns it to othe receive_binary dispatch function, which prints out the structure based on its decoded type:
if (obj) {
switch (dt) {
case TEST1_DT:
s1 = (TestStruct1 *) obj;
sls_pinfo1("First is %d, last is %d,
msg is `%s'\n",
s1->first, s1->last, s1->msg);
break;
/* ... */
}
}
return (Gal_Frame) NULL;
}
Gal_Frame reinitialize(Gal_Frame f, void *server_data)
{
Gal_Frame fr = Gal_MakeFrame("main", GAL_CLAUSE);
TestStruct1 *s1;
s1 = (TestStruct1 *) malloc(sizeof(TestStruct1));
s1->first = Gal_GetInt(f, ":test_first");
s1->last = Gal_GetInt(f, ":test_last");
s1->msg = Gal_GetString(f, ":test_msg");
Gal_SetProp(fr, ":binary_data", MGal_OpaqueObject((void *) s1,
TEST1_DT));
/* ... */
/* Satisfy the response to reinitialize() */
GalSS_WriteFrameToHub(f, server_data, 0);
/* Send the new message */
return fr;
}
License / Documentation home / Help and feedback |