//
// Compact size
-// size < 253 -- 1 byte
-// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
-// size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
-// size > UINT_MAX -- 9 bytes (255 + 8 bytes)
+// size < 253 -- 1 byte
+// size <= UINT16_MAX -- 3 bytes (253 + 2 bytes)
+// size <= UINT32_MAX -- 5 bytes (254 + 4 bytes)
+// size > UINT32_MAX -- 9 bytes (255 + 8 bytes)
//
-inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
+inline uint32_t GetSizeOfCompactSize(uint64_t nSize)
{
- if (nSize < 253) return sizeof(unsigned char);
- else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
- else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
- else return sizeof(unsigned char) + sizeof(uint64_t);
+ if (nSize < 0xfd)
+ return 1;
+ if (nSize <= std::numeric_limits<uint16_t>::max())
+ return 3;
+ if (nSize <= std::numeric_limits<uint32_t>::max())
+ return 5;
+ return 9;
}
template<typename Stream>
iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
- void insert(iterator it, const_iterator first, const_iterator last)
- {
- assert(last - first >= 0);
- if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
- {
- // special case for inserting at the front when there's room
- nReadPos -= (unsigned int)(last - first);
- memcpy(&vch[nReadPos], &first[0], last - first);
- }
- else
- vch.insert(it, first, last);
- }
-
-#ifndef _MSC_VER
void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
{
assert(last - first >= 0);
else
vch.insert(it, first, last);
}
-#endif
void insert(iterator it, const char* first, const char* last)
{
nReadPos = 0;
}
- bool Rewind(size_type n)
- {
- // Rewind by n characters if the buffer hasn't been compacted yet
- if (n > nReadPos)
- return false;
- nReadPos -= (unsigned int)n;
- return true;
- }
-
+ bool Rewind(size_type n);
//
// Stream subset
//
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
+ void setstate(short bits, const char* psz);
bool eof() const { return size() == 0; }
bool fail() const { return (state & (std::ios::badbit | std::ios::failbit)) != 0; }
bool good() const { return !eof() && (state == 0); }
void ReadVersion() { *this >> nVersion; }
void WriteVersion() { *this << nVersion; }
- CDataStream& read(char* pch, int nSize)
- {
- // Read from the beginning of the buffer
- assert(nSize >= 0);
- unsigned int nReadPosNext = nReadPos + nSize;
- if (nReadPosNext >= vch.size())
- {
- if (nReadPosNext > vch.size())
- {
- setstate(std::ios::failbit, "CDataStream::read() : end of data");
- memset(pch, 0, nSize);
- nSize = (int)(vch.size() - nReadPos);
- }
- memcpy(pch, &vch[nReadPos], nSize);
- nReadPos = 0;
- vch.clear();
- return (*this);
- }
- memcpy(pch, &vch[nReadPos], nSize);
- nReadPos = nReadPosNext;
- return (*this);
- }
-
- CDataStream& ignore(int nSize)
- {
- // Ignore from the beginning of the buffer
- assert(nSize >= 0);
- unsigned int nReadPosNext = nReadPos + nSize;
- if (nReadPosNext >= vch.size())
- {
- if (nReadPosNext > vch.size())
- setstate(std::ios::failbit, "CDataStream::ignore() : end of data");
- nReadPos = 0;
- vch.clear();
- return (*this);
- }
- nReadPos = nReadPosNext;
- return (*this);
- }
-
- CDataStream& write(const char* pch, int nSize)
- {
- // Write to the end of the buffer
- assert(nSize >= 0);
- vch.insert(vch.end(), pch, pch + nSize);
- return (*this);
- }
+ CDataStream& read(char* pch, int nSize);
+ CDataStream& ignore(int nSize);
+ CDataStream& write(const char* pch, int nSize);
template<typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
return (*this);
}
- void GetAndClear(CSerializeData &data) {
- vch.swap(data);
- CSerializeData().swap(vch);
- }
+ void GetAndClear(CSerializeData &data);
};
-
-
-
-
-
-
-
-
-/** RAII wrapper for FILE*.
- *
- * Will automatically close the file when it goes out of scope if not null.
- * If you're returning the file pointer, return file.release().
- * If you need to close the file early, use file.fclose() instead of fclose(file).
- */
+// RAII wrapper for FILE*.
+//
+// Will automatically close the file when it goes out of scope if not null.
+// If you're returning the file pointer, return file.release().
+// If you need to close the file early, use file.fclose() instead of fclose(file).
class CAutoFile
{
protected:
int nType;
int nVersion;
- CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
- {
- file = filenew;
- nType = nTypeIn;
- nVersion = nVersionIn;
- state = 0;
- exceptmask = std::ios::badbit | std::ios::failbit;
- }
-
- ~CAutoFile()
- {
- fclose();
- }
-
- void fclose()
- {
- if (file != NULL && file != stdin && file != stdout && file != stderr)
- ::fclose(file);
- file = NULL;
- }
+ CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn);
+ ~CAutoFile();
+ void fclose();
FILE* release() { FILE* ret = file; file = NULL; return ret; }
operator FILE*() { return file; }
//
// Stream subset
//
- void setstate(short bits, const char* psz)
- {
- state |= bits;
- if (state & exceptmask)
- throw std::ios_base::failure(psz);
- }
-
+ void setstate(short bits, const char* psz);
bool fail() const { return (state & (std::ios::badbit | std::ios::failbit)) != 0; }
bool good() const { return state == 0; }
void clear(short n = 0) { state = n; }
void ReadVersion() { *this >> nVersion; }
void WriteVersion() { *this << nVersion; }
- CAutoFile& read(char* pch, size_t nSize)
- {
- if (!file)
- throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
- if (fread(pch, 1, nSize, file) != nSize)
- setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
- return (*this);
- }
-
- CAutoFile& write(const char* pch, size_t nSize)
- {
- if (!file)
- throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
- if (fwrite(pch, 1, nSize, file) != nSize)
- setstate(std::ios::failbit, "CAutoFile::write : write failed");
- return (*this);
- }
+ CAutoFile& read(char* pch, size_t nSize);
+ CAutoFile& write(const char* pch, size_t nSize);
template<typename T>
unsigned int GetSerializeSize(const T& obj)