diff --git a/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.cpp b/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.cpp new file mode 100644 index 0000000..9e6d100 --- /dev/null +++ b/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.cpp @@ -0,0 +1,213 @@ +/*---------------------------------------------------------------------------* + Project: Horizon + File: NinjaXmlReader.cpp + + Copyright (C)2015 Nintendo Co., Ltd. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Rev$ + *---------------------------------------------------------------------------*/ +#include "NinjaXmlReader.h" +#include "SimpleXmlPreprocessor.h" +#include "HeapManager.h" + +#include +#include + +namespace ConsoleRestore +{ + +NinjaXmlReader::NinjaXmlReader() +{ + // TODO 自動生成されたコンストラクター・スタブ + +} + +NinjaXmlReader::~NinjaXmlReader() +{ + // TODO Auto-generated destructor stub +} + +void NinjaXmlReader::GetNsUid(char* pNsUid, size_t size, std::string xml) +{ + if(!SimpleXmlPreprocessor::Canonicalize(xml)) + { + return; + } + nn::xml::simple::SimpleXmlParser parser(common::GetAllocator()); + parser.parse(reinterpret_cast(const_cast(xml.c_str())), xml.size()); + + GetContentOfElement(parser, "ns_uid", pNsUid, size); +} + +bool NinjaXmlReader::HasContentLock(std::string xml) +{ + return HasElement(xml, "content_lock"); +} + +bool NinjaXmlReader::HasExternalSeed(std::string xml) +{ + return HasElement(xml, "external_seed"); +} + +nn::fnd::DateTime NinjaXmlReader::GetPlayableDate(std::string xml) +{ + if(!SimpleXmlPreprocessor::Canonicalize(xml)) + { + return nn::fnd::DateTime::MIN_DATETIME; + } + + const size_t BUF_SIZE = 1024 * 1024; + common::HeapManager manager(BUF_SIZE); + void* buf = manager.GetAddr(); + char* playableDateStr = reinterpret_cast(buf); + if(playableDateStr) + { + nn::xml::simple::SimpleXmlParser parser(common::GetAllocator()); + parser.parse(reinterpret_cast(const_cast(xml.c_str())), xml.size()); + GetContentOfElement(parser, "playable_date", playableDateStr, BUF_SIZE); + + // playable_date は YYYY-MM-DD 形式 + std::string yearStr(std::string(playableDateStr).substr(0, 4)); + std::string monthStr(std::string(playableDateStr).substr(5, 2)); + std::string dayStr(std::string(playableDateStr).substr(8, 2)); + char* end = '\0'; + s32 year = std::strtol(yearStr.c_str(),&end, 10); + s32 month = std::strtol(monthStr.c_str(),&end, 10); + s32 day = std::strtol(dayStr.c_str(),&end, 10); + nn::fnd::DateTime playableDate = nn::fnd::DateTime::FromParameters(year, month, day); + return playableDate; + } + + return nn::fnd::DateTime::MIN_DATETIME; +} + +bool NinjaXmlReader::HasElement(std::string xml, const char* element) +{ + if(!SimpleXmlPreprocessor::Canonicalize(xml)) + { + return false; + } + nn::xml::simple::SimpleXmlParser parser(common::GetAllocator()); + parser.parse(reinterpret_cast(const_cast(xml.c_str())), xml.size()); + + return GetElement(parser, element); +} + +bool NinjaXmlReader::GetContentOfElement(nn::xml::simple::SimpleXmlParser& parser, const char* target, char* content, size_t bufSize) +{ + if ( !parser.isError() ) + { + const nn::xml::simple::SimpleXmlParser::Node* pRootNode = parser.getRootNode(); + + int rootNameSize = pRootNode->nameSize + 1; + char* pRootName = new char[ rootNameSize ]; + std::strlcpy( pRootName, (char*)pRootNode->name, rootNameSize ); + NN_LOG( "rootNode name: %s\n", pRootName ); + delete pRootName; + + bool found = false; + GetNodes(pRootNode, target, content, bufSize, found); + return found; + } + + return false; +} + +bool NinjaXmlReader::GetElement(nn::xml::simple::SimpleXmlParser& parser, const char* element) +{ + const size_t BUF_SIZE = 1024 * 1024; + common::HeapManager manager(BUF_SIZE); + void* addr = manager.GetAddr(); + if(addr) + { + return GetContentOfElement(parser, element, reinterpret_cast(addr), BUF_SIZE); + } + return false; +} + + +void NinjaXmlReader::GetNodes( const nn::xml::simple::SimpleXmlParser::Node* topNodes, const char* target, char* content, size_t bufSize, bool& found) +{ + const nn::xml::simple::SimpleXmlParser::Node* pTargetNode = topNodes->firstChild; + + while ( pTargetNode != NULL ) + { + // 見つかるまで更新する + // 同じ名前の要素が複数ある場合1つ目の要素を見つけた時点でtrueになる + bool targetIsCurrentNode = GetNodeName(pTargetNode, target); + if(!found) + { + found = targetIsCurrentNode; + } + + /* + * [Point]子ノードのみを持つノードのcontentSizeは0となる。 + */ + if(pTargetNode->contentSize > 0) + { + GetNodeContent(pTargetNode, targetIsCurrentNode, content, bufSize); + } + else + { + GetNodes(pTargetNode, target, content, bufSize, found); + } + + pTargetNode = pTargetNode->next; + } +} + +bool NinjaXmlReader::GetNodeName( const nn::xml::simple::SimpleXmlParser::Node* pNode, const char* target) +{ + /* + * [Point] Node::nameには、そのノードの名前(タグ名)以外のデータも含まれる。ただしそのノードの名前は必ずデータの先頭に来るため、 + * Node::nameSize分のデータをNode::nameの先頭から取得することで、そのノードの名前を取得することができる。 + */ + char* pNodeName = new char[ pNode->nameSize+1 ]; + std::strlcpy( pNodeName, (char*)pNode->name, pNode->nameSize+1 ); + NN_LOG( "Node name: %s\n", pNodeName ); + if(!std::strcmp(pNodeName, target)) + { + delete pNodeName; + return true; + } + else + { + delete pNodeName; + return false; + } +} + +void NinjaXmlReader::GetNodeContent( const nn::xml::simple::SimpleXmlParser::Node* pNode, bool found, char* content, size_t bufSize ) +{ + if(pNode->contentSize > 0) + { + /* + * [Point] Node::contentには、そのノードのコンテンツ以外のデータも含まれる。ただしそのノードのコンテンツは必ずデータの先頭に来るため、 + * Node::contentSize分のデータをNode::contentの先頭から取得することで、そのノードのコンテンツを取得することができる。 + */ + char* pNodeContent = new char[ pNode->contentSize+1 ]; + std::strlcpy( pNodeContent, (char*)pNode->content, pNode->contentSize+1); + //行頭タブ挿し入れ + NN_LOG( "Node content: %s\n", pNodeContent ); + if(found) + { + if(pNode->contentSize+1 < bufSize) + { + std::strlcpy(content, (char*)pNode->content, pNode->contentSize+1); + } + else + { + std::strlcpy(content, (char*)pNode->content, bufSize); + } + } + delete pNodeContent; + } +} + +} /* namespace ConsoleRestore */ diff --git a/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.h b/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.h new file mode 100644 index 0000000..1f24d25 --- /dev/null +++ b/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.h @@ -0,0 +1,65 @@ +/*---------------------------------------------------------------------------* + Project: Horizon + File: NinjaXmlReader.h + + Copyright (C)2015 Nintendo Co., Ltd. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Rev$ + *---------------------------------------------------------------------------*/ +#ifndef SOURCES_CONSOLERESTORE_NINJAXMLREADER_H_ +#define SOURCES_CONSOLERESTORE_NINJAXMLREADER_H_ + +#include +#include +#include + +namespace ConsoleRestore +{ + +//!@brief Ninjaから取得したXMLデータ読み取るためのクラスです +class NinjaXmlReader +{ +public: + NinjaXmlReader(); + virtual ~NinjaXmlReader(); + + //!@brief XMLをパースしてns_uidを取得します + //!@param[out] pNsUid ns_uidを格納するためのバッファ + //!@param[in] size pNsUidのバッファサイズ + //!@param[in] xml Ninjaから取得したXMLデータ + void GetNsUid(char* pNsUid, size_t size, std::string xml); + + //!@brief XMLをパースしてcontent_lock要素があるかどうかを返します + //!@param[in] xml Ninjaから取得したXMLデータ + //!@return content_lock要素があるかどうか + bool HasContentLock(std::string xml); + + //!@brief XMLをパースしてexternal_seed要素があるかどうかを返します + //!@param[in] xml Ninjaから取得したXMLデータ + //!@return external_seed要素があるかどうか + bool HasExternalSeed(std::string xml); + + //!@brief XMLをパースしてプレイ可能日を取得します + //!@param[in] xml Ninjaから取得したXMLデータ + //!@return DateTime型のプレイ可能日 + nn::fnd::DateTime GetPlayableDate(std::string xml); + + +private: + bool HasElement(std::string xml, const char* element); + bool GetContentOfElement(nn::xml::simple::SimpleXmlParser& parser, const char* element, char* content, size_t bufSize); + bool GetElement(nn::xml::simple::SimpleXmlParser& parser, const char* element); + void GetNodes( const nn::xml::simple::SimpleXmlParser::Node* topNodes, const char* target, char* content, size_t bufSize, bool& found); + bool GetNodeName( const nn::xml::simple::SimpleXmlParser::Node* pNode, const char* target); + void GetNodeContent( const nn::xml::simple::SimpleXmlParser::Node* pNode, bool found, char* content, size_t bufSize ); +}; + +} /* namespace ConsoleRestore */ + +#endif /* SOURCES_CONSOLERESTORE_NINJAXMLREADER_H_ */