@blog.justoneplanet.info

日々勉強

TizenアプリでJSONをパースする

サンプルアプリのJsonParserAppを見る。

■JsonForm.cpp

void JsonForm::ParseAndDisplay(void)

// なるべく簡略化したいのでエラー処理はコメントアウトしておく。

// fileを読み込み専用で開く。
File file;
String filePath = App::GetInstance()->GetAppRootPath() + L"data/jsonSample.json";
result r = file.Construct(filePath, L"r");
#TryReturnVoid(r == E_SUCCESS, "file construction failure with [%s]", GetErrorMessage(r));

FileAttributes att;
r = File::GetAttributes(filePath, att);
#TryReturnVoid(r == E_SUCCESS, "file GetAttributes failure with [%s]", GetErrorMessage(r));
long long size = att.GetFileSize();
#TryReturnVoid(size > 0, "file does not contain valid data, size of file [%ld]", size);
ByteBuffer buf;
r = buf.Construct(size + 1);// fileサイズ+1で初期化
#TryReturnVoid(r == E_SUCCESS, "bytebuffer construct failure with [%s]", GetErrorMessage(r));

r = file.Read(buf);// fileを読み込む
#TryReturnVoid(r == E_SUCCESS, "file read failure with [%s]", GetErrorMessage(r));

// 読み込んだデータをJSONにパース
IJsonValue* pJson = JsonParser::ParseN(buf);
TryCatch(pJson, , "ParseN failed with [%s]", GetErrorMessage(GetLastResult()));

AppLog("Before traverse %d", _pList->GetItemCount());
_pJsonKeyList->RemoveAll(true);
_pValueList->RemoveAll(true);
TraverseFunction(pJson);
AppLog("After traverse");

fileにclose的なものがないけどいいのかな。

void JsonForm::TraverseFunction(IJsonValue* pValue)

パースしたIJsonValueのオブジェクトを実際にどう扱うか見てみる。このメソッドは、pValue->GetType()で分岐してある。typeによっては自身を呼び出し再帰処理している。

FWebJsonIJsonValue.h

jsonの値の型は以下のように定義されている。

enum JsonType
{
	JSON_TYPE_STRING,   /**< The JSON string type*/
	JSON_TYPE_NUMBER,   /**< The JSON number type*/
	JSON_TYPE_OBJECT,   /**< The JSON object type*/
	JSON_TYPE_ARRAY,    /**< The JSON array type*/
	JSON_TYPE_BOOL,     /**< The JSON bool type*/
	JSON_TYPE_NULL      /**< The JSON null type*/
};
nullの時
TryReturnVoid(_pList, "_pList is null");

TryReturnVoid(pValue, "input jsonvalue pointer is null");
オブジェクトの時

Mapにしてkeyとvalueを取り出し、valueを引き数にして再帰呼び出ししている。

case JSON_TYPE_OBJECT:
{
	JsonObject* pObject = static_cast< JsonObject* >(pValue);
	IMapEnumeratorT< const String*, IJsonValue* >* pMapEnum = pObject->GetMapEnumeratorN();
	while (pMapEnum->MoveNext() == E_SUCCESS)
	{
		const String* key = null;
		IJsonValue* value = null;
		pMapEnum->GetKey(key);
		String* pListKey = new (std::nothrow) String(*key);
		_pJsonKeyList->Add(*pListKey);

		String* pStr = null;
		_isArray = 0;
		pMapEnum->GetValue(value);
		if (value->GetType() == JSON_TYPE_OBJECT)
		{
			pStr = new (std::nothrow) String("Value is an Object");
			_pValueList->Add(*pStr);
		}
		else if (value->GetType() == JSON_TYPE_ARRAY)
		{
			pStr = new (std::nothrow) String("Value is an Array");
			_pValueList->Add(*pStr);
		}
		TraverseFunction(value);
	}
	delete pMapEnum;
}
break;
文字列の場合

_pValueListに追加している。

case JSON_TYPE_STRING:
{
	JsonString* pVal = static_cast< JsonString* >(pValue);
	if (_isArray == 0)
	{
		String* pStr = new (std::nothrow) String(*pVal);
		_pValueList->Add(*pStr);
	}
}
break;
配列の場合

keyとvalueを取り出し、valueを引き数にして再帰呼び出ししている。

case JSON_TYPE_ARRAY:
{
	JsonArray* pJsonArray = static_cast< JsonArray* >(pValue);
	pJsonArray->GetCount();
	IEnumeratorT< IJsonValue* >* pEnum = pJsonArray->GetEnumeratorN();
	while (pEnum->MoveNext() == E_SUCCESS)
	{
		IJsonValue* pValue = null;
		pEnum->GetCurrent(pValue);
		if ((pValue->GetType() == JSON_TYPE_STRING) || (pValue->GetType() == JSON_TYPE_NUMBER) || (pValue->GetType() == JSON_TYPE_BOOL) || (pValue->GetType() == JSON_TYPE_NULL))
			_isArray = 1;
		TraverseFunction(pValue);
	}
	delete pEnum;
}
break;
数値の場合

JsonNumberをtoStringして文字列にし、_pValueListにaddしている。

case JSON_TYPE_NUMBER:
{
	JsonNumber* pVal = static_cast< JsonNumber* >(pValue);
	String* pStr = new (std::nothrow) String((pVal->ToString()));
	if (_isArray == 0)
		_pValueList->Add(*pStr);
}
break;
真偽値の場合

条件分岐して、文字列を_pValueListにaddするようにしている。

case JSON_TYPE_BOOL:
{
	String* pStr = null;
	JsonBool* pVal = static_cast< JsonBool* >(pValue);
	if (*pVal == true)
		pStr = new (std::nothrow) String("true");
	else
		pStr = new (std::nothrow) String("false");
	if (_isArray == 0)
		_pValueList->Add(*pStr);
}
break;
nullの場合

nullという文字列を_pValueListにaddするようにしている。

case JSON_TYPE_NULL:
{
	String* pStr = null;
	pStr = new (std::nothrow) String("null");
	if (_isArray == 0)
		_pValueList->Add(*pStr);
}
break;

読むのが面倒だったがC++の基本が分かる良いコードだった。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment