// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SERIALIZE_H
#define BITCOIN_SERIALIZE_H
#if defined(_MSC_VER) && _MSC_VER < 1300
#define for if (false) ; else for
#endif
+
+#ifdef WIN32
+#include <windows.h>
+// This is used to attempt to keep keying material out of swap
+// Note that VirtualLock does not provide this as a guarantee on Windows,
+// but, in practice, memory that has been VirtualLock'd almost never gets written to
+// the pagefile except in rare circumstances where memory is extremely low.
+#include <windows.h>
+#define mlock(p, n) VirtualLock((p), (n));
+#define munlock(p, n) VirtualUnlock((p), (n));
+#else
+#include <sys/mman.h>
+#include <limits.h>
+/* This comes from limits.h if it's not defined there set a sane default */
+#ifndef PAGESIZE
+#include <unistd.h>
+#define PAGESIZE sysconf(_SC_PAGESIZE)
+#endif
+#define mlock(a,b) \
+ mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
+ (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
+#define munlock(a,b) \
+ munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
+ (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
+#endif
+
class CScript;
class CDataStream;
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
-static const int VERSION = 32200;
+static const int VERSION = 50601;
static const char* pszSubVer = "";
static const bool VERSION_IS_BETA = true;
-
-
-
-
+// Used to bypass the rule against non-const reference to temporary
+// where it makes sense with wrappers such as CFlatData or CTxDB
+template<typename T>
+inline T& REF(const T& val)
+{
+ return const_cast<T&>(val);
+}
/////////////////////////////////////////////////////////////////
//
const bool fRead = false; \
unsigned int nSerSize = 0; \
ser_streamplaceholder s; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
s.nType = nType; \
s.nVersion = nVersion; \
{statements} \
const bool fWrite = true; \
const bool fRead = false; \
unsigned int nSerSize = 0; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
{statements} \
} \
template<typename Stream> \
const bool fWrite = false; \
const bool fRead = true; \
unsigned int nSerSize = 0; \
+ assert(fGetSize||fWrite||fRead); /* suppress warning */ \
{statements} \
}
//
-// Allocator that clears its contents before deletion
+// Allocator that locks its contents from being paged
+// out of memory and clears its contents before deletion.
//
template<typename T>
struct secure_allocator : public std::allocator<T>
template<typename _Other> struct rebind
{ typedef secure_allocator<_Other> other; };
+ T* allocate(std::size_t n, const void *hint = 0)
+ {
+ T *p;
+ p = std::allocator<T>::allocate(n, hint);
+ if (p != NULL)
+ mlock(p, sizeof(T) * n);
+ return p;
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL)
+ {
+ memset(p, 0, sizeof(T) * n);
+ munlock(p, sizeof(T) * n);
+ }
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+
+//
+// Allocator that clears its contents before deletion.
+//
+template<typename T>
+struct zero_after_free_allocator : public std::allocator<T>
+{
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> base;
+ typedef typename base::size_type size_type;
+ typedef typename base::difference_type difference_type;
+ typedef typename base::pointer pointer;
+ typedef typename base::const_pointer const_pointer;
+ typedef typename base::reference reference;
+ typedef typename base::const_reference const_reference;
+ typedef typename base::value_type value_type;
+ zero_after_free_allocator() throw() {}
+ zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
+ template <typename U>
+ zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
+ ~zero_after_free_allocator() throw() {}
+ template<typename _Other> struct rebind
+ { typedef zero_after_free_allocator<_Other> other; };
+
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
class CDataStream
{
protected:
- typedef std::vector<char, secure_allocator<char> > vector_type;
+ typedef std::vector<char, zero_after_free_allocator<char> > vector_type;
vector_type vch;
unsigned int nReadPos;
short state;
int nType;
int nVersion;
- typedef FILE element_type;
-
CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
{
file = filenew;