C++ json deserializer [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
We can C++ project and we need to (de) serialize objects from and into json.
In C# we are using JSON.NET. We simple call:
string json = JsonConvert.SerializeObject(product);
var myNewObject = JsonConvert.DeserializeObject<MyClass>(json);
Very simple and useful.
Does anybody know about free C++ library, which can be used in the same simple way like in C#?
We are using JsonCpp, but it does not support it.
Thanks very much
Regards

C++ does not support reflection so you necessarily have to write your own serialize and deserialize functions for each object.

I'm using https://github.com/nlohmann/json in a C++ websocket server talking to a html/javascript client. The websocket framework is https://github.com/zaphoyd/websocketpp. So sending the json structure 'matches' from the server goes like
msg->set_payload(matches.dump());
m_server.send(hdl, msg);
And like wise from the client
var m = "la_liga";
var msg = {
"type": "request",
"data": m
}
msg = JSON.stringify(msg);
ws.send(msg);
When I receive json on the server I parse it and then a try-catch
void on_message(connection_hdl hdl, server::message_ptr msg) {
connection_ptr con = m_server.get_con_from_hdl(hdl);
nlohmann::json jdata;
std::string payload = msg->get_payload();
try {
jdata.clear();
jdata = nlohmann::json::parse(payload);
if (jdata["type"] == "update") {
<do something with this json structure>
}
} catch (const std::exception& e) {
msg->set_payload("Unable to parse json");
m_server.send(hdl, msg);
std::cerr << "Unable to parse json: " << e.what() << std::endl;
}
}
And likewise on the client
ws.onmessage = function (e) {
var receivedMsg = JSON.parse(e.data);
if (receivedMsg.type == "table") {
<sort and display updated table standing>
}
}
Websocketpp requires boost libraries.

I wrote this serializer/deserializer for c++ since I couldn't find any non boost serializer that fit my needs:
Pakal Persist
It supports both json and xml and polymorphics objets as well.

Related

loop failing when wrapped in try catch to run few times [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Improve this question
Have this code where i am trying to run a loop for few times to make sure i do get my result, but for some reason, i am still getting an error displayed on sreen and it is not even doing the cflog so i can know what is going on, any help will be appreciated
var aData = [];
for (i = 1; i <= 10; i++) {
try {
var a = {};
var as = calltoapitoogetdata;
a['count'] = as;
ArrayAppend(aData, mData);
var retJSON = serializeJSON(aData);
writedump(retJSON);
//return serializeJSON(aData);
break;
} catch (any e) {
i = i + 1;
cflog(text = "Call failed #i#", application = true, file = "loogevent");
writedump(i);
}
}
Thanks
If your code is still erroring it is most likely coming from the cflog call being made in your cfcatch. If you are running a version of Adobe ColdFusion the script version would be :
WriteLog(type="Error", file="myapp.log", text="[#ex.type#] #ex.message#");
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-t-z/writelog.html
Lucee has made many of the CFScript functions equivalent of their tag names but with Adobe CF there are a number of functions that do not comply with this. <cfdump> -> writeDump for example.
Too long for a comment.
I think troubleshooting is easier if all available information is right in front of you on the screen. So, I would troubleshoot like this. Your code is below with my additions in uppercase:
var aData = [];
for (i = 1; i <= 10; i++) {
try {
WRITEOUTPUT('TRY NUMBER #I# <BR>);
var a = {};
var as = calltoapitoogetdata;
WRITEDUMP(AS);
a['count'] = as;
ArrayAppend(aData, mData);
var retJSON = serializeJSON(aData);
writedump(retJSON);
//return serializeJSON(aData);
break;
} catch (any e) {
i = i + 1; // THIS LINE IS NOT NECESSARY
WRITEOUTPUT('CATCH NUMBER #I# <BR>);
cflog(text = "Call failed #i#", application = true, file = "loogevent"); //THIS LINE GETS REPLACED BY
WRITEDUMP(E);
writedump(i); // THIS LINE GOES AWAY
}
}

Parser JSON ON QT [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Is it possible to use an operator || in json like this :
{
"ven":{
"source":"logicCtrl" ,
"msg":"radio_volume" || "radio-mute", || "radio3",
"type":"int"
}
}
i can after get data by parsing data in C++ side like this :
QFile jsonFile("VenParser.json");
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "problème d'overture du fichier, exit";
}
QByteArray jsonData = jsonFile.readAll();
QJsonParseError *err = new QJsonParseError();
QJsonDocument doc = QJsonDocument::fromJson(jsonData, err);
if (err->error != 0)
qDebug() << err->errorString();
Venparser myparser;
if (doc.isNull())
{
qDebug() << "Document invalide";
}
else if (doc.isObject())
{
//recuperer l'object json
QJsonObject jObject = doc.object();
//convertir l'object json to variantmap
QVariantMap mainMap = jObject.toVariantMap();
// variant map
QVariantMap Map = mainMap["ven"].toMap();
myparser.source = Map["source"].toString();
myparser.msg = Map["msg"].toString();
myparser.type = Map["type"].toString();
header.H file : i define my struct
struct Venparser {
QString source;
QString msg;
QString type;
My problem is that i don't want a list in my "msg" but something like this :
when i call myparser.msg , then it will check just the value i need in msg and return it.
"msg":"radio_volume" || "radio-mute", || "radio3",
Thanks,
Your example with the || token is not a valid JSON. You can read more about its format here. However, if I understand you correctly, you can easily use JSON arrays for your task.
JSON:
{
"ven": {
"source": "logicCtrl",
"msg": ["radio_volume", "radio-mute", "radio3"],
"type": "int"
}
}
C++:
You can access the msg array using the toStringList() method. Also, you can use QVariantList and toList() respectively if you fill your array with data different from strings.
QStringList messages = Map["msg"].toStringList();
Now the messages variable contains "radio_volume", "radio-mute" and "radio3" values so you can extract the required string any way you need using your code.
If you still need to parse your exact example (which is technically not a valid JSON as I said before), you will have to go with writing your own parser, which is a bit wide topic for the answer.

C++ Legacy Driver mongoDB Replicaset in Class of a DLL

I have built a dll which includes a class implementing the mongoDB replicaset operations. Here is a summary of the class.
#include "mongo/client/dbclient.h"
mongoimp::mongoimp() {
mongo::client::initialize();
}
mongoimp::~mongoimp() {
mongo::client::shutdown();
}
int mongoimp::queryTRecords() {
string errmsg;
vector<mongo::HostAndPort> hosts = { mongo::HostAndPort("xx-a0.yyyy.com:xxxxx"), mongo::HostAndPort("xx-a1.yyyy.com:xxxxx") };
static mongo::DBClientReplicaSet con("xx", hosts, 0);
con.connect();
con.auth("dbname", "username", "password", errmsg);
auto_ptr<DBClientCursor> cursor = con.query("dbname.t", BSONObj());
BSONObj response;
con.logout("xx", response);
if (cursor->more()) {
BSONObj recordnm = cursor->nextSafe();
return(recordnm.getIntField("lastid"));
} else return(-1);
}
The above code is working. But here are my questions:
1) With the above setting, I can do normal mongoDB operations with the dll but since my application needs to constantly update mongoDB data (close to real-time, up to hundreds a second), I am getting error (No valid replicaset instance servers found) when updating data.
2) Only the server needs to talk to the mongoDB database. So basically I just need one connection to the database. So I want to declare the mongo::DBClientReplicaSet con as a static global variable and connect to it in the class construct function. But it seemed I cannot do it. My application cannot run at all. With that, I constantly get the following error.
Assertion failed: px != 0, file C:\Boost\include\boost-1_62\boost/smart_ptr/scoped_ptr.hpp, line 105
Does anybody know how to solve the problem?
Below is the code I tried:
static mongo::DBClientReplicaSet con("xx", { mongo::HostAndPort("xx-a0.yyyy.com:xxxxx"), mongo::HostAndPort("xx-a1.yyyy.com:xxxxx") }, 0);
mongoimp::mongoimp() {
mongo::client::initialize();
string errmsg;
con.connect();
con.auth("dbname", "username", "password", errmsg);
}
mongoimp::~mongoimp() {
BSONObj response;
con.logout("xx", response);
mongo::client::shutdown();
}
int mongoimp::queryTRecords() {
auto_ptr<DBClientCursor> cursor = con.query("dbname.t", BSONObj());
if (cursor->more()) {
BSONObj recordnm = cursor->nextSafe();
return(recordnm.getIntField("lastid"));
} else return(-1);
}
3) Last question, I noticed there is mongo/client/dbclient_rs.h" file for replicaset. But it seemed I cannot use it. With that, I am getting error for initialize() and auto_ptr cursor. How can I use the file and take full advantage of replicaset features? How can I initialize the relica set if I can use "dbclient_rs.h"? How do I do query and fetch data in that case?
Thanks a lot in advance!
For question No. 2, I remembered the reason for the error:
You need to call mongo::client::initialize before you construct any driver objects, or BSON for that matter.
But how to make that global definition possible, I still need a solution.

Renaming placed containers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm just wondering is there a way to give or rename a container like chest that is already on ground?
I mean not using NMS. But the spigot API to edit the names?
There is no API for it but it is possible with NMS. I made this method some time ago, it allows you to name any tile entity.
You give it a normal bukkit block and name that will be applied to the block. Name can have § coloring char.
With this code you can make version using reflections if you want to avoid NMS and CB imports.
import net.minecraft.server.v1_8_R1.INamableTileEntity;
import net.minecraft.server.v1_8_R1.TileEntity;
import net.minecraft.server.v1_8_R1.TileEntityBrewingStand;
import net.minecraft.server.v1_8_R1.TileEntityChest;
import net.minecraft.server.v1_8_R1.TileEntityCommand;
import net.minecraft.server.v1_8_R1.TileEntityDispenser;
import net.minecraft.server.v1_8_R1.TileEntityEnchantTable;
import net.minecraft.server.v1_8_R1.TileEntityFurnace;
import net.minecraft.server.v1_8_R1.TileEntityHopper;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
public static void setName(String name, Block block) {
final CraftWorld world = (CraftWorld) block.getWorld();
final TileEntity nmsTileEntity = world.getTileEntityAt(block.getX(), block.getY(), block.getZ());
if (nmsTileEntity instanceof INamableTileEntity) {
if (nmsTileEntity instanceof TileEntityChest) {
((TileEntityChest) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityFurnace) {
((TileEntityFurnace) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityDispenser) {
((TileEntityDispenser) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityHopper) {
((TileEntityHopper) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityBrewingStand) {
((TileEntityBrewingStand) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityEnchantTable) {
((TileEntityEnchantTable) nmsTileEntity).a(name);
} else if (nmsTileEntity instanceof TileEntityCommand) {
((TileEntityCommand) nmsTileEntity).getCommandBlock().setName(name);
}
nmsTileEntity.update();
}
}

FTP Recursive File Upload, Download and Delete

I use wxFTP to make simple client and I'm stucked on how to Upload recursively my folder or do download (which would should be same as delete) from FTP server. I know how to upload single file, make FTP folder and delete file. I will appreciate an article (not necessarily in C/C++) that teaches the concept or if someone can help me here.
Code example will be appreciated but take that as secondary.
Sorry if it already asked and answered, I searched and didn't get anything that answered my question.
I translated the code in answer to this question to C++ and that was it.
Since So won't accept the answer and adds it to comments I have added Java code that I translated to C++. My current code is too long (in that it involves few functions and so not fit for SO I guess!
public void saveFilesToServer(String remoteDest, File localSrc) throws IOException {
FTPClient ftp = new FTPClient();
ftp.connect("ftp.foobar.com");
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
ftp.disconnect();
log.fatal("FTP not disconnected");
}
ftp.login("foo", "qwerty");
log.info("Connected to server .");
log.info(ftp.getReplyString());
ftp.changeWorkingDirectory(remoteDest);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
try {
upload(localSrc, ftp);
}
finally {
ftp.disconnect();
log.info("FTP disconnected");
}
}
public void upload(File src, FTPClient ftp) throws IOException {
if (src.isDirectory()) {
ftp.makeDirectory(src.getName());
ftp.changeWorkingDirectory(src.getName());
for (File file : src.listFiles()) {
upload(file, ftp);
}
ftp.changeToParentDirectory();
}
else {
InputStream srcStream = null;
try {
srcStream = src.toURI().toURL().openStream();
ftp.storeFile(src.getName(), srcStream);
}
finally {
IOUtils.closeQuietly(srcStream);
}
}
}