#include "verify.h" #include "fileops.h" #include "verifypr.h" #include "highlevel.h" #include "listname.h" #include "display.h" #include #include Boolean Errorfound=FALSE; int VerifyVRS (ifstream & nameVRSFile, ofstream& outputfile); int VerifyMOV (ifstream & nameMOVFile, int numReviews, ofstream& outputfile, char Movfilename[35]); int VerifyREV (ifstream & nameREVFile, ofstream& outputfile); int VerifyMRS (ifstream & nameMRSFile, ofstream & outputfile); /********************************************************************** * * Function: Verify * Input: nameFile -- A reference to a file to process * numReviews -- The number of reviews in the file (only .MOV) * filetype -- The type of file to be processed * outputfile -- a reference to the report file to output * * Returns: void * * Description: * A recursive function to process all of the various verification procedures. * This function serves as a shell for the individual functions. * * Variables: none * * Called by: DoFiles * * Calls: VerifyVRS * VerifyMOV * VerifyREV * VerifyMRS * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ void Verify (ifstream & nameFile, int numReviews, char filetype, ofstream& outputfile, char outputfilename[35]) { switch (filetype) { case 'v': { VerifyVRS(nameFile, outputfile); break; } case 'm': { VerifyMOV(nameFile, numReviews, outputfile, outputfilename); break; } case 'r': { VerifyREV(nameFile, outputfile); break; } case 's': { VerifyMRS(nameFile, outputfile); break; } } } /********************************************************************** * * Function: VerifyVRS * Input: nameVRSFile -- A reference to a file to process * * Returns: int 0 * * Description: * A function to process the category file and create nodes for the data * within the category file. It is important to have these nodes because * of the recursive nature of the Verify function. This function is rather * large, but is simple because there are two identical loops. * * Variables: int realnumlines -- the actual number of lines in the category file * DLnkNodePtr head -- Pointer to the first category node in the list * DLnkNodePtr Line -- Pointer to the current category node * DLnkNodePtr Prev -- Pointer to the previous category node * Boolean errorFlag -- Used for errors * int decnum -- The number of categories from the first line * char filename -- holds the filename until inserted * int numreviews -- holds number of reviews until inserted * char title -- holds title until inserted * * Called by: Verify * * Calls: CheckExtension * Fexists * CheckNumReviews * Verify * Insert * strcpy * SetList * BinarySearch * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ int VerifyVRS (ifstream & nameVRSFile, ofstream& outputfile) { DLnkNodePtr Line = NULL; DLnkNodePtr head = NULL; DLnkNodePtr Remind = NULL; int realnumlines=0; //the actual count of lines in the category file Boolean errorFlag=FALSE; int decnum; char filename[35]; int numreviews; char title[20]; nameVRSFile >> decnum; realnumlines++; while (!nameVRSFile.eof()) //this will continue to add nodes to the list until EOF. { nameVRSFile.get(); for (int index=0;index<28;index++) { title[index]='\0'; } for (index=0;index<28;index++) { nameVRSFile.get(title[index]); if ((title[index]==' ') && (title[index-1]==' ')) { title[index-1]='\0'; title[index]='\0'; break; } } if ((nameVRSFile.eof()) || (nameVRSFile.fail())) { break; } nameVRSFile >> numreviews; //read from the file to get the number of reviews nameVRSFile >> filename; //read from the file to get the next file name realnumlines++; // increment the number of actual lines if (CheckExtension(filename, movieFileExt)) { if (Fexists(filename)) { if (CheckNumReviews(numreviews)) { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line " << realnumlines << ": Invalid number of reviews." << endl; } } else { outputfile << "Line " << realnumlines << ": File '" << filename << "' does not exist." << endl; SetErrorFlag(TRUE); errorFlag=TRUE; } } else { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line " << realnumlines << ": Invalid file name extension for the file '" << filename << "'." << endl; } if (!Insert(Line, filename, FALSE, 0)) Response(JUST_ENTER, 1, "There was an error allocating memory. Please press 'ENTER' to continue."); Line->Item.filetype='M'; strcpy (Line->Item.title, title); Line->Item.revieworrating=numreviews; } while (GetPrevLink(Line)) { Line=GetPrevLink(Line); } head=Line; SetList(head); if (decnum != (realnumlines-1)) { outputfile << "Line 1: Number of lines in file do not match." << endl; errorFlag=TRUE; SetErrorFlag(TRUE); } if (errorFlag==FALSE) { outputfile <<"No errors encountered."<Item.filetype=='M') && (head->Item.verified==FALSE)) { if (CheckExtension(head->Item.filename, movieFileExt)) { if (Fexists(head->Item.filename)) { if (CheckNumReviews(numreviews)) { SetErrorFlag(TRUE); errorFlag=TRUE; } ifstream nameMOVFile(head->Item.filename); SetList(head); // we want to pass the right name when we verify outputfile << endl << head->Item.filename << endl; outputfile << "==============" << endl; strcpy(placeholder, head->Item.filename); head->Item.verified=TRUE; Verify (nameMOVFile, numreviews, 'm', outputfile, head->Item.filename); BinarySearch(head, placeholder); nameMOVFile.close(); } else { SetErrorFlag(TRUE); errorFlag=TRUE; } } else { SetErrorFlag(TRUE); errorFlag=TRUE; } } head=head->Link; } SetList(Line); return 0; } /********************************************************************** * * Function: VerifyMOV * Input: nameMOVFile -- A reference to a file to process * numReviews -- Stated number of reviews from category file * outputfile -- A reference to the output file * * Returns: int 0 * * Description: * A function to process the movie file and create nodes for the data * within the movie file. It is important to have these nodes because * of the recursive nature of the Verify function. This function has * two similar loops, which are used for convience. * * Variables: int numlines -- the actual number of lines in the movie file * Boolean errorFlag -- indicates if an error was found * DLnkNodePtr head -- Pointer to the first category node in the list * DLnkNodePtr MOVLine -- Pointer to the current category node * DLnkNodePtr MOVPrev -- Pointer to the previous category node * char title -- holds title until insertion * char filename -- holds filename until insertion * float starRating -- holds star rating until insertion * int index -- a counter * * Called by: Verify * * Calls: CheckExtension * Fexists * CheckStarRating * GetList * SetList * Insert * toupper * Verify * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ int VerifyMOV (ifstream & nameMOVFile, int numReviews, ofstream& outputfile, char Movfilename[35]) { int numlines=0; //the actual count of lines in the movie file Boolean MerrorFlag=FALSE; DLnkNodePtr Line=NULL; DLnkNodePtr MOVLine=NULL; DLnkNodePtr head=NULL; char title[29]; char filename[35]; float starRating; while (!nameMOVFile.eof()) { for (int index=0;index<28;index++) { title[index]='\0'; } for (index=0;index<28;index++) { nameMOVFile.get(title[index]); if ((title[index]==' ') && (title[index-1]==' ')) { title[index-1]='\0'; title[index]='\0'; break; } } if ((nameMOVFile.eof()) || (nameMOVFile.fail())) { //this indicates some type of problem with the beginning of the file. //more than likely, the file is not of the correct type break; } nameMOVFile >> starRating; nameMOVFile >> filename; for (index=0;index<(abs(strlen(filename)));index++) { filename[index]=toupper(filename[index]); } nameMOVFile.get(); numlines++; // increment the number of actual lines Line=GetList(); BinarySearch(Line, Movfilename); MOVLine=GetList(); if (!Insert(Line, filename, TRUE, MOVLine->Item.movieindex)) Response(JUST_ENTER, 1, "There was an error allocating memory. Please press 'ENTER' to continue."); //The following group of statements is to do the verification //for the current file before the jump into the next file. //This block does not actually do the recursive calls. if (CheckExtension(filename, reviewFileExt)) { if (Fexists(filename)) { if (CheckStarRating(starRating)) { SetErrorFlag(TRUE); MerrorFlag=TRUE; outputfile << "Line " << numlines << ": Invalid star rating."<< endl; } } else { outputfile << "Line " << numlines << ": File '" << filename <<"' does not exist." << endl; SetErrorFlag(TRUE); MerrorFlag=TRUE; } } else { MerrorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line " << numlines << ": Invalid file name extension for the file '" << filename << "'." << endl; } Line->Item.filetype='R'; strcpy (Line->Item.title, title); Line->Item.revieworrating=(int)(starRating*10.0); } if (numlines == numReviews) { if (MerrorFlag==FALSE) { outputfile << "File is correctly formatted." << endl; } } else { outputfile << "The number of movies differed from the category or review set file." << endl; } //The following while statement actually dives into the files. //While it is slightly inefficient to do the checks twice, it is worse //to try to store the results of the earlier checks, or to try to format //all of the output in one loop. For this reason, only the earlier //sequence of checks creates any error output. Line=GetList(); head=Line; while (GetPrevLink(Line)) { Line=GetPrevLink(Line); } head=Line; while (head!=NULL) { if ((head->Item.filetype == 'R') && (head->Item.verified==FALSE)) { if (CheckExtension(filename, reviewFileExt)) { if (Fexists(filename)) { ifstream nameREVFile(head->Item.filename); outputfile << endl << head->Item.filename << endl; outputfile << "===============" << endl; Verify (nameREVFile, 0, 'r', outputfile, head->Item.filename); head->Item.verified=TRUE; while (GetPrevLink(head)) { head=GetPrevLink(head); } nameREVFile.close(); } } } head=head->Link; } SetList(Line); return 0; } /********************************************************************** * * Function: VerifyREV * Input: nameREVFile -- A reference to a file to process * outputfile -- a reference to the output file * * Returns: int 0 * * Description: * A function to process the review file and confirm that the values fall * within the specified parameters. Outputs errors when there is a problem. * * Variables: int L -- a loop counter * int numrevlines -- stated number of review lines * int revline -- accumulated number of review lines * int year -- the year the movie was released * char junk -- a garbage array for extracting the unused information * Boolean errorFlag -- used to determine when a file is correct * tm* newtime -- used to hold the time as a structure * time_t aclock -- used to hold the current time in seconds * * Called by: Verify * * Calls: none * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ int VerifyREV (ifstream & nameREVFile, ofstream& outputfile) { int L=1; int numrevlines=0; int revline=0; int year=0; char junk[256]; Boolean errorFlag=FALSE; while (L<3) { nameREVFile.getline(junk, 256, '\n'); L++; } nameREVFile >> year; nameREVFile.getline(junk, 256, '\n'); tm *newtime; time_t aclock; time( &aclock ); /* Get time in seconds */ newtime = localtime( &aclock ); /* Convert time to struct */ if ((year < 0) && (year < 1900) || (year >= ((newtime->tm_year)+1901))) { outputfile << "ERROR: Movie year is not correct." << endl; SetErrorFlag(TRUE); errorFlag=TRUE; } L++; while (L<6) { nameREVFile.getline(junk, 256,'\n'); L++; } nameREVFile >> numrevlines; nameREVFile.getline(junk, 256, '\n'); while (!nameREVFile.eof()) { nameREVFile.ignore(200, '\n'); revline++; } if (revline > numrevlines) { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line 6: There are more review lines than stated. Possibly extra line feeds." << endl; } if (revline < numrevlines) { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line 6: The number of review lines is less than declared. " << endl; } if (errorFlag==FALSE) { outputfile << "File is correctly formatted." << endl; } return 0; } /********************************************************************** * * Function: VerifyMRS * Input: nameVRSFile -- A reference to a file to process * * Returns: int 0 * * Description: * A function to process the MRS file and create nodes for the data * within the file. There is not a full verification in this function, * but enough so that most plausible errors will be found. * * Variables: int realnumlines -- the actual number of lines in the category file * DLnkNodePtr head -- Pointer to the first category node in the list * DLnkNodePtr Line -- Pointer to the current category node * DLnkNodePtr Prev -- Pointer to the previous category node * Boolean errorFlag -- Used for errors * int decnum -- The number of categories from the first line * char filename -- holds the filename until inserted * int numreviews -- holds number of reviews until inserted * char title -- holds title until inserted * char type -- holds the type until inserted * * Called by: Verify * * Calls: CheckExtension * Fexists * CheckNumReviews * Verify * Insert * strcpy * SetList * toupper * CheckStarRating * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ int VerifyMRS (ifstream & nameMRSFile, ofstream& outputfile) { DLnkNodePtr Line = NULL; DLnkNodePtr head = NULL; DLnkNodePtr Remind = NULL; Boolean errorFlag=FALSE; int realnumlines=0; char filename[35]; int numreviews; char title[29]; char type; int index; while (!nameMRSFile.eof()) //this will continue to add nodes to the list until EOF. { nameMRSFile >> type; if ((nameMRSFile.eof()) || (nameMRSFile.fail())) { break; } nameMRSFile.eatwhite(); for (int indice=0;indice<29;indice++) { title[indice]='\0'; } for (indice=0;indice<29;indice++) { nameMRSFile.get(title[indice]); if ((title[indice]==' ') && (title[indice-1]==' ')) { title[indice-1]='\0'; title[indice]='\0'; break; } } if ((nameMRSFile.eof()) || (nameMRSFile.fail())) { break; } nameMRSFile >> numreviews; //read from the file to get the number of reviews nameMRSFile >> index; //read from the file to get the next file name nameMRSFile >> filename; for (indice=0;indice<(abs(strlen(filename)));indice++) { filename[indice]=toupper(filename[indice]); } realnumlines++; type=toupper(type); switch(type) { case 'M': if (!CheckExtension(filename, movieFileExt)) { SetErrorFlag(TRUE); errorFlag=TRUE; outputfile << "Line " << realnumlines << ": File name and type for the file '" << filename << "' do not match." << endl; } if (CheckNumReviews(numreviews)) { SetErrorFlag(TRUE); errorFlag=TRUE; outputfile << "Line " << realnumlines << ": Invalid number of reviews." << endl; } break; case 'R': if (!CheckExtension(filename, reviewFileExt)) { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line " << realnumlines << ": File name and type for the file '" << filename << "' do not match." << endl; } float starRating; starRating=(float(numreviews)/10); if (CheckStarRating(starRating)) { errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line " << realnumlines << ": Invalid star rating."<< endl; } break; default: errorFlag=TRUE; SetErrorFlag(TRUE); outputfile << "Line" << realnumlines << ": Invalid file type '" << type << "'." << endl; break; } if (!Insert(Line, filename, TRUE, index)) Response(JUST_ENTER, 1, "There was an error allocating memory. Please press 'ENTER' to continue."); Line->Item.filetype=type; strcpy (Line->Item.title, title); Line->Item.revieworrating=numreviews; if (!Fexists(filename)) { outputfile << "Line " << realnumlines << ": File '" << filename << "' does not exist." << endl; SetErrorFlag(TRUE); errorFlag=TRUE; } } while (GetPrevLink(Line)) { Line=GetPrevLink(Line); } head=Line; SetList(head); if (errorFlag==FALSE) { outputfile <<"No errors encountered."<Item.filetype=='M') && (head->Item.verified==FALSE) && (CheckExtension(head->Item.filename, movieFileExt))) { if(Fexists(head->Item.filename)) { ifstream nameMOVFile(head->Item.filename); SetList(head); outputfile << endl << head->Item.filename << endl; outputfile << "==============" << endl; head->Item.verified=TRUE; Verify (nameMOVFile, head->Item.revieworrating, 'm', outputfile, head->Item.filename); while (GetPrevLink(head)) { head=GetPrevLink(head); } nameMOVFile.close(); } } if ((head->Item.filetype=='R') && (head->Item.verified==FALSE) && (CheckExtension(head->Item.filename, reviewFileExt))) { if(Fexists(head->Item.filename)) { ifstream nameREVFile(head->Item.filename); outputfile << endl << head->Item.filename << endl; outputfile << "===============" << endl; Verify (nameREVFile, 0, 'r', outputfile, head->Item.filename); head->Item.verified=TRUE; while (GetPrevLink(head)) { head=GetPrevLink(head); } nameREVFile.close(); } } head=head->Link; } SetList(Line); return 0; } /********************************************************************** * * Function: SetErrorFlag * Input: Boolean setvalue * * Returns: void * * Description: * Sets the error found flag * * Variables: none * * Called by: VerifyVRS * VerifyMRS * VerifyMOV * VerifyREV * * Calls: none * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ void SetErrorFlag(Boolean setvalue) { Errorfound=setvalue; } /********************************************************************** * * Function: GetErrorFlag * Input: counter * * Returns: void * * Description: * Returns the status of the error flag * * Variables: none * * Called by: ReadMRS * ReadVRS * * Calls: none * * Author: Tim McGaughey * Revisions: none * Version: 1.0 * * **********************************************************************/ Boolean GetErrorFlag(void) { return Errorfound; }