// Larry Bush April 26, 2002 // // email : bushl2@rpi.edu // Lawrence_Bush@dps.state.ny.us // // Student ID : 660 220 742 // // File Name : buffer.h // Final Proj. : Grep for Windows // Class : Operating Systems // Instructor : Susan Bonner // Language : C++ // //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** //************* ************** //************* Buffer Object ************** //************* ************** //************* Implementation ************** //************* ************** //****************************************************************************************** //****************************************************************************************** //****************************************************************************************** // buffer.h Declares and implements the buffer class. // The buffer class is called by the traverse function and processes // a given file. Processing the file includes opening the file, reading // the file into memory (using the line class to store each line), storing // a temporary copy of the file to disk, searching the file for // a user specified search word (line by line using the line class), // replacing the word with the user specified replacement word (if provided), // saving the revised file back to disk, closing the file and deleting the // temporary file. // // Define makes sure we don't compile this file twice. // Don't define this unique (it is safe to say) variable twice. #if !defined(AFX_BUFFER_H__A892AC06_6934_41DF_A784_5C8E45F6EEED__INCLUDED_) #define AFX_BUFFER_H__A892AC06_6934_41DF_A784_5C8E45F6EEED__INCLUDED_ #include #include #include "line.h" using namespace std; //**************************** // Buffer Class //**************************** // Buffer abstract data type definition. // This classs processs a file including opening, reading, storing // a temporary copy to disk, searching, replacing, saving, closing // and deleting the temporary file. // template // Templated Class class Buffer { private: list v; // instantiate list template from STL list::iterator current; // instantiate current iterator to point to current line int size; // stores number of lines in buffer char *iofile; // stores name of iofile char *tmpfile; // stores name of iofile WIN32_FIND_DATA findData; public: //******************************************************* //******************************************************* //******** ********* //******** Constructors ********* //******** ********* //******************************************************* //******************************************************* // Creates new object. // I don't use this one. Buffer() { // default constructor current=v.begin(); size=0; } // Creates new object. // Opens the file. Buffer(char *file, WIN32_FIND_DATA passed_in_findData) { // constructor findData = passed_in_findData; iofile=file; // copy file name passed to constructor to a class variable tmpfile = new char[strlen(file)+5];// add .tmp and 1 (null terminate) strcpy(tmpfile, file); // copy file name passed to constructor to a class variable strcat(tmpfile, ".tmp"); // add .tmp to file name to uniquely identify it current=v.begin(); // set current pointer to beginning of file size=0; // how many lines in buffer? zero lines in buffer get_lines_from_file(file); // Opens the file. (member function) and gets lines from file savetempfile(); } //******************************************************* //******************************************************* //******** ********* //******** Destructor ********* //******** ********* //******************************************************* //******************************************************* // This closes out any open stuff in Buffer. // In particular, it gets rid of the temp file. ~Buffer() { deleteTempFile(); // deletes file from hard drive and // space allocated for the path name } //******************************************************* //******************************************************* //******** ********* //******** get_lines_rom_file ********* //******** ********* //******************************************************* //******************************************************* // Opens the file and reads in it's lines. // It puts each line into a new Line object. void get_lines_from_file(char *file) { T temp; // Template Type object string str_choice; // Input string to hold the line temporarily. ifstream in; // instantiate ifstream object in.open(file); // open file and set in to point to it if (in == NULL) { // if it is empty, output error and quit cerr << "Sorry, could not open the file '" << file <<"'"<< endl; // cin >> i; exit(0); } while (!in.eof()) { // input lines til end of file getline(in,str_choice,'\n'); temp.setLineFromFile( const_cast(str_choice.c_str())); // set line from file InsertAfter(temp); //adds to end } silentdeleteline(); // delete last line of buffer, without outputting anything //cout << "Loaded " << size << " lines from " << file<< endl; // end iofile } //end get_lines_from_file from file //******************************************************* //******************************************************* //******** ********* //******** savefile ********* //******** ********* //******************************************************* //******************************************************* // Save the file back to the file pointer. // This is done after a search and replace // IF a match was found. void savefile() { ofstream out; // out stream object out.open(iofile); // open the out stream if (out == NULL) { // if the out stream is not ok. cerr << "Sorry, could not open the file" << iofile << endl; //cin >>i; exit(0); // bad out stream so exit } list::iterator i; // Create an iterator to a list of lines to store file. for (i=v.begin(); i != v.end(); ++i) { // Iterate through the list of lines. out << i->getL() << endl; // Print out each line to the file. } // cout << endl; out.close(); // close the out stream } //******************************************************* //******************************************************* //******** ********* //******** delete temp file ********* //******** ********* //******************************************************* //******************************************************* // Deletes the temp file. // When the file processing is all done, we can delete this. void deleteTempFile() { if(!DeleteFile(tmpfile)) { // If successful... // Return Values // Nonzero indicates success. Zero indicates failure. cerr << "\nError Deleting temporary file.\n"; } // At least we notified the user. delete [] tmpfile; // Deallocate the space for the file name. } //******************************************************* //******************************************************* //******** ********* //******** save temp file ********* //******** ********* //******************************************************* //******************************************************* // Saves the file to a temp file. void savetempfile() { ofstream tmpout; // Create out stream object. tmpout.open(tmpfile); // Open the file path. if (tmpout == NULL) { // Is the out stream ok? cerr << "Sorry, could not open the file" << tmpfile << endl; //cin >>i; exit(0); // Bad out stream so quit. } list::iterator i; // Create an iterator to a list of lines to store file. for (i=v.begin(); i != v.end(); ++i) { // Iterate through the list of lines. tmpout << i->getL() << endl; // Print out each line to the file. } // cout << endl; tmpout.close(); // close the out stream }// end of iofile part //*********************************************** //******************************************************* //******************************************************* //******** ********* //******** Insert After ********* //******** ********* //******************************************************* //******************************************************* // Inserts a line into the list. // Does some record keeping. void InsertAfter(const T& item) { //adds to end T t(item); // Create and insert line. v.insert(current,t); // Insert into list. size++; // Increment size } //******************************************************* //******** silent delete line ********* //******************************************************* // Quick fix on the buffer list. //begin silent delete. bool silentdeleteline(){ if (size>1) { list::iterator eline; eline=current; eline--; v.erase(eline); // The list stores lines (not pointers to lines), therefore, the actual line object is deleted (aka erased in stl speak). size--; // Debug: cout << "return true"; if (current != v.begin()) { current++; } return true; } // Debug: cout << "Only one blank line is in the buffer; "<::iterator i; // declare iterator cout << " The list contents are: "<< endl; for (i=v.begin(); i != v.end(); ++i) { // iterate through list i->printline(); // print one line cout << endl; } // cout << *i << " "; cout << endl; } //******************************************************* //******************************************************* //******** ********* //******** search list ********* //******** ********* //******************************************************* //******************************************************* // Search each line of the file for the word. void search_list(char * word_to_find) // search whole buffer { list::iterator i; // declare iterator //cout << " Searching File... for : "<< word_to_find << endl; for (i=v.begin(); i != v.end(); ++i) {// iterate through list //i->printline(); // Call function to find match. if ( (i->match_first(word_to_find)) ) { // If match, print it out. // User Output: cout<<"\n\nMATCH\nFile: " << findData.cFileName; // Print filename cout<<"\nLine: "; i->printline();// print match line // cout << endl; } else {// else do nothing (go to next line) //cout<<"no match that line"; } } //Debug: cout << *i << " "<< endl; } //******************************************************* //******************************************************* //******** ********* //******** search and replace list ********* //******** ********* //******************************************************* //******************************************************* // Search each line of the file for the word. // Replace it if you find it. // This function does this by iterating through the list and // calling the match and replace list function. bool search_and_replace_list(char * word_to_find, char * replacement_word ) { // search whole buffer bool matches; // flag matches = false; //set flag list::iterator i; // declare iterator // Debug: cout << " Searching File... for : "<< word_to_find << endl; for (i=v.begin(); i != v.end(); ++i) { // iterate through list //i->printline(); // check line i for the word. if ( (i->match_first(word_to_find)) ) { // if found, then matches = true; // set flag to true (for this file) // Print user output. // User Output: cout<<"\nMATCH\nFile: " << findData.cFileName; cout<<"\nOld Line: "; i->printline(); // output the line // Replace the matches in the line using the line member function. i->replace_matches_on_this_line(word_to_find, replacement_word); cout<<"\nNew Line: "; i->printline(); // Print line again. cout << endl; } else { //Debug: cout<<"no match that line"; } } //Debug: cout << *i << " "<< endl; // Return flag to calling function (this says to save the changed file. return matches; } //******************************************************* //******************************************************* //******** ********* //******** grep with replacement ********* //******** ********* //******************************************************* //******************************************************* // Main Function to call grep with replacement functions. void grep_with_replacement(char * word_to_find,char * replacement_word) { //cout << "Searching...\n"; // search whole buffer for word, and replace it with other word if(search_and_replace_list(word_to_find, replacement_word) ) { savefile(); // save file if fn returns true. } //debug cout << "End Execute Command\n\n"; } //******************************************************* //******************************************************* //******** ********* //******** grep search only ********* //******** ********* //******************************************************* //******************************************************* // Main Function to call grep search only functions. void grep_search_only(char * word_to_find) // { //cout << "Searching...\n"; // This did do more before. // Now it is a mere shell of a function search_list(word_to_find); // search whole buffer // cout << "End Execute Command\n\n"; } }; #endif // !defined(AFX_BUFFER_H__A892AC06_6934_41DF_A784_5C8E45F6EEED__INCLUDED_)