18 #include "FileStream.hpp" 20 #include "utils/PVAssert.hpp" 21 #include "utils/PVLog.hpp" 27 FileStream::FileStream(
char const *path, std::ios_base::openmode mode,
bool verifyWrites) {
28 setOutStream(mFStream);
29 openFile(path, mode, verifyWrites);
32 FileStream::~FileStream() {}
34 void FileStream::openFile(
char const *path, std::ios_base::openmode mode,
bool verifyWrites) {
35 string fullPath = expandLeadingTilde(path);
38 mVerifyWrites = verifyWrites;
40 while (!mFStream.is_open()) {
41 mFStream.open(fullPath, mode);
42 if (!mFStream.fail()) {
46 WarnLog() <<
"Failed to open \"" << fullPath <<
"\" on attempt " << attempts <<
"\n";
47 if (attempts < mMaxAttempts) {
54 if (!mFStream.is_open()) {
55 Fatal() <<
"FileStream::openFile failure (" << strerror(errno) <<
") for \"" << fullPath
56 <<
"\": MAX_FILESYSTEMCALL_TRIES = " << mMaxAttempts <<
" exceeded.\n";
58 else if (attempts > 0) {
59 WarnLog() <<
"FileStream::openFile succeeded for \"" << fullPath <<
"\" on attempt " 60 << attempts + 1 <<
"\n";
62 verifyFlags(
"openFile");
65 void FileStream::verifyFlags(
const char *caller) {
66 FatalIf(mFStream.fail(),
"%s %s: Logical error.\n", mFileName.c_str(), caller);
67 FatalIf(mFStream.bad(),
"%s %s: Read / Write error.\n", mFileName.c_str(), caller);
68 FatalIf(writeable() && getOutPos() == -1,
"%s %s: out pos == -1\n", mFileName.c_str(), caller);
69 FatalIf(readable() && getInPos() == -1,
"%s %s: in pos == -1\n", mFileName.c_str(), caller);
72 void FileStream::write(
void const *data,
long length) {
73 long startPos = getOutPos();
74 mFStream.write((
char *)data, length);
78 errmsg.append(
"writing ").append(std::to_string(length)).append(
" bytes");
79 verifyFlags(errmsg.c_str());
81 std::ios_base::openmode mode = std::ios_base::in;
83 mode |= std::ios_base::binary;
85 FileStream writeVerifier(mFileName.c_str(), mode,
false);
87 writeVerifier.setInPos(startPos,
true);
88 std::vector<uint8_t> check(length);
91 writeVerifier.read(check.data(), length);
92 if (memcmp(check.data(), data, length) != 0) {
93 Fatal() <<
"Verify write failed when writing " << length <<
" bytes to position " 100 void FileStream::read(
void *data,
long length) {
101 FatalIf(mFStream.eof(),
"Attempting to read after EOF.\n");
102 long startPos = getInPos();
103 mFStream.read((
char *)data, length);
104 long numRead = mFStream.gcount();
107 "Expected to read %d bytes from %s at position %d; read %d instead. " 108 "New read position: %d\n",
117 void FileStream::setOutPos(
long pos, std::ios_base::seekdir seekAnchor) {
118 mFStream.seekp(pos, seekAnchor);
119 verifyFlags(
"setOutPos");
122 void FileStream::setOutPos(
long pos,
bool fromBeginning) {
123 if (!fromBeginning) {
124 mFStream.seekp(pos, std::ios_base::cur);
129 verifyFlags(
"setOutPos");
132 void FileStream::setInPos(
long pos, std::ios_base::seekdir seekAnchor) {
133 mFStream.seekg(pos, seekAnchor);
134 verifyFlags(
"setInPos");
137 void FileStream::setInPos(
long pos,
bool fromBeginning) {
138 if (!fromBeginning) {
139 mFStream.seekg(pos, std::ios_base::cur);
144 verifyFlags(
"setInPos");
147 long FileStream::getOutPos() {
return mFStream.tellp(); }
149 long FileStream::getInPos() {
return mFStream.tellg(); }