Galaxy Communicator Tutorial:

Introducing Frames and Objects

License / Documentation home / Help and feedback

As we've already learned, the basic structure which is passed between server and Hub is called a frame. In this lesson, we'll learn how to manipulate frames, and also a little about how they're built.

Once you learn enough, you can consult the frame and object reference.


What's in a frame?

A frame consists of By convention, the names of keys start with a colon (":"). There are many available types for the values, but we will focus on integers, strings, lists, and frames. Here's what the printed representation of all these types looks like:
A frame in C is a structure called a Gal_Frame. The values are all different basic C types: integers are C int, frames are C Gal_Frame, strings are C char *. In order to be able to manipulate these values with a common interface, they are wrapped in a C structure called a Gal_Object, which contains the data and a constant of type Gal_ObjectType indicating the data type. Lists, for instance, are implemented as arrays of Gal_Objects, so that it's possible to put elements of different types in the same list. Here's approximately what the frame above looks like, structurally:

Here's a table of the properties of the four types we'll be discussing.
 
Gal_ObjectType C type printed representation comments
GAL_FRAME Gal_Frame {<type> <name> <key> <value> ... } whitespace between opening bracket and type is forbidden; whitespace between elements (type, name, keys, values) is obligatory
GAL_STRING (char *) "foo" whitespace in strings is preserved; escape character is backslash (\)
GAL_INT 32 bit integer 5 explicit sign prefixes (+,-) also recognized
GAL_LIST an array of Gal_Objects ( <obj> <obj> <obj> ) lists are heterogeneous (multiple object types can appear in a single list); whitespace between elements is obligatory


Making and freeing frames

The fundamental functions for creating a frame is Gal_MakeFrame. In C, because you have to do your own memory management, you must also free the frames you use with the function Gal_FreeFrame.
/* Create the frame */
Gal_Frame f = Gal_MakeFrame("output", GAL_CLAUSE);

/* Do something with the frame */
...
/* Free the frame */
Gal_FreeFrame(f);

Alternatively, you can use the function Gal_ReadFrameFromString to convert the string representation of a frame into a Gal_Frame structure:
/* Create the frame */
Gal_Frame f = Gal_ReadFrameFromString("{c output }");

/* Do something with the frame */
...
/* Free the frame */
Gal_FreeFrame(f);


Making, using and freeing objects

Wrapping data in objects

For each type, there's a function for creating an appropriate Gal_Object, as well as a function for extracting that datatype from the created Gal_Object:
 
Gal_ObjectType Creating a Gal_Object Extracting the data from the Gal_Object
GAL_FRAME Gal_FrameObject Gal_FrameValue
GAL_STRING Gal_StringObject Gal_StringValue
GAL_INT Gal_IntObject Gal_IntValue
GAL_LIST Gal_ListObject Gal_ListValue

All these objects can be freed using the function Gal_FreeObject. Here are some examples with frames, strings and integers:

Gal_Object frame_obj, string_obj, int_obj, list_obj;
Gal_Object list_array[3];
Gal_Frame output_frame;
char *foo;
int five;
int list_length;
Gal_Object *list_contents;

/* Create a frame and wrap an object around it */
frame_obj = Gal_FrameObject(Gal_ReadFrameFromString("{c output }"));

/* Wrap an object around a string */
string_obj = Gal_StringObject("foo");

/* Wrap an object around an integer */
int_obj = Gal_IntObject(5);

/* Extract the frame from the object */
output_frame = Gal_FrameValue(frame_obj);

/* Extract the string from the object */
foo = Gal_StringValue(string_obj);

/* Extract the integer from the object */
five = Gal_IntValue(int_object);

/* Populate the list array */
list_array[0] = frame_obj;
list_array[1] = string_obj;
list_array[3] = int_obj;

/* Wrap a list around the array.
   Printed representation of the list is

   ( {c output } "foo" 5 )
*/
list_obj = Gal_ListObject(list_array, 3);

/* Extract the list from the object. The list_length integer will
   contain the length of the list (i.e., 3) */
list_contents = Gal_ListValue(list_array, &list_length);

/* Free the list object. See the memory management note. */
Gal_FreeObject(list_obj);

Memory management note. The rules of memory management for frames and objects is a little complicated, and we won't go into it here. The only point worth noting at this point is that for the set of functions we use here, when frames and objects are freed, all the frames and objects in them are freed. The full reference has complete details, as well as alternative functions which give you more control over memory management.

Creating and accessing key-value pairs in frames

The two basic functions for manipulating objects in frames are Gal_SetProp and Gal_GetObject. Let's use strings as an example:
Gal_Object string_obj;
char *string;
/* Create the frame */
Gal_Frame f = Gal_MakeFrame("output", GAL_CLAUSE);

/* Add a string. Printed representation of the frame is now

  {c output :output_string "hello" }
*/
Gal_SetProp(f, ":output_string", Gal_StringObject("hello"));

/* Extract the string object. */
string_obj = Gal_GetObject(f, ":output_string");
string = Gal_StringValue(string_obj);

To extract the data from the frames directly, there's a set of shorthand functions that we frequently use. These functions find the appropriate key-value pair and check to see that the value is of the appropriate type:
 
Gal_ObjectType Extracting the data from the frame
GAL_FRAME Gal_GetFrame
GAL_STRING Gal_GetString
GAL_INT Gal_GetInt
GAL_LIST Gal_GetList

So the example above could be rewritten as follows:

char *string;
/* Create the frame */
Gal_Frame f = Gal_MakeFrame("output", GAL_CLAUSE);

/* Add a string. Printed representation of the frame is now

  {c output :output_string "hello" }
*/
Gal_SetProp(f, ":output_string", Gal_StringObject("hello"));

/* Extract the string object. */
string = Gal_GetString(f, ":output_string");

Lists and integers have some special properties. For integers, the problem is that all these functions return NULL when they don't find the appropriate key-value pair. This is a problem for Gal_GetInt, because NULL is equivalent in C to 0; as a result, Gal_GetInt can't distinguish between a value of 0 and the absence of a key. So we recommend using Gal_GetObject followed by Gal_IntValue if the distinction is important to you.

For lists, there is an additional function Gal_GetListObject which extracts the nth element of a list in a key-value pair:

Gal_Frame f = Gal_ReadFrameFromString("{c listframe :list ( 5 6 7 ) }");
Gal_Object int_obj;

/* int_obj will be a Gal_Object wrapped around the integer 7 */
int_obj = Gal_GetListObject(f, ":list", 2);


Summary

There are many more ways of manipulating frames and objects. There are functions to You can find all this information in the frame and object reference. However, for the purposes of this course, we've introduced in this lesson all the functions you'll need to understand how frames and objects are being manipulated: In the next lesson, we'll see how these are used in writing Communicator-compliant servers.

Next: Server basics


License / Documentation home / Help and feedback
Last updated September 12, 2001