// parserelease.cpp Release-specific parsing functions #include "parserelease.h" /******************************************************************************* // FUNCTION NAME: GetReleaseInfo // // DESCRIPTION OF FUNCTION: Checks each record in the Release Section of a BAM // file for errors and stores the records into ReleaseList // // DESCRIPTION OF ALGORITHM: While AnotherRecord returns true, calls ReadRecord // to pull record data into a string, CheckReleaseRecord to parse it, and // ReleaseListType::insert to store it into the list. When AnotherRecord returns // false, if no errors were discovered, calls WriteNoErrors. Always calls // WriteSectionFooter just before returning // // CALLED BY: ParseFile // CALLS: WriteSectionHeader,WriteNoErrors,WriteSectionFooter,AnotherRecord, // ReadRecord,CheckReleaseRecord,ReleaseListType::insert, // ReleaseListType::smallestIndex // // PARAMETERS: / inout / inputFile - input filestream that has been opened to // the appropriate BAM data file // / inout / outputFile - output filestream that has been opened to // the appropriate BAC error file // / in / FileName - string that contains the name of the BAM file // / out / ReleaseList - ReleaseListType to hold the records stored in // the BAM data file // // PRECONDITIONS: inputFile has been properly intialized to the appropriate // BAM file, and outputFile has been proprely initalized to the appropriate // BAC file. // // POSTCONDITIONS: The releases section has been removed from the input file, // any errors located in the section were written to the output file, // all records that were in the section of the BAM file have been stored into // the list // // AUTHOR: Amy Langill *2B DATE: 3/28/1999 *******************************************************************************/ void GetReleaseInfo(ifstream& inputFile,ofstream& outputFile,string FileName, ReleaseListType& ReleaseList) { // Functions called only by GetReleaseinfo void CheckReleaseRecord(string& dataString,ofstream& errorFile, ReleaseRecord& record,bool& errorFound,int& lineNumber, int recordCounter,int minIndex); // Variables declared within GetReleaseInfo: bool notDoneYet=false; // Are we done yet? bool errorsFound=false; // Have any errors been encountered in the file? string recordData; // To hold record data pulled from file ReleaseRecord tempRecord; // To hold data before storing in list BALSectionType section=RELEASE; // Keep track of which section we're in int recordCounter=0; // Keep track of how many records have been parsed int lineCounter=0; // Keep track of what line of input file we're on int recIndex; // Create an index for each record inputFile.ignore(200,'\n'); // Skip label line of input file WriteSectionHeader(outputFile,FileName,section); // Write section Label notDoneYet=AnotherRecord(inputFile); while (notDoneYet) // As long as there's another record { recordCounter++;lineCounter++; // duh... increment the counters recIndex=(ReleaseList.smallestIndex()-1); // find default index // Read the record, parse it, insert into the list ReadRecord(inputFile,recordData,section); CheckReleaseRecord(recordData,outputFile,tempRecord,errorsFound,lineCounter, recordCounter,recIndex); ReleaseList.insert(tempRecord); if (AnotherRecord(inputFile)) // If there's more in the file, { inputFile.ignore(200,'\n'); // Skip the record delimiter tempRecord.Reset(); // Reset record for next bunch o' data } else notDoneYet=false; } // end of the while-loop if (!errorsFound) // If there weren't any errors, say so WriteNoErrors(outputFile); WriteSectionFooter(outputFile); // Write section delimiter line return; } /******************************************************************************* // FUNCTION NAME: CheckReleaseRecord // // DESCRIPTION OF FUNCTION: Parses Release record data as stored in dataString, // writes any errors contained therein to the specified errorFile, and stores // valid data values into record. // // DESCRIPTION OF ALGORITHM: For each field in the record, pulls the field // label off the front dataString and compares it to the define field label // with ReleaseRecord::FieldLabel and calls WriteLabeError if necessary, then // pulls the data off the front of dataString, stores it into record, and // checks to see if the field now contains a valid value. If the field is // invalid, the function calls WriteDataError. If the index is invalid, // the function assigns a default index to the record. // // CALLED BY: GetReleaseInfo // CALLS: WriteLabelError,WriteDataError,ReleaseRecord::FieldLabel, // ReleaseRecord::FieldWidth,ReleaseRecord::NewIndex,ReleaseRecord::Reset, // ReleaseRecord::fieldOK // // PARAMETERS: / in / dataString - string that holds record data // / inout / errorFile - ofstream for BAC error report // / out / record - ReleaseRecordType for storing data // / inout / errorFound - Show whether any errors have been found // in the BAM file // / inout / lineNumber - The line of the BAM file a field shows // up on // / in / recordCounter - The number of this record in the BAM file // / in / minIndex - A default index to be used if the one in the // BAM file is invalid // // PRECONDITIONS: dataString contains an entire record of data, with the labels // and data separated by spaces. errorFile has been properly initalized to the // appropriate error file. // // POSTCONDITIONS: The record is checked, stored, and any applicable errors are // written to the errorFile filestream // // AUTHOR: Amy Langill *2B DATE: 3/28/1999 *******************************************************************************/ void CheckReleaseRecord(string& dataString,ofstream& errorFile, ReleaseRecord& record,bool& errorFound,int& lineNumber, int recordCounter,int minIndex) { DataErrorType currentError; // Tracking what error has occurred ReleaseFieldType currFld; string fieldData; string fieldLabel; for (currFld=R_RDEX;currFld<=R_LOFT;currFld=ReleaseFieldType(currFld+1)) { // Pull the label off the front of the record string: fieldLabel=dataString.substr(0,(dataString.find(" ",0)+1)); dataString.erase(0,(fieldLabel.length())); if (fieldLabel!=record.FieldLabel(currFld)) // If the label's wrong { WriteLabelError(errorFile,errorFound,fieldLabel, record.FieldLabel(currFld),recordCounter, lineNumber); errorFound=true; } // Pull the data off the front of the record string fieldData=dataString.substr(0,record.FieldWidth(currFld)); dataString.erase(0,(record.FieldWidth(currFld)+1)); record.Update(fieldData,currFld); // Store into the record currentError = record.fieldOK(currFld); // Check the Record if (currentError!=NO_PROB) // If something's wrong { WriteDataError(errorFile,currentError,errorFound, record.FieldContains(currFld),record.FieldLabel(currFld), recordCounter,lineNumber); errorFound = true; record.Reset(currFld); } if (currentError==INDEX_RANGE_ERR) // Index is negative record.NewIndex(minIndex); } return; }