aboutsummaryrefslogtreecommitdiff
path: root/src/serialize.h
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2015-10-29 07:11:24 +0100
committerPieter Wuille <pieter.wuille@gmail.com>2015-11-13 18:15:20 +0100
commit114b5812f6283f2325fc31e186b26c6d76f9551a (patch)
tree6c04a7ee882b7d8a291bb9507ddd5cf17e23f704 /src/serialize.h
parent4f09b77c7fa50afc19d4458c9dd05219c82a298d (diff)
Prevector type
Diffstat (limited to 'src/serialize.h')
-rw-r--r--src/serialize.h157
1 files changed, 119 insertions, 38 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 53d8af142f..5fe7fc1f35 100644
--- a/src/serialize.h
+++ b/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; }
@@ -486,6 +492,20 @@ template<typename Stream, typename C> void Serialize(Stream& os, const std::basi
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.
*/
@@ -500,13 +520,6 @@ template<typename Stream, typename T, typename A, typename V> void Unserialize_i
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
*/
template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
@@ -588,6 +601,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
*/
template<typename T, typename A>
@@ -678,28 +781,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
*/
template<typename K, typename T>