nlib
msgpack/usertype/usertype.cpp

ユーザーデータ型をMessagePack(JSON)で読み書きするサンプルです。以下のようなことを行なっています。

以下がサンプルのソースコードになります。
#include <string>
#include "nn/nlib/msgpack/JsonStreamParser.h"
#include "nn/nlib/msgpack/JsonStreamGenerator.h"
using nlib_ns::msgpack::MpObject;
using nlib_ns::msgpack::JsonStreamParser;
using nlib_ns::msgpack::JsonStreamGenerator;
using nlib_ns::msgpack::JsonStreamGeneratorSettings;
class MenuItem {
public:
MenuItem() : itemcode_(0), price_(0) {}
void SetItemCode(int code) { itemcode_ = code; }
void SetDescription(const std::string& rhs) { description_ = rhs; }
void SetPrice(int price) { price_ = price; }
int GetItemCode() const { return itemcode_; }
const std::string& GetDescription() const { return description_; }
int GetPrice() const { return price_; }
bool operator!=(const MenuItem& rhs) {
return itemcode_ != rhs.itemcode_ || description_ != rhs.description_ ||
price_ != rhs.price_;
}
void Print() {
nlib_printf("code: %d, \"%s\", price: %d\n", itemcode_, description_.c_str(), price_);
}
bool Read(JsonStreamParser* parser) {
JsonStreamParser::Event ev;
if ((ev = parser->Next()) != JsonStreamParser::EVENT_START_MAP) return false;
while ((ev = parser->Next()) != JsonStreamParser::EVENT_END_MAP) {
if (ev != JsonStreamParser::EVENT_KEY_NAME) return false;
if (strcmp("itemCode", parser->GetToken().buf) == 0) {
ev = parser->Next();
int32_t itemcode;
if (JsonStreamParser::ToInt32(parser->GetToken(), &itemcode) != 0)
return false;
SetItemCode(itemcode);
} else if (strcmp("itemName", parser->GetToken().buf) == 0) {
ev = parser->Next();
if (ev != JsonStreamParser::EVENT_STRING) return false;
SetDescription(parser->GetToken().buf);
} else if (strcmp("itemPrice", parser->GetToken().buf) == 0) {
ev = parser->Next();
int32_t price;
if (JsonStreamParser::ToInt32(parser->GetToken(), &price) != 0)
return false;
SetPrice(price);
}
}
return true;
}
bool Write(JsonStreamGenerator* gen) {
gen->StartMap(3);
gen->Key("itemCode").Int32(GetItemCode());
gen->Key("itemName").String(GetDescription().c_str());
gen->Key("itemPrice").Int32(GetPrice());
gen->EndMap();
return !!(*gen);
}
private:
int itemcode_;
std::string description_;
int price_;
};
bool ReadWriteUserType() {
MenuItem menu[3];
menu[0].SetItemCode(91);
menu[0].SetDescription("ramen with salt based soup");
menu[0].SetPrice(800);
menu[1].SetItemCode(94);
menu[1].SetDescription("ramen with miso based soup");
menu[1].SetPrice(790);
menu[2].SetItemCode(95);
menu[2].SetDescription("ramen with a pork bone broth");
menu[2].SetPrice(820);
nlib_printf("MENU to be serialized:\n");
menu[0].Print();
menu[1].Print();
menu[2].Print();
// Serializes onto the memory
ReallocOutputStream ostr;
JsonStreamGenerator gen;
JsonStreamGeneratorSettings settings;
settings.msgpack = true; // write JSON if commented out
if (nlib_is_error(gen.Init(settings))) return false;
if (nlib_is_error(gen.Open(&ostr))) return false;
gen.StartArray(3);
if (nlib_is_error(gen)) return false;
if (!menu[0].Write(&gen)) return false;
if (!menu[1].Write(&gen)) return false;
if (!menu[2].Write(&gen)) return false;
gen.EndArray();
if (nlib_is_error(gen)) return false;
if (nlib_is_error(gen.Flush())) return false;
if (nlib_is_error(gen.Close())) return false;
// Reads the serialized data
JsonStreamParser parser;
MenuItem copiedMenu[3];
ReallocOutputStream::UniquePtrType data;
size_t data_size = ostr.Release(&data);
MemoryInputStream istr(data.get(), data_size);
if (nlib_is_error(parser.Init())) return false;
if (nlib_is_error(parser.Open(&istr))) return false;
if (parser.Next() != JsonStreamParser::EVENT_START_ARRAY) return false;
for (int i = 0; i < 3; ++i) {
if (!copiedMenu[i].Read(&parser)) return false;
}
if (parser.Next() != JsonStreamParser::EVENT_END_ARRAY) return false;
nlib_printf("\nDeserialized MENU:\n");
copiedMenu[0].Print();
copiedMenu[1].Print();
copiedMenu[2].Print();
if (copiedMenu[0] != menu[0]) return false;
if (copiedMenu[1] != menu[1]) return false;
if (copiedMenu[2] != menu[2]) return false;
return true;
}
bool SampleMain(int, char**) { return ReadWriteUserType(); }
NLIB_MAINFUNC