Changeset View
Changeset View
Standalone View
Standalone View
src/streams.h
Show First 20 Lines • Show All 728 Lines • ▼ Show 20 Lines | bool Fill() { | ||||
if (readNow == 0) { | if (readNow == 0) { | ||||
return false; | return false; | ||||
} | } | ||||
size_t nBytes = fread((void *)&vchBuf[pos], 1, readNow, src); | size_t nBytes = fread((void *)&vchBuf[pos], 1, readNow, src); | ||||
if (nBytes == 0) { | if (nBytes == 0) { | ||||
throw std::ios_base::failure( | throw std::ios_base::failure( | ||||
feof(src) ? "CBufferedFile::Fill: end of file" | feof(src) ? "CBufferedFile::Fill: end of file" | ||||
: "CBufferedFile::Fill: fread failed"); | : "CBufferedFile::Fill: fread failed"); | ||||
} else { | } | ||||
nSrcPos += nBytes; | nSrcPos += nBytes; | ||||
return true; | return true; | ||||
} | } | ||||
} | |||||
public: | public: | ||||
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, | CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, | ||||
int nTypeIn, int nVersionIn) | int nTypeIn, int nVersionIn) | ||||
: nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), | : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), | ||||
nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), | nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), | ||||
vchBuf(nBufSize, 0) { | vchBuf(nBufSize, 0) { | ||||
if (nRewindIn >= nBufSize) { | |||||
throw std::ios_base::failure( | |||||
"Rewind limit must be less than buffer size"); | |||||
} | |||||
src = fileIn; | src = fileIn; | ||||
} | } | ||||
~CBufferedFile() { fclose(); } | ~CBufferedFile() { fclose(); } | ||||
// Disallow copies | // Disallow copies | ||||
CBufferedFile(const CBufferedFile &) = delete; | CBufferedFile(const CBufferedFile &) = delete; | ||||
CBufferedFile &operator=(const CBufferedFile &) = delete; | CBufferedFile &operator=(const CBufferedFile &) = delete; | ||||
Show All 11 Lines | public: | ||||
//! check whether we're at the end of the source file | //! check whether we're at the end of the source file | ||||
bool eof() const { return nReadPos == nSrcPos && feof(src); } | bool eof() const { return nReadPos == nSrcPos && feof(src); } | ||||
//! read a number of bytes | //! read a number of bytes | ||||
void read(char *pch, size_t nSize) { | void read(char *pch, size_t nSize) { | ||||
if (nSize + nReadPos > nReadLimit) { | if (nSize + nReadPos > nReadLimit) { | ||||
throw std::ios_base::failure("Read attempted past buffer limit"); | throw std::ios_base::failure("Read attempted past buffer limit"); | ||||
} | } | ||||
if (nSize + nRewind > vchBuf.size()) { | |||||
throw std::ios_base::failure("Read larger than buffer size"); | |||||
} | |||||
while (nSize > 0) { | while (nSize > 0) { | ||||
if (nReadPos == nSrcPos) { | if (nReadPos == nSrcPos) { | ||||
Fill(); | Fill(); | ||||
} | } | ||||
unsigned int pos = nReadPos % vchBuf.size(); | unsigned int pos = nReadPos % vchBuf.size(); | ||||
size_t nNow = nSize; | size_t nNow = nSize; | ||||
if (nNow + pos > vchBuf.size()) { | if (nNow + pos > vchBuf.size()) { | ||||
nNow = vchBuf.size() - pos; | nNow = vchBuf.size() - pos; | ||||
} | } | ||||
if (nNow + nReadPos > nSrcPos) { | if (nNow + nReadPos > nSrcPos) { | ||||
nNow = nSrcPos - nReadPos; | nNow = nSrcPos - nReadPos; | ||||
} | } | ||||
memcpy(pch, &vchBuf[pos], nNow); | memcpy(pch, &vchBuf[pos], nNow); | ||||
nReadPos += nNow; | nReadPos += nNow; | ||||
pch += nNow; | pch += nNow; | ||||
nSize -= nNow; | nSize -= nNow; | ||||
} | } | ||||
} | } | ||||
//! return the current reading position | //! return the current reading position | ||||
uint64_t GetPos() const { return nReadPos; } | uint64_t GetPos() const { return nReadPos; } | ||||
//! rewind to a given reading position | //! rewind to a given reading position | ||||
bool SetPos(uint64_t nPos) { | bool SetPos(uint64_t nPos) { | ||||
nReadPos = nPos; | size_t bufsize = vchBuf.size(); | ||||
if (nReadPos + nRewind < nSrcPos) { | if (nPos + bufsize < nSrcPos) { | ||||
nReadPos = nSrcPos - nRewind; | // rewinding too far, rewind as far as possible | ||||
nReadPos = nSrcPos - bufsize; | |||||
return false; | return false; | ||||
} else if (nReadPos > nSrcPos) { | } | ||||
if (nPos > nSrcPos) { | |||||
// can't go this far forward, go as far as possible | |||||
nReadPos = nSrcPos; | nReadPos = nSrcPos; | ||||
return false; | return false; | ||||
} else { | |||||
return true; | |||||
} | } | ||||
nReadPos = nPos; | |||||
return true; | |||||
} | } | ||||
bool Seek(uint64_t nPos) { | bool Seek(uint64_t nPos) { | ||||
long nLongPos = nPos; | long nLongPos = nPos; | ||||
if (nPos != (uint64_t)nLongPos) { | if (nPos != (uint64_t)nLongPos) { | ||||
return false; | return false; | ||||
} | } | ||||
if (fseek(src, nLongPos, SEEK_SET)) { | if (fseek(src, nLongPos, SEEK_SET)) { | ||||
Show All 39 Lines |