From 418638ad16007b16e3da702c2f914f6814d9049e Mon Sep 17 00:00:00 2001 From: Tom Ritchford Date: Mon, 7 Jul 2014 20:40:50 -0400 Subject: [PATCH] Serialization code improvements: * Add generics to eliminate duplicate code in STHash * Use generics in Serializer and callers --- Builds/VisualStudio2013/RippleD.vcxproj | 7 + .../VisualStudio2013/RippleD.vcxproj.filters | 9 + src/ripple/module/data/protocol/STBitString.h | 137 +++++ src/ripple/module/data/protocol/STInteger.cpp | 179 +++++++ src/ripple/module/data/protocol/STInteger.h | 101 ++++ .../module/data/protocol/STParsedJSON.cpp | 4 +- .../module/data/protocol/SerializedObject.h | 3 +- .../module/data/protocol/SerializedTypes.cpp | 188 +------ .../module/data/protocol/SerializedTypes.h | 478 +----------------- .../module/data/protocol/Serializer.cpp | 35 +- src/ripple/module/data/protocol/Serializer.h | 76 ++- src/ripple/unity/data.cpp | 1 + 12 files changed, 510 insertions(+), 708 deletions(-) create mode 100644 src/ripple/module/data/protocol/STBitString.h create mode 100644 src/ripple/module/data/protocol/STInteger.cpp create mode 100644 src/ripple/module/data/protocol/STInteger.h diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index db89d1f4eb..e06e05b0fb 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2590,6 +2590,13 @@ True + + + + True + + + True diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 63bfa1277a..27e9c62a0d 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -3696,6 +3696,15 @@ ripple\module\data\protocol + + ripple\module\data\protocol + + + ripple\module\data\protocol + + + ripple\module\data\protocol + ripple\module\data\protocol diff --git a/src/ripple/module/data/protocol/STBitString.h b/src/ripple/module/data/protocol/STBitString.h new file mode 100644 index 0000000000..6c32610466 --- /dev/null +++ b/src/ripple/module/data/protocol/STBitString.h @@ -0,0 +1,137 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_STBITS_H +#define RIPPLE_STBITS_H + +#include + +namespace ripple { + +template +class STBitString : public SerializedType +{ +public: + typedef base_uint BitString; + + STBitString () {} + STBitString (SField::ref n) : SerializedType (n) {} + STBitString (const BitString& v) : bitString_ (v) {} + + STBitString (SField::ref n, const BitString& v) + : SerializedType (n), bitString_ (v) + { + } + + STBitString (SField::ref n, const char* v) : SerializedType (n) + { + bitString_.SetHex (v); + } + + STBitString (SField::ref n, const std::string& v) : SerializedType (n) + { + bitString_.SetHex (v); + } + + static std::unique_ptr deserialize ( + SerializerIterator& sit, SField::ref name) + { + return std::unique_ptr (construct (sit, name)); + } + + SerializedTypeID getSType () const; + + std::string getText () const + { + return to_string (bitString_); + } + + bool isEquivalent (const SerializedType& t) const + { + const STBitString* v = dynamic_cast (&t); + return v && (bitString_ == v->bitString_); + } + + void add (Serializer& s) const + { + assert (fName->isBinary ()); + assert (fName->fieldType == getSType()); + s.addBitString (bitString_); + } + + const BitString& getValue () const + { + return bitString_; + } + + template + void setValue (base_uint const& v) + { + bitString_.copyFrom(v); + } + + operator BitString () const + { + return bitString_; + } + + virtual bool isDefault () const + { + return bitString_ == zero; + } + +private: + BitString bitString_; + + STBitString* duplicate () const + { + return new STBitString (*this); + } + + static STBitString* construct (SerializerIterator& u, SField::ref name) + { + return new STBitString (name, u.getBitString ()); + } +}; + +template <> +inline SerializedTypeID STBitString<128>::getSType () const +{ + return STI_HASH128; +} + +template <> +inline SerializedTypeID STBitString<160>::getSType () const +{ + return STI_HASH160; +} + +template <> +inline SerializedTypeID STBitString<256>::getSType () const +{ + return STI_HASH256; +} + +using STHash128 = STBitString<128>; +using STHash160 = STBitString<160>; +using STHash256 = STBitString<256>; + +} // ripple + +#endif diff --git a/src/ripple/module/data/protocol/STInteger.cpp b/src/ripple/module/data/protocol/STInteger.cpp new file mode 100644 index 0000000000..e33496b720 --- /dev/null +++ b/src/ripple/module/data/protocol/STInteger.cpp @@ -0,0 +1,179 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include + +namespace ripple { + +template <> +SerializedTypeID STUInt8::getSType () const +{ + return STI_UINT8; +} + +template <> +STUInt8* STUInt8::construct (SerializerIterator& u, SField::ref name) +{ + return new STUInt8 (name, u.get8 ()); +} + +template <> +std::string STUInt8::getText () const +{ + if (getFName () == sfTransactionResult) + { + std::string token, human; + + if (transResultInfo (static_cast (value_), token, human)) + return human; + } + + return beast::lexicalCastThrow (value_); +} + +template <> +Json::Value STUInt8::getJson (int) const +{ + if (getFName () == sfTransactionResult) + { + std::string token, human; + + if (transResultInfo (static_cast (value_), token, human)) + return token; + else + WriteLog (lsWARNING, SerializedType) + << "Unknown result code in metadata: " << value_; + } + + return value_; +} + +//------------------------------------------------------------------------------ + +template <> +SerializedTypeID STUInt16::getSType () const +{ + return STI_UINT16; +} + +template <> +STUInt16* STUInt16::construct (SerializerIterator& u, SField::ref name) +{ + return new STUInt16 (name, u.get16 ()); +} + +template <> +std::string STUInt16::getText () const +{ + if (getFName () == sfLedgerEntryType) + { + auto item = LedgerFormats::getInstance ()->findByType ( + static_cast (value_)); + + if (item != nullptr) + return item->getName (); + } + + if (getFName () == sfTransactionType) + { + TxFormats::Item const* const item = + TxFormats::getInstance()->findByType (static_cast (value_)); + + if (item != nullptr) + return item->getName (); + } + + return beast::lexicalCastThrow (value_); +} + +template <> +Json::Value STUInt16::getJson (int) const +{ + if (getFName () == sfLedgerEntryType) + { + LedgerFormats::Item const* const item = + LedgerFormats::getInstance ()->findByType (static_cast (value_)); + + if (item != nullptr) + return item->getName (); + } + + if (getFName () == sfTransactionType) + { + TxFormats::Item const* const item = + TxFormats::getInstance()->findByType (static_cast (value_)); + + if (item != nullptr) + return item->getName (); + } + + return value_; +} + +//------------------------------------------------------------------------------ + +template <> +SerializedTypeID STUInt32::getSType () const +{ + return STI_UINT32; +} + +template <> +STUInt32* STUInt32::construct (SerializerIterator& u, SField::ref name) +{ + return new STUInt32 (name, u.get32 ()); +} + +template <> +std::string STUInt32::getText () const +{ + return beast::lexicalCastThrow (value_); +} + +template <> +Json::Value STUInt32::getJson (int) const +{ + return value_; +} + +template <> +SerializedTypeID STUInt64::getSType () const +{ + return STI_UINT64; +} + +template <> +STUInt64* STUInt64::construct (SerializerIterator& u, SField::ref name) +{ + return new STUInt64 (name, u.get64 ()); +} + +template <> +std::string STUInt64::getText () const +{ + return beast::lexicalCastThrow (value_); +} + +template <> +Json::Value STUInt64::getJson (int) const +{ + return strHex (value_); +} + +} // ripple diff --git a/src/ripple/module/data/protocol/STInteger.h b/src/ripple/module/data/protocol/STInteger.h new file mode 100644 index 0000000000..eea54fb347 --- /dev/null +++ b/src/ripple/module/data/protocol/STInteger.h @@ -0,0 +1,101 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_STINTEGER_H +#define RIPPLE_STINTEGER_H + +#include + +namespace ripple { + +template +class STInteger : public SerializedType +{ +public: + STInteger (Integer v = 0) : value_ (v) + { + } + + STInteger (SField::ref n, Integer v = 0) : SerializedType (n), value_ (v) + { + } + + static std::unique_ptr deserialize ( + SerializerIterator& sit, SField::ref name) + { + return std::unique_ptr (construct (sit, name)); + } + + SerializedTypeID getSType () const + { + return STI_UINT8; + } + + Json::Value getJson (int) const; + std::string getText () const; + + void add (Serializer& s) const + { + assert (fName->isBinary ()); + assert (fName->fieldType == getSType ()); + s.addInteger (value_); + } + + Integer getValue () const + { + return value_; + } + void setValue (Integer v) + { + value_ = v; + } + + operator Integer () const + { + return value_; + } + virtual bool isDefault () const + { + return value_ == 0; + } + + bool isEquivalent (const SerializedType& t) const + { + const STInteger* v = dynamic_cast (&t); + return v && (value_ == v->value_); + } + +private: + Integer value_; + + STInteger* duplicate () const + { + return new STInteger (*this); + } + static STInteger* construct (SerializerIterator&, SField::ref f); +}; + +using STUInt8 = STInteger; +using STUInt16 = STInteger; +using STUInt32 = STInteger; +using STUInt64 = STInteger; + +} // ripple + +#endif diff --git a/src/ripple/module/data/protocol/STParsedJSON.cpp b/src/ripple/module/data/protocol/STParsedJSON.cpp index ff8ecb8dc1..b1a6821681 100644 --- a/src/ripple/module/data/protocol/STParsedJSON.cpp +++ b/src/ripple/module/data/protocol/STParsedJSON.cpp @@ -17,9 +17,9 @@ */ //============================================================================== -#include - +#include #include +#include namespace ripple { diff --git a/src/ripple/module/data/protocol/SerializedObject.h b/src/ripple/module/data/protocol/SerializedObject.h index 9642a1a91a..b55bc4e915 100644 --- a/src/ripple/module/data/protocol/SerializedObject.h +++ b/src/ripple/module/data/protocol/SerializedObject.h @@ -236,7 +236,8 @@ public: if (rf->getSType () == STI_NOTPRESENT) rf = makeFieldPresent (field); - if (auto cf = dynamic_cast (rf)) + using Bits = STBitString<160>; + if (auto cf = dynamic_cast (rf)) cf->setValue (v); else throw std::runtime_error ("Wrong field type"); diff --git a/src/ripple/module/data/protocol/SerializedTypes.cpp b/src/ripple/module/data/protocol/SerializedTypes.cpp index 10cb3a55fa..324fb6176c 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.cpp +++ b/src/ripple/module/data/protocol/SerializedTypes.cpp @@ -62,191 +62,9 @@ std::string SerializedType::getFullText () const return ret; } -STUInt8* STUInt8::construct (SerializerIterator& u, SField::ref name) -{ - return new STUInt8 (name, u.get8 ()); -} - -std::string STUInt8::getText () const -{ - if (getFName () == sfTransactionResult) - { - std::string token, human; - - if (transResultInfo (static_cast (value), token, human)) - return human; - } - - return beast::lexicalCastThrow (value); -} - -Json::Value STUInt8::getJson (int) const -{ - if (getFName () == sfTransactionResult) - { - std::string token, human; - - if (transResultInfo (static_cast (value), token, human)) - return token; - else - WriteLog (lsWARNING, SerializedType) << "Unknown result code in metadata: " << value; - } - - return value; -} - -bool STUInt8::isEquivalent (const SerializedType& t) const -{ - const STUInt8* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STUInt16* STUInt16::construct (SerializerIterator& u, SField::ref name) -{ - return new STUInt16 (name, u.get16 ()); -} - -std::string STUInt16::getText () const -{ - if (getFName () == sfLedgerEntryType) - { - LedgerFormats::Item const* const item = - LedgerFormats::getInstance ()->findByType (static_cast (value)); - - if (item != nullptr) - return item->getName (); - } - - if (getFName () == sfTransactionType) - { - TxFormats::Item const* const item = - TxFormats::getInstance()->findByType (static_cast (value)); - - if (item != nullptr) - return item->getName (); - } - - return beast::lexicalCastThrow (value); -} - -Json::Value STUInt16::getJson (int) const -{ - if (getFName () == sfLedgerEntryType) - { - LedgerFormats::Item const* const item = - LedgerFormats::getInstance ()->findByType (static_cast (value)); - - if (item != nullptr) - return item->getName (); - } - - if (getFName () == sfTransactionType) - { - TxFormats::Item const* const item = - TxFormats::getInstance()->findByType (static_cast (value)); - - if (item != nullptr) - return item->getName (); - } - - return value; -} - -bool STUInt16::isEquivalent (const SerializedType& t) const -{ - const STUInt16* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STUInt32* STUInt32::construct (SerializerIterator& u, SField::ref name) -{ - return new STUInt32 (name, u.get32 ()); -} - -std::string STUInt32::getText () const -{ - return beast::lexicalCastThrow (value); -} - -Json::Value STUInt32::getJson (int) const -{ - return value; -} - -bool STUInt32::isEquivalent (const SerializedType& t) const -{ - const STUInt32* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STUInt64* STUInt64::construct (SerializerIterator& u, SField::ref name) -{ - return new STUInt64 (name, u.get64 ()); -} - -std::string STUInt64::getText () const -{ - return beast::lexicalCastThrow (value); -} - -Json::Value STUInt64::getJson (int) const -{ - return strHex (value); -} - -bool STUInt64::isEquivalent (const SerializedType& t) const -{ - const STUInt64* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STHash128* STHash128::construct (SerializerIterator& u, SField::ref name) -{ - return new STHash128 (name, u.get128 ()); -} - -std::string STHash128::getText () const -{ - return to_string (value); -} - -bool STHash128::isEquivalent (const SerializedType& t) const -{ - const STHash128* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STHash160* STHash160::construct (SerializerIterator& u, SField::ref name) -{ - return new STHash160 (name, u.get160 ()); -} - -std::string STHash160::getText () const -{ - return to_string (value); -} - -bool STHash160::isEquivalent (const SerializedType& t) const -{ - const STHash160* v = dynamic_cast (&t); - return v && (value == v->value); -} - -STHash256* STHash256::construct (SerializerIterator& u, SField::ref name) -{ - return new STHash256 (name, u.get256 ()); -} - -std::string STHash256::getText () const -{ - return to_string (value); -} - -bool STHash256::isEquivalent (const SerializedType& t) const -{ - const STHash256* v = dynamic_cast (&t); - return v && (value == v->value); -} +// +// STVariableLength +// STVariableLength::STVariableLength (SerializerIterator& st, SField::ref name) : SerializedType (name) { diff --git a/src/ripple/module/data/protocol/SerializedTypes.h b/src/ripple/module/data/protocol/SerializedTypes.h index d3bf282ced..5b5eb429a6 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.h +++ b/src/ripple/module/data/protocol/SerializedTypes.h @@ -22,487 +22,13 @@ #include #include +#include +#include #include #include namespace ripple { -// TODO(tom): make STUInt8, STUInt16, STUInt32, STUInt64 a single templated -// class to reduce the quadruple redundancy we have all over the rippled code -// regarding uint-like types. - -class STUInt8 : public SerializedType -{ -public: - - STUInt8 (unsigned char v = 0) : value (v) - { - ; - } - STUInt8 (SField::ref n, unsigned char v = 0) : SerializedType (n), value (v) - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_UINT8; - } - std::string getText () const; - Json::Value getJson (int) const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_UINT8); - s.add8 (value); - } - - unsigned char getValue () const - { - return value; - } - void setValue (unsigned char v) - { - value = v; - } - - operator unsigned char () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value == 0; - } - -private: - unsigned char value; - - STUInt8* duplicate () const - { - return new STUInt8 (*this); - } - static STUInt8* construct (SerializerIterator&, SField::ref f); -}; - -//------------------------------------------------------------------------------ - -class STUInt16 : public SerializedType -{ -public: - - STUInt16 (std::uint16_t v = 0) : value (v) - { - ; - } - STUInt16 (SField::ref n, std::uint16_t v = 0) : SerializedType (n), value (v) - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_UINT16; - } - std::string getText () const; - Json::Value getJson (int) const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_UINT16); - s.add16 (value); - } - - std::uint16_t getValue () const - { - return value; - } - void setValue (std::uint16_t v) - { - value = v; - } - - operator std::uint16_t () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value == 0; - } - -private: - std::uint16_t value; - - STUInt16* duplicate () const - { - return new STUInt16 (*this); - } - static STUInt16* construct (SerializerIterator&, SField::ref name); -}; - -//------------------------------------------------------------------------------ - -class STUInt32 : public SerializedType -{ -public: - - STUInt32 (std::uint32_t v = 0) : value (v) - { - ; - } - STUInt32 (SField::ref n, std::uint32_t v = 0) : SerializedType (n), value (v) - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_UINT32; - } - std::string getText () const; - Json::Value getJson (int) const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_UINT32); - s.add32 (value); - } - - std::uint32_t getValue () const - { - return value; - } - void setValue (std::uint32_t v) - { - value = v; - } - - operator std::uint32_t () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value == 0; - } - -private: - std::uint32_t value; - - STUInt32* duplicate () const - { - return new STUInt32 (*this); - } - static STUInt32* construct (SerializerIterator&, SField::ref name); -}; - -//------------------------------------------------------------------------------ - -class STUInt64 : public SerializedType -{ -public: - STUInt64 (std::uint64_t v = 0) : value (v) - { - ; - } - STUInt64 (SField::ref n, std::uint64_t v = 0) : SerializedType (n), value (v) - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_UINT64; - } - std::string getText () const; - Json::Value getJson (int) const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_UINT64); - s.add64 (value); - } - - std::uint64_t getValue () const - { - return value; - } - void setValue (std::uint64_t v) - { - value = v; - } - - operator std::uint64_t () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value == 0; - } - -private: - std::uint64_t value; - - STUInt64* duplicate () const - { - return new STUInt64 (*this); - } - static STUInt64* construct (SerializerIterator&, SField::ref name); -}; - -//------------------------------------------------------------------------------ - -// TODO(tom): make STHash128, STHash160 and STHash256 a single templated class -// to reduce the triple redundancy we have all over the rippled code regarding -// hash-like classes. - -class STHash128 : public SerializedType -{ -public: - STHash128 (const uint128& v) : value (v) - { - ; - } - STHash128 (SField::ref n, const uint128& v) : SerializedType (n), value (v) - { - ; - } - STHash128 (SField::ref n, const char* v) : SerializedType (n) - { - value.SetHex (v); - } - STHash128 (SField::ref n, const std::string& v) : SerializedType (n) - { - value.SetHex (v); - } - STHash128 (SField::ref n) : SerializedType (n) - { - ; - } - STHash128 () - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_HASH128; - } - virtual std::string getText () const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_HASH128); - s.add128 (value); - } - - const uint128& getValue () const - { - return value; - } - void setValue (const uint128& v) - { - value = v; - } - - operator uint128 () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value.isZero (); - } - -private: - uint128 value; - - STHash128* duplicate () const - { - return new STHash128 (*this); - } - static STHash128* construct (SerializerIterator&, SField::ref name); -}; - -//------------------------------------------------------------------------------ - -class STHash160 : public SerializedType -{ -public: - STHash160 (uint160 const& v) : value (v) - { - ; - } - STHash160 (SField::ref n, uint160 const& v) : SerializedType (n), value (v) - { - ; - } - STHash160 (SField::ref n, const char* v) : SerializedType (n) - { - value.SetHex (v); - } - STHash160 (SField::ref n, const std::string& v) : SerializedType (n) - { - value.SetHex (v); - } - STHash160 (SField::ref n) : SerializedType (n) - { - ; - } - STHash160 () - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_HASH160; - } - virtual std::string getText () const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_HASH160); - s.add160 (value); - } - - uint160 const& getValue () const - { - return value; - } - - template - void setValue (base_uint<160, Tag> const& v) - { - value.copyFrom(v); - } - - operator uint160 () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value.isZero (); - } - -private: - uint160 value; - - STHash160* duplicate () const - { - return new STHash160 (*this); - } - static STHash160* construct (SerializerIterator&, SField::ref name); -}; - -//------------------------------------------------------------------------------ - -class STHash256 : public SerializedType -{ -public: - STHash256 (uint256 const& v) : value (v) - { - ; - } - STHash256 (SField::ref n, uint256 const& v) : SerializedType (n), value (v) - { - ; - } - STHash256 (SField::ref n, const char* v) : SerializedType (n) - { - value.SetHex (v); - } - STHash256 (SField::ref n, const std::string& v) : SerializedType (n) - { - value.SetHex (v); - } - STHash256 (SField::ref n) : SerializedType (n) - { - ; - } - STHash256 () - { - ; - } - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - SerializedTypeID getSType () const - { - return STI_HASH256; - } - std::string getText () const; - void add (Serializer& s) const - { - assert (fName->isBinary ()); - assert (fName->fieldType == STI_HASH256); - s.add256 (value); - } - - uint256 const& getValue () const - { - return value; - } - void setValue (uint256 const& v) - { - value = v; - } - - operator uint256 () const - { - return value; - } - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return value.isZero (); - } - -private: - uint256 value; - - STHash256* duplicate () const - { - return new STHash256 (*this); - } - static STHash256* construct (SerializerIterator&, SField::ref); -}; - //------------------------------------------------------------------------------ // variable length byte string diff --git a/src/ripple/module/data/protocol/Serializer.cpp b/src/ripple/module/data/protocol/Serializer.cpp index 15cf0986fd..d2f369553f 100644 --- a/src/ripple/module/data/protocol/Serializer.cpp +++ b/src/ripple/module/data/protocol/Serializer.cpp @@ -63,6 +63,11 @@ int Serializer::add64 (std::uint64_t i) return ret; } +template <> int Serializer::addInteger(unsigned char i) { return add8(i); } +template <> int Serializer::addInteger(std::uint16_t i) { return add16(i); } +template <> int Serializer::addInteger(std::uint32_t i) { return add32(i); } +template <> int Serializer::addInteger(std::uint64_t i) { return add64(i); } + int Serializer::add128 (const uint128& i) { int ret = mData.size (); @@ -620,36 +625,6 @@ std::uint64_t SerializerIterator::get64 () return val; } -uint128 SerializerIterator::get128 () -{ - uint128 val; - - if (!mSerializer.get128 (val, mPos)) throw std::runtime_error ("invalid serializer get128"); - - mPos += 128 / 8; - return val; -} - -uint160 SerializerIterator::get160 () -{ - uint160 val; - - if (!mSerializer.get160 (val, mPos)) throw std::runtime_error ("invalid serializer get160"); - - mPos += 160 / 8; - return val; -} - -uint256 SerializerIterator::get256 () -{ - uint256 val; - - if (!mSerializer.get256 (val, mPos)) throw std::runtime_error ("invalid serializer get256"); - - mPos += 256 / 8; - return val; -} - Blob SerializerIterator::getVL () { int length; diff --git a/src/ripple/module/data/protocol/Serializer.h b/src/ripple/module/data/protocol/Serializer.h index dad40bfbcd..5d7fe73f45 100644 --- a/src/ripple/module/data/protocol/Serializer.h +++ b/src/ripple/module/data/protocol/Serializer.h @@ -67,20 +67,29 @@ public: int add64 (std::uint64_t); // native currency amounts int add128 (const uint128&); // private key generators int add256 (uint256 const& ); // transaction and ledger hashes - int addRaw (Blob const& vector); - int addRaw (const void* ptr, int len); - int addRaw (const Serializer& s); - int addZeros (size_t uBytes); + + template + int addInteger(Integer); + + template + int addBitString(base_uint const& v) { + int ret = mData.size (); + mData.insert (mData.end (), v.begin (), v.end ()); + return ret; + } // TODO(tom): merge with add128 and add256. template int add160 (base_uint<160, Tag> const& i) { - int ret = mData.size (); - mData.insert (mData.end (), i.begin (), i.end ()); - return ret; + return addBitString<160, Tag>(i); } + int addRaw (Blob const& vector); + int addRaw (const void* ptr, int len); + int addRaw (const Serializer& s); + int addZeros (size_t uBytes); + int addVL (Blob const& vector); int addVL (const std::string& string); int addVL (const void* ptr, int len); @@ -93,16 +102,39 @@ public: bool get64 (std::uint64_t&, int offset) const; bool get128 (uint128&, int offset) const; bool get256 (uint256&, int offset) const; + + template + bool getInteger(Integer& number, int offset) { + static const auto bytes = sizeof(Integer); + if ((offset + bytes) > mData.size ()) + return false; + number = 0; + + auto ptr = &mData[offset]; + for (auto i = 0; i < bytes; ++i) + { + if (i) + number <<= 8; + number |= *ptr++; + } + return true; + } + + template + bool getBitString(base_uint& data, int offset) const { + auto success = (offset + (Bits / 8)) <= mData.size (); + if (success) + memcpy (data.begin (), & (mData.front ()) + offset, (Bits / 8)); + return success; + } + uint256 get256 (int offset) const; // TODO(tom): merge with get128 and get256. template bool get160 (base_uint<160, Tag>& o, int offset) const { - auto success = (offset + (160 / 8)) <= mData.size (); - if (success) - memcpy (o.begin (), & (mData.front ()) + offset, (160 / 8)); - return success; + return getBitString<160, Tag>(o, offset); } bool getRaw (Blob&, int offset, int length) const; @@ -313,9 +345,25 @@ public: std::uint16_t get16 (); std::uint32_t get32 (); std::uint64_t get64 (); - uint128 get128 (); - uint160 get160 (); - uint256 get256 (); + + uint128 get128 () { return getBitString<128>(); } + uint160 get160 () { return getBitString<160>(); } + uint256 get256 () { return getBitString<256>(); } + + template + void getBitString (base_uint& bits) { + if (!mSerializer.getBitString (bits, mPos)) + throw std::runtime_error ("invalid serializer getBitString"); + + mPos += Bits / 8; + } + + template + base_uint getBitString () { + base_uint bits; + getBitString(bits); + return bits; + } void getFieldID (int& type, int& field); diff --git a/src/ripple/unity/data.cpp b/src/ripple/unity/data.cpp index d54b794844..bbe0dea1a9 100644 --- a/src/ripple/unity/data.cpp +++ b/src/ripple/unity/data.cpp @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include