-
- 빠르고 가벼운 JSON 파서: RapidJSON
- JSON Schema 기반 C++ 코드 자동 생성: Python + Jinja2
으로 전체 구조와 예제를 제공하겠습니다.
✅ 목표
- RapidJSON만 사용하여 가볍고 빠른 JSON 파싱
- JSON Schema 기반 Python 코드 생성기로 C++ 구조체 자동 생성
- from_json() / to_json() 대신 RapidJSON의 DOM API 사용
🧩 1. JSON Schema 예시
📁 schema/character.schema.json
{ "title": "Character", "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "hp": { "type": "integer" }, "class": { "type": "string", "enum": ["Warrior", "Mage", "Archer"] } }, "required": ["id", "name", "hp", "class"] }
🛠️ 2. Python + Jinja2: 구조체 생성기
📁 template/class.hpp.jinja2
#pragma once #include <string> #include <rapidjson/document.h> enum class {{ enum_name }} { {% for val in enum_values %} {{ val }}{{ "," if not loop.last }} {% endfor %} }; struct {{ struct_name }} { int id; std::string name; int hp; {{ enum_name }} class_type; // RapidJSON을 이용한 역직렬화 static {{ struct_name }} FromJSON(const rapidjson::Value& obj) { {{ struct_name }} c; c.id = obj["id"].GetInt(); c.name = obj["name"].GetString(); c.hp = obj["hp"].GetInt(); std::string cls = obj["class"].GetString(); if (cls == "Warrior") c.class_type = {{ enum_name }}::Warrior; else if (cls == "Mage") c.class_type = {{ enum_name }}::Mage; else if (cls == "Archer") c.class_type = {{ enum_name }}::Archer; return c; } };
📁 codegen.py
import json import jinja2 def main(): with open("schema/character.schema.json") as f: schema = json.load(f) struct_name = schema["title"] enum_name = "CharacterClass" enum_values = schema["properties"]["class"]["enum"] env = jinja2.Environment(loader=jinja2.FileSystemLoader("template")) tmpl = env.get_template("class.hpp.jinja2") output = tmpl.render( struct_name=struct_name, enum_name=enum_name, enum_values=enum_values ) with open("output/character.hpp", "w") as f: f.write(output) if __name__ == "__main__": main()
🧪 3. 예제 main.cpp
📁 main.cpp
#include <iostream> #include <rapidjson/document.h> #include <fstream> #include <sstream> #include "character.hpp" int main() { std::ifstream in("data.json"); std::stringstream ss; ss << in.rdbuf(); std::string json_str = ss.str(); rapidjson::Document doc; doc.Parse(json_str.c_str()); if (!doc.IsObject()) { std::cerr << "Invalid JSON\n"; return 1; } Character c = Character::FromJSON(doc); std::cout << "ID: " << c.id << ", Name: " << c.name << ", HP: " << c.hp << "\n"; }
📄 예제 JSON 입력 (data.json)
{ "id": 1001, "name": "Auron", "hp": 180, "class": "Warrior" }
⚙️ CMake 설정
📁 CMakeLists.txt
cmake_minimum_required(VERSION 3.15) project(MMORPG_RapidJSON) set(CMAKE_CXX_STANDARD 17) include_directories(${CMAKE_SOURCE_DIR}/external/rapidjson/include) add_executable(server main.cpp output/character.hpp)
external/rapidjson/include는 RapidJSON을 clone한 경로입니다.
📌 요약
항목 사용 도구 설명
JSON 파서 RapidJSON 매우 빠르고 가벼움, MMORPG 서버에 적합 코드 생성 Python + Jinja2 JSON Schema → 구조체 자동 생성 enum / struct 변환 직접 구현 RapidJSON DOM 기반 구조 파싱 지원