Skip to content

Instantly share code, notes, and snippets.

@Loki-Astari
Last active February 10, 2017 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Loki-Astari/8201956 to your computer and use it in GitHub Desktop.
Save Loki-Astari/8201956 to your computer and use it in GitHub Desktop.
Tested on Distributor ID: Ubuntu Description: Ubuntu 12.04.3 LTS Release: 12.04 Codename: precise Note: The api I use is not guaranteed to be there in the future. but I think you can easily make it point where you want.
Instructions:
> #
> # Dowload the libraries.
> git clone git@github.com:Loki-Astari/ThorsSerializer.git
> git clone git@github.com:Loki-Astari/ThorsStream.git
> #
> # Install/Build third party dependencies (like unit tests)
> ThorsSerializer/third/setup
> ThorsStream/third/setup
> #
> # Setup up build destiation (so both linraries install into the same location)
> export PREFIX=$(pwd)/build
> #
> # Build libraries
> pushd ThorsSerializer
> make install
> popd
> pushd ThorsStream
> make install
> popd
> #
> # Copy file below into => SimpleTest.cpp
> # Then build on the command line like this:
> #
> g++ -std=c++0x -DTHOR_USE_CPLUSPLUS11 SimpleTest.cpp -I ${PREFIX}/include -L ${PREFIX}/lib -lThorsStream11 -lSerialize11 -lJson11 -lcurl
> LD_LIBRARY_PATH=${PREFIX}/lib/ ./a.out
Serialized: 01.02.030
1.2.30
{"version": "01.02.030", "majorVer": 1, "minorVer": 2, "build": 30 }
#include "Serialize/json.h"
#include "ThorsStream/ThorsStream.h"
#include <iostream>
// The object we are going to serialize with.
// The API http://iPubCrawlMaps.com/api/version will return a json object like this
// I just happen to be working with (experimenting but don't rely on it being there forever)
// {
// version: "01.02.030"
// major: 1,
// minor: 2,
// build: 30
// }
class Ver
{
std::string version;
int majorVer;
int minorVer;
int build;
// Set up some friends to maintain cohesion
friend struct ThorsAnvil::Serialize::Json::JsonSerializeTraits<Ver>;
friend std::ostream& operator<<(std::ostream& s, Ver const& data)
{
// Simple print function so we can look at internals.
// Just so we can compare against the serialized version
return s << "Serialized: " << data.version << "\n" << data.majorVer << "." << data.minorVer << "." << data.build << "\n";
}
};
// Set up the Serialization traits.
// Note: This is a vardac macro.
// You can add as many members as you like
JsonSerializeTraits_MAKE(void, Ver, version, majorVer, minorVer, build);
// The code should now be simple.
int main()
{
namespace thor = ThorsAnvil::Stream;
namespace serz = ThorsAnvil::Serialize;
thor::IThorStream socket("http://iPubCrawlMaps.com/api/version");
Ver version;
socket >> serz::jsonImport(version);
std::cout << version;
std::cout << serz::jsonExport(version) << "\n";
}
@rcampbell88
Copy link

Thank you, I was wondering if you have an example of how to build a class which has an array in the Json received. Thank you. Example:

{
"id" : user_created_id, // Optional.
"streams" : [ streams+ ], // Optional.
"accounts" : [ account_ids+ ], // Optional.
"accounts_proposed" : [ account_ids+ ], // Optional.
"books" : [ {
"snapshot": boolean, // Optional, default false.
"both": boolean, // Optional, default false.
"taker_gets" : { "currency": currency, "issuer" : address },
"taker_pays" : { "currency": currency, "issuer" : address },
"taker" : address, // Optional, default false
"proof" : boolean // Optional, default false.
}, ... ], // optional
"ledger_index" : ledger_index, // Optional
"url" : url, // Optional
"url_username" : string, // Optional
"url_password" : string, // Optional
}

Here is some of the real world Json I would like to parse:
{"engine_result":"tesSUCCESS","engine_result_code":0,"engine_result_message":"The transaction was applied.","ledger_hash":"B9079495FCD2D2B48F55D150AAA5BE70BC591A77543494A6CE778389F8C23BFC","ledger_index":4166115,"meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"Offer","LedgerIndex":"0CF688289BF55980C1087B9EAC93427DD92E32F1D45FA626C4AEBF1C9844F6F0","NewFields":{"Account":"rp3CkVqNwtG989W93wtEXJAVd9wdiUEX97","BookDirectory":"37AAC93D336021AE94310D0430FFA090F7137C97D473488C4A0D39B7B80EF6A4","Sequence":5074,"TakerGets":"2014701450","TakerPays":{"currency":"BTC","issuer":"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B","value":"0.075"}}}},{"CreatedNode":{"LedgerEntryType":"DirectoryNode","LedgerIndex":"37AAC93D336021AE94310D0430FFA090F7137C97D473488C4A0D39B7B80EF6A4","NewFields":{"ExchangeRate":"4A0D39B7B80EF6A4","RootIndex":"37AAC93D336021AE94310D0430FFA090F7137C97D473488C4A0D39B7B80EF6A4","TakerPaysCurrency":"0000000000000000000000004254430000000000","TakerPaysIssuer":"0A20B3C85F482532A9578DBB3950B85CA06594D1"}}},{"ModifiedNode":{"FinalFields":{"Account":"rp3CkVqNwtG989W93wtEXJAVd9wdiUEX97","Balance":"39874120367020","Flags":0,"OwnerCount":3,"Sequence":5075},"LedgerEntryType":"AccountRoot","LedgerIndex":"65506DF0A3634A0C8B04C89FBD2F4D3B6EA9D66FA3F116412D195AA8FCFF64CC","PreviousFields":{"Balance":"39874120367035","OwnerCount":2,"Sequence":5074},"PreviousTxnID":"82ACB65C985BE07C654748A687D542C9A93A185B82D9CAB8B3899A54EF837197","PreviousTxnLgrSeq":4166109}},{"ModifiedNode":{"FinalFields":{"Flags":0,"Owner":"rp3CkVqNwtG989W93wtEXJAVd9wdiUEX97","RootIndex":"E55FC74138A106315508DBA06D7E1E577E8BDDCFA4BDACFDA8AE606AB1E2AC0E"},"LedgerEntryType":"DirectoryNode","LedgerIndex":"E55FC74138A106315508DBA06D7E1E577E8BDDCFA4BDACFDA8AE606AB1E2AC0E"}}],"TransactionIndex":1,"TransactionResult":"tesSUCCESS"},"status":"closed","transaction":{"Account":"rp3CkVqNwtG989W93wtEXJAVd9wdiUEX97","Fee":"15","Flags":0,"Sequence":5074,"SigningPubKey":"030D37D8512824C9FD5023AA548929B14F6686EEF0A18EB64DEEC82B6E797F8C55","TakerGets":"2014701450","TakerPays":{"currency":"BTC","issuer":"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B","value":"0.075"},"TransactionType":"OfferCreate","TxnSignature":"30450221008BAF55E7E0665CC73E82BB4C2C027C4CA4C65349E78BB39E5F6A07C5191DC4950220465FE8E5C73ED83D27361B763E244F520F3F73411EB188622E728ABAC9C8507C","date":441769950,"hash":"C070B53A9177B9A5D6BD3461281521197164835214FDED857491FAF771E323B0"},"type":"transaction","validated":true}"

Thank you very much and Happy New Year to you and your family!!

Ray

@Loki-Astari
Copy link
Author

@rcampbell88

The code automatically handles array via std::vector<X>.

Your dump is too large/messy and lacking in detailed specification for me to wade through and give you an exact answer. But given the first section I came up with a first pass that may help you.

https://gist.github.com/Loki-Astari/8203447

Basically what you need to do is define a set of C++ classes that represent objects in your json. For each C++ class you need to declare what members are going to be serialized via JsonSerializeTraits_MAKE()

@Loki-Astari
Copy link
Author

ps I update the ISocketStream class so it uses better C++ techniques and some C++11 features for mutex/conditional variables and exception safe locking.

@Loki-Astari
Copy link
Author

Added an example Makefile to make things easier to run.

@rcampbell88
Copy link

I am having a little problem getting my program to compile, I figured out a way around the buffer input problem by doing this:

struct membuf : std::streambuf {
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};

std::istringstream sstr;
membuf sbuf((char
)(dataPtr + 17), (char_)(dataPtr + 10));
std::istream in(&sbuf);

But now I can't get past the boost static assertion:

my class:

struct TransactionIndexField {
friend struct ThorsAnvil::Serialize::Json::JsonSerializeTraits;
friend std::ostream& operator<<(std::ostream& stream, TransactionIndexField const& value);
virtual ~TransactionIndexField() throw() {}
int TransactionIndex;
};

Program:

TransactionIndexField msg;
membuf sbuf((char
)(dataPtr + 17), (char_)(dataPtr + 10));
std::istream in(&sbuf);
in >> ThorsAnvil::Serialize::jsonImport(_msg);
std::cout << _msg;

Error:
In file included from /home/prod/ThorsSerializer/Serialize/json.h:16:0,
from /home/prod/catsdata/DEV/Danyth/Core/RPL10/RPL10Common.h:13,
from DGWFrame.cpp:15:
/home/prod/ThorsSerializer/Serialize/Serialize.h: In instantiation of ‘ThorsAnvil::Serialize::Importer<T, typename S::Parser > ThorsAnvil::Serialize::importObj(T&) [with S = ThorsAnvil::Serialize::Json::JsonSerializer; T = TransactionIndexField; typename S::Parser = ThorsAnvil::Serialize::Json::JsonSerializer::Parser<TransactionIndexField, (ThorsAnvil::Serialize::Json::JsonSerializeType)0u>]’:
/home/prod/ThorsSerializer/Serialize/json.h:36:53: required from ‘ThorsAnvil::Serialize::Importer<T, ThorsAnvil::Serialize::Json::JsonSerializer::Parser > ThorsAnvil::Serialize::jsonImport(T&) [with T = TransactionIndexField]’
DGWFrame.cpp:195:53: required from here
/home/prod/ThorsSerializer/Serialize/Serialize.h:35:5: error: static assertion failed: S::template Parser::Parsable::value

Any help would be greatly appreciated. Thanks,

@xdjxdaveyx
Copy link

Your compiler is failing to parse so I would suggest checking all syntax with a toothcomb first. Might not be it, but it's just an idea and somewhere to start?

@xdjxdaveyx
Copy link

long time since i did C++ but shouldn't 'in' be 'cin'?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment