From 567ac3c84651c270673fa38e21564eba2b36bada Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 19 May 2012 01:09:59 -0700 Subject: [PATCH] STPathElement and STPath classes. Better Json-ization of serialized types. --- src/SerializedObject.cpp | 10 ++- src/SerializedObject.h | 2 +- src/SerializedTypes.cpp | 157 +++++++++++++++++++++++++++++++++++++++ src/SerializedTypes.h | 140 ++++++++++++++++++++++------------ 4 files changed, 259 insertions(+), 50 deletions(-) diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index 4fd6f38a4..41443033a 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -42,6 +42,9 @@ std::auto_ptr STObject::makeDefaultObject(SerializedTypeID id, c case STI_ACCOUNT: return std::auto_ptr(new STAccount(name)); + case STI_PATH: + return std::auto_ptr(new STPath(name)); + default: throw std::runtime_error("Unknown object type"); } @@ -85,6 +88,9 @@ std::auto_ptr STObject::makeDeserializedObject(SerializedTypeID case STI_ACCOUNT: return STAccount::deserialize(sit, name); + case STI_PATH: + return STPath::deserialize(sit, name); + default: throw std::runtime_error("Unknown object type"); } @@ -568,8 +574,8 @@ Json::Value STObject::getJson(int options) const if (it->getSType() != STI_NOTPRESENT) { if (it->getName() == NULL) - ret[boost::lexical_cast(index)] = it->getText(); - else ret[it->getName()] = it->getText(); + ret[boost::lexical_cast(index)] = it->getJson(options); + else ret[it->getName()] = it->getJson(options); } } return ret; diff --git a/src/SerializedObject.h b/src/SerializedObject.h index fd9dd054f..505aa6374 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -99,7 +99,7 @@ public: void set(SOElement *t, SerializerIterator& u); int getLength() const; - SerializedTypeID getSType() const { return STI_OBJECT; } + virtual SerializedTypeID getSType() const { return STI_OBJECT; } virtual bool isEquivalent(const SerializedType& t) const; void add(Serializer& s) const; diff --git a/src/SerializedTypes.cpp b/src/SerializedTypes.cpp index 92ebe4c06..e200d8ffe 100644 --- a/src/SerializedTypes.cpp +++ b/src/SerializedTypes.cpp @@ -227,6 +227,19 @@ std::string STTaggedList::getText() const return ret; } +Json::Value STTaggedList::getJson(int) const +{ + Json::Value ret(Json::arrayValue); + for (std::vector::const_iterator it=value.begin(); it!=value.end(); ++it) + { + Json::Value elem(Json::arrayValue); + elem.append(it->first); + elem.append(strHex(it->second)); + ret.append(elem); + } + return ret; +} + STTaggedList* STTaggedList::construct(SerializerIterator& u, const char *name) { return new STTaggedList(name, u.getTaggedList()); @@ -244,3 +257,147 @@ bool STTaggedList::isEquivalent(const SerializedType& t) const const STTaggedList* v = dynamic_cast(&t); return v && (value == v->value); } + +STPath* STPath::construct(SerializerIterator& s, const char *name) +{ + std::vector path; + do + { + switch(s.get8()) + { + case STPathElement::typeEnd: + return new STPath(name, path); + + case STPathElement::typeAccount: + { + STPathElement element; + element.mType = STPathElement::typeAccount; + element.mNode = s.get160(); + path.push_back(element); + break; + } + + case STPathElement::typeOffer: + { + STPathElement element; + element.mType = STPathElement::typeOffer; + element.mNode = s.get160(); + element.mCurrency = s.get160(); + path.push_back(element); + break; + } + + default: throw std::runtime_error("Unknown path element"); + } + } while(1); +} + +int STPath::getLength() const +{ + int ret = 1; // for end of path + for (std::vector::const_iterator it = value.begin(), end = value.end(); it != end; ++it) + { + switch (it->mType) + { + case STPathElement::typeAccount: + ret += 1 + 160 / 8; // type, account ID + break; + + case STPathElement::typeOffer: + ret += 1 + 320 / 8; // type, account ID, and currency + break; + + default: throw std::runtime_error("Unknown path element"); + } + } + return ret; +} + +Json::Value STPath::getJson(int) const +{ + Json::Value ret(Json::arrayValue); + for (std::vector::const_iterator it = value.begin(), end = value.end(); it != end; ++it) + { + switch (it->mType) + { + case STPathElement::typeAccount: + { + NewcoinAddress account; + account.setAccountID(it->mNode); + ret.append(account.humanAccountID()); + break; + } + + case STPathElement::typeOffer: + { + Json::Value elem(Json::objectValue); + NewcoinAddress account; + account.setAccountID(it->mNode); + elem["Offer"] = account.humanAccountID(); + elem["Currency"] = it->mCurrency.GetHex(); // FIXME: We need a way to display currencies + ret.append(elem); + break; + } + + default: throw std::runtime_error("Unknown path element"); + } + } + return ret; +} + +std::string STPath::getText() const +{ + std::string ret; + bool first = true; + for (std::vector::const_iterator it = value.begin(), end = value.end(); it != end; ++it) + { + if (!first) ret += ", "; + switch (it->mType) + { + case STPathElement::typeAccount: + { + NewcoinAddress account; + account.setAccountID(it->mNode); + ret += account.humanAccountID(); + break; + } + case STPathElement::typeOffer: + { + NewcoinAddress account; + account.setAccountID(it->mNode); + ret += account.humanAccountID(); + ret += "/"; + ret += it->mCurrency.GetHex(); // FIXME: We need a way to display currencies + break; + } + + default: throw std::runtime_error("Unknown path element"); + } + first = false; + } + return ret; +} + +void STPath::add(Serializer& s) const +{ + for (std::vector::const_iterator it = value.begin(), end = value.end(); it != end; ++it) + { + switch (it->mType) + { + case STPathElement::typeAccount: + s.add8(STPathElement::typeAccount); + s.add160(it->mNode); + break; + + case STPathElement::typeOffer: + s.add8(STPathElement::typeOffer); + s.add160(it->mNode); + s.add160(it->mCurrency); + break; + + default: throw std::runtime_error("Unknown path element"); + } + } + + s.add8(STPathElement::typeEnd); +} diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index 9622d55dd..f0b59e0d2 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -4,6 +4,8 @@ #include #include +#include "../json/value.h" + #include "uint256.h" #include "Serializer.h" @@ -15,7 +17,7 @@ enum SerializedTypeID // standard types STI_OBJECT=1, STI_UINT8=2, STI_UINT16=3, STI_UINT32=4, STI_UINT64=5, STI_HASH128=6, STI_HASH160=7, STI_HASH256=8, STI_VL=9, STI_TL=10, - STI_AMOUNT=11, + STI_AMOUNT=11, STI_PATH=12, // high level types STI_ACCOUNT=100, STI_TRANSACTION=101, STI_LEDGERENTRY=102 @@ -24,21 +26,21 @@ enum SerializedTypeID class SerializedType { protected: - const char *name; + const char* name; virtual SerializedType* duplicate() const { return new SerializedType(name); } public: SerializedType() : name(NULL) { ; } - SerializedType(const char *n) : name(n) { ; } + SerializedType(const char* n) : name(n) { ; } SerializedType(const SerializedType& n) : name(n.name) { ; } virtual ~SerializedType() { ; } - static std::auto_ptr deserialize(const char *name) + static std::auto_ptr deserialize(const char* name) { return std::auto_ptr(new SerializedType(name)); } - void setName(const char *n) { name=n; } + void setName(const char* n) { name=n; } const char *getName() const { return name; } virtual int getLength() const { return 0; } @@ -48,6 +50,8 @@ public: virtual std::string getFullText() const; virtual std::string getText() const // just the value { return std::string(); } + virtual Json::Value getJson(int) const + { return getText(); } virtual void add(Serializer& s) const { return; } @@ -68,13 +72,13 @@ protected: unsigned char value; STUInt8* duplicate() const { return new STUInt8(name, value); } - static STUInt8* construct(SerializerIterator&, const char *name = NULL); + static STUInt8* construct(SerializerIterator&, const char* name = NULL); public: STUInt8(unsigned char v=0) : value(v) { ; } - STUInt8(const char *n, unsigned char v=0) : SerializedType(n), value(v) { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + STUInt8(const char* n, unsigned char v=0) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 1; } @@ -96,13 +100,13 @@ protected: uint16 value; STUInt16* duplicate() const { return new STUInt16(name, value); } - static STUInt16* construct(SerializerIterator&, const char *name = NULL); + static STUInt16* construct(SerializerIterator&, const char* name = NULL); public: STUInt16(uint16 v=0) : value(v) { ; } - STUInt16(const char *n, uint16 v=0) : SerializedType(n), value(v) { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + STUInt16(const char* n, uint16 v=0) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 2; } @@ -124,13 +128,13 @@ protected: uint32 value; STUInt32* duplicate() const { return new STUInt32(name, value); } - static STUInt32* construct(SerializerIterator&, const char *name = NULL); + static STUInt32* construct(SerializerIterator&, const char* name = NULL); public: STUInt32(uint32 v=0) : value(v) { ; } - STUInt32(const char *n, uint32 v=0) : SerializedType(n), value(v) { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + STUInt32(const char* n, uint32 v=0) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 4; } @@ -152,13 +156,13 @@ protected: uint64 value; STUInt64* duplicate() const { return new STUInt64(name, value); } - static STUInt64* construct(SerializerIterator&, const char *name = NULL); + static STUInt64* construct(SerializerIterator&, const char* name = NULL); public: STUInt64(uint64 v=0) : value(v) { ; } - STUInt64(const char *n, uint64 v=0) : SerializedType(n), value(v) { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + STUInt64(const char* n, uint64 v=0) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 8; } @@ -195,7 +199,7 @@ protected: void canonicalize(); STAmount* duplicate() const { return new STAmount(name, mCurrency, mValue, mOffset); } - static STAmount* construct(SerializerIterator&, const char *name = NULL); + static STAmount* construct(SerializerIterator&, const char* name = NULL); static const int cMinOffset = -96, cMaxOffset = 80; static const uint64 cMinValue = 1000000000000000ull, cMaxValue = 9999999999999999ull; @@ -206,17 +210,17 @@ public: STAmount(uint64 v = 0) : mValue(v), mOffset(0), mIsNative(true) { ; } - STAmount(const char *n, uint64 v = 0) : SerializedType(n), mValue(v), mOffset(0), mIsNative(true) + STAmount(const char* n, uint64 v = 0) : SerializedType(n), mValue(v), mOffset(0), mIsNative(true) { ; } STAmount(const uint160& currency, uint64 v = 0, int off = 0) : mCurrency(currency), mValue(v), mOffset(off) { canonicalize(); } - STAmount(const char *n, const uint160& currency, uint64 v = 0, int off = 0) : SerializedType(n), + STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0) : SerializedType(n), mCurrency(currency), mValue(v), mOffset(off) { canonicalize(); } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return mIsNative ? 8 : 28; } @@ -272,7 +276,7 @@ public: // Native currency conversions, to/from display format friend uint64 convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit); friend STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit, - const char *name = NULL); + const char* name = NULL); static STAmount deSerialize(SerializerIterator&); }; @@ -283,15 +287,15 @@ protected: uint128 value; STHash128* duplicate() const { return new STHash128(name, value); } - static STHash128* construct(SerializerIterator&, const char *name = NULL); + static STHash128* construct(SerializerIterator&, const char* name = NULL); public: STHash128(const uint128& v) : value(v) { ; } - STHash128(const char *n, const uint128& v) : SerializedType(n), value(v) { ; } - STHash128(const char *n) : SerializedType(n) { ; } + STHash128(const char* n, const uint128& v) : SerializedType(n), value(v) { ; } + STHash128(const char* n) : SerializedType(n) { ; } STHash128() { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 20; } @@ -313,15 +317,15 @@ protected: uint160 value; STHash160* duplicate() const { return new STHash160(name, value); } - static STHash160* construct(SerializerIterator&, const char *name = NULL); + static STHash160* construct(SerializerIterator&, const char* name = NULL); public: STHash160(const uint160& v) : value(v) { ; } - STHash160(const char *n, const uint160& v) : SerializedType(n), value(v) { ; } - STHash160(const char *n) : SerializedType(n) { ; } + STHash160(const char* n, const uint160& v) : SerializedType(n), value(v) { ; } + STHash160(const char* n) : SerializedType(n) { ; } STHash160() { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 20; } @@ -343,15 +347,15 @@ protected: uint256 value; STHash256* duplicate() const { return new STHash256(name, value); } - static STHash256* construct(SerializerIterator&, const char *name = NULL); + static STHash256* construct(SerializerIterator&, const char* name = NULL); public: STHash256(const uint256& v) : value(v) { ; } - STHash256(const char *n, const uint256& v) : SerializedType(n), value(v) { ; } - STHash256(const char *n) : SerializedType(n) { ; } + STHash256(const char* n, const uint256& v) : SerializedType(n), value(v) { ; } + STHash256(const char* n) : SerializedType(n) { ; } STHash256() { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const { return 32; } @@ -373,16 +377,16 @@ protected: std::vector value; virtual STVariableLength* duplicate() const { return new STVariableLength(name, value); } - static STVariableLength* construct(SerializerIterator&, const char *name = NULL); + static STVariableLength* construct(SerializerIterator&, const char* name = NULL); public: STVariableLength(const std::vector& v) : value(v) { ; } - STVariableLength(const char *n, const std::vector& v) : SerializedType(n), value(v) { ; } - STVariableLength(const char *n) : SerializedType(n) { ; } - STVariableLength(SerializerIterator&, const char *name = NULL); + STVariableLength(const char* n, const std::vector& v) : SerializedType(n), value(v) { ; } + STVariableLength(const char* n) : SerializedType(n) { ; } + STVariableLength(SerializerIterator&, const char* name = NULL); STVariableLength() { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const; @@ -404,15 +408,15 @@ class STAccount : public STVariableLength { protected: virtual STAccount* duplicate() const { return new STAccount(name, value); } - static STAccount* construct(SerializerIterator&, const char *name = NULL); + static STAccount* construct(SerializerIterator&, const char* name = NULL); public: STAccount(const std::vector& v) : STVariableLength(v) { ; } - STAccount(const char *n, const std::vector& v) : STVariableLength(n, v) { ; } - STAccount(const char *n) : STVariableLength(n) { ; } + STAccount(const char* n, const std::vector& v) : STVariableLength(n, v) { ; } + STAccount(const char* n) : STVariableLength(n) { ; } STAccount() { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } SerializedTypeID getSType() const { return STI_ACCOUNT; } @@ -426,21 +430,62 @@ public: bool isValueH160() const; }; +class STPathElement +{ +public: + static const int typeEnd = 0; + static const int typeAccount = 1; // Rippling through an account + static const int typeOffer = 2; // Claiming an offer + + int mType; + uint160 mNode, mCurrency; +}; + +class STPath : public SerializedType +{ +protected: + std::vector value; + + STPath* duplicate() const { return new STPath(name, value); } + static STPath* construct(SerializerIterator&, const char* name = NULL); + +public: + + STPath() { ; } + STPath(const char* n) : SerializedType(n) { ; } + STPath(const std::vector& v) : value(v) { ; } + STPath(const char* n, const std::vector& v) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) + { return std::auto_ptr(construct(sit, name)); } + + int getLength() const; + std::string getText() const; + void add(Serializer& s) const; + virtual Json::Value getJson(int) const; + + SerializedTypeID getSType() const { return STI_PATH; } + int getPathLength() const { return value.size(); } + const STPathElement& getElement(int off) const { return value[off]; } + STPathElement& peekElement(int off) { return value[off]; } + void emptyPath() { value.empty(); } + void addPathElement(const STPathElement& e) { value.push_back(e); } +}; + class STTaggedList : public SerializedType { protected: std::vector value; STTaggedList* duplicate() const { return new STTaggedList(name, value); } - static STTaggedList* construct(SerializerIterator&, const char *name = NULL); + static STTaggedList* construct(SerializerIterator&, const char* name = NULL); public: STTaggedList() { ; } - STTaggedList(const char *n) : SerializedType(n) { ; } + STTaggedList(const char* n) : SerializedType(n) { ; } STTaggedList(const std::vector& v) : value(v) { ; } - STTaggedList(const char *n, const std::vector& v) : SerializedType(n), value(v) { ; } - static std::auto_ptr deserialize(SerializerIterator& sit, const char *name) + STTaggedList(const char* n, const std::vector& v) : SerializedType(n), value(v) { ; } + static std::auto_ptr deserialize(SerializerIterator& sit, const char* name) { return std::auto_ptr(construct(sit, name)); } int getLength() const; @@ -451,6 +496,7 @@ public: const std::vector& peekValue() const { return value; } std::vector& peekValue() { return value; } std::vector getValue() const { return value; } + virtual Json::Value getJson(int) const; void setValue(const std::vector& v) { value=v; }