[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/cheny56/cpp-ethereum/develop/libdevcore/RLP.cpp [Back]  [Original]

/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see .
*/
/** @file RLP.cpp
 * @author Gav Wood 
 * @date 2014
 */

#include "RLP.h"
using namespace std;
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_currentItem.retarget(m_currentItem.next().data(), m_remaining);
		m_currentItem = m_currentItem.cropped(0, sizeAsEncoded(m_currentItem));
		m_remaining -= std::min(m_remaining, m_currentItem.size());
	}
	else
		m_currentItem.retarget(m_currentItem.next().data(), 0);
	return *this;
}

RLP::iterator::iterator(RLP const& _parent, bool _begin)
{
	if (_begin && _parent.isList())
	{
		auto pl = _parent.payload();
		m_currentItem = pl.cropped(0, sizeAsEncoded(pl));
		m_remaining = pl.size() - m_currentItem.size();
	}
	else
	{
		m_currentItem = _parent.data().cropped(_parent.data().size());
		m_remaining = 0;
	}
}

RLP RLP::operator[](size_t _i) const
{
	if (_i < m_lastIndex)
	{
		m_lastEnd = sizeAsEncoded(payload());
		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, sizeAsEncoded(m_lastItem));
		m_lastEnd += m_lastItem.size();
	}
	return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall);
}

RLPs RLP::toList(int _flags) const
{
	RLPs ret;
	if (!isList())
	{
		if (_flags & ThrowOnFail)
			BOOST_THROW_EXCEPTION(BadCast());
		else
			return ret;
	}
	for (auto const& i: *this)
		ret.push_back(i);
	return ret;
}

size_t RLP::actualSize() const
{
	if (isNull())
		return 0;
	if (isSingleByte())
		return 1;
	if (isData() || isList())
		return payloadOffset() + length();
	return 0;
}

void RLP::requireGood() const
{
	if (isNull())
		BOOST_THROW_EXCEPTION(BadRLP());
	byte n = m_data[0];
	if (n != c_rlpDataImmLenStart + 1)
		return;
	if (m_data.size() < 2)
		BOOST_THROW_EXCEPTION(BadRLP());
	if (m_data[1] < c_rlpDataImmLenStart)
		BOOST_THROW_EXCEPTION(BadRLP());
}

bool RLP::isInt() const
{
	if (isNull())
		return false;
	requireGood();
	byte n = m_data[0];
	if (n < c_rlpDataImmLenStart)
		return !!n;
	else if (n == c_rlpDataImmLenStart)
		return true;
	else if (n 

Web Proxy Viewer  |  New URL  |  Original Page