Browse Source

Fix for vector_ref (yes, crazy that it's been dormant for so long).

Fixes to ABI.
cl-refactor
Gav Wood 10 years ago
parent
commit
5062f7190a
  1. 96
      abi/main.cpp
  2. 3
      libdevcore/vector_ref.h

96
abi/main.cpp

@ -303,7 +303,7 @@ tuple<bytes, ABIType, Format> fromUser(std::string const& _arg, Tristate _prefix
type.noteDecimalInput(); type.noteDecimalInput();
return make_tuple(toCompactBigEndian(bigint(val.substr(1))), type, Format::Decimal); return make_tuple(toCompactBigEndian(bigint(val.substr(1))), type, Format::Decimal);
} }
if (val.substr(0, 1) == "@") if (val.substr(0, 1) == "'")
{ {
type.noteBinaryInput(); type.noteBinaryInput();
return make_tuple(asBytes(val.substr(1)), type, Format::Binary); return make_tuple(asBytes(val.substr(1)), type, Format::Binary);
@ -335,6 +335,7 @@ tuple<bytes, ABIType, Format> fromUser(std::string const& _arg, Tristate _prefix
throw InvalidUserString(); throw InvalidUserString();
} }
struct ExpectedAdditionalParameter: public Exception {};
struct ExpectedOpen: public Exception {}; struct ExpectedOpen: public Exception {};
struct ExpectedClose: public Exception {}; struct ExpectedClose: public Exception {};
@ -394,10 +395,10 @@ struct ABIMethod
ss << "constant "; ss << "constant ";
if (!outs.empty()) if (!outs.empty())
{ {
ss << "returns ("; ss << "returns(";
f = 0; f = 0;
for (ABIType const& i: outs) for (ABIType const& i: outs)
ss << (f ? ", " : "") << i.canon() << " " << i.name; ss << (f++ ? ", " : "") << i.canon() << " " << i.name;
ss << ")"; ss << ")";
} }
return ss.str(); return ss.str();
@ -417,11 +418,15 @@ struct ABIMethod
for (ABIType const& a: ins) for (ABIType const& a: ins)
{ {
if (pi >= _params.size())
throw ExpectedAdditionalParameter();
auto put = [&]() { auto put = [&]() {
if (a.isBytes()) if (a.isBytes())
ret += h256(u256(_params[pi].first.size())).asBytes(); ret += h256(u256(_params[pi].first.size())).asBytes();
suffix += a.unrender(_params[pi].first, _params[pi].second); suffix += a.unrender(_params[pi].first, _params[pi].second);
pi++; pi++;
if (pi >= _params.size())
throw ExpectedAdditionalParameter();
}; };
function<void(vector<int>, unsigned)> putDim = [&](vector<int> addr, unsigned q) { function<void(vector<int>, unsigned)> putDim = [&](vector<int> addr, unsigned q) {
if (addr.size() == a.dims.size()) if (addr.size() == a.dims.size())
@ -430,13 +435,14 @@ struct ABIMethod
{ {
if (_params[pi].second != Format::Open) if (_params[pi].second != Format::Open)
throw ExpectedOpen(); throw ExpectedOpen();
++pi;
int l = a.dims[addr.size()]; int l = a.dims[addr.size()];
if (l == -1) if (l == -1)
{ {
// read ahead in params and discover the arity. // read ahead in params and discover the arity.
unsigned depth = 0; unsigned depth = 0;
l = 0; l = 0;
for (unsigned pi2 = pi + 1; depth || _params[pi2].second != Format::Close;) for (unsigned pi2 = pi; depth || _params[pi2].second != Format::Close;)
{ {
if (_params[pi2].second == Format::Open) if (_params[pi2].second == Format::Open)
++depth; ++depth;
@ -454,6 +460,7 @@ struct ABIMethod
putDim(addr, q); putDim(addr, q);
if (_params[pi].second != Format::Close) if (_params[pi].second != Format::Close)
throw ExpectedClose(); throw ExpectedClose();
++pi;
} }
}; };
putDim(vector<int>(), 1); putDim(vector<int>(), 1);
@ -463,8 +470,6 @@ struct ABIMethod
string decode(bytes const& _data, int _index, EncodingPrefs _ep) string decode(bytes const& _data, int _index, EncodingPrefs _ep)
{ {
stringstream out; stringstream out;
if (_index == -1)
out << "[";
unsigned di = 0; unsigned di = 0;
vector<unsigned> catDims; vector<unsigned> catDims;
for (ABIType const& a: outs) for (ABIType const& a: outs)
@ -481,7 +486,6 @@ struct ABIMethod
put(); put();
else else
{ {
out << "[";
int l = a.dims[addr.size()]; int l = a.dims[addr.size()];
if (l == -1) if (l == -1)
{ {
@ -492,7 +496,6 @@ struct ABIMethod
q *= l; q *= l;
for (addr.push_back(0); addr.back() < l; ++addr.back()) for (addr.push_back(0); addr.back() < l; ++addr.back())
putDim(addr, q); putDim(addr, q);
out << "]";
} }
}; };
putDim(vector<int>(), 1); putDim(vector<int>(), 1);
@ -500,12 +503,20 @@ struct ABIMethod
unsigned d = 0; unsigned d = 0;
for (ABIType const& a: outs) for (ABIType const& a: outs)
{ {
if (_index == -1 && out.tellp() > 0)
out << ", ";
auto put = [&]() { auto put = [&]() {
unsigned l = 32;
if (a.isBytes()) if (a.isBytes())
l = (catDims[d++] + 31 / 32) * 32; {
out << a.render(bytesConstRef(&_data).cropped(di, l).toBytes(), _ep) << ", "; out << a.render(bytesConstRef(&_data).cropped(di, catDims[d]).toBytes(), _ep);
di += l; di += ((catDims[d] + 31) / 32) * 32;
d++;
}
else
{
out << a.render(bytesConstRef(&_data).cropped(di, 32).toBytes(), _ep);
di += 32;
}
}; };
function<void(vector<int>)> putDim = [&](vector<int> addr) { function<void(vector<int>)> putDim = [&](vector<int> addr) {
if (addr.size() == a.dims.size()) if (addr.size() == a.dims.size())
@ -527,22 +538,22 @@ struct ABIMethod
} }
}; };
putDim(vector<int>()); putDim(vector<int>());
if (_index == -1)
out << ", ";
} }
(void)_data;
if (_index == -1)
out << "]";
return out.str(); return out.str();
} }
}; };
string canonSig(string const& _name, vector<ABIType> const& _args) string canonSig(string const& _name, vector<ABIType> const& _args)
{ {
string methodArgs; try {
for (auto const& arg: _args) string methodArgs;
methodArgs += (methodArgs.empty() ? "" : ",") + arg.canon(); for (auto const& arg: _args)
return _name + "(" + methodArgs + ")"; methodArgs += (methodArgs.empty() ? "" : ",") + arg.canon();
return _name + "(" + methodArgs + ")";
}
catch (...) {
return string();
}
} }
struct UnknownMethod: public Exception {}; struct UnknownMethod: public Exception {};
@ -632,6 +643,7 @@ int main(int argc, char** argv)
int outputIndex = -1; int outputIndex = -1;
vector<pair<bytes, Format>> params; vector<pair<bytes, Format>> params;
vector<ABIType> args; vector<ABIType> args;
string incoming;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
@ -656,8 +668,6 @@ int main(int argc, char** argv)
typePrefix = Tristate::True; typePrefix = Tristate::True;
else if (arg == "-T" || arg == "--no-typing") else if (arg == "-T" || arg == "--no-typing")
typePrefix = Tristate::False; typePrefix = Tristate::False;
else if (arg == "-v" || arg == "--verbose")
verbose = true;
else if (arg == "-x" || arg == "--hex") else if (arg == "-x" || arg == "--hex")
prefs.e = Encoding::Hex; prefs.e = Encoding::Hex;
else if (arg == "-d" || arg == "--decimal" || arg == "--dec") else if (arg == "-d" || arg == "--decimal" || arg == "--dec")
@ -665,21 +675,23 @@ int main(int argc, char** argv)
else if (arg == "-b" || arg == "--binary" || arg == "--bin") else if (arg == "-b" || arg == "--binary" || arg == "--bin")
prefs.e = Encoding::Binary; prefs.e = Encoding::Binary;
else if (arg == "-v" || arg == "--verbose") else if (arg == "-v" || arg == "--verbose")
version(); verbose = true;
else if (arg == "-V" || arg == "--version") else if (arg == "-V" || arg == "--version")
version(); version();
else if (method.empty()) else if (method.empty())
method = arg; method = arg;
else else if (mode == Mode::Encode)
{ {
auto u = fromUser(arg, formatPrefix, typePrefix); auto u = fromUser(arg, formatPrefix, typePrefix);
args.push_back(get<1>(u)); args.push_back(get<1>(u));
params.push_back(make_pair(get<0>(u), get<2>(u))); params.push_back(make_pair(get<0>(u), get<2>(u)));
} }
else if (mode == Mode::Decode)
incoming += arg;
} }
string abiData; string abiData;
if (abiFile.empty()) if (!abiFile.empty())
abiData = contentsString(abiFile); abiData = contentsString(abiFile);
if (mode == Mode::Encode) if (mode == Mode::Encode)
@ -695,13 +707,30 @@ int main(int argc, char** argv)
try { try {
m = abi.method(method, args); m = abi.method(method, args);
} }
catch(...) catch (...)
{ {
cerr << "Unknown method in ABI." << endl; cerr << "Unknown method in ABI." << endl;
exit(-1); exit(-1);
} }
} }
userOutput(cout, m.encode(params), encoding); try {
userOutput(cout, m.encode(params), encoding);
}
catch (ExpectedAdditionalParameter const&)
{
cerr << "Expected additional parameter in input." << endl;
exit(-1);
}
catch (ExpectedOpen const&)
{
cerr << "Expected open-bracket '[' in input." << endl;
exit(-1);
}
catch (ExpectedClose const&)
{
cerr << "Expected close-bracket ']' in input." << endl;
exit(-1);
}
} }
else if (mode == Mode::Decode) else if (mode == Mode::Decode)
{ {
@ -725,9 +754,14 @@ int main(int argc, char** argv)
exit(-1); exit(-1);
} }
string encoded; string encoded;
for (int i = cin.get(); i != -1; i = cin.get()) if (incoming == "--" || incoming.empty())
encoded.push_back((char)i); for (int i = cin.get(); i != -1; i = cin.get())
cout << m.decode(fromHex(encoded), outputIndex, prefs); encoded.push_back((char)i);
else
{
encoded = contentsString(incoming);
}
cout << m.decode(fromHex(boost::trim_copy(encoded)), outputIndex, prefs) << endl;
} }
} }

3
libdevcore/vector_ref.h

@ -39,7 +39,8 @@ public:
size_t size() const { return m_count; } size_t size() const { return m_count; }
bool empty() const { return !m_count; } bool empty() const { return !m_count; }
vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); } vector_ref<_T> next() const { return vector_ref<_T>(m_data + m_count, m_count); }
vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } vector_ref<_T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin + _count <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
vector_ref<_T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<_T>(m_data + _begin, m_count - _begin); else return vector_ref<_T>(); }
void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; } void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; }
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); } void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }

Loading…
Cancel
Save