From 803f5b56132c6257fc053e83f204924a0c6567dd Mon Sep 17 00:00:00 2001 From: seelabs Date: Thu, 12 Mar 2015 11:54:15 -0700 Subject: [PATCH] Use buffer in STBlob --- src/ripple/basics/Buffer.h | 22 ++++++- src/ripple/protocol/STAccount.h | 12 ++-- src/ripple/protocol/STBlob.h | 72 ++++++++--------------- src/ripple/protocol/STObject.h | 4 +- src/ripple/protocol/Serializer.h | 11 +++- src/ripple/protocol/impl/STAccount.cpp | 6 +- src/ripple/protocol/impl/STBlob.cpp | 6 +- src/ripple/protocol/impl/STObject.cpp | 7 ++- src/ripple/protocol/impl/STParsedJSON.cpp | 3 +- src/ripple/protocol/impl/Serializer.cpp | 36 +++++++++--- 10 files changed, 102 insertions(+), 77 deletions(-) diff --git a/src/ripple/basics/Buffer.h b/src/ripple/basics/Buffer.h index 374a6ed37..e73eca5b7 100644 --- a/src/ripple/basics/Buffer.h +++ b/src/ripple/basics/Buffer.h @@ -75,9 +75,7 @@ public: /** Create a buffer as a copy of existing memory. */ Buffer (void const* data, std::size_t size) - : p_ (size ? - new std::uint8_t[size] : nullptr) - , size_ (size) + : Buffer (size) { std::memcpy(p_.get(), data, size); } @@ -89,6 +87,12 @@ public: return size_; } + bool + empty () const noexcept + { + return 0 == size_; + } + /** Return a pointer to beginning of the storage. @note The return type is guaranteed to be a pointer to a single byte, to facilitate pointer arithmetic. @@ -144,6 +148,18 @@ public: } }; +inline bool operator==(Buffer const& lhs, Buffer const& rhs) noexcept +{ + if (lhs.size () != rhs.size ()) + return false; + return !std::memcmp (lhs.data (), rhs.data (), lhs.size ()); +} + +inline bool operator!=(Buffer const& lhs, Buffer const& rhs) noexcept +{ + return !(lhs == rhs); +} + } // ripple #endif diff --git a/src/ripple/protocol/STAccount.h b/src/ripple/protocol/STAccount.h index 3f58fd45f..4034f5371 100644 --- a/src/ripple/protocol/STAccount.h +++ b/src/ripple/protocol/STAccount.h @@ -30,11 +30,8 @@ class STAccount final : public STBlob { public: - STAccount (Blob const& v) : STBlob (v) - { - ; - } - STAccount (SField::ref n, Blob const& v) : STBlob (n, v) + STAccount (SField::ref n, Buffer&& v) + : STBlob (n, std::move(v)) { ; } @@ -64,8 +61,7 @@ public: template void setValueH160 (base_uint<160, Tag> const& v) { - peekValue ().clear (); - peekValue ().insert (peekValue ().end (), v.begin (), v.end ()); + peekValue () = Buffer (v.data (), v.size ()); assert (peekValue ().size () == (160 / 8)); } @@ -74,7 +70,7 @@ public: { auto success = isValueH160 (); if (success) - memcpy (v.begin (), & (peekValue ().front ()), (160 / 8)); + memcpy (v.begin (), peekValue ().data (), (160 / 8)); return success; } diff --git a/src/ripple/protocol/STBlob.h b/src/ripple/protocol/STBlob.h index 6952b8be8..fb79841f7 100644 --- a/src/ripple/protocol/STBlob.h +++ b/src/ripple/protocol/STBlob.h @@ -36,6 +36,11 @@ public: using value_type = Slice; STBlob () = default; + STBlob (STBlob const& rhs) + :STBase(rhs) + , value_ (rhs.data (), rhs.size ()) + { + } /** Construct with size and initializer. Init will be called as: @@ -44,40 +49,19 @@ public: template STBlob (SField::ref f, std::size_t size, Init&& init) - : STBase(f) + : STBase(f), value_ (size) { - value.resize(size); - init(value.data(), value.size()); + init(value_.data(), value_.size()); } STBlob (SField::ref f, void const* data, std::size_t size) - : STBase(f) + : STBase(f), value_ (data, size) { - value.resize(size); - std::memcpy(value.data(), data, size); } STBlob (SField const& f, Buffer&& b) - : STBase(f) - { - // VFALCO TODO Really move the buffer - value.resize(b.size()); - std::memcpy(value.data(), - b.data(), b.size()); - auto tmp = std::move(b); - } - - // VFALCO DEPRECATED - STBlob (Blob const& v) - : value (v) - { - } - - // VFALCO DEPRECATED - STBlob (SField::ref n, Blob const& v) - : STBase (n) - , value (v) + : STBase(f), value_(std::move (b)) { } @@ -92,20 +76,20 @@ public: std::unique_ptr deserialize (SerialIter& sit, SField::ref name) { - return std::make_unique (name, sit.getVL ()); + return std::make_unique (name, sit.getVLBuffer ()); } std::size_t size() const { - return value.size(); + return value_.size(); } std::uint8_t const* data() const { return reinterpret_cast< - std::uint8_t const*>(value.data()); + std::uint8_t const*>(value_.data()); } SerializedTypeID @@ -123,44 +107,38 @@ public: assert (fName->isBinary ()); assert ((fName->fieldType == STI_VL) || (fName->fieldType == STI_ACCOUNT)); - s.addVL (value); + s.addVL (value_.data (), value_.size ()); } - Blob const& + Buffer const& peekValue () const { - return value; + return value_; } - Blob& + Buffer& peekValue () { - return value; + return value_; } - Blob + Buffer getValue () const { - return value; + return Buffer(value_.data (), value_.size ()); } void - setValue (Blob const& v) + setValue (Buffer&& b) { - value = v; + value_ = std::move (b); } void setValue (void const* data, std::size_t size) { - value.resize(size); - std::memcpy(value.data(), data, size); - } - - explicit - operator Blob () const - { - return value; + value_.alloc (size); + std::memcpy(value_.data(), data, size); } bool @@ -169,7 +147,7 @@ public: bool isDefault () const override { - return value.empty (); + return value_.empty (); } std::unique_ptr @@ -179,7 +157,7 @@ public: } private: - Blob value; + Buffer value_; }; } // ripple diff --git a/src/ripple/protocol/STObject.h b/src/ripple/protocol/STObject.h index 1851a1e04..221e12b30 100644 --- a/src/ripple/protocol/STObject.h +++ b/src/ripple/protocol/STObject.h @@ -388,6 +388,8 @@ private: template void setFieldUsingSetValue (SField::ref field, V value) { + static_assert(!std::is_lvalue_reference::value, ""); + STBase* rf = getPField (field, true); if (!rf) @@ -401,7 +403,7 @@ private: if (!cf) throw std::runtime_error ("Wrong field type"); - cf->setValue (value); + cf->setValue (std::move (value)); } // Implementation for setting fields using assignment diff --git a/src/ripple/protocol/Serializer.h b/src/ripple/protocol/Serializer.h index c3e9b0b21..c348801b6 100644 --- a/src/ripple/protocol/Serializer.h +++ b/src/ripple/protocol/Serializer.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -319,7 +320,6 @@ private: std::uint8_t const* p_; std::size_t remain_; std::size_t used_ = 0; - public: SerialIter (void const* data, std::size_t size) noexcept; @@ -405,6 +405,15 @@ public: // VFALCO DEPRECATED Returns a copy Blob getVL(); + + Buffer + getVLBuffer(); + +private: + int getVLDataLength (); + + template + T getRawHelper (int size); }; template diff --git a/src/ripple/protocol/impl/STAccount.cpp b/src/ripple/protocol/impl/STAccount.cpp index 2b0a6ed35..c47cd4948 100644 --- a/src/ripple/protocol/impl/STAccount.cpp +++ b/src/ripple/protocol/impl/STAccount.cpp @@ -37,12 +37,12 @@ std::string STAccount::getText () const STAccount* STAccount::construct (SerialIter& u, SField::ref name) { - return new STAccount (name, u.getVL ()); + return new STAccount (name, u.getVLBuffer ()); } -STAccount::STAccount (SField::ref n, Account const& v) : STBlob (n) +STAccount::STAccount (SField::ref n, Account const& v) + : STBlob (n, v.data (), v.size ()) { - peekValue ().insert (peekValue ().end (), v.begin (), v.end ()); } bool STAccount::isValueH160 () const diff --git a/src/ripple/protocol/impl/STBlob.cpp b/src/ripple/protocol/impl/STBlob.cpp index 198040650..b91dec6ba 100644 --- a/src/ripple/protocol/impl/STBlob.cpp +++ b/src/ripple/protocol/impl/STBlob.cpp @@ -25,21 +25,21 @@ namespace ripple { STBlob::STBlob (SerialIter& st, SField::ref name) : STBase (name) + , value_ (st.getVLBuffer ()) { - value = st.getVL (); } std::string STBlob::getText () const { - return strHex (value); + return strHex (value_.data (), value_.size ()); } bool STBlob::isEquivalent (const STBase& t) const { const STBlob* v = dynamic_cast (&t); - return v && (value == v->value); + return v && (value_ == v->value_); } } // ripple diff --git a/src/ripple/protocol/impl/STObject.cpp b/src/ripple/protocol/impl/STObject.cpp index 0e92a25fe..201a9af9b 100644 --- a/src/ripple/protocol/impl/STObject.cpp +++ b/src/ripple/protocol/impl/STObject.cpp @@ -735,7 +735,9 @@ Account STObject::getFieldAccount160 (SField::ref field) const Blob STObject::getFieldVL (SField::ref field) const { - return getFieldByValue (field); + STBlob empty; + STBlob const& b = getFieldByConstRef (field, empty); + return Blob (b.data (), b.data () + b.size ()); } STAmount const& STObject::getFieldAmount (SField::ref field) const @@ -835,7 +837,8 @@ void STObject::setFieldAccount (SField::ref field, Account const& v) void STObject::setFieldVL (SField::ref field, Blob const& v) { - setFieldUsingSetValue (field, v); + setFieldUsingSetValue + (field, Buffer(v.data (), v.size ())); } void STObject::setFieldAmount (SField::ref field, STAmount const& v) diff --git a/src/ripple/protocol/impl/STParsedJSON.cpp b/src/ripple/protocol/impl/STParsedJSON.cpp index abd0dffdf..5f6d23ed2 100644 --- a/src/ripple/protocol/impl/STParsedJSON.cpp +++ b/src/ripple/protocol/impl/STParsedJSON.cpp @@ -418,7 +418,8 @@ static std::unique_ptr parseLeaf ( if (!vBlob.second) throw std::invalid_argument ("invalid data"); - ret = std::make_unique (field, vBlob.first); + ret = std::make_unique (field, vBlob.first.data (), + vBlob.first.size ()); } catch (...) { diff --git a/src/ripple/protocol/impl/Serializer.cpp b/src/ripple/protocol/impl/Serializer.cpp index 2f9a1daf1..f82fb6e02 100644 --- a/src/ripple/protocol/impl/Serializer.cpp +++ b/src/ripple/protocol/impl/Serializer.cpp @@ -662,24 +662,31 @@ SerialIter::getFieldID (int& type, int& name) } } -// VFALCO DEPRECATED Returns a copy -Blob -SerialIter::getRaw (int size) +// getRaw for blob or buffer +template +T SerialIter::getRawHelper (int size) { + static_assert(std::is_same::value || + std::is_same::value, ""); if (remain_ < size) throw std::runtime_error( "invalid SerialIter getRaw"); - Blob b (p_, p_ + size); + T result (size); + memcpy(result.data (), p_, size); p_ += size; used_ += size; remain_ -= size; - return b; - + return result; } // VFALCO DEPRECATED Returns a copy Blob -SerialIter::getVL() +SerialIter::getRaw (int size) +{ + return getRawHelper (size); +} + +int SerialIter::getVLDataLength () { int b1 = get8(); int datLen; @@ -700,7 +707,20 @@ SerialIter::getVL() int b3 = get8(); datLen = Serializer::decodeVLLength (b1, b2, b3); } - return getRaw(datLen); + return datLen; +} + +// VFALCO DEPRECATED Returns a copy +Blob +SerialIter::getVL() +{ + return getRaw(getVLDataLength ()); +} + +Buffer +SerialIter::getVLBuffer() +{ + return getRawHelper (getVLDataLength ()); }