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

View File

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

View File

@ -21,9 +21,8 @@ enum OpenMode {
NOT_OPEN, NOT_OPEN,
}; };
class File { class File : public std::fstream {
private: private:
std::fstream stream;
OpenMode mode; OpenMode mode;
FileLocHint hint; FileLocHint hint;
std::string filepath; std::string filepath;
@ -37,9 +36,11 @@ public:
File(std::string, FileLocHint); File(std::string, FileLocHint);
~File(); ~File();
const char *get_filepath(); const char *get_filepath();
const unsigned int get_version();
bool exists(); bool exists();
bool open(OpenMode); bool open(OpenMode);
bool close(); bool close();
std::string getline();
}; };
#endif /* OCARINA_FILE_H */ #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) 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; std::string dir;
@ -58,6 +58,11 @@ const char *File :: get_filepath()
return filepath.c_str(); return filepath.c_str();
} }
const unsigned int File :: get_version()
{
return version;
}
bool File :: exists() bool File :: exists()
{ {
return g_file_test(filepath.c_str(), G_FILE_TEST_EXISTS); return g_file_test(filepath.c_str(), G_FILE_TEST_EXISTS);
@ -70,15 +75,16 @@ bool File :: open_read()
return false; return false;
} }
stream.open(filepath.c_str(), std::fstream::in); std::fstream::open(filepath.c_str(), std::fstream::in);
if (stream.fail()) { if (std::fstream::fail()) {
dprint("ERROR: Could not open file for reading (%s)\n", filepath.c_str()); dprint("ERROR: Could not open file for reading (%s)\n", filepath.c_str());
return false; return false;
} }
mode = OPEN_READ; mode = OPEN_READ;
stream >> version; std::fstream::operator>>(version);
return stream.good(); getline();
return std::fstream::good();
} }
bool File :: open_write() bool File :: open_write()
@ -95,15 +101,15 @@ bool File :: open_write()
return false; return false;
} }
stream.open(filepath.c_str(), std::fstream::out); std::fstream::open(filepath.c_str(), std::fstream::out);
if (stream.fail()) { if (std::fstream::fail()) {
dprint("ERROR: Could not open file for writing (%s)\n", filepath.c_str()); dprint("ERROR: Could not open file for writing (%s)\n", filepath.c_str());
return false; return false;
} }
mode = OPEN_WRITE; mode = OPEN_WRITE;
stream << version << std::endl; std::fstream::operator<<(FILE_VERSION) << std::endl;
return stream.good(); return std::fstream::good();
} }
bool File :: open(OpenMode m) bool File :: open(OpenMode m)
@ -125,7 +131,14 @@ bool File :: open(OpenMode m)
bool File :: close() bool File :: close()
{ {
if (mode != NOT_OPEN) if (mode != NOT_OPEN)
stream.close(); std::fstream::close();
mode = NOT_OPEN; 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", "compile.cpp")
Test("file", "open.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