Browse Source

use baseType to encode arrays

cl-refactor
yann300 10 years ago
parent
commit
e1f4c2e0e5
  1. 12
      mix/CodeModel.cpp
  2. 2
      mix/CodeModel.h
  3. 32
      mix/ContractCallDataEncoder.cpp
  4. 2
      mix/ContractCallDataEncoder.h
  5. 1
      mix/SolidityType.h

12
mix/CodeModel.cpp

@ -493,9 +493,18 @@ dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, co
return m_compiledContracts.at(_contractName);
}
void CodeModel::retrieveSubType(SolidityType& _wrapperType, dev::solidity::Type const* _type)
{
if (_type->getCategory() == Type::Category::Array)
{
ArrayType const* arrayType = dynamic_cast<ArrayType const*>(_type);
_wrapperType.baseType = std::make_shared<dev::mix::SolidityType const>(nodeType(arrayType->getBaseType().get()));
}
}
SolidityType CodeModel::nodeType(dev::solidity::Type const* _type)
{
SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector<SolidityDeclaration>(), std::vector<QString>() };
SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector<SolidityDeclaration>(), std::vector<QString>(), nullptr };
if (!_type)
return r;
switch (_type->getCategory())
@ -536,6 +545,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type)
r.count = static_cast<unsigned>(array->getLength());
r.dynamicSize = _type->isDynamicallySized();
r.array = true;
retrieveSubType(r, _type);
}
break;
case Type::Category::Enum:

2
mix/CodeModel.h

@ -224,6 +224,8 @@ public:
Q_INVOKABLE void unregisterContractSrc(QString const& _documentId);
/// Convert solidity type info to mix type
static SolidityType nodeType(dev::solidity::Type const* _type);
/// Retrieve subtype
static void retrieveSubType(SolidityType& _wrapperType, dev::solidity::Type const* _type);
/// Check if given location belongs to contract or function
bool isContractOrFunctionLocation(dev::SourceLocation const& _location);
/// Get funciton name by location

32
mix/ContractCallDataEncoder.cpp

@ -37,24 +37,6 @@ using namespace dev;
using namespace dev::solidity;
using namespace dev::mix;
static QList<int> extractDimension(QString const& _type)
{
QList<int> dim;
QRegExp dimExtract("(\\[[^\\]]*\\])");
int pos = dimExtract.indexIn(_type);
while (pos != -1)
{
QString d = dimExtract.cap(0);
pos += d.length();
pos = dimExtract.indexIn(_type, pos);
if (d == "[]")
dim.push_front(-1);
else
dim.push_front(d.replace("[", "").replace("]", "").toInt());
}
return dim;
}
bytes ContractCallDataEncoder::encodedData()
{
bytes r(m_encodedData);
@ -81,25 +63,24 @@ void ContractCallDataEncoder::encode(QFunctionDefinition const* _function)
m_encodedData.insert(m_encodedData.end(), hash.begin(), hash.end());
}
void ContractCallDataEncoder::encodeArray(QJsonArray const& _array, QList<int> _dim, SolidityType const& _type, bytes& _content)
void ContractCallDataEncoder::encodeArray(QJsonArray const& _array, SolidityType const& _type, bytes& _content)
{
size_t offsetStart = _content.size();
if (_dim[0] == -1)
if (_type.dynamicSize)
{
bytes count = bytes(32);
toBigEndian((u256)_array.size(), count);
_content += count; //reserved space for count
}
_dim.pop_front();
int k = 0;
for (QJsonValue const& c: _array)
{
if (c.isArray())
{
if (_dim[0] == -1)
if (_type.baseType->dynamicSize)
m_dynamicOffsetMap.push_back(std::make_pair(m_dynamicData.size() + offsetStart + 32 + k * 32, m_dynamicData.size() + _content.size()));
encodeArray(c.toArray(), _dim, _type, _content);
encodeArray(c.toArray(), *_type.baseType, _content);
}
else
{
@ -128,16 +109,15 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const&
}
else if (_type.array)
{
QList<int> dim = extractDimension(_type. name);
bytes content;
size_t size = m_encodedData.size();
if (dim.front() == -1)
if (_type.dynamicSize)
{
m_encodedData += bytes(32); // reserve space for offset
m_staticOffsetMap.push_back(std::make_pair(size, m_dynamicData.size()));
}
QJsonDocument jsonDoc = QJsonDocument::fromJson(_data.toString().toUtf8());
encodeArray(jsonDoc.array(), dim, _type, content);
encodeArray(jsonDoc.array(), _type, content);
if (!_type.dynamicSize)
m_encodedData.insert(m_encodedData.end(), content.begin(), content.end());

2
mix/ContractCallDataEncoder.h

@ -71,7 +71,7 @@ private:
QString toString(bool _b);
QString toString(dev::bytes const& _b);
bool asString(dev::bytes const& _b, QString& _str);
void encodeArray(QJsonArray const& _array, QList<int> _dim, SolidityType const& _type, bytes& _content);
void encodeArray(QJsonArray const& _array, SolidityType const& _type, bytes& _content);
QString toChar(dev::bytes const& _b);
private:

1
mix/SolidityType.h

@ -57,6 +57,7 @@ struct SolidityType
QString name;
std::vector<SolidityDeclaration> members; //for struct
std::vector<QString> enumNames; //for enum
std::shared_ptr<SolidityType const> baseType;
};
struct SolidityDeclaration

Loading…
Cancel
Save