Browse Source

Merge remote-tracking branch 'upstream/develop' into addTests

cl-refactor
CJentzsch 10 years ago
parent
commit
c2c37ad520
  1. 2
      libdevcore/Exceptions.h
  2. 31
      libdevcore/RLP.cpp
  3. 34
      libdevcore/RLP.h

2
libdevcore/Exceptions.h

@ -44,6 +44,8 @@ struct BadHexCharacter: virtual Exception {};
struct RLPException: virtual Exception {};
struct BadCast: virtual RLPException {};
struct BadRLP: virtual RLPException {};
struct OversizeRLP: virtual RLPException {};
struct UndersizeRLP: virtual RLPException {};
struct NoNetworking: virtual Exception {};
struct NoUPnPDevice: virtual Exception {};
struct RootNotFound: virtual Exception {};

31
libdevcore/RLP.cpp

@ -26,12 +26,31 @@ using namespace dev;
bytes dev::RLPNull = rlp("");
bytes dev::RLPEmptyList = rlpList();
RLP::RLP(bytesConstRef _d, Strictness _s):
m_data(_d)
{
if ((_s & FailIfTooBig) && actualSize() < _d.size())
{
if (_s & ThrowOnFail)
BOOST_THROW_EXCEPTION(OversizeRLP());
else
m_data.reset();
}
if ((_s & FailIfTooSmall) && actualSize() > _d.size())
{
if (_s & ThrowOnFail)
BOOST_THROW_EXCEPTION(UndersizeRLP());
else
m_data.reset();
}
}
RLP::iterator& RLP::iterator::operator++()
{
if (m_remaining)
{
m_lastItem.retarget(m_lastItem.next().data(), m_remaining);
m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem).actualSize());
m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize());
m_remaining -= std::min<unsigned>(m_remaining, m_lastItem.size());
}
else
@ -44,7 +63,7 @@ RLP::iterator::iterator(RLP const& _parent, bool _begin)
if (_begin && _parent.isList())
{
auto pl = _parent.payload();
m_lastItem = pl.cropped(0, RLP(pl).actualSize());
m_lastItem = pl.cropped(0, RLP(pl, ThrowOnFail | FailIfTooSmall).actualSize());
m_remaining = pl.size() - m_lastItem.size();
}
else
@ -58,17 +77,17 @@ RLP RLP::operator[](unsigned _i) const
{
if (_i < m_lastIndex)
{
m_lastEnd = RLP(payload()).actualSize();
m_lastEnd = RLP(payload(), ThrowOnFail | FailIfTooSmall).actualSize();
m_lastItem = payload().cropped(0, m_lastEnd);
m_lastIndex = 0;
}
for (; m_lastIndex < _i && m_lastItem.size(); ++m_lastIndex)
{
m_lastItem = payload().cropped(m_lastEnd);
m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem).actualSize());
m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize());
m_lastEnd += m_lastItem.size();
}
return RLP(m_lastItem);
return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall);
}
RLPs RLP::toList() const
@ -154,7 +173,7 @@ unsigned RLP::items() const
bytesConstRef d = payload().cropped(0, length());
unsigned i = 0;
for (; d.size(); ++i)
d = d.cropped(RLP(d).actualSize());
d = d.cropped(RLP(d, ThrowOnFail | FailIfTooSmall).actualSize());
return i;
}
return 0;

34
libdevcore/RLP.h

@ -62,20 +62,34 @@ static const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount -
class RLP
{
public:
/// Conversion flags
enum
{
AllowNonCanon = 1,
ThrowOnFail = 4,
FailIfTooBig = 8,
FailIfTooSmall = 16,
Strict = ThrowOnFail | FailIfTooBig,
VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall,
LaisezFaire = AllowNonCanon
};
using Strictness = int;
/// Construct a null node.
RLP() {}
/// Construct a node of value given in the bytes.
explicit RLP(bytesConstRef _d): m_data(_d) {}
explicit RLP(bytesConstRef _d, Strictness _s = VeryStrict);
/// Construct a node of value given in the bytes.
explicit RLP(bytes const& _d): m_data(&_d) {}
explicit RLP(bytes const& _d, Strictness _s = VeryStrict): RLP(&_d, _s) {}
/// Construct a node to read RLP data in the bytes given.
RLP(byte const* _b, unsigned _s): m_data(bytesConstRef(_b, _s)) {}
RLP(byte const* _b, unsigned _s, Strictness _st = VeryStrict): RLP(bytesConstRef(_b, _s), _st) {}
/// Construct a node to read RLP data in the string.
explicit RLP(std::string const& _s): m_data(bytesConstRef((byte const*)_s.data(), _s.size())) {}
explicit RLP(std::string const& _s, Strictness _st = VeryStrict): RLP(bytesConstRef((byte const*)_s.data(), _s.size()), _st) {}
/// The bare data of the RLP.
bytesConstRef data() const { return m_data; }
@ -236,18 +250,6 @@ public:
return ret;
}
/// Int conversion flags
enum
{
AllowNonCanon = 1,
ThrowOnFail = 4,
FailIfTooBig = 8,
FailIfTooSmall = 16,
Strict = ThrowOnFail | FailIfTooBig,
VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall,
LaisezFaire = AllowNonCanon
};
/// Converts to int of type given; if isString(), decodes as big-endian bytestream. @returns 0 if not an int or string.
template <class _T = unsigned> _T toInt(int _flags = Strict) const
{

Loading…
Cancel
Save