blob: cea03bbd446dba6ce1e92e4d5648aac6cdbbb74c [file] [log] [blame]
/*
* Name: getInsertCommand
* Input: FILE pointer
* Output: data object
* Return: GET_INSERT_SUCCESS, or
* GET_INSERT_IO_ERROR
* GET_INSERT_EARLY_EOI
* GET_INSERT_UNKNOWN_DATA_OBJECT_TYPE
* GET_INSERT_ALLOCATION_ERROR
* Description: Reads an Insert command from the input stream via FILE
* pointer. Assumes the current stream pointer is correct,
* and returns file pointer open and current position
* immediately after command just read. The file pointer is
* expected to be at the beginning of the Insert command
* immediately after the command code. The Insert command
* consists of the data object type identifier and a complete
* listing of the attributes (key and non-key) for the
* object. Each command is carrriage return delimited, i.e.,
* one line per command. The command is read by first reading
* the type, allocating the correct amount of memory for that
* type, setting a local variable to determine how many
* attributes need to be read, and then processing the line.
* An error occurs if the object is of an unknown type, any
* of the attributes are missing, or a memory allocation
* failure for the non-key attribute character sequencyes.
* For any error during the read (missing attributes, bad
* conversions, etc.), the routine will leave the current
* values of the command attribute list intact, clear the
* current line, and return the error code. The output of the
* routine is the data object which is ready to be inserted
* into the index.
* Calls: clearLine()
* errorMessage()
* getInt()
* getKeyAttribute()
* getNonKeyAttribute()
* System:
* Author: M.L.Rivas
*
* Revision History:
*
* Date Name Revision
* ------- --------------- ------------------------------
* 24May99 Matthew Rivas Created
*
* Copyright 1999, Atlantic Aerospace Electronics Corp.
*/
#include <assert.h> /* for assert() */
#include <stdio.h> /* for FILE definition */
#include "dataManagement.h" /* for primitive data types */
#include "dataObject.h" /* for DataObject definition */
#include "errorMessage.h" /* for errorMessage() definition */
#include "getInt.h" /* for getInt() and return code definitions */
#include "getKeyAttribute.h" /* for prototype and return code definitions */
#include "getInsertCommand.h" /* for getInsertCommand() return codes */
#include "getNonKeyAttribute.h" /* for prototype and return code definitions */
Int getInsertCommand( FILE *file, /* file for reading */
DataObject **dataObject ) /* data object */
{ /* begin getInsertCommand() */
Int i; /* looping index variable for attributes */
Int returnCode; /* return code from various routines */
Int dataObjectType; /* data object type read from file */
Int numberOfAttributes; /* number of attributes to read from file and */
/* based on data object type */
static Char name[] = "getInsertCommand";
assert( file );
assert( dataObject );
assert( MIN_ATTRIBUTE_CODE < NUM_OF_KEY_ATTRIBUTES );
assert( MIN_ATTRIBUTE_CODE < MAX_ATTRIBUTE_CODE );
assert( MAX_ATTRIBUTE_CODE < NUM_OF_LARGE_ATTRIBUTES );
assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_SMALL_ATTRIBUTES );
assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_MEDIUM_ATTRIBUTES );
assert( NUM_OF_KEY_ATTRIBUTES < NUM_OF_LARGE_ATTRIBUTES );
/*
* The first parameter to read is the type of data object identifier. The
* value is one of three types: SMALL, MEDIUM, or LARGE. The value is
* read and the return code is checked. An early EOF marker or low-level
* error causes an error message to be inserted in buffer, clears the
* line, and returns with the appropriate error code. If all error checks
* pass, the value read determines the creation of the data object and
* sets the local variable, numberOfAttributes, to be used later when
* processing the line. If the type is unknown, that also causes an error
* message, clears the line, and returns.
*/
returnCode = getInt( file, &dataObjectType );
if ( returnCode == GET_INT_SUCCESS ) {
/*
* empty
*/
}
else if ( returnCode == GET_INT_EOI ) {
errorMessage( "improper format - early EOI", REPLACE );
errorMessage( name, PREPEND );
return ( GET_INSERT_EARLY_EOI );
} /* end of if ( returnCode == GET_INT_EOI ) */
else if ( returnCode == GET_INT_RANGE_EXCEEDED ) {
errorMessage( "unknown data object type", REPLACE );
errorMessage( name, PREPEND );
return ( GET_INSERT_IO_ERROR );
} /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
else if ( returnCode == GET_INT_BAD_CONVERSION) {
errorMessage( "improper format - type must be an integer", REPLACE );
errorMessage( name, PREPEND );
return ( GET_INSERT_IO_ERROR );
} /* end of if ( returnCode == GET_INT_GET_STRING_FAILURE ) */
/*
* Create proper data object from type and store number of attributes
*/
if ( dataObjectType == SMALL ) {
*dataObject = createDataObject( SMALL );
numberOfAttributes = NUM_OF_SMALL_ATTRIBUTES;
} /* end of if ( dataObjectType == SMALL ) */
else if ( dataObjectType == MEDIUM ) {
*dataObject = createDataObject( MEDIUM );
numberOfAttributes = NUM_OF_MEDIUM_ATTRIBUTES;
} /* end of if ( dataObjectType == MEDIUM ) */
else if ( dataObjectType == LARGE ) {
*dataObject = createDataObject( LARGE );
numberOfAttributes = NUM_OF_LARGE_ATTRIBUTES;
} /* end of if ( dataObjectType == LARGE ) */
else {
/*
* Done: unknown data object type
*/
errorMessage( "unknown data object type", REPLACE );
errorMessage( name, PREPEND );
return ( GET_INSERT_UNKNOWN_DATA_OBJECT_TYPE );
} /* end of data object type branches */
/*
* Check memory allocation error for data object
*/
if ( *dataObject == NULL ) {
errorMessage( "allocation failure", REPLACE );
errorMessage( name, PREPEND );
return ( GET_INSERT_ALLOCATION_ERROR );
} /* end of if ( *dataObject == NULL ) */
/*
* The attributes for the data object are specified to be in the "proper"
* order, i.e., by the attribute code in the DIS Benchmark Suite:Data
* Management document. This means that the first NUM_OF_KEY_ATTRIBUTE
* values are key values (floats). A fixed loop reads these values. Each
* read is followed by a check for error conditions where each error
* condition causes a return with appropriate error code.
*/
for ( i = MIN_ATTRIBUTE_CODE; i < NUM_OF_KEY_ATTRIBUTES; i++ ) {
Float temp;
returnCode = getKeyAttribute( file, &temp );
if ( returnCode == GET_KEY_ATTRIBUTE_SUCCESS ) {
(*dataObject)->attributes[ i ].value.key = temp;
} /* end of if returnCode == GET_KEY_ATTRIBUTE_SUCCESS */
else if ( returnCode == GET_KEY_ATTRIBUTE_EOI ) {
errorMessage( "improper format - early EOI", REPLACE );
errorMessage( name, PREPEND );
(*dataObject)->attributes[ i ].value.key = MINIMUM_VALUE_OF_FLOAT;
return ( GET_INSERT_EARLY_EOI );
} /* end of if returnCode == GET_KEY_ATTRIBUTE_EOI */
else if ( returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE ) {
errorMessage( "low-level I/O error", REPLACE );
errorMessage( name, PREPEND );
(*dataObject)->attributes[ i ].value.key = MINIMUM_VALUE_OF_FLOAT;
return ( GET_INSERT_IO_ERROR );
} /* end of if returnCode == GET_KEY_ATTRIBUTE_GET_FLOAT_FAILURE */
} /* end of loop for key attributes */
/*
* The next series of attributes are non-key values (character sequences).
* The number of strings to read is determined by the local variable
* numberOfAttributes which is determined by the data object type
* specifier read at the beginning of the line. A fixed loop reads the
* correct number of strings. Each read is followed by a check for error
* conditions where each error condition causes a return with appropriate
* error code.
*/
for ( i = NUM_OF_KEY_ATTRIBUTES; i < numberOfAttributes; i++ ) {
Char *temp;
returnCode = getNonKeyAttribute( file, &temp );
if ( returnCode == GET_NON_KEY_ATTRIBUTE_SUCCESS ) {
(*dataObject)->attributes[ i ].value.nonKey = temp;
} /* end of if ( returnCode == GET_STRING_SUCCESS ) */
else if ( returnCode == GET_NON_KEY_ATTRIBUTE_EOI ) {
errorMessage( "improper format - early EOI", REPLACE );
errorMessage( name, PREPEND );
(*dataObject)->attributes[ i ].value.nonKey = NULL;
return ( GET_INSERT_EARLY_EOI );
} /* end of returnCode == GET_NON_KEY_ATTRIBUTE_EOI */
else if ( returnCode == GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE ) {
errorMessage( "allocation failure for non-key attribute", REPLACE );
errorMessage( name, PREPEND );
(*dataObject)->attributes[ i ].value.nonKey = NULL;
return ( GET_INSERT_ALLOCATION_ERROR );
} /* end of returnCode == GET_NON_KEY_ATTRIBUTE_ALLOCATION_FAILURE */
} /* end of loop for non-key attributes */
return ( GET_INSERT_SUCCESS );
} /* end of getInsertCommand() */