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); 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 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) if (!_type)
return r; return r;
switch (_type->getCategory()) switch (_type->getCategory())
@ -536,6 +545,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type)
r.count = static_cast<unsigned>(array->getLength()); r.count = static_cast<unsigned>(array->getLength());
r.dynamicSize = _type->isDynamicallySized(); r.dynamicSize = _type->isDynamicallySized();
r.array = true; r.array = true;
retrieveSubType(r, _type);
} }
break; break;
case Type::Category::Enum: case Type::Category::Enum:

2
mix/CodeModel.h

@ -224,6 +224,8 @@ public:
Q_INVOKABLE void unregisterContractSrc(QString const& _documentId); Q_INVOKABLE void unregisterContractSrc(QString const& _documentId);
/// Convert solidity type info to mix type /// Convert solidity type info to mix type
static SolidityType nodeType(dev::solidity::Type const* _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 /// Check if given location belongs to contract or function
bool isContractOrFunctionLocation(dev::SourceLocation const& _location); bool isContractOrFunctionLocation(dev::SourceLocation const& _location);
/// Get funciton name by location /// Get funciton name by location

32
mix/ContractCallDataEncoder.cpp

@ -37,24 +37,6 @@ using namespace dev;
using namespace dev::solidity; using namespace dev::solidity;
using namespace dev::mix; 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 ContractCallDataEncoder::encodedData()
{ {
bytes r(m_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()); 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(); size_t offsetStart = _content.size();
if (_dim[0] == -1) if (_type.dynamicSize)
{ {
bytes count = bytes(32); bytes count = bytes(32);
toBigEndian((u256)_array.size(), count); toBigEndian((u256)_array.size(), count);
_content += count; //reserved space for count _content += count; //reserved space for count
} }
_dim.pop_front();
int k = 0; int k = 0;
for (QJsonValue const& c: _array) for (QJsonValue const& c: _array)
{ {
if (c.isArray()) 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())); 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 else
{ {
@ -128,16 +109,15 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const&
} }
else if (_type.array) else if (_type.array)
{ {
QList<int> dim = extractDimension(_type. name);
bytes content; bytes content;
size_t size = m_encodedData.size(); size_t size = m_encodedData.size();
if (dim.front() == -1) if (_type.dynamicSize)
{ {
m_encodedData += bytes(32); // reserve space for offset m_encodedData += bytes(32); // reserve space for offset
m_staticOffsetMap.push_back(std::make_pair(size, m_dynamicData.size())); m_staticOffsetMap.push_back(std::make_pair(size, m_dynamicData.size()));
} }
QJsonDocument jsonDoc = QJsonDocument::fromJson(_data.toString().toUtf8()); QJsonDocument jsonDoc = QJsonDocument::fromJson(_data.toString().toUtf8());
encodeArray(jsonDoc.array(), dim, _type, content); encodeArray(jsonDoc.array(), _type, content);
if (!_type.dynamicSize) if (!_type.dynamicSize)
m_encodedData.insert(m_encodedData.end(), content.begin(), content.end()); 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(bool _b);
QString toString(dev::bytes const& _b); QString toString(dev::bytes const& _b);
bool asString(dev::bytes const& _b, QString& _str); 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); QString toChar(dev::bytes const& _b);
private: private:

1
mix/SolidityType.h

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

Loading…
Cancel
Save