The purpose of this assignment is to test your programming skills and to prepare you for future assignments.
Each time you start a new part of this assignment, create a new directory. When you are finished, you should have an assign1 directory with subdirectories part0, part1, and part2. When creating one of these directories, start by copying into it the contents of the previous directory. Each time you write a main program, use lint and make sure you understand all of the warning messages. Save the lint output. Read this information about running lint.
Obtaining help
You are to do this assignment on your own, but you may ask me for help at any
time. The earlier you start the assignment, the more help will be available.
You may obtain help from me before or after class, by coming to my office,
or by email.
Read through the entire assignment and look at the cover sheet before writing any code. You will be graded not only on the correctness of your programs, but their clarity and the methods you used for testing.
Motivation
When processes in different environments need to communicate information it is often necessary to change the information into a common form before transmission. For example, one machine might use 32-bit integers while another uses 64-bit integers. Or one machine might use a little endian representation while the other uses big endian. In this case we cannot just send the raw bytes between machines. We need to perform an operation call marshalling the arguments, which involves changing them into a common form. If we wish to send a record (data structure) we need to find a way to send the fields in a given order. The method we will use is a form of serialization which produces a sequence of printing characters. Assuming both machines use 8-bit bytes, they can agree on the interpretation of these bytes.
In this assignment you will write two functions to marshal and unmarshal arguments using a form of serialization.
Part 0:
Write the function:
char *serialize3(char *s1, int val1, char *s2, int val2, char *s3, int val3);
which allocates the memory for a string, fills the string based on the
arguments, and returns the string. It should be possible to
free the
returned string using free.
For each pair of string and integer
arguments, sn, valn, insert the string,
sn followed by a colon, a blank, and the digits representing
the value of valn. Insert a blank before inserting the
characters for the next pair. Your program should not make any assumptions
about the maximum size or length of any of the arguments or the number of
bits in an int. If the required string cannot be generated, the
function should return NULL. Be sure to handle the case of a
NULL pointer being passed.
For example,
serialize3("length", 3, "width", 34, "height", 192);
will return the string:
"length: 3 width: 34 height: 192"
Note that this string does not contain a newline unless one of the arguments
does.
Hint: The problem here is to determine how many bytes to allocate. Look at the man page for snprintf and read about the return value. Consider using this with n=1.
Put the function in a file called serialize.c. Create a file called serialize.h with prototypes of all of the functions in serialize.c. Include this in both serialize.c and the main program. Write a main program called test3 that tests serialize3 with several sets of parameters and prints the returned string. Create a makefile that will compile or lint the program.
Part 1:
Write the function:
int parse_for_int_token(char *s, char *token);
that searches the string s for the given token followed by a colon,
and, if found,
returns the integer after that token. If the token or value is not found,
the function returns -1. For example, if the string, s is as in the
previous example, parse_for_int_token(s,"width") would return 34.
Do not assume that there is exactly one blank after the colon.
Put your function in serialize.c and write a main program called
testparse.c to test this. Modify serialize.h and
your makefile appropriately.
Part 2:
Write the function:
info_t deserialize(char *s);
that returns a structure defined by the
following typedef:
typedef struct info { int pid; int tid; int message; } info_t;which should be put in serialize.h.
"abcdefg message: 92345 xyz tid: 3 pid:45 a"Put your function in serialize.c and write a main program called testdes to test this. Modify your makefile appropriately.
Handing in your program:
Use this cover sheet. Consecutively number all of
the other pages you turn in. Each page that contains your work should have
a number on it. Make sure you have answered the questions from the cover sheet.
Turn this in at the beginning of lecture on the due date.