ctr_Repair/trunk/ConsoleDataMigration/sources/ConsoleRestore/NinjaXmlReader.cpp
N2614 bc3916b6b2 r834の追加忘れ
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@836 385bec56-5757-e545-9c3a-d8741f4650f1
2015-03-18 04:34:34 +00:00

214 lines
7.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
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 <nn/xml/simple/xml_simple_SimpleXmlParser.h>
#include <nn.h>
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<u8*>(const_cast<char*>(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<char*>(buf);
if(playableDateStr)
{
nn::xml::simple::SimpleXmlParser parser(common::GetAllocator());
parser.parse(reinterpret_cast<u8*>(const_cast<char*>(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<u8*>(const_cast<char*>(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<char*>(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 */