4 template<typename Stream>
5 void WriteCompactSize(Stream& os, uint64_t nSize)
9 unsigned char chSize = (unsigned char)nSize;
10 WRITEDATA(os, chSize);
12 else if (nSize <= std::numeric_limits<unsigned short>::max())
14 unsigned char chSize = 253;
15 unsigned short xSize = (unsigned short)nSize;
16 WRITEDATA(os, chSize);
19 else if (nSize <= std::numeric_limits<unsigned int>::max())
21 unsigned char chSize = 254;
22 unsigned int xSize = (unsigned int)nSize;
23 WRITEDATA(os, chSize);
28 unsigned char chSize = 255;
29 uint64_t xSize = nSize;
30 WRITEDATA(os, chSize);
37 template<typename Stream>
38 uint64_t ReadCompactSize(Stream& is)
42 uint64_t nSizeRet = 0;
47 else if (chSize == 253)
53 else if (chSize == 254)
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 void CBufferedFile::setstate(short bits, const char *psz)
88 if (state & exceptmask)
89 throw std::ios_base::failure(psz);
92 bool CBufferedFile::Fill()
94 unsigned int pos = (unsigned int)(nSrcPos % vchBuf.size());
95 unsigned int readNow = (unsigned int)(vchBuf.size() - pos);
96 unsigned int nAvail = (unsigned int)(vchBuf.size() - (nSrcPos - nReadPos) - nRewind);
101 size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
103 setstate(std::ios_base::failbit, feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
111 CBufferedFile::CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
112 src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0),
113 state(0), exceptmask(std::ios_base::badbit | std::ios_base::failbit), nType(nTypeIn), nVersion(nVersionIn) { }
115 bool CBufferedFile::good() const
120 bool CBufferedFile::eof() const
122 return nReadPos == nSrcPos && feof(src);
125 CBufferedFile& CBufferedFile::read(char *pch, size_t nSize)
127 if (nSize + nReadPos > nReadLimit)
128 throw std::ios_base::failure("Read attempted past buffer limit");
129 if (nSize + nRewind > vchBuf.size())
130 throw std::ios_base::failure("Read larger than buffer size");
132 if (nReadPos == nSrcPos)
134 unsigned int pos = (unsigned int)(nReadPos % vchBuf.size());
136 if (nNow + pos > vchBuf.size())
137 nNow = vchBuf.size() - pos;
138 if (nNow + nReadPos > nSrcPos)
139 nNow = (size_t)(nSrcPos - nReadPos);
140 memcpy(pch, &vchBuf[pos], nNow);
148 uint64_t CBufferedFile::GetPos()
153 bool CBufferedFile::SetPos(uint64_t nPos)
156 if (nReadPos + nRewind < nSrcPos) {
157 nReadPos = nSrcPos - nRewind;
159 } else if (nReadPos > nSrcPos) {
167 bool CBufferedFile::Seek(uint64_t nPos)
169 long nLongPos = (long)nPos;
170 if (nPos != (uint64_t)nLongPos)
172 if (fseek(src, nLongPos, SEEK_SET))
174 nLongPos = ftell(src);
181 bool CBufferedFile::SetLimit(uint64_t nPos)
189 void CBufferedFile::FindByte(char ch)
192 if (nReadPos == nSrcPos)
194 if (vchBuf[nReadPos % vchBuf.size()] == ch)