mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Prevector type
This commit is contained in:
157
src/serialize.h
157
src/serialize.h
@@ -20,7 +20,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class CScript;
|
||||
#include "prevector.h"
|
||||
|
||||
static const unsigned int MAX_SIZE = 0x02000000;
|
||||
|
||||
@@ -49,26 +49,26 @@ inline T* NCONST_PTR(const T* val)
|
||||
* @note These functions avoid the undefined case of indexing into an empty
|
||||
* vector, as well as that of indexing after the end of the vector.
|
||||
*/
|
||||
template <class T, class TAl>
|
||||
inline T* begin_ptr(std::vector<T,TAl>& v)
|
||||
template <typename V>
|
||||
inline typename V::value_type* begin_ptr(V& v)
|
||||
{
|
||||
return v.empty() ? NULL : &v[0];
|
||||
}
|
||||
/** Get begin pointer of vector (const version) */
|
||||
template <class T, class TAl>
|
||||
inline const T* begin_ptr(const std::vector<T,TAl>& v)
|
||||
template <typename V>
|
||||
inline const typename V::value_type* begin_ptr(const V& v)
|
||||
{
|
||||
return v.empty() ? NULL : &v[0];
|
||||
}
|
||||
/** Get end pointer of vector (non-const version) */
|
||||
template <class T, class TAl>
|
||||
inline T* end_ptr(std::vector<T,TAl>& v)
|
||||
template <typename V>
|
||||
inline typename V::value_type* end_ptr(V& v)
|
||||
{
|
||||
return v.empty() ? NULL : (&v[0] + v.size());
|
||||
}
|
||||
/** Get end pointer of vector (const version) */
|
||||
template <class T, class TAl>
|
||||
inline const T* end_ptr(const std::vector<T,TAl>& v)
|
||||
template <typename V>
|
||||
inline const typename V::value_type* end_ptr(const V& v)
|
||||
{
|
||||
return v.empty() ? NULL : (&v[0] + v.size());
|
||||
}
|
||||
@@ -391,6 +391,12 @@ public:
|
||||
pbegin = (char*)begin_ptr(v);
|
||||
pend = (char*)end_ptr(v);
|
||||
}
|
||||
template <unsigned int N, typename T, typename S, typename D>
|
||||
explicit CFlatData(prevector<N, T, S, D> &v)
|
||||
{
|
||||
pbegin = (char*)begin_ptr(v);
|
||||
pend = (char*)end_ptr(v);
|
||||
}
|
||||
char* begin() { return pbegin; }
|
||||
const char* begin() const { return pbegin; }
|
||||
char* end() { return pend; }
|
||||
@@ -485,6 +491,20 @@ template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& s
|
||||
template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
|
||||
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
|
||||
|
||||
/**
|
||||
* prevector
|
||||
* prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
|
||||
*/
|
||||
template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
|
||||
template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&);
|
||||
template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion);
|
||||
template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
|
||||
template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&);
|
||||
template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion);
|
||||
template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
|
||||
template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&);
|
||||
template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion);
|
||||
|
||||
/**
|
||||
* vector
|
||||
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
|
||||
@@ -499,13 +519,6 @@ template<typename Stream, typename T, typename A> void Unserialize_impl(Stream&
|
||||
template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
|
||||
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
|
||||
|
||||
/**
|
||||
* others derived from vector
|
||||
*/
|
||||
extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
|
||||
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
|
||||
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
|
||||
|
||||
/**
|
||||
* pair
|
||||
*/
|
||||
@@ -587,6 +600,96 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* prevector
|
||||
*/
|
||||
template<unsigned int N, typename T>
|
||||
unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
|
||||
{
|
||||
return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
|
||||
}
|
||||
|
||||
template<unsigned int N, typename T, typename V>
|
||||
unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&)
|
||||
{
|
||||
unsigned int nSize = GetSizeOfCompactSize(v.size());
|
||||
for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
|
||||
nSize += GetSerializeSize((*vi), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<unsigned int N, typename T>
|
||||
inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion)
|
||||
{
|
||||
return GetSerializeSize_impl(v, nType, nVersion, T());
|
||||
}
|
||||
|
||||
|
||||
template<typename Stream, unsigned int N, typename T>
|
||||
void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
if (!v.empty())
|
||||
os.write((char*)&v[0], v.size() * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename Stream, unsigned int N, typename T, typename V>
|
||||
void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&)
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
|
||||
::Serialize(os, (*vi), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, unsigned int N, typename T>
|
||||
inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion)
|
||||
{
|
||||
Serialize_impl(os, v, nType, nVersion, T());
|
||||
}
|
||||
|
||||
|
||||
template<typename Stream, unsigned int N, typename T>
|
||||
void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
|
||||
{
|
||||
// Limit size per read so bogus size value won't cause out of memory
|
||||
v.clear();
|
||||
unsigned int nSize = ReadCompactSize(is);
|
||||
unsigned int i = 0;
|
||||
while (i < nSize)
|
||||
{
|
||||
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
|
||||
v.resize(i + blk);
|
||||
is.read((char*)&v[i], blk * sizeof(T));
|
||||
i += blk;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Stream, unsigned int N, typename T, typename V>
|
||||
void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&)
|
||||
{
|
||||
v.clear();
|
||||
unsigned int nSize = ReadCompactSize(is);
|
||||
unsigned int i = 0;
|
||||
unsigned int nMid = 0;
|
||||
while (nMid < nSize)
|
||||
{
|
||||
nMid += 5000000 / sizeof(T);
|
||||
if (nMid > nSize)
|
||||
nMid = nSize;
|
||||
v.resize(nMid);
|
||||
for (; i < nMid; i++)
|
||||
Unserialize(is, v[i], nType, nVersion);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Stream, unsigned int N, typename T>
|
||||
inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion)
|
||||
{
|
||||
Unserialize_impl(is, v, nType, nVersion, T());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* vector
|
||||
*/
|
||||
@@ -677,28 +780,6 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersio
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* others derived from vector
|
||||
*/
|
||||
inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
|
||||
{
|
||||
return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
|
||||
{
|
||||
Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
|
||||
{
|
||||
Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* pair
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user