4 template<typename Stream>
5 void WriteCompactSize(Stream& os, uint64_t nSize)
9 auto chSize = (uint8_t)nSize;
10 WRITEDATA(os, chSize);
12 else if (nSize <= std::numeric_limits<uint16_t>::max())
14 uint8_t chSize = 0xfd;
15 auto xSize = (uint16_t)nSize;
16 WRITEDATA(os, chSize);
19 else if (nSize <= std::numeric_limits<uint32_t>::max())
21 uint8_t chSize = 0xfe;
22 auto xSize = (uint32_t)nSize;
23 WRITEDATA(os, chSize);
28 uint8_t chSize = 0xff;
30 WRITEDATA(os, chSize);
37 template<typename Stream>
38 uint64_t ReadCompactSize(Stream& is)
42 uint64_t nSizeRet = 0;
47 else if (chSize == 0xfd)
53 else if (chSize == 0xfe)
65 if (nSizeRet > (uint64_t)MAX_SIZE)
66 throw std::ios_base::failure("ReadCompactSize() : size too large");
72 // Template instantiation
74 template void WriteCompactSize<CAutoFile>(CAutoFile&, uint64_t);
75 template void WriteCompactSize<CDataStream>(CDataStream&, uint64_t);
76 template void WriteCompactSize<CHashWriter>(CHashWriter&, uint64_t);
78 template uint64_t ReadCompactSize<CAutoFile>(CAutoFile&);
79 template uint64_t ReadCompactSize<CDataStream>(CDataStream&);
85 CAutoFile::CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
89 nVersion = nVersionIn;
91 exceptmask = std::ios::badbit | std::ios::failbit;
94 CAutoFile::~CAutoFile()
99 void CAutoFile::fclose()
101 if (file != NULL && file != stdin && file != stdout && file != stderr)
106 void CAutoFile::setstate(short bits, const char* psz)
109 if (state & exceptmask)
110 throw std::ios_base::failure(psz);
113 CAutoFile& CAutoFile::read(char* pch, size_t nSize)
116 throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
117 if (fread(pch, 1, nSize, file) != nSize)
118 setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
122 CAutoFile& CAutoFile::write(const char* pch, size_t nSize)
125 throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
126 if (fwrite(pch, 1, nSize, file) != nSize)
127 setstate(std::ios::failbit, "CAutoFile::write : write failed");
135 void CBufferedFile::setstate(short bits, const char *psz)
138 if (state & exceptmask)
139 throw std::ios_base::failure(psz);
142 bool CBufferedFile::Fill()
144 auto pos = (uint32_t)(nSrcPos % vchBuf.size());
145 auto readNow = (uint32_t)(vchBuf.size() - pos);
146 auto nAvail = (uint32_t)(vchBuf.size() - (nSrcPos - nReadPos) - nRewind);
147 if (nAvail < readNow)
151 size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
153 setstate(std::ios_base::failbit, feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
161 CBufferedFile::CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
162 src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0),
163 state(0), exceptmask(std::ios_base::badbit | std::ios_base::failbit), nType(nTypeIn), nVersion(nVersionIn) { }
165 bool CBufferedFile::good() const
170 bool CBufferedFile::eof() const
172 return nReadPos == nSrcPos && feof(src);
175 CBufferedFile& CBufferedFile::read(char *pch, size_t nSize)
177 if (nSize + nReadPos > nReadLimit)
178 throw std::ios_base::failure("Read attempted past buffer limit");
179 if (nSize + nRewind > vchBuf.size())
180 throw std::ios_base::failure("Read larger than buffer size");
182 if (nReadPos == nSrcPos)
184 auto pos = (uint32_t)(nReadPos % vchBuf.size());
186 if (nNow + pos > vchBuf.size())
187 nNow = vchBuf.size() - pos;
188 if (nNow + nReadPos > nSrcPos)
189 nNow = (size_t)(nSrcPos - nReadPos);
190 memcpy(pch, &vchBuf[pos], nNow);
198 uint64_t CBufferedFile::GetPos()
203 bool CBufferedFile::SetPos(uint64_t nPos)
206 if (nReadPos + nRewind < nSrcPos) {
207 nReadPos = nSrcPos - nRewind;
209 } else if (nReadPos > nSrcPos) {
217 bool CBufferedFile::Seek(uint64_t nPos)
219 long nLongPos = (long)nPos;
220 if (nPos != (uint64_t)nLongPos)
222 if (fseek(src, nLongPos, SEEK_SET))
224 nLongPos = ftell(src);
231 bool CBufferedFile::SetLimit(uint64_t nPos)
239 void CBufferedFile::FindByte(char ch)
242 if (nReadPos == nSrcPos)
244 if (vchBuf[nReadPos % vchBuf.size()] == ch)