#include #include #include #include "configLoader.h" #include "CommonLogger.h" namespace common { Result ConfigFileLoader::Initialize(const wchar_t* fileName, void* buffer, const size_t bufferSize) { s64 fileSize; FileInputStream fi; COMMON_LOGGER_RETURN_RESULT_IF_FAILED(fi.TryInitialize(fileName)); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(fi.TryGetSize(&fileSize)); // NULL終端ぶん読めるサイズを減らす if (fileSize > bufferSize - sizeof(wchar_t)) { NN_TLOG_("Too Large File\n"); return Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_TOO_LARGE); } m_Buffer = static_cast(buffer); COMMON_LOGGER_RETURN_RESULT_IF_FAILED(fi.TryRead(&m_UsedBufferSize, m_Buffer, fileSize)); NN_LOG("config size = %d\n", m_UsedBufferSize); return ParseData(); } void ConfigFileLoader::Finalize() { m_Buffer = 0; m_ParamNum = 0; } Result ConfigFileLoader::ParseData() { if (!m_Buffer) { return Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_INVALID_STATE, nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_NOT_INITIALIZED); } int pos = 0; // ビッグエンディアンでないことを確認 NN_ASSERTMSG(m_Buffer[0] != 0xfffe, "Invalid Config File's Endian\n"); if (m_Buffer[0] == 0xfeff) { // UTF-16 BOMの調整 pos++; } m_ParamNum = 0; m_ParamName[m_ParamNum] = &(m_Buffer[pos]); m_ParamValue[m_ParamNum] = L""; m_Buffer[m_UsedBufferSize / sizeof(wchar_t)] = L'\0'; // NULL終端しておく // ダブルクウォート中なら : も文字として読み取る bool inEscape = false; // # で行末までコメント bool inComment = false; // : で行頭から:までがkey、:から行末までがvalue bool inSettingKeyValue = false; while (pos < m_UsedBufferSize / sizeof(m_Buffer[0])) { switch (m_Buffer[pos]) { case L'"': { inEscape = !inEscape; } break; case L'#': { inComment = true; } break; case L':': { if (inEscape || inComment) { break; } if (inSettingKeyValue) { break; } else { inSettingKeyValue = true; } m_Buffer[pos] = L'\0'; m_ParamValue[m_ParamNum++] = &(m_Buffer[pos + 1]); } break; case L'\r': case L'\n': { if (inComment) { inComment = false; } if (inSettingKeyValue) { inSettingKeyValue = false; } m_Buffer[pos] = L'\0'; m_ParamName[m_ParamNum] = &(m_Buffer[pos + 1]); m_ParamValue[m_ParamNum] = L""; } break; } if (PARAM_MAX_NUM <= m_ParamNum) { NN_TLOG_("Too Many Params\n"); return Result(nn::Result::LEVEL_FATAL, nn::Result::SUMMARY_OUT_OF_RESOURCE, nn::Result::MODULE_COMMON, nn::Result::DESCRIPTION_TOO_LARGE); } pos++; } return ResultSuccess(); } s32 ConfigFileLoader::SearchParamName(const wchar_t *paramName) { if (!m_Buffer) { NN_TLOG_("ConfigFileLoader not initialized.\n"); return -1; } for (s32 i = 0; i < m_ParamNum; i++) { if (wcscmp(m_ParamName[i], paramName) == 0) { return i; } } return -1; } const wchar_t *ConfigFileLoader::ReadAsWChar(const wchar_t *paramName) { s32 idx = SearchParamName(paramName); if (idx < 0) { NN_LOG("Unknown Parameter Name %ls\n", paramName); } return (idx < 0) ? NULL : m_ParamValue[idx]; } const char *ConfigFileLoader::ReadAsChar(const wchar_t *paramName) { memset(m_ReadCharBuffer, 0, sizeof(m_ReadCharBuffer)); const wchar_t *value = ReadAsWChar(paramName); if(value == NULL) { return NULL; } wcstombs(m_ReadCharBuffer, value, sizeof(m_ReadCharBuffer)); // NULL終端する m_ReadCharBuffer[sizeof(m_ReadCharBuffer) - 1] = '\0'; return m_ReadCharBuffer; } int ConfigFileLoader::ReadAsInteger(const wchar_t *paramName) { return atoi(ReadAsChar(paramName)); } }