More work on the JSON conversion code.

This commit is contained in:
JoelKatz
2012-10-01 08:32:23 -07:00
parent 98d8823be0
commit c4275c6d80
6 changed files with 157 additions and 20 deletions

View File

@@ -5,6 +5,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
// These must stay at the top of this file
@@ -82,3 +83,15 @@ std::string SField::getName() const
return boost::lexical_cast<std::string>(static_cast<int>(fieldType)) + "/" +
boost::lexical_cast<std::string>(fieldValue);
}
SField::ref SField::getField(const std::string& fieldName)
{ // OPTIMIZEME me with a map. CHECKME this is case sensitive
boost::mutex::scoped_lock sl(mapMutex);
typedef std::pair<const int, SField::ptr> int_sfref_pair;
BOOST_FOREACH(const int_sfref_pair& fieldPair, codeToField)
{
if (fieldPair.second->fieldName == fieldName)
return *(fieldPair.second);
}
return sfInvalid;
}

View File

@@ -58,6 +58,7 @@ public:
static SField::ref getField(int fieldCode);
static SField::ref getField(int fieldType, int fieldValue);
static SField::ref getField(const std::string& fieldName);
static SField::ref getField(SerializedTypeID type, int value) { return getField(FIELD_CODE(type, value)); }
std::string getName() const;

View File

@@ -2,9 +2,9 @@
#include "LedgerFormats.h"
#define LEF_BASE \
{ sfLedgerIndex, SOE_OPTIONAL }, \
{ sfLedgerEntryType, SOE_REQUIRED }, \
{ sfFlags, SOE_REQUIRED }, \
{ sfLedgerIndex, SOE_OPTIONAL },
{ sfFlags, SOE_REQUIRED },
LedgerEntryFormat LedgerFormats[]=
{

View File

@@ -429,6 +429,20 @@ void STObject::makeFieldAbsent(SField::ref field)
mData.replace(index, makeDefaultObject(f.getFName()));
}
bool STObject::delField(SField::ref field)
{
int index = getFieldIndex(field);
if (index == -1)
return false;
delField(index);
return true;
}
void STObject::delField(int index)
{
mData.erase(mData.begin() + index);
}
std::string STObject::getFieldString(SField::ref field) const
{
const SerializedType* rf = peekAtPField(field);
@@ -777,18 +791,126 @@ STArray* STArray::construct(SerializerIterator& sit, SField::ref field)
return new STArray(field, value);
}
STObject::STObject(const Json::Value& object, SField::ref name) : SerializedType(name)
std::auto_ptr<STObject> STObject::parseJson(const Json::Value& object, SField::ref name, int depth)
{
if (!object.isObject())
throw std::runtime_error("Value is not an object");
boost::ptr_vector<SerializedType> data;
Json::Value::Members members(object.getMemberNames());
for (Json::Value::Members::iterator it = members.begin(), end = members.end(); it != end; ++it)
{
const std::string& name = *it;
const Json::Value& value = object[name];
// WRITEME
SField::ref field = SField::getField(name);
if (field == sfInvalid)
throw std::runtime_error("Unknown field: " + name);
switch (field.fieldType)
{
case STI_UINT8:
if (value.isString())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt8(field, boost::lexical_cast<unsigned char>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT16:
if (value.isString())
{
std::string strValue = value.asString();
if (!strValue.empty() && (strValue[0]<'0' || strValue[0]>'9'))
{
if (field == sfTransactionType)
{
// WRITEME
}
else if (field == sfLedgerEntryType)
{
// WRITEME
}
else
throw std::runtime_error("Invalid field data");
}
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(strValue)));
}
else if (value.isInt())
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt16(field, boost::lexical_cast<uint16>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT32:
if (value.isString())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt32(field, boost::lexical_cast<uint32>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_UINT64:
if (value.isString())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asString())));
else if (value.isInt())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asInt())));
else if (value.isUInt())
data.push_back(new STUInt64(field, boost::lexical_cast<uint64>(value.asUInt())));
else
throw std::runtime_error("Incorrect type");
break;
case STI_HASH128:
// WRITEME
case STI_HASH160:
// WRITEME
case STI_HASH256:
// WRITEME
case STI_VL:
// WRITEME
case STI_AMOUNT:
// WRITEME
case STI_VECTOR256:
// WRITEME
case STI_PATHSET:
// WRITEME
case STI_OBJECT:
case STI_ACCOUNT:
case STI_TRANSACTION:
case STI_LEDGERENTRY:
case STI_VALIDATION:
if (!value.isObject())
throw std::runtime_error("Inner value is not an object");
if (depth > 64)
throw std::runtime_error("Json nest depth exceeded");
data.push_back(parseJson(value, field, depth + 1));
break;
case STI_ARRAY:
// WRITEME
default:
throw std::runtime_error("Invalid field type");
}
}
return std::auto_ptr<STObject>(new STObject(name, data));
}
#if 0

View File

@@ -28,6 +28,7 @@ protected:
std::vector<SOElement::ptr> mType;
STObject* duplicate() const { return new STObject(*this); }
STObject(SField::ref name, boost::ptr_vector<SerializedType>& data) : SerializedType(name) { mData.swap(data); }
public:
STObject() { ; }
@@ -40,7 +41,7 @@ public:
STObject(SOElement::ptrList type, SerializerIterator& sit, SField::ref name) : SerializedType(name)
{ set(sit); setType(type); }
STObject(const Json::Value& value, SField::ref name);
static std::auto_ptr<STObject> parseJson(const Json::Value& value, SField::ref name, int depth = 0);
virtual ~STObject() { ; }
@@ -127,6 +128,8 @@ public:
bool isFieldPresent(SField::ref field) const;
SerializedType* makeFieldPresent(SField::ref field);
void makeFieldAbsent(SField::ref field);
bool delField(SField::ref field);
void delField(int index);
static std::auto_ptr<SerializedType> makeDefaultObject(SerializedTypeID id, SField::ref name);
static std::auto_ptr<SerializedType> makeDeserializedObject(SerializedTypeID id, SField::ref name,

View File

@@ -91,7 +91,7 @@ protected:
public:
STUInt8(unsigned char v = 0) : value(v) { ; }
STUInt8(SField::ref n, unsigned char v=0) : SerializedType(n), value(v) { ; }
STUInt8(SField::ref n, unsigned char v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
@@ -116,8 +116,8 @@ protected:
public:
STUInt16(uint16 v=0) : value(v) { ; }
STUInt16(SField::ref n, uint16 v=0) : SerializedType(n), value(v) { ; }
STUInt16(uint16 v = 0) : value(v) { ; }
STUInt16(SField::ref n, uint16 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
@@ -143,7 +143,7 @@ protected:
public:
STUInt32(uint32 v = 0) : value(v) { ; }
STUInt32(SField::ref n, uint32 v=0) : SerializedType(n), value(v) { ; }
STUInt32(SField::ref n, uint32 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
@@ -168,8 +168,8 @@ protected:
public:
STUInt64(uint64 v=0) : value(v) { ; }
STUInt64(SField::ref n, uint64 v=0) : SerializedType(n), value(v) { ; }
STUInt64(uint64 v = 0) : value(v) { ; }
STUInt64(SField::ref n, uint64 v = 0) : SerializedType(n), value(v) { ; }
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name)
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
@@ -225,6 +225,8 @@ protected:
: SerializedType(name), mCurrency(cur), mIssuer(iss), mValue(val), mOffset(off),
mIsNative(isNat), mIsNegative(isNeg) { ; }
STAmount(SField::ref name, const Json::Value& value);
uint64 toUInt64() const;
static uint64 muldiv(uint64, uint64, uint64);
@@ -232,13 +234,13 @@ public:
static uint64 uRateOne;
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
{ if (v==0) mIsNegative = false; }
{ if (v == 0) mIsNegative = false; }
STAmount(SField::ref n, uint64 v = 0)
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
{ ; }
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, uint64 uV=0, int iOff=0, bool bNegative=false)
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, uint64 uV = 0, int iOff = 0, bool bNegative = false)
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
{ canonicalize(); }
@@ -254,14 +256,10 @@ public:
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
static STAmount saFromRate(uint64 uRate = 0)
{
return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false);
}
{ return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false); }
static STAmount saFromSigned(const uint160& uCurrencyID, const uint160& uIssuerID, int64 iV=0, int iOff=0)
{
return STAmount(uCurrencyID, uIssuerID, iV < 0 ? -iV : iV, iOff, iV < 0);
}
static STAmount saFromSigned(const uint160& uCurrencyID, const uint160& uIssuerID, int64 iV = 0, int iOff = 0)
{ return STAmount(uCurrencyID, uIssuerID, iV < 0 ? -iV : iV, iOff, iV < 0); }
SerializedTypeID getSType() const { return STI_AMOUNT; }
std::string getText() const;