diff --git a/src/Store/BStore.cpp b/src/Store/BStore.cpp index 27532dd..3a53e4a 100644 --- a/src/Store/BStore.cpp +++ b/src/Store/BStore.cpp @@ -746,7 +746,7 @@ bool BStore::Serialise(BinaryStream &bs){ // do return properly bs & output; bs & m_lookup; GetEntry(0); - /* +#if 0 save; if(bs.m_write){ @@ -761,9 +761,9 @@ bool BStore::Serialise(BinaryStream &bs){ // do return properly close open } - */ +#endif - /* +#if 0 bs & m_lookup; @@ -789,7 +789,7 @@ bool BStore::Serialise(BinaryStream &bs){ // do return properly if(!GetHeader()) return false; if(!GetEntry(0)) return false; - */ +#endif @@ -801,7 +801,7 @@ bool BStore::Serialise(BinaryStream &bs){ // do return properly ///// - /* // uncomment here to start +#if 0 // uncomment here to start //writing if(bs.m_write){ if(not ram){ @@ -856,7 +856,7 @@ bool BStore::Serialise(BinaryStream &bs){ // do return properly } - /* +#if 0 //std::cout<<"p1"< in C++11 + template + class is_base_of { + private: + static short check(const Base*); + static char check(...); + public: + static const bool value + = sizeof(check(static_cast(0))) == sizeof(short); + }; + + // Equivalent to std::enable_if in C++11 + template struct enable_if {}; + + template + struct enable_if { + typedef T type; + }; public: @@ -56,329 +75,179 @@ class BinaryStream : public SerialisableObject{ //operator overloads - bool operator<<(std::string& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.length(); - ret*=(*this) << tmp; - if(tmp) ret*=Bwrite(&(rhs[0]), tmp); - return ret; - } - else return false; - } - - bool operator>>(std::string& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - rhs.resize(tmp); - if(tmp) ret*=Bread(&(rhs[0]), tmp); - return ret; - } - else return false; - } - - bool operator&(std::string& rhs){ - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; + template bool operator&(const T& rhs) { + if (!m_write) return false; + return *this << rhs; } - bool operator<<(const std::string& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.length(); - ret*=(*this) << tmp; - if(tmp) ret*=Bwrite(&(rhs[0]), tmp); - return ret; - } - else return false; - } - - bool operator&(const std::string& rhs){ - if(m_write) return (*this) << rhs; - return false; + template bool operator&(T& rhs) { + if (m_write) return *this << rhs; + return *this >> rhs; } - - template bool operator<<(T& rhs){ - if(m_mode!=READ){ - if(check_base::value){ - SerialisableObject* tmp=reinterpret_cast(&rhs); - m_write=true; - return tmp->SerialiseWrapper(*this); - } - else return Bwrite(&rhs, sizeof(T)); - } - else return false; + template bool operator<<(const T& rhs) { + if (m_mode == READ) return false; + return serialise(rhs); } - - - template bool operator>>(T& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - if(check_base::value){ - SerialisableObject* tmp=reinterpret_cast(&rhs); - m_write=false; - return tmp->SerialiseWrapper(*this); - } - else return Bread(&rhs, sizeof(T)); - } - return false; - } - - - template bool operator&(T& rhs){ - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; - } - - template bool operator<<(const T& rhs){ - if(m_mode!=READ){ - if(check_base::value){ - SerialisableObject* tmp=reinterpret_cast(&rhs); - m_write=true; - return tmp->SerialiseWrapper(*this); - } - return Bwrite(&rhs, sizeof(T)); - } - else return false; - } - - template bool operator&(const T& rhs){ - if(m_write) return (*this) << rhs; - return false; - } - - - template bool operator<<(std::vector& rhs){ - - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.size(); - ret*=(*this) << tmp; - if(tmp){ - if(check_base::value){ - for(typename std::vector::iterator it=rhs.begin(); it!=rhs.end(); it++) ret*=(*this) << (*it); - } - else ret*=Bwrite(&(rhs[0]), tmp*sizeof(T)); - } - return ret; - } - else return false; - } - - template bool operator>>(std::vector& rhs){ - - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - rhs.resize(tmp); - if(tmp){ - if(check_base::value){ - for(typename std::vector::iterator it=rhs.begin(); it!=rhs.end(); it++) ret*=(*this) >> (*it); - } - else ret*=Bread(&(rhs[0]), tmp*sizeof(T)); - } - return ret; - } - else return false; + + template bool operator<<(T& rhs) { + if (m_mode == READ) return false; + return serialise(rhs); } - - template bool operator&(std::vector& rhs){ - - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; + + template bool operator>>(T& rhs) { + if (m_mode == NEW || m_mode == APPEND) return false; + return deserialise(rhs); } - - bool operator<<(std::vector& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.size(); - ret*=(*this) << tmp; - for(unsigned int i=0; i + typename enable_if::value, bool>::type + serialise(T& rhs) { + m_write = true; + return rhs.SerialiseWrapper(*this); } - - bool operator>>(std::vector& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - rhs.resize(tmp); - for(unsigned int i=0; i> rhs.at(i); - } - return ret; - } - else return false; + + template + typename enable_if::value, bool>::type + deserialise(T& rhs) { + m_write = false; + return rhs.SerialiseWrapper(*this); } - - bool operator&(std::vector& rhs){ - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; + + template + typename enable_if::value, bool>::type + serialise(const T& rhs) { + return Bwrite(&rhs, sizeof(T)); } - - template bool operator<<(std::map& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.size(); - ret*=(*this) << tmp; - for (typename std::map::iterator it=rhs.begin(); it!=rhs.end(); ++it){ - T key=it->first; - U value=it->second; - ret*=(*this) << key; - ret*=(*this) << value; - } - return ret; - } - else return false; + + template + typename enable_if::value, bool>::type + deserialise(T& rhs) { + if (m_mode == NEW || m_mode == APPEND) return false; + return Bread(&rhs, sizeof(T)); } - - template bool operator>>(std::map& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - for (unsigned int i=0; i> key; - ret*=(*this) >> value; - rhs[key]=value; - } - return ret; - } - else return false; + + bool serialise(const std::string& rhs) { + unsigned int len = rhs.length(); + if (!serialise(len)) return false; + if (len == 0) return true; + return Bwrite(&rhs[0], len); } - - template bool operator&(std::map& rhs){ - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; - } - - template bool operator<<(std::deque& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.size(); - ret*=(*this) << tmp; - if(tmp){ - if(check_base::value){ - for(typename std::deque::iterator it=rhs.begin(); it!=rhs.end(); it++) ret*=(*this) << (*it); - } - else ret*=Bwrite(&(rhs[0]), tmp*sizeof(T)); - } - return ret; - } - else return false; + + bool deserialise(std::string& rhs) { + unsigned int len = 0; + if (!deserialise(len)) return false; + rhs.resize(len); + if (len == 0) return true; + return Bread(&rhs[0], len); } - - template bool operator>>(std::deque& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - rhs.resize(tmp); - if(tmp){ - if(check_base::value){ - for(typename std::deque::iterator it=rhs.begin(); it!=rhs.end(); it++) ret*=(*this) >> (*it); - } - else ret*=Bread(&(rhs[0]), tmp*sizeof(T)); - } - return ret; - } - else return false; + + template + typename enable_if::value, bool>::type + serialise(std::vector& rhs) { + return serialise_container(rhs); } - - template bool operator&(std::deque& rhs){ - if(m_write) return(*this) << rhs; - else return(*this) >> rhs; + + template + typename enable_if::value, bool>::type + deserialise(std::vector& rhs) { + return deserialise_container(rhs); } - - bool operator<<(std::deque& rhs){ - if(m_mode!=READ){ - bool ret=true; - unsigned int tmp=rhs.size(); - ret*=(*this) << tmp; - for(unsigned int i=0; i + typename enable_if::value, bool>::type + serialise(const std::vector& rhs) { + unsigned int size = rhs.size(); + if (!serialise(size)) return false; + if (size == 0) return true; + return Bwrite(rhs.data(), size * sizeof(T)); } - - bool operator>>(std::deque& rhs){ - if(m_mode!=NEW && m_mode!=APPEND){ - bool ret=true; - unsigned int tmp=0; - ret*=(*this) >> tmp; - rhs.resize(tmp); - for(unsigned int i=0; i> rhs.at(i); - } - return ret; - } - else return false; + + template + typename enable_if::value, bool>::type + deserialise(std::vector& rhs) { + unsigned int size = 0; + if (!deserialise(size)) return false; + rhs.resize(size); + if (size == 0) return true; + return Bread(rhs.data(), size * sizeof(T)); } - - bool operator&(std::deque& rhs){ - if(m_write) return (*this) << rhs; - else return (*this) >> rhs; - } - - - private: - int def(FILE *source, FILE *dest, int level); - int inf(FILE *source, FILE *dest); - void zerr(int ret); - - template struct Host{ - - operator B*() const; - operator D*(); - + bool serialise(const std::vector& rhs) { + return serialise_container(rhs); }; - - - template struct check_base { - template - static short check(D*, T); - static char check(B*, int); - - static const bool value = sizeof(check(Host(), int())) == sizeof(short); + + bool deserialise(std::vector& rhs) { + return deserialise_container(rhs); }; - - - - /* -derived: - yes D*(Host(),T) = D*(B* const, T); not allowed - = D*(D*, T); -----------------------------------------------------------------------------------> preferred as D*->D* better than D*->B* : answer yes + template + bool serialise(std::pair& rhs) { + return serialise(rhs.first) && serialise(rhs.second); + } - no B*(Host(), int) = B*(B* const, int); - = B*(D*, int); preferred as not const and object called on is not const-----------------------> + template + bool deserialise(std::pair& rhs) { + return deserialise(rhs.first) && deserialise(rhs.second); + } + template bool serialise(std::map& rhs) { + return serialise_container(rhs); + } -not derrived: + template bool deserialise(std::map& rhs) { + // std::map has no resize, so we cannot use deserialise_container + unsigned int size = 0; + if (!deserialise(size)) return false; - yes D*(Host(),T) = D*(B* const, T); not allowed - = D*(D*, T); ------------------------------> + for (unsigned int i = 0; i < size; ++i) { + T key; + U value; + if (!(deserialise(key) && deserialise(value))) return false; + rhs[key] = value; + }; + return true; + } - no B*(Host(), int) = B*(B* const, int);-----------------------> preffered as not templated : answer no - = B*(D*, int); not allowed + template bool serialise(std::deque& rhs) { + return serialise_container(rhs); + } + template bool deserialise(std::deque& rhs) { + return deserialise_container(rhs); + } - */ + template + bool serialise_container(const Container& container) { + unsigned int size = container.size(); + if (!serialise(size)) return false; + if (size == 0) return true; + for (typename Container::const_iterator i = container.begin(); + i != container.end(); + ++i) + if (!serialise(*i)) return false; + return true; + } + template + bool deserialise_container(Container& container) { + unsigned int size = 0; + if (!deserialise(size)) return false; + if (size == 0) return true; + container.resize(size); + for (typename Container::iterator i = container.begin(); + i != container.end(); + ++i) + if (!deserialise(*i)) return false; + return true; + } }; - #endif diff --git a/src/Store/SerialisableObject.h b/src/Store/SerialisableObject.h index 60ec016..d4853c1 100644 --- a/src/Store/SerialisableObject.h +++ b/src/Store/SerialisableObject.h @@ -20,6 +20,8 @@ class SerialisableObject{ public: + virtual ~SerialisableObject() {}; + bool SerialiseWrapper(BinaryStream &bs); virtual bool Serialise(BinaryStream &bs)=0; virtual std::string GetVersion()=0;