Serialization code improvements:

* Add generics to eliminate duplicate code in STHash
* Use generics in Serializer and callers
This commit is contained in:
Tom Ritchford
2014-07-07 20:40:50 -04:00
committed by Vinnie Falco
parent 9fb09d3109
commit 418638ad16
12 changed files with 510 additions and 708 deletions

View File

@@ -2590,6 +2590,13 @@
<ClCompile Include="..\..\src\ripple\module\data\protocol\STAmountRound.cpp"> <ClCompile Include="..\..\src\ripple\module\data\protocol\STAmountRound.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClInclude Include="..\..\src\ripple\module\data\protocol\STBitString.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\data\protocol\STInteger.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\data\protocol\STInteger.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\data\protocol\STParsedJSON.cpp"> <ClCompile Include="..\..\src\ripple\module\data\protocol\STParsedJSON.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild> <ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile> </ClCompile>

View File

@@ -3696,6 +3696,15 @@
<ClCompile Include="..\..\src\ripple\module\data\protocol\STAmountRound.cpp"> <ClCompile Include="..\..\src\ripple\module\data\protocol\STAmountRound.cpp">
<Filter>ripple\module\data\protocol</Filter> <Filter>ripple\module\data\protocol</Filter>
</ClCompile> </ClCompile>
<ClInclude Include="..\..\src\ripple\module\data\protocol\STBitString.h">
<Filter>ripple\module\data\protocol</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\data\protocol\STInteger.cpp">
<Filter>ripple\module\data\protocol</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\data\protocol\STInteger.h">
<Filter>ripple\module\data\protocol</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\data\protocol\STParsedJSON.cpp"> <ClCompile Include="..\..\src\ripple\module\data\protocol\STParsedJSON.cpp">
<Filter>ripple\module\data\protocol</Filter> <Filter>ripple\module\data\protocol</Filter>
</ClCompile> </ClCompile>

View File

@@ -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 <ripple/module/data/protocol/SerializedType.h>
namespace ripple {
template <std::size_t Bits>
class STBitString : public SerializedType
{
public:
typedef base_uint<Bits> 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<SerializedType> deserialize (
SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<const STBitString*> (&t);
return v && (bitString_ == v->bitString_);
}
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == getSType());
s.addBitString<Bits> (bitString_);
}
const BitString& getValue () const
{
return bitString_;
}
template <typename Tag>
void setValue (base_uint<Bits, Tag> 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<Bits> ());
}
};
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

View File

@@ -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 <ripple/module/data/protocol/STInteger.h>
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<TER> (value_), token, human))
return human;
}
return beast::lexicalCastThrow <std::string> (value_);
}
template <>
Json::Value STUInt8::getJson (int) const
{
if (getFName () == sfTransactionResult)
{
std::string token, human;
if (transResultInfo (static_cast<TER> (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 <LedgerEntryType> (value_));
if (item != nullptr)
return item->getName ();
}
if (getFName () == sfTransactionType)
{
TxFormats::Item const* const item =
TxFormats::getInstance()->findByType (static_cast <TxType> (value_));
if (item != nullptr)
return item->getName ();
}
return beast::lexicalCastThrow <std::string> (value_);
}
template <>
Json::Value STUInt16::getJson (int) const
{
if (getFName () == sfLedgerEntryType)
{
LedgerFormats::Item const* const item =
LedgerFormats::getInstance ()->findByType (static_cast <LedgerEntryType> (value_));
if (item != nullptr)
return item->getName ();
}
if (getFName () == sfTransactionType)
{
TxFormats::Item const* const item =
TxFormats::getInstance()->findByType (static_cast <TxType> (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 <std::string> (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 <std::string> (value_);
}
template <>
Json::Value STUInt64::getJson (int) const
{
return strHex (value_);
}
} // ripple

View File

@@ -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 <ripple/module/data/protocol/SerializedType.h>
namespace ripple {
template <typename Integer>
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<SerializedType> deserialize (
SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<const STInteger*> (&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<unsigned char>;
using STUInt16 = STInteger<std::uint16_t>;
using STUInt32 = STInteger<std::uint32_t>;
using STUInt64 = STInteger<std::uint64_t>;
} // ripple
#endif

View File

@@ -17,9 +17,9 @@
*/ */
//============================================================================== //==============================================================================
#include <cassert> #include <ripple/module/data/protocol/STInteger.h>
#include <beast/module/core/text/LexicalCast.h> #include <beast/module/core/text/LexicalCast.h>
#include <cassert>
namespace ripple { namespace ripple {

View File

@@ -236,7 +236,8 @@ public:
if (rf->getSType () == STI_NOTPRESENT) if (rf->getSType () == STI_NOTPRESENT)
rf = makeFieldPresent (field); rf = makeFieldPresent (field);
if (auto cf = dynamic_cast<STHash160*> (rf)) using Bits = STBitString<160>;
if (auto cf = dynamic_cast<Bits*> (rf))
cf->setValue (v); cf->setValue (v);
else else
throw std::runtime_error ("Wrong field type"); throw std::runtime_error ("Wrong field type");

View File

@@ -62,191 +62,9 @@ std::string SerializedType::getFullText () const
return ret; return ret;
} }
STUInt8* STUInt8::construct (SerializerIterator& u, SField::ref name) //
{ // STVariableLength
return new STUInt8 (name, u.get8 ()); //
}
std::string STUInt8::getText () const
{
if (getFName () == sfTransactionResult)
{
std::string token, human;
if (transResultInfo (static_cast<TER> (value), token, human))
return human;
}
return beast::lexicalCastThrow <std::string> (value);
}
Json::Value STUInt8::getJson (int) const
{
if (getFName () == sfTransactionResult)
{
std::string token, human;
if (transResultInfo (static_cast<TER> (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<const STUInt8*> (&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 <LedgerEntryType> (value));
if (item != nullptr)
return item->getName ();
}
if (getFName () == sfTransactionType)
{
TxFormats::Item const* const item =
TxFormats::getInstance()->findByType (static_cast <TxType> (value));
if (item != nullptr)
return item->getName ();
}
return beast::lexicalCastThrow <std::string> (value);
}
Json::Value STUInt16::getJson (int) const
{
if (getFName () == sfLedgerEntryType)
{
LedgerFormats::Item const* const item =
LedgerFormats::getInstance ()->findByType (static_cast <LedgerEntryType> (value));
if (item != nullptr)
return item->getName ();
}
if (getFName () == sfTransactionType)
{
TxFormats::Item const* const item =
TxFormats::getInstance()->findByType (static_cast <TxType> (value));
if (item != nullptr)
return item->getName ();
}
return value;
}
bool STUInt16::isEquivalent (const SerializedType& t) const
{
const STUInt16* v = dynamic_cast<const STUInt16*> (&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 <std::string> (value);
}
Json::Value STUInt32::getJson (int) const
{
return value;
}
bool STUInt32::isEquivalent (const SerializedType& t) const
{
const STUInt32* v = dynamic_cast<const STUInt32*> (&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 <std::string> (value);
}
Json::Value STUInt64::getJson (int) const
{
return strHex (value);
}
bool STUInt64::isEquivalent (const SerializedType& t) const
{
const STUInt64* v = dynamic_cast<const STUInt64*> (&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<const STHash128*> (&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<const STHash160*> (&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<const STHash256*> (&t);
return v && (value == v->value);
}
STVariableLength::STVariableLength (SerializerIterator& st, SField::ref name) : SerializedType (name) STVariableLength::STVariableLength (SerializerIterator& st, SField::ref name) : SerializedType (name)
{ {

View File

@@ -22,487 +22,13 @@
#include <ripple/module/data/protocol/FieldNames.h> #include <ripple/module/data/protocol/FieldNames.h>
#include <ripple/module/data/protocol/Serializer.h> #include <ripple/module/data/protocol/Serializer.h>
#include <ripple/module/data/protocol/STBitString.h>
#include <ripple/module/data/protocol/STInteger.h>
#include <ripple/module/data/protocol/SerializedType.h> #include <ripple/module/data/protocol/SerializedType.h>
#include <ripple/module/data/protocol/STAmount.h> #include <ripple/module/data/protocol/STAmount.h>
namespace ripple { 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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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 <class Tag>
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<SerializedType> deserialize (SerializerIterator& sit, SField::ref name)
{
return std::unique_ptr<SerializedType> (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 // variable length byte string

View File

@@ -63,6 +63,11 @@ int Serializer::add64 (std::uint64_t i)
return ret; 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 Serializer::add128 (const uint128& i)
{ {
int ret = mData.size (); int ret = mData.size ();
@@ -620,36 +625,6 @@ std::uint64_t SerializerIterator::get64 ()
return val; 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 () Blob SerializerIterator::getVL ()
{ {
int length; int length;

View File

@@ -67,20 +67,29 @@ public:
int add64 (std::uint64_t); // native currency amounts int add64 (std::uint64_t); // native currency amounts
int add128 (const uint128&); // private key generators int add128 (const uint128&); // private key generators
int add256 (uint256 const& ); // transaction and ledger hashes int add256 (uint256 const& ); // transaction and ledger hashes
int addRaw (Blob const& vector);
int addRaw (const void* ptr, int len); template <typename Integer>
int addRaw (const Serializer& s); int addInteger(Integer);
int addZeros (size_t uBytes);
template <int Bits, class Tag>
int addBitString(base_uint<Bits, Tag> const& v) {
int ret = mData.size ();
mData.insert (mData.end (), v.begin (), v.end ());
return ret;
}
// TODO(tom): merge with add128 and add256. // TODO(tom): merge with add128 and add256.
template <class Tag> template <class Tag>
int add160 (base_uint<160, Tag> const& i) int add160 (base_uint<160, Tag> const& i)
{ {
int ret = mData.size (); return addBitString<160, Tag>(i);
mData.insert (mData.end (), i.begin (), i.end ());
return ret;
} }
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 (Blob const& vector);
int addVL (const std::string& string); int addVL (const std::string& string);
int addVL (const void* ptr, int len); int addVL (const void* ptr, int len);
@@ -93,16 +102,39 @@ public:
bool get64 (std::uint64_t&, int offset) const; bool get64 (std::uint64_t&, int offset) const;
bool get128 (uint128&, int offset) const; bool get128 (uint128&, int offset) const;
bool get256 (uint256&, int offset) const; bool get256 (uint256&, int offset) const;
template <typename Integer>
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 <int Bits, typename Tag = void>
bool getBitString(base_uint<Bits, Tag>& 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; uint256 get256 (int offset) const;
// TODO(tom): merge with get128 and get256. // TODO(tom): merge with get128 and get256.
template <class Tag> template <class Tag>
bool get160 (base_uint<160, Tag>& o, int offset) const bool get160 (base_uint<160, Tag>& o, int offset) const
{ {
auto success = (offset + (160 / 8)) <= mData.size (); return getBitString<160, Tag>(o, offset);
if (success)
memcpy (o.begin (), & (mData.front ()) + offset, (160 / 8));
return success;
} }
bool getRaw (Blob&, int offset, int length) const; bool getRaw (Blob&, int offset, int length) const;
@@ -313,9 +345,25 @@ public:
std::uint16_t get16 (); std::uint16_t get16 ();
std::uint32_t get32 (); std::uint32_t get32 ();
std::uint64_t get64 (); std::uint64_t get64 ();
uint128 get128 ();
uint160 get160 (); uint128 get128 () { return getBitString<128>(); }
uint256 get256 (); uint160 get160 () { return getBitString<160>(); }
uint256 get256 () { return getBitString<256>(); }
template <std::size_t Bits, typename Tag = void>
void getBitString (base_uint<Bits, Tag>& bits) {
if (!mSerializer.getBitString<Bits> (bits, mPos))
throw std::runtime_error ("invalid serializer getBitString");
mPos += Bits / 8;
}
template <std::size_t Bits, typename Tag = void>
base_uint<Bits, Tag> getBitString () {
base_uint<Bits, Tag> bits;
getBitString(bits);
return bits;
}
void getFieldID (int& type, int& field); void getFieldID (int& type, int& field);

View File

@@ -71,6 +71,7 @@
#include <ripple/module/data/protocol/HashPrefix.cpp> #include <ripple/module/data/protocol/HashPrefix.cpp>
#include <ripple/module/data/protocol/LedgerFormats.cpp> #include <ripple/module/data/protocol/LedgerFormats.cpp>
#include <ripple/module/data/protocol/RippleAddress.cpp> #include <ripple/module/data/protocol/RippleAddress.cpp>
#include <ripple/module/data/protocol/STInteger.cpp>
#include <ripple/module/data/protocol/SerializedTypes.cpp> #include <ripple/module/data/protocol/SerializedTypes.cpp>
#include <ripple/module/data/protocol/Serializer.cpp> #include <ripple/module/data/protocol/Serializer.cpp>
#include <ripple/module/data/protocol/SerializedObjectTemplate.cpp> #include <ripple/module/data/protocol/SerializedObjectTemplate.cpp>