ctr_Repair/trunk/ConsoleDataMigration/sources/ConsoleRestore/SimpleXmlPreprocessor.cpp
N2614 4a966ec4fd BGSとの通信結果をsimplexmlライブラリでパースするための正規化クラスを追加
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@562 385bec56-5757-e545-9c3a-d8741f4650f1
2012-01-17 08:28:25 +00:00

177 lines
4.3 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: SimpleXmlPreprocessor.cpp
Copyright 2009-2011 Nintendo. 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 "SimpleXmlPreprocessor.h"
#include <nn.h>
namespace ConsoleRestore
{
bool SimpleXmlPreprocessor::Canonicalize(std::string& str)
{
if(!EraseXmlDeclaration(str))
{
NN_LOG("invalid xml!\n");
return false;
}
if(!EraseEmptyTag(str))
{
NN_LOG("can't erase empty tag");
return false;
}
if(!EraseAttribute(str))
{
NN_LOG("can't erase attribute\n");
return false;
}
if(!EraseNsTagEnd(str))
{
NN_LOG("can't erase ns end\n");
return false;
}
if(!EraseNsTagStart(str))
{
NN_LOG("can't erase ns start\n");
return false;
}
return true;
}
bool SimpleXmlPreprocessor::EraseXmlDeclaration(std::string& str)
{
std::string::size_type start = str.find("<?xml");
if (start == std::string::npos)
{
return false;
}
std::string::size_type end = str.find(">");
if (end == std::string::npos)
{
return false;
}
str.erase(start, end + 1 - start);
return true;
}
bool SimpleXmlPreprocessor::EraseEmptyTag(std::string& str)
{
// XMLとしては正しい前提
std::string::size_type end = str.find("/>");
if (end == std::string::npos)
{
return true;
}
std::string::size_type start = str.rfind("<", end);
if (start == std::string::npos)
{
return false;
}
str.erase(start, end + 2 - start);
return true;
}
bool SimpleXmlPreprocessor::EraseNsTagEnd(std::string& str)
{
std::string::size_type start = str.rfind("</");
while (start != std::string::npos)
{
std::string::size_type end = str.find(">", start);
if (end == std::string::npos)
{
// 不正なXML
return false;
}
std::string::size_type colon = str.substr(start, end - start).find(":");
if (colon == std::string::npos)
{
// 名前空間無し
start = str.rfind("</", start - 1);
continue;
}
str.erase(start + 2, colon - 1);
start = str.rfind("</", start - 1);
}
return true;
}
bool SimpleXmlPreprocessor::EraseNsTagStart(std::string& str)
{
std::string::size_type start = str.find("<");
while (start != std::string::npos)
{
std::string::size_type end = str.find(">", start);
if (end == std::string::npos)
{
// 不正なXML
return false;
}
std::string::size_type colon = str.substr(start, end - start).find(":");
if (colon == std::string::npos)
{
// 名前空間無し
start = str.find("<", end);
continue;
}
str.erase(start + 1, colon);
start = str.find("<", end - colon);
}
return true;
}
bool SimpleXmlPreprocessor::EraseAttribute(std::string& str)
{
std::string::size_type start = str.find("<");
while (start != std::string::npos)
{
std::string::size_type end = str.find(">", start);
if (end == std::string::npos)
{
// 不正なXML
return false;
}
std::string::size_type space = str.substr(start, end - start).find(" ");
if (space == std::string::npos)
{
// 属性なし
start = str.find("<", end);
continue;
}
str.erase(start + space, end - (start + space));
start = str.find("<", start + space);
}
return true;
}
} /* namespace ConsoleRestore */