Phoenix Libraries

Description
	The functions provided in the Phoenix library will allow programs to 
access data with phoenix formatted summary headers. To use this library, the 
phoenix2.a object library must be linked in with the driver routine and the 
phoenix.h file should be included in the driver routine.  

Bugs
	There is one know bug with the Phoenix Libraries.  The buffered write 
will not write the last block on the write_hdr procedure.  This is necessary 
when writing the write_sig section immediately afterwards.  If just headers are
desired do a buffered_write(File stream,"Flush",0);.  This will empty the 
buffer.

General Information
	It is not necessary to do both a read_hdr and read_sig.  The read_sig 
program will read both the header and the data use read_hdr when only the 
header data is desired.

Compiling
	To compile just the libraries type:  make
	To compile the driver program type:  make driver
	To compile your own program substitute your program name for fix on the 
		"EXEC = fix" line and type:  make fix

	Note:  The ar command may not be in the /usr/ccs/bin directory.

Differences from phoenix1.a to phoenix2.a
	The major change between phoenix1.a and phoenix2.a is that the 
read_hdr, read_sig, write_hdr, and write_sig routines now expect a file 
pointer.  That is the files should be opened with fopen instead of open.

	The bytes_written argument for the write_hdr and write_sig routines 
is no longer used.
	The routine get_header_names has been added.

Phoenix2.a contains the following functions:
	read_sig()
	get_sig_addr()
	set_unbuffered_read()
	read_hdr()
	get_header_names()
	set_buffered_read()
	write_hdr()
	get_sig_size()
	set_buffered_write()
	write_sig()
	get_data_ptr()
	set_unbuffered_write()
	get_hdr_value()
	get_native_hdr_ptr()
	iQuit()
	put_hdr_value()
	get_phoenix_size()
	remove_hdr_parameter()

The following section has descriptions of the functions with examples of how 
they are used.  There is also an example makefile.  For more examples of how 
the functions are used, see the driver.c program included.

---------------------------------------------------------------------------
read_sig(file pointer)

This routine reads in a file with a Phoenix header. It returns an error code 
based on the outcome of the read. All error codes are defined in phoenix.h. The 
read errors are as follows:

	* ALLOC_ER:	Error allocating memory for signature/image
	* EOF_ER:	Reached end of file during read process
	* FREAD_ERR:	Hardware read error

example:
    int		results;
    FILE 	*fp;

	fp = fopen("hb03333.0000", "rb");
	results = read_sig(fp);
---------------------------------------------------------------------------
read_hdr(file pointer)

This routine reads in just the Phoenix header from a file with a Phoenix 
header. It returns an error code based on the outcome of the read. All 
error codes are defined in phoenix.h. The read errors are as follows:

	* ALLOC_ER:	Error allocating memory for signature/image
	* EOF_ER:	Reached end of file during read process
	* FREAD_ERR:	Hardware read error

example:
    int		results;
    FILE	*fp;

	fp = fopen("hb03333.0000", "rb");
	results = read_hdr(fp);
---------------------------------------------------------------------------
write_hdr(file pointer)

This routine writes the Phoenix header to the output file. 

example:
    int		results;
    FILE	*fp_out;

	fp_out = fopen("output_file.txt", "wb");
	results = write_hdr(fp_out);
---------------------------------------------------------------------------
write_sig(file pointer, the address of where to start writing, the number of 
bytes to write)

This routine will write the specified number of bytes to the output file 
starting at the given address.  

example:
    int			results;
    FILE		*fp_out;
    unsigned long	size;

	fp_out = fopen("output_file.txt", "wb");
	results = write_hdr(fp_out);
	/* get the size of the native header plus data */
	size = get_sig_size() - get_phoenix_size();
	results = write_sig(fp_out, get_native_hdr_ptr(), size);
---------------------------------------------------------------------------
get_hdr_value(the name of the parameter exactly as it appears in the header, 
the address of the value to be returned, the data type of the returned value)

This routine assigns the value of the input parameter name to the value argument 
as the specified type.  It returns an error code based on whether the parameter 
name was found in the phoenix header: 0-parameter found, 1-parameter not found.

Note:  The type of the phoenix parameter argument can either be a phoenix_type 
pointer or a return type pointer.

Allowable types:	FLOAT, INT, DOUBLE, SHORT, ASCII

example:
    short		profile_number;
    float		az;
    phoenix_type	temp_phoenix;
    int			results;

	results = get_hdr_value("profile", &profile_number, SHORT);
	printf("Profile = %hd\n", profile_number);
	results = get_hdr_value("azimuth", &az, FLOAT);
	printf("Profile = %f\n", az);
	results = get_hdr_value("profile", &temp_phoenix, SHORT);
	printf("Profile = %hd\n", temp_phoenix.short_value);

---------------------------------------------------------------------------
get_header_names(string to identify parameter names, list of qualifying names, 
max number of names to return)

This routine gets a list of all Phoenix header parameters containing a given 
string.  It returns the number of parameters that meet the criteria.  The 
search is not case sensitive.  (The return value could be greater than the 
max number of names to return.)

example:
    int		max,i;
    char	*names[20];

	for(i=0; i<20; i++) 
	    names[i] = (char *)malloc(40);
	max = get_header_names("TarGet",names,20);
	printf("max = %i\n",max);
	for(i=0; i<max; i++) 
	    printf("%s\n",arr[i]);
---------------------------------------------------------------------------
put_hdr_value(the name of the parameter exactly as it appears in the header or 
as defined by the user, the value to be input, the data type of the input value)

This routine puts the input value into the parameter as the specified type. If 
the parameter does not exist, it is added to the Phoenix header.

Note:  The type of the input argument can either be a phoenix_type variable 
or a return type pointer.

example:
    short		profile_number;
    float		az;
    phoenix_type	temp_phoenix;
    int			results;

	profile_number = 27;
	results = put_hdr_value("profile", &profile_number, SHORT);
	az = 37.875;
	results = put_hdr_value("az", &az, FLOAT);
	temp_phoenix.int_value = 3765
	results = put_hdr_value("range", temp_phoenix, INT);
---------------------------------------------------------------------------
remove_hdr_parameter(the name of the parameter exactly as it appears in the 
header)

This routine removes the specified parameter from the summary header.

example:
    int		results;

	results = remove_hdr_parameter("az");
---------------------------------------------------------------------------
get_sig_addr()

This routine returns a void pointer to the beginning of the signature/image, 
that is, to the beginning of the Phoenix header.

example:
    char	*sig_ptr;

	sig_ptr = (char *) get_sig_addr();
---------------------------------------------------------------------------
get_sig_size()

This routine returns the total record size of the signature/image as an 
unsigned long.

example:
    unsigned long	size;

	size = get_sig_size();
---------------------------------------------------------------------------
get_data_ptr()

This routine returns a void pointer to the beginning of the actual data. 
(Process_data is a dummy routine which would do some sort of processing
on the signature/image data.)

example:
    int	results;

	results = process_data(get_data_ptr());
---------------------------------------------------------------------------
get_native_hdr_ptr()

This routine returns a void pointer to the beginning of the native header.

example:
    int			results;
    FILE		*fp_out;
    unsigned long	size;

	/* get the size of the native header plus data */
	size = get_sig_size()- get_phoenix_size();
	rc = write_sig(fp_out, get_native_hdr_ptr(), size);
---------------------------------------------------------------------------
get_phoenix_size()

This routine returns the size of the summary header as an unsigned long.

example:
    unsigned long	size;

	/* get the size of the native header plus data */
	size = get_sig_size() - get_phoenix_size();
---------------------------------------------------------------------------
set_buffered_read()

Sets the read routine to read in buffered mode. For use with reading from tape.

example:
    int		results;
    FILE	*fp;

	set_buffered_read();
	fp = fopen("/dev/nrst0", "rb");
	results = read_sig(fp);
---------------------------------------------------------------------------
set_unbuffered_read()

Sets the read routine to read in unbuffered mode. For use with reading from 
disk.

example:
    int		results;
    FILE	*fp;

	set_unbuffered_read();
	fp = fopen("header.out", "rb");
	results = read_sig(fp);
---------------------------------------------------------------------------
set_buffered_write()

Sets the write routine to write in buffered mode. For use with writing to tape.

example:
    int			results;
    FILE		*fp_out;
    unsigned long	size;

	set_buffered_write();
	fp_out = fopen("/dev/nrst0", "wb");
	results = write_hdr(fp_out);
	/* get the size of the native header plus data */
	size = get_sig_size() - get_phoenix_size();
	results = write_sig(fp_out, get_native_hdr_ptr(), size);
---------------------------------------------------------------------------
set_unbuffered_write()

Sets the write routine to write in unbuffered mode. For use with writing to 
disk.

example:
    int			results;
    FILE		*fp_out;
    unsigned long	size;

	set_unbuffered_write();
	fp_out = fopen("output.dat", "wb");
	results = write_hdr(fp_out);
	/* get the size of the native header plus data */
	size = get_sig_size() - get_phoenix_size();
	results = write_sig(fp_out, get_native_hdr_ptr(), size);
---------------------------------------------------------------------------
iQuit(exit number)

This routine flushes the stdout and stderr streams and then exits with the 
specified exit number.

example:

	iQuit(1);
---------------------------------------------------------------------------

Example makefile

The following is an example makefile for use with the phoenix libraries.  The 
PHOENIX_PATH will need to be modified to reflect were the phoenix libraries 
were installed.  

EXEC= example

PHOENIX_PATH= ./LIBS

CFLAGS= -g -I$(PHOENIX_PATH)

LDFLAGS=

AR= /usr/ccs/bin/ar

USER_LIBS= $(PHOENIX_PATH)/phoenix2.a

LIBS= -lm

OBJECTS= $(EXEC).o

$(EXEC): $(USER_LIBS) $(OBJECTS)
	$(LINK.c) -o $(EXEC) $(EXEC) $(OBJECTS) $(USER_LIBS) $(LIBS) 

$(OBJECTS):   $(PHOENIX_PATH)/phoenix.h

CLEAN:
	- rm *.o

NEW:
	- rm *.o
	- rm $(EXEC)

