nlib
msgpack/json/json.cpp

To read and write JSON, this sample uses either DOM(MpObject) or the streaming interface. When using DOM(MpObject), it operates as described below:

When using the streaming interface, it operates as described below:

Though using DOM generally allows the process to be more simply described, more amount of memory is required. Using the streaming interface requires less amount of memory, but the process cannot be simply described. It is also possible to partially use DOM for one JSON to describe the process.
The source code of the sample is shown below.
/*--------------------------------------------------------------------------------*
Project: CrossRoad
Copyright (C)Nintendo All rights reserved.
These coded instructions, statements, and computer programs contain proprietary
information of Nintendo and/or its licensed developers and are protected by
national and international copyright laws. They may not be disclosed to third
parties or copied or duplicated in any form, in whole or in part, without the
prior written consent of Nintendo.
The content herein is highly confidential and should be handled accordingly.
*--------------------------------------------------------------------------------*/
#include "nn/nlib/msgpack/JsonStreamParser.h"
#include "nn/nlib/msgpack/JsonStreamGenerator.h"
#include "nn/nlib/Nlist.h"
using nlib_ns::msgpack::MpObject;
using nlib_ns::msgpack::JsonStreamParser;
using nlib_ns::msgpack::JsonStreamGenerator;
const char jsontext[] =
"{ \"item\": ["
"{\"itemCode\":91, \"itemName\" : \"ramen with salt based soup\", \"itemPrice\":300},"
"{\"itemCode\":94, \"itemName\" : \"ramen with miso based soup\", \"itemPrice\":290}, "
"{\"itemCode\":95, \"itemName\" : \"ramen with a pork bone broth\", \"itemPrice\":320} "
"] } ";
bool ReadModifyWriteJsonByDom() {
UniquePtr<MpObject> obj;
// Reads the menu data in JSON.
if (JsonStreamParser::Parse(obj, jsontext) != 0) return false;
// You want to raise the prices.
MpObject* price;
int val;
MpObject* items = obj->GetMapItem("item");
if (!items) return false;
MpObject* salt = items->GetArrayItem(0);
if (!salt) return false;
price = salt->GetMapItem("itemPrice");
if (!price) return false;
if (nlib_is_error(price->Unbox(&val))) return false; // Unboxes 'price' and retrieve an integer value.
val += 500; // Changes the price
if (nlib_is_error(price->Box(val))) return false; // Boxes 'val' and updates 'price'.
MpObject* miso = items->GetArrayItem(1);
if (!miso) return false;
price = miso->GetMapItem("itemPrice");
if (!price) return false;
if (nlib_is_error(price->Unbox(&val))) return false;
val += 500;
price->Box(val); // Boxing primitive objects never returns an error.
MpObject* pork = items->GetArrayItem(2);
if (!pork) return false;
price = pork->GetMapItem("itemPrice");
if (!price) return false;
if (nlib_is_error(price->Unbox(&val))) return false;
val += 500;
// You can use the assignment operators instead of boxing
// when you box primitive objects.
*price = val;
// Writes the menu data in JSON.
char str[1024];
if (JsonStreamGenerator::Generate(NULL, str, *obj.get()) != 0) return false;
nlib_printf("%s\n", str);
return true;
}
bool ReadAndWritePriceJsonByStreaming() {
JsonStreamParser parser;
MemoryInputStream istr(jsontext);
if (nlib_is_error(parser.Init())) return false;
if (nlib_is_error(parser.Open(&istr))) return false;
Nlist<int> prices;
JsonStreamParser::Event ev;
if ((ev = parser.Next()) != JsonStreamParser::kEventStartMap) return false;
while ((ev = parser.Next()) != JsonStreamParser::kEventEndMap) {
if (ev != JsonStreamParser::kEventKeyName) return false;
if (strcmp(parser.GetToken().buf, "item") == 0) {
if ((ev = parser.Next()) != JsonStreamParser::kEventStartArray) return false;
while ((ev = parser.Next()) != JsonStreamParser::kEventEndArray) {
if (ev != JsonStreamParser::kEventStartMap) return false;
while ((ev = parser.Next()) != JsonStreamParser::kEventEndMap) {
if (ev != JsonStreamParser::kEventKeyName) return false;
if (strcmp(parser.GetToken().buf, "itemPrice") == 0) {
ev = parser.Next();
int num;
if (nlib_is_error(JsonStreamParser::ToInt32(parser.GetToken(), &num)))
return false;
prices.push_back(num);
} else {
if (nlib_is_error(parser.Skip())) return false;
}
}
}
} else {
if (nlib_is_error(parser.Skip())) return false;
}
}
JsonStreamGenerator gen;
char str[1024];
MemoryOutputStream ostr(str);
if (nlib_is_error(gen.Init())) return false;
if (nlib_is_error(gen.Open(&ostr))) return false;
size_t prices_size = prices.size();
gen.StartArray(prices_size);
for (size_t i = 0; i < prices_size; ++i) {
gen.Int32(prices[i]);
}
gen.EndArray();
if (nlib_is_error(gen)) return false;
gen.Close();
if (nlib_is_error(ostr.Write('\0'))) return false;
nlib_printf("%s\n", str);
return true;
}
bool SampleMain(int, char**) {
return ReadModifyWriteJsonByDom() && ReadAndWritePriceJsonByStreaming();
}
NLIB_MAINFUNC