Project 0: Warmup Assignment


Introduction

The purpose of this assignment is to get you back in the swing of coding, using some of the particular skills that you will need for these assignments. In particular, it uses binary files instead of files of standard ASCII characters. It will also demonstrate the use of Makefiles in the sense that we will be using them in the Minibase project. There will be some bits of Java or C++ that will be new to you that won't be covered explicitly in class.


Getting Started

First create a directory for storing all the code that you write associated with this course. Once you have done so, navigate to that directory, then copy the entire directory /Accounts/courses/cs347/proj0java or /Accounts/courses/cs347/proj0cpp (depending on which language you are using) to your current directory. You'll need to use the Linux cp -r command in order to do this.

Navigate into the directory that you just copied, and take a look at all of the files contained within. You should have all the files that you need to work on the assignment. If you type make, this will invoke the commands in the Makefile to compile your code. However, you are missing the code that you actually need, so this will result in an error message. If you are programming in Java, you need to fill in the code for the EmployeeNode.java and EmployeeList.java files. If you are programming in C++, you will find EmployeeNode.h and EmployeeList.h files already present, but you will need to add your own EmployeeNode.cpp and EmployeeList.cpp files. This is how all our project assignments will work: the directory will contain some code related to the assignment, but will be missing some code.

Take a look at the file Makefile. You are free to add more sources files other than the ones already specified in the assignment, but if you do so you will have to add these files to the Makefile.

You can find the API for these files by clicking on the appropriate link for Java or C++.


What You Have to Do

You will have to implement the EmployeeList class that manages a singly linked list of EmployeeNode objects storing information about employees. Each EmployeeNode object stores the name and salary of an employee. The employee name is a String in Java (it's a null-terminated character string in C++), and the salary is an integer.

One of the main operations that you have to implement for an employee list is reading employee information from a binary file and adding it to the list. The format of this binary file is described below. The employee list is always maintained sorted alphabetically by employee name. The employee records in the files used to populate the list are also sorted alphabetically by employee name. You should be able to read a file containing employee records into an empty list, or into a list that already contains employee nodes. In the latter case, the records read from the file should be merged with the nodes already in the employee list so that the list remains sorted by employee name.


Format of Employee Files

Each employee file is a binary file that stores a sequence of variable length employee records.

The very first entry in the file is a standard 4 byte integer indicating how many records follow it in the file.

Following this initial count are the records. Each record contains the length of the employee name (4 byte integer), the actual employee name (number of bytes equal to the length indicated in the previous field), and salary (4 byte integer). To illustrate graphically, the format of an employee record is as follows:

 ------------------------------ ... -----------------------------------------
|    4 byte integer     |     N character string     |    4 byte integer     |
| Number of characters  |        Employee name       |    Employee salary    |
| in employee name (N)  |    (not null-terminated)   |                       |
 ------------------------------ ... -----------------------------------------

To read integers and character strings from a binary file, in Java, you can use:

     DataInputStream infile = new DataInputStream(new FileInputStream(filename));
     int nameLen = infile.readInt();
     byte[] b = new byte[nameLen];
     infile.read(b);
     ... etc ...   
     infile.close();

To read integers and character strings from a binary file, in C++, you can use:

     fstream infile(filename,ios::in | ios::binary);
     int nameLen;
     char *name;
     infile.read((char*)&nameLen,sizeof(int));
     name = new char[nameLen+1];
     infile.read(name,nameLen);
     // add the null character, '\0', to the end of the name ...
     name[nameLen] = '\0';
     ... etc ...
     infile.close();

Writing integers and character strings to a binary file is similar. In Java:

     DataOutputStream infile = new DataOutputStream(new FileOutputStream(filename));
     int nameLen = ...
     String name = ...;
     outfile.writeInt(nameLen);
     outFile.writeBytes(name);
     ...
     outfile.close();

In C++:

     fstream outfile(filename,ios::out | ios::binary);
     int nameLen = ...;
     char *name = ...;
     outfile.write((char*)&nameLen,sizeof(int));
     outfile.write(name,nameLen);
     ...
     outfile.close();

When you are done with implementing the employee list classes, you should be able to type make and have your code compile to give an executable called Tester. Run this executable to test your code.


Testing Your Code

The file Tester.java / Tester.cpp contains code that tests your employee list class. First, it reads the file inputlist.dat into an employee list, l. Next, it reads a file secondlist.dat into the same employee list, l. After that it prints the employee list, and computes and prints the number of employees and their average salary. It then writes the employee list to the file mergedlist.dat.

inputlist.dat contains the following records:

Name            Salary
----            ------
Brown, Steve    82
Chen, Jessica   91
Engelbart, Mark 30

secondlist.dat contains the following records:

Name            Salary
----            ------
Abel, Jean      95
Dickson, Eric   65
Fredrik, Cathy  50

The screen output of your program should look something like this (the precise formatting isn't important):

Abel, Jean: 95
Brown, Steve: 82
Chen, Jessica: 75
Dickson, Eric: 65
Engelbart, Mark: 30
Fredrik, Cathy: 50

The file mergedList.dat should contain this same output in the same file format as the original data.

When you hand in your code, we will test it with other input files in addition to these. This means that you should try testing your code on other files that you create as well. Feel free to swap test files with each other: I encourage you to do so.

If you are coding in C++, we will be using the program valgrind to make sure that you don't have any memory errors (Java has checks for these built-in). You should run valgrind on your program before submitting it to make sure that your program doesn't exhibit memory leaks or other bad behavior. To do so, execute the following command:

valgrind --leak-check=full Tester

where Tester is, in this case, the name of your executable.


Handing in Your Code

If you are working in a team (and please do!), only one of you should submit the code. Make sure that both of your names appear in program documentation at the top.

Use hsp to hand in the entire directory containing your code, which should be called proj0java or proj0cpp.

Good luck, have fun, and ask questions!