From 1ac9694dbc02b4f856bb5d4f79cf10cb9e81f421 Mon Sep 17 00:00:00 2001 From: Joe Loser Date: Mon, 20 Aug 2018 22:38:40 -0400 Subject: [PATCH] Simplify strHex: Problem: - There are several specific overloads with some custom code that can be easily replaced using Boost.Hex. Solution: - Introduce `strHex(itr, itr)` to return a string given a begin and end iterator. - Remove `strHex(itr, size)` in favor of the `strHex(T)` where T is something that has a `begin()` member function. This allows us to remove the strHex overloads for `std::string`, Blob, and Slice. --- src/ripple/basics/Buffer.h | 26 ++++++++++++++ src/ripple/basics/Slice.h | 32 ++++++++++++++--- src/ripple/basics/StringUtilities.h | 21 +----------- src/ripple/basics/base_uint.h | 2 +- src/ripple/basics/impl/strHex.cpp | 8 +---- src/ripple/basics/strHex.h | 42 ++++++++++++++++------- src/ripple/protocol/PublicKey.h | 26 ++++++++++++++ src/ripple/protocol/STPathSet.h | 2 +- src/ripple/protocol/SecretKey.h | 26 ++++++++++++++ src/ripple/protocol/Seed.h | 26 ++++++++++++++ src/ripple/protocol/impl/PublicKey.cpp | 2 +- src/ripple/protocol/impl/STBlob.cpp | 2 +- src/ripple/protocol/impl/STPathSet.cpp | 2 +- src/ripple/protocol/impl/SecretKey.cpp | 2 +- src/ripple/protocol/impl/UintTypes.cpp | 2 +- src/ripple/rpc/handlers/WalletPropose.cpp | 4 +-- src/test/rpc/AccountSet_test.cpp | 3 +- 17 files changed, 174 insertions(+), 54 deletions(-) diff --git a/src/ripple/basics/Buffer.h b/src/ripple/basics/Buffer.h index bfb119d6c..f9af0d84d 100644 --- a/src/ripple/basics/Buffer.h +++ b/src/ripple/basics/Buffer.h @@ -39,6 +39,8 @@ private: std::size_t size_ = 0; public: + using const_iterator = std::uint8_t const*; + Buffer() = default; /** Create an uninitialized buffer with the given size. */ @@ -191,6 +193,30 @@ public: { return alloc(n); } + + const_iterator + begin() const noexcept + { + return p_.get(); + } + + const_iterator + cbegin() const noexcept + { + return p_.get(); + } + + const_iterator + end() const noexcept + { + return p_.get() + size_; + } + + const_iterator + cend() const noexcept + { + return p_.get() + size_; + } }; inline bool operator==(Buffer const& lhs, Buffer const& rhs) noexcept diff --git a/src/ripple/basics/Slice.h b/src/ripple/basics/Slice.h index 076dbb0ac..c710ce3fe 100644 --- a/src/ripple/basics/Slice.h +++ b/src/ripple/basics/Slice.h @@ -47,6 +47,8 @@ private: std::size_t size_ = 0; public: + using const_iterator = std::uint8_t const*; + /** Default constructed Slice has length 0. */ Slice() noexcept = default; @@ -114,6 +116,31 @@ public: return temp += n; } /** @} */ + + + const_iterator + begin() const noexcept + { + return data_; + } + + const_iterator + cbegin() const noexcept + { + return data_; + } + + const_iterator + end() const noexcept + { + return data_ + size_; + } + + const_iterator + cend() const noexcept + { + return data_ + size_; + } }; //------------------------------------------------------------------------------ @@ -159,7 +186,7 @@ operator< (Slice const& lhs, Slice const& rhs) noexcept template Stream& operator<<(Stream& s, Slice const& v) { - s << strHex(v.data(), v.size()); + s << strHex(v); return s; } @@ -192,9 +219,6 @@ makeSlice (std::basic_string const& s) return Slice(s.data(), s.size()); } -std::string -strHex (Slice const& slice); - } // ripple #endif diff --git a/src/ripple/basics/StringUtilities.h b/src/ripple/basics/StringUtilities.h index 2f5b5b6e2..f3d5039ec 100644 --- a/src/ripple/basics/StringUtilities.h +++ b/src/ripple/basics/StringUtilities.h @@ -22,32 +22,13 @@ #include #include -#include + #include #include #include #include namespace ripple { - -// NIKB TODO Remove the need for all these overloads. Move them out of here. -inline const std::string strHex (std::string const& strSrc) -{ - return strHex (strSrc.begin (), strSrc.size ()); -} - -inline std::string strHex (Blob const& vucData) -{ - return strHex (vucData.begin (), vucData.size ()); -} - -inline std::string strHex (const std::uint64_t uiHost) -{ - uint64_t uBig = boost::endian::native_to_big (uiHost); - - return strHex ((unsigned char*) &uBig, sizeof (uBig)); -} - inline static std::string sqlEscape (std::string const& strSrc) { static boost::format f ("X'%s'"); diff --git a/src/ripple/basics/base_uint.h b/src/ripple/basics/base_uint.h index d1da0b5e7..c3bad19eb 100644 --- a/src/ripple/basics/base_uint.h +++ b/src/ripple/basics/base_uint.h @@ -510,7 +510,7 @@ inline const base_uint operator+ ( template inline std::string to_string (base_uint const& a) { - return strHex (a.begin (), a.size ()); + return strHex (a.cbegin (), a.cend ()); } // Function templates that return a base_uint given text in hexadecimal. diff --git a/src/ripple/basics/impl/strHex.cpp b/src/ripple/basics/impl/strHex.cpp index 293ce5b96..4920cb78d 100644 --- a/src/ripple/basics/impl/strHex.cpp +++ b/src/ripple/basics/impl/strHex.cpp @@ -17,9 +17,9 @@ */ //============================================================================== -#include #include #include +#include namespace ripple { @@ -51,10 +51,4 @@ int charUnHex (unsigned char c) return xtab[c]; } -std::string -strHex(Slice const& slice) -{ - return strHex(slice.data(), slice.size()); -} - } diff --git a/src/ripple/basics/strHex.h b/src/ripple/basics/strHex.h index 3c14ea393..3620f2675 100644 --- a/src/ripple/basics/strHex.h +++ b/src/ripple/basics/strHex.h @@ -28,6 +28,9 @@ #include #include +#include +#include + namespace ripple { /** Converts an integer to the corresponding hex digit @@ -62,22 +65,35 @@ charUnHex (char c) } /** @} */ -// NIKB TODO cleanup this function and reduce the need for the many overloads -// it has in various places. -template -std::string strHex (FwdIt first, int size) +template +std::string +strHex(FwdIt begin, FwdIt end) { - std::string s; - s.resize (size * 2); - for (int i = 0; i < size; i++) - { - unsigned char c = *first++; - s[i * 2] = charHex (c >> 4); - s[i * 2 + 1] = charHex (c & 15); - } - return s; + static_assert( + std::is_convertible< + typename std::iterator_traits::iterator_category, + std::forward_iterator_tag>::value, + "FwdIt must be a forward iterator"); + std::string result; + result.reserve(2 * std::distance(begin, end)); + boost::algorithm::hex(begin, end, std::back_inserter(result)); + return result; } +template ().begin())> +std::string strHex(T const& from) +{ + return strHex(from.begin(), from.end()); +} + +inline std::string strHex (const std::uint64_t uiHost) +{ + uint64_t uBig = boost::endian::native_to_big (uiHost); + + auto const begin = (unsigned char*) &uBig; + auto const end = begin + sizeof(uBig); + return strHex(begin, end); +} } #endif diff --git a/src/ripple/protocol/PublicKey.h b/src/ripple/protocol/PublicKey.h index 1ca4fe951..b640da94b 100644 --- a/src/ripple/protocol/PublicKey.h +++ b/src/ripple/protocol/PublicKey.h @@ -63,6 +63,8 @@ protected: std::uint8_t buf_[33]; // should be large enough public: + using const_iterator = std::uint8_t const*; + PublicKey() = default; PublicKey (PublicKey const& other); PublicKey& operator= (PublicKey const& other); @@ -87,6 +89,30 @@ public: return size_; } + const_iterator + begin() const noexcept + { + return buf_; + } + + const_iterator + cbegin() const noexcept + { + return buf_; + } + + const_iterator + end() const noexcept + { + return buf_ + size_; + } + + const_iterator + cend() const noexcept + { + return buf_ + size_; + } + bool empty() const noexcept { diff --git a/src/ripple/protocol/STPathSet.h b/src/ripple/protocol/STPathSet.h index 70b791114..b14fcd282 100644 --- a/src/ripple/protocol/STPathSet.h +++ b/src/ripple/protocol/STPathSet.h @@ -120,7 +120,7 @@ public: STPathElement(STPathElement const&) = default; STPathElement& operator=(STPathElement const&) = default; - int + auto getNodeType () const { return mType; diff --git a/src/ripple/protocol/SecretKey.h b/src/ripple/protocol/SecretKey.h index 6174ed40e..b371ac65a 100644 --- a/src/ripple/protocol/SecretKey.h +++ b/src/ripple/protocol/SecretKey.h @@ -38,6 +38,8 @@ private: std::uint8_t buf_[32]; public: + using const_iterator = std::uint8_t const*; + SecretKey() = default; SecretKey (SecretKey const&) = default; SecretKey& operator= (SecretKey const&) = default; @@ -66,6 +68,30 @@ public: */ std::string to_string() const; + + const_iterator + begin() const noexcept + { + return buf_; + } + + const_iterator + cbegin() const noexcept + { + return buf_; + } + + const_iterator + end() const noexcept + { + return buf_ + sizeof(buf_); + } + + const_iterator + cend() const noexcept + { + return buf_ + sizeof(buf_); + } }; inline diff --git a/src/ripple/protocol/Seed.h b/src/ripple/protocol/Seed.h index 411d283c7..ebe346e0c 100644 --- a/src/ripple/protocol/Seed.h +++ b/src/ripple/protocol/Seed.h @@ -35,6 +35,8 @@ private: std::array buf_; public: + using const_iterator = std::array::const_iterator; + Seed() = delete; Seed (Seed const&) = default; @@ -62,6 +64,30 @@ public: { return buf_.size(); } + + const_iterator + begin() const noexcept + { + return buf_.begin(); + } + + const_iterator + cbegin() const noexcept + { + return buf_.cbegin(); + } + + const_iterator + end() const noexcept + { + return buf_.end(); + } + + const_iterator + cend() const noexcept + { + return buf_.cend(); + } }; //------------------------------------------------------------------------------ diff --git a/src/ripple/protocol/impl/PublicKey.cpp b/src/ripple/protocol/impl/PublicKey.cpp index 3a4b1f4c5..8a80bad7e 100644 --- a/src/ripple/protocol/impl/PublicKey.cpp +++ b/src/ripple/protocol/impl/PublicKey.cpp @@ -31,7 +31,7 @@ namespace ripple { std::ostream& operator<<(std::ostream& os, PublicKey const& pk) { - os << strHex(pk.data(), pk.size()); + os << strHex(pk); return os; } diff --git a/src/ripple/protocol/impl/STBlob.cpp b/src/ripple/protocol/impl/STBlob.cpp index e1dc2eb1d..91944af7e 100644 --- a/src/ripple/protocol/impl/STBlob.cpp +++ b/src/ripple/protocol/impl/STBlob.cpp @@ -31,7 +31,7 @@ STBlob::STBlob (SerialIter& st, SField const& name) std::string STBlob::getText () const { - return strHex (value_.data (), value_.size ()); + return strHex (value_); } bool diff --git a/src/ripple/protocol/impl/STPathSet.cpp b/src/ripple/protocol/impl/STPathSet.cpp index ddb65bc2f..20b6a4711 100644 --- a/src/ripple/protocol/impl/STPathSet.cpp +++ b/src/ripple/protocol/impl/STPathSet.cpp @@ -156,7 +156,7 @@ STPath::getJson (int) const for (auto it: mPath) { Json::Value elem (Json::objectValue); - int iType = it.getNodeType (); + auto const iType = it.getNodeType (); elem[jss::type] = iType; elem[jss::type_hex] = strHex (iType); diff --git a/src/ripple/protocol/impl/SecretKey.cpp b/src/ripple/protocol/impl/SecretKey.cpp index c0e0a97c0..cd4e5ce6f 100644 --- a/src/ripple/protocol/impl/SecretKey.cpp +++ b/src/ripple/protocol/impl/SecretKey.cpp @@ -51,7 +51,7 @@ SecretKey::SecretKey (Slice const& slice) std::string SecretKey::to_string() const { - return strHex(data(), size()); + return strHex(*this); } //------------------------------------------------------------------------------ diff --git a/src/ripple/protocol/impl/UintTypes.cpp b/src/ripple/protocol/impl/UintTypes.cpp index 5699a785c..1a8c66be6 100644 --- a/src/ripple/protocol/impl/UintTypes.cpp +++ b/src/ripple/protocol/impl/UintTypes.cpp @@ -61,7 +61,7 @@ std::string to_string(Currency const& currency) } } - return strHex (currency.begin (), currency.size ()); + return strHex (currency); } bool to_currency(Currency& currency, std::string const& code) diff --git a/src/ripple/rpc/handlers/WalletPropose.cpp b/src/ripple/rpc/handlers/WalletPropose.cpp index 1a896f178..a9f0e8810 100644 --- a/src/ripple/rpc/handlers/WalletPropose.cpp +++ b/src/ripple/rpc/handlers/WalletPropose.cpp @@ -108,7 +108,7 @@ Json::Value walletPropose (Json::Value const& params) Json::Value obj (Json::objectValue); auto const seed1751 = seedAs1751 (*seed); - auto const seedHex = strHex (seed->data(), seed->size()); + auto const seedHex = strHex (*seed); auto const seedBase58 = toBase58 (*seed); obj[jss::master_seed] = seedBase58; @@ -117,7 +117,7 @@ Json::Value walletPropose (Json::Value const& params) obj[jss::account_id] = toBase58(calcAccountID(publicKey)); obj[jss::public_key] = toBase58(TokenType::AccountPublic, publicKey); obj[jss::key_type] = to_string (keyType); - obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size()); + obj[jss::public_key_hex] = strHex (publicKey); // If a passphrase was specified, and it was hashed and used as a seed // run a quick entropy check and add an appropriate warning, because diff --git a/src/test/rpc/AccountSet_test.cpp b/src/test/rpc/AccountSet_test.cpp index 6beace52a..0568c3102 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -212,7 +212,8 @@ public: env(jt); BEAST_EXPECT(! env.le(alice)->isFieldPresent(sfMessageKey)); - jt[sfMessageKey.fieldName] = strHex("NOT_REALLY_A_PUBKEY"); + using namespace std::string_literals; + jt[sfMessageKey.fieldName] = strHex("NOT_REALLY_A_PUBKEY"s); env(jt, ter(telBAD_PUBLIC_KEY)); }