SpiderMonkeyでJSON読み込み
あまり使われていないのか情報は少なかったが
SpiderMonkeyを使用してJSON形式を読み込む方法の調べがついた。
文字列、数字、配列、オブジェクト、NULL, BOOLEAN と普通に使う種類のはOK。
オブジェクトと配列のネストも問題なし。
標準入力からJSONを読み込むサンプル
#include <iostream> #include <string> #include <sstream> #include <js/jsapi.h> JSRuntime *pRuntime; JSContext *pContext; JSObject *pGlobal; void js_print(jsval jsVal, int indentLevel) { // indent std::cout << std::string(indentLevel*2, ' '); if(JSVAL_IS_NULL(jsVal)){ std::cout << "NULL" << std::endl; } else if(JSVAL_IS_OBJECT(jsVal)){ if(JS_IsArrayObject(pContext, JSVAL_TO_OBJECT(jsVal))){ // Array std::cout << "ARRAY:[" << std::endl; JSObject *array=JSVAL_TO_OBJECT(jsVal); jsuint length; if(!JS_GetArrayLength(pContext, array, &length)) return; for(int i=0; i<length; i++){ jsval vp; JS_GetElement(pContext, array, i, &vp); js_print(vp, indentLevel+1); } std::cout << std::string(indentLevel*2, ' ') << "]" << std::endl; } else{ // Object std::cout << "OBJECT:{" << std::endl; JSObject *it=JS_NewPropertyIterator(pContext, JSVAL_TO_OBJECT(jsVal)); jsval keyId; jsval keyVal; jsval propVal; JSString *keyStr; while(JS_NextProperty(pContext, it, &keyId)){ if(keyId==JSVAL_VOID) break; JS_IdToValue(pContext, keyId, &keyVal); keyStr=JS_ValueToString(pContext, keyVal); std::cout << std::string((indentLevel+1)*2, ' ') << JS_GetStringBytes(keyStr) << "=>" << std::endl; JS_GetProperty(pContext, JSVAL_TO_OBJECT(jsVal), JS_GetStringBytes(keyStr), &propVal); js_print(propVal, indentLevel+2); } std::cout << std::string(indentLevel*2, ' ') << "}" << std::endl; } } else if(JSVAL_IS_PRIMITIVE(jsVal)){ std::cout << "PRIMITIVE:"; if(JSVAL_IS_NUMBER(jsVal)){ std::cout << "NUMBER:"; if(JSVAL_IS_INT(jsVal)){ std::cout << "INT:" << JSVAL_TO_INT(jsVal); } if(JSVAL_IS_DOUBLE(jsVal)){ std::cout << "DOUBLE:" << *JSVAL_TO_DOUBLE(jsVal); } } if(JSVAL_IS_STRING(jsVal)){ JSString *str=JS_ValueToString(pContext, jsVal); std::cout << "STRING:\"" << JS_GetStringBytes(str) << "\""; } if(JSVAL_IS_BOOLEAN(jsVal)){ std::cout << "BOOLEAN:" << JSVAL_TO_BOOLEAN(jsVal); } std::cout << std::endl; } else{ std::cout << "else:" << std::endl; } } int main(int argc, char** argv) { // SpiderMokeyの初期化 pRuntime = JS_NewRuntime(8L * 1024L * 1024L); if(!pRuntime) return 1; // contextの作成 pContext = JS_NewContext(pRuntime, 8192); if(!pContext) return 2; // global objectの初期化 pGlobal = JS_NewObject(pContext, NULL, 0, 0); if(!pGlobal) return 3; // builtin classの初期化 if(!JS_InitStandardClasses(pContext, pGlobal)) return 4; // 標準入力からJSONデータを読み込む std::string line; std::stringstream buf; buf << "var json="; while(std::getline(std::cin, line)){ //std::cout << line << std::endl; buf << line << std::endl; } buf << ";"; // JSONを評価する jsval jsVal; if(!JS_EvaluateScript(pContext, pGlobal, buf.str().c_str(), buf.str().size(), NULL, 0, &jsVal)) return 5; // 評価した変数をゲットする if (!JS_GetProperty(pContext, pGlobal, "json", &jsVal)) return 6; // 読み込んだ変数を表示する js_print(jsVal, 0); // contextの破棄 JS_DestroyContext(pContext); // runtimeの破棄 JS_DestroyRuntime(pRuntime); return 0; }
gcc -DXP_UNIX -o js_print js_print.cpp -lstdc++ -ljs
使い方
$ echo "{ key:1, values:[1, 'text', false, null]}" | ./js_print