file: Implement reading and writing

- Inherit from fstream to gain access to << and >> operators.
- Make the file version accessable to the outside world.

Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
Bryan Schumaker 2013-07-28 22:33:40 -04:00 committed by Anna Schumaker
parent ecd56831f6
commit 328c6f70e8
8 changed files with 116 additions and 49 deletions

View File

@ -165,11 +165,8 @@ On-disk files: (lib/file.cpp)
}
- File:
class File {
class File : std::fstream {
private:
ifstream in;
ofstream out;
unsigned int version;
OpenMode mode;
FileLocHint hint;
@ -179,18 +176,16 @@ On-disk files: (lib/file.cpp)
File(string, FileLocHint);
~File();
const char *get_filepath();
const unsigned int get_version();
bool exists();
bool open(OpenMode);
bool close();
const File &operator<<(File &);
const File &operator>>(File &);
void getline(string &);
string getline();
}
- File format:
File << FILE_VERSION << endl;
File << <OTHER_DATA> << endl;
File << <OTHER_DATA>;
- API:
File : File(string filepath, FileLocHint hint)
@ -207,6 +202,9 @@ On-disk files: (lib/file.cpp)
const char *get_filepath()
Return the full filepath to the file.
const unsigned int get_version()
Return the file version number.
bool File : exists()
Return true if the file exists in the filesystem.
Return false otherwise.
@ -227,17 +225,13 @@ On-disk files: (lib/file.cpp)
Return false if the file is already open.
Return false if there are any other errors.
void File : close()
bool File : close()
Close a file after IO.
File : operator<<()
Write data to the file.
File : operator>>()
Read data from the file.
File : getline(string);
Read an entire line from the file, strip whitespace on either end
string File : getline();
Read an entire line from the file and return it to the caller.
In theory a return value optimization will occur so returning
a string by value won't be a problem.

View File

@ -46,11 +46,8 @@ On-disk files: (lib/file.cpp)
}
- File:
class File {
class File : std::fstream {
private:
ifstream in;
ofstream out;
unsigned int version;
OpenMode mode;
FileLocHint hint;
@ -60,18 +57,16 @@ On-disk files: (lib/file.cpp)
File(string, FileLocHint);
~File();
const char *get_filepath();
const unsigned int get_version();
bool exists();
bool open(OpenMode);
bool close();
const File &operator<<(File &);
const File &operator>>(File &);
void getline(string &);
string getline();
}
- File format:
File << FILE_VERSION << endl;
File << <OTHER_DATA> << endl;
File << <OTHER_DATA>;
- API:
File : File(string filepath, FileLocHint hint)
@ -88,6 +83,9 @@ On-disk files: (lib/file.cpp)
const char *get_filepath()
Return the full filepath to the file.
const unsigned int get_version()
Return the file version number.
bool File : exists()
Return true if the file exists in the filesystem.
Return false otherwise.
@ -108,14 +106,10 @@ On-disk files: (lib/file.cpp)
Return false if the file is already open.
Return false if there are any other errors.
void File : close()
bool File : close()
Close a file after IO.
File : operator<<()
Write data to the file.
File : operator>>()
Read data from the file.
File : getline(string);
Read an entire line from the file, strip whitespace on either end
string File : getline();
Read an entire line from the file and return it to the caller.
In theory a return value optimization will occur so returning
a string by value won't be a problem.

View File

@ -21,9 +21,8 @@ enum OpenMode {
NOT_OPEN,
};
class File {
class File : public std::fstream {
private:
std::fstream stream;
OpenMode mode;
FileLocHint hint;
std::string filepath;
@ -37,9 +36,11 @@ public:
File(std::string, FileLocHint);
~File();
const char *get_filepath();
const unsigned int get_version();
bool exists();
bool open(OpenMode);
bool close();
std::string getline();
};
#endif /* OCARINA_FILE_H */

View File

@ -40,7 +40,7 @@ void File :: find_dir(std::string &res)
}
File :: File(std::string path, FileLocHint file_hint)
: mode(NOT_OPEN), hint(file_hint), version(FILE_VERSION)
: mode(NOT_OPEN), hint(file_hint)
{
std::string dir;
@ -58,6 +58,11 @@ const char *File :: get_filepath()
return filepath.c_str();
}
const unsigned int File :: get_version()
{
return version;
}
bool File :: exists()
{
return g_file_test(filepath.c_str(), G_FILE_TEST_EXISTS);
@ -70,15 +75,16 @@ bool File :: open_read()
return false;
}
stream.open(filepath.c_str(), std::fstream::in);
if (stream.fail()) {
std::fstream::open(filepath.c_str(), std::fstream::in);
if (std::fstream::fail()) {
dprint("ERROR: Could not open file for reading (%s)\n", filepath.c_str());
return false;
}
mode = OPEN_READ;
stream >> version;
return stream.good();
std::fstream::operator>>(version);
getline();
return std::fstream::good();
}
bool File :: open_write()
@ -95,15 +101,15 @@ bool File :: open_write()
return false;
}
stream.open(filepath.c_str(), std::fstream::out);
if (stream.fail()) {
std::fstream::open(filepath.c_str(), std::fstream::out);
if (std::fstream::fail()) {
dprint("ERROR: Could not open file for writing (%s)\n", filepath.c_str());
return false;
}
mode = OPEN_WRITE;
stream << version << std::endl;
return stream.good();
std::fstream::operator<<(FILE_VERSION) << std::endl;
return std::fstream::good();
}
bool File :: open(OpenMode m)
@ -125,7 +131,14 @@ bool File :: open(OpenMode m)
bool File :: close()
{
if (mode != NOT_OPEN)
stream.close();
std::fstream::close();
mode = NOT_OPEN;
return stream.good();
return std::fstream::good();
}
std::string File :: getline()
{
std::string res;
std::getline(*static_cast<std::fstream *>(this), res);
return res;
}

View File

@ -5,3 +5,4 @@ CONFIG.FILE = True
Test("file", "compile.cpp")
Test("file", "open.cpp")
Test("file", "io.cpp")

7
tests/file/io-debug.good Normal file
View File

@ -0,0 +1,7 @@
Writing data to file: /home/anna/.local/share/ocarina-test/test.io
Closing file
Reading file
File version is: 0
Hello, World!
This is a multi-line file =)
a: 1, b: 2, c: 3, d: 4, e: 5

50
tests/file/io.cpp Normal file
View File

@ -0,0 +1,50 @@
/*
* Test reading and writing to files
*/
#include <file.h>
#include <test.h>
#include <print.h>
int main(int argc, char **argv)
{
int a, b, c, d, e;
File file("test.io", FILE_TYPE_DATA);
rm_test_data();
print("Writing data to file: %s\n", file.get_filepath());
if (!file.open(OPEN_WRITE))
return 1;
file << "Hello, World!" << std::endl;
file << "This is a multi-line file =)" << std::endl;
file << "1 2 3 4 5" << std::endl;
print("Closing file\n");
if (!file.close())
return 1;
print("Reading file\n");
if (!file.open(OPEN_READ))
return 1;
print("File version is: %u\n", file.get_version());
print("\t%s\n", file.getline().c_str());
if (!file.good())
return 1;
print("\t%s\n", file.getline().c_str());
if (!file.good())
return 1;
file >> a >> b >> c >> d >> e;
if (!file.good())
return 1;
print("\ta: %d, b: %d, c: %d, d: %d, e: %d\n", a, b, c, d, e);
if (!file.close())
return 1;
return 0;
}

7
tests/file/io.good Normal file
View File

@ -0,0 +1,7 @@
Writing data to file: /home/anna/.local/share/ocarina-test/test.io
Closing file
Reading file
File version is: 0
Hello, World!
This is a multi-line file =)
a: 1, b: 2, c: 3, d: 4, e: 5