1 /*
2  *  Copyright (C) 2010  Regents of the University of Michigan
3  *
4  *   This program is free software: you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation, either version 3 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __GLF_FILE_H__
19 #define __GLF_FILE_H__
20 
21 #include "InputFile.h"
22 #include "GlfHeader.h"
23 #include "GlfRefSection.h"
24 #include "GlfRecord.h"
25 #include "GlfStatus.h"
26 
27 /// This class allows a user to easily read/write a GLF file.
28 class GlfFile
29 {
30 public:
31     /// Enum for indicating whether to open the file for read or write.
32     enum OpenType
33         {
34             READ, ///< open for reading.
35             WRITE ///< open for writing.
36         };
37 
38     /// Default Constructor.
39     GlfFile();
40 
41     /// Constructor that opens the specified file based on the specified mode
42     /// (READ/WRITE).  Default is READ.
43     /// \param filename name of the file to open.
44     /// \param mode mode to use for opening the file (defaults to READ).
45     GlfFile(const char* filename, OpenType mode = READ);
46 
47     /// Closes the file if there is one open, adding an end marker record
48     /// if there is a previous section and one has not already been written.
49     virtual ~GlfFile();
50 
51     /// Open a glf file for reading with the specified filename.
52     /// \param  filename glf file to open for reading.
53     /// \return true = success; false = failure.
54     bool openForRead(const char * filename);
55 
56     /// Open a glf file for reading with the specified filename and read the
57     /// header into the specified header.
58     /// \param  filename glf file to open for reading.
59     /// \param  header header object to populate with the file's glf header.
60     /// \return true = success; false = failure.
61     bool openForRead(const char * filename, GlfHeader& header);
62 
63     /// Open a glf file for writing with the specified filename.
64     /// \param  filename glf file to open for writing.
65     /// \param  compressed whether or not to compress the file, defaults to true
66     /// \return true = success; false = failure.
67     bool openForWrite(const char * filename, bool compressed = true);
68 
69     /// Close the file if there is one open, adding an end marker record
70     /// if there is a previous section and one has not already been written.
71     void close();
72 
73     /// Returns whether or not the end of the file has been reached.
74     /// \return true = EOF; false = not eof.
75     /// If the file is not open, true is returned.
76     bool isEOF();
77 
78     /// Reads the header section from the file and stores it in
79     /// the passed in header.
80     /// \param  header header object to populate with the file's glf header.
81     /// \return true = success; false = failure.
82     bool readHeader(GlfHeader& header);
83 
84     /// Writes the specified header into the file.
85     /// \param  header header object to write into the file.
86     /// \return true = success; false = failure.
87     bool writeHeader(GlfHeader& header);
88 
89     /// Gets the next reference section from the file & stores it in the
90     /// passed in section, consuming records until a new section is found.
91     /// \param  refSection object to populate with the file's next reference
92     ///                    section.
93     /// \return true  = section was successfully set.
94     ///         false = section was not successfully set.
95     bool getNextRefSection(GlfRefSection& refSection);
96 
97     /// Write the reference section to the file, adding an end marker record
98     /// if there is a previous section and one has not already been written.
99     /// \param  refSection reference section to write to the file.
100     /// \return true = succes; false = failure.
101     bool writeRefSection(const GlfRefSection& refSection);
102 
103     /// Gets the nextrecord from the file & stores it in the
104     /// passed in record.
105     /// \param  record object to populate with the file's next record.
106     /// \return true  = record was successfully set.
107     ///         false = record not successfully set or for the endMarker record.
108     bool getNextRecord(GlfRecord& record);
109 
110     /// Writes the specified record into the file.
111     /// \param record record to write to the file.
112     /// \return true = success; false = failure.
113     bool writeRecord(const GlfRecord& record);
114 
115     /// Return the number of records that have been read/written so far.
116     /// \return number of records that have been read/written so far.
117     uint32_t getCurrentRecordCount();
118 
119     /// Get the Status of the last call that sets status.
120     /// To remain backwards compatable - will be removed later.
getFailure()121     inline GlfStatus::Status getFailure()
122     {
123         return(getStatus());
124     }
125 
126     /// Get the Status of the last call that sets status.
127     /// \return status of the last method that sets a status.
getStatus()128     inline GlfStatus::Status getStatus()
129     {
130         return(myStatus.getStatus());
131     }
132 
133     /// Get the Status of the last call that sets status.
134     /// \return status message of the last method that sets a status.
getStatusMessage()135     inline const char* getStatusMessage()
136     {
137         return(myStatus.getStatusMessage());
138     }
139 
140 private:
141     /// reset this file including all its attributes.
142     void resetFile();
143 
144     /// Pointer to the file
145     IFILE  myFilePtr;
146 
147     /// Flag to indicate if a file is open for reading.
148     bool myIsOpenForRead;
149     /// Flag to indicate if a file is open for writing.
150     bool myIsOpenForWrite;
151 
152     /// End marker that is inserted when writing files if a new section
153     /// is specified without one or if the file is closed without writing
154     /// an endMarker.
155     GlfRecord myEndMarker;
156 
157     /// Track the state of this file as to what it is expecting to read next.
158     enum EXPECTED_SECTION
159     {
160         HEADER,
161         REF_SECTION,
162         RECORD
163     } myNextSection;
164 
165     /// Keep count of the number of records that have been read/written so far.
166     uint32_t myRecordCount;
167 
168     /// The status of the last GlfFile command.
169     GlfStatus myStatus;
170 };
171 
172 
173 class GlfFileReader : public GlfFile
174 {
175 public:
176 
177     /// Default Constructor.
178     GlfFileReader();
179 
180     /// Constructor that opens the specified file for read.
181      /// \param filename file to open for reading.
182    GlfFileReader(const char* filename);
183 
184     virtual ~GlfFileReader();
185 };
186 
187 
188 class GlfFileWriter : public GlfFile
189 {
190 public:
191     /// Default Constructor.
192     GlfFileWriter();
193 
194     /// Constructor that opens the specified file for write.
195     /// \param filename file to open for writing.
196     GlfFileWriter(const char* filename);
197 
198     virtual ~GlfFileWriter();
199 };
200 
201 #endif
202