PC上でのテストを追加

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@553 385bec56-5757-e545-9c3a-d8741f4650f1
This commit is contained in:
N2614 2012-01-13 08:10:32 +00:00
parent 0c029d7368
commit 372d4d759a
12 changed files with 8992 additions and 0 deletions

View File

@ -15,7 +15,12 @@
#ifndef _REGION_ID_MODIFIER_H_
#define _REGION_ID_MODIFIER_H_
#if defined(__ARMCC_VERSION)
#include <nn.h>
#else
#include <cstddef>
#include "types.h"
#endif
struct PathList
{

View File

@ -0,0 +1,27 @@
#外のディレクトリにあるので個別に記述
EXTERNAL_SRC = ../../../ConsoleRestore/RegionIdModifier.cpp
EXTERNAL_OBJ = $(notdir $(EXTERNAL_SRC:.cpp=.o))
SRC = testRegionIdModifier.cpp testUtil.cpp
OBJ = $(SRC:.cpp=.o) $(EXTERNAL_OBJ)
INCLUDE_DIRECTORY = -I../../../ConsoleRestore -I./
LIBS = -lgtest -lgtest_main
#googletestのインストール先
GTEST_LIB_DIRECTORY = -L/usr/local/lib
GCC = g++
TARGET = testRegionIdModifier
$(TARGET).exe: $(OBJ)
$(GCC) -o $@ $(OBJ) $(INCLUDE_DIRECTORY) $(LIBS) $(GTEST_LIB_DIRECTORY)
$(EXTERNAL_OBJ):
$(GCC) -c $(EXTERNAL_SRC) $(INCLUDE_DIRECTORY)
.cpp.o:
$(GCC) -c $< $(INCLUDE_DIRECTORY)
test: $(TARGET).exe
./$(TARGET).exe
clean:
rm -rf *.exe *.o

View File

@ -0,0 +1,430 @@
#include <gtest/gtest.h>
#include <cstring>
#include "RegionIdModifier.h"
#include "testUtil.h"
namespace
{
const wchar_t dash[] = {0x2014, 0x0000};
}
class RegionIdModifierId : public RegionIdModifier
{
public:
RegionIdModifierId(u16 id);
};
RegionIdModifierId::RegionIdModifierId(u16 id) : RegionIdModifier(id, 0, 0, NULL)
{
}
TEST(testRegionIdModifier, IsValid)
{
{
RegionIdModifierId rim(0x0000);
ASSERT_TRUE(rim.IsValid());
}
{
RegionIdModifierId rim(0xffff);
ASSERT_TRUE(rim.IsValid());
}
{
RegionIdModifierId rim(0x0102);
ASSERT_TRUE(rim.IsValid());
}
{
RegionIdModifierId rim(0x0111);
ASSERT_TRUE(rim.IsValid());
}
{
RegionIdModifierId rim(0x0201);
ASSERT_FALSE(rim.IsValid());
}
}
class RegionIdModifierDirPath : public RegionIdModifier
{
public:
RegionIdModifierDirPath(u8 nupVersion, u8 regionCode);
const wchar_t* GetPath(u8 index);
private:
PathList m_DirPath[3];
};
RegionIdModifierDirPath::RegionIdModifierDirPath(u8 nupVersion, u8 regionCode) : RegionIdModifier(0, nupVersion, regionCode, NULL)
{
}
const wchar_t* RegionIdModifierDirPath::GetPath(u8 index)
{
std::memset(m_DirPath, 0, sizeof(m_DirPath));
size_t dirNum = GetDirectoryPathNum();
std::memcpy(m_DirPath, GetDirectoryPath(), sizeof(PathList) * dirNum);
return m_DirPath[index].path;
}
TEST(testRegionIdModifier, GetDirectoryPath)
{
{
RegionIdModifierDirPath rim(0, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
}
{
RegionIdModifierDirPath rim(0, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
}
{
RegionIdModifierDirPath rim(0, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
}
{
RegionIdModifierDirPath rim(1, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
}
{
RegionIdModifierDirPath rim(1, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
}
{
RegionIdModifierDirPath rim(1, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
}
{
RegionIdModifierDirPath rim(2, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
}
{
RegionIdModifierDirPath rim(2, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
}
{
RegionIdModifierDirPath rim(2, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
}
{
RegionIdModifierDirPath rim(3, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
}
{
RegionIdModifierDirPath rim(3, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
}
{
RegionIdModifierDirPath rim(3, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
}
{
RegionIdModifierDirPath rim(4, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
}
{
RegionIdModifierDirPath rim(4, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
}
{
RegionIdModifierDirPath rim(4, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
}
{
RegionIdModifierDirPath rim(5, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
}
{
RegionIdModifierDirPath rim(5, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
}
{
RegionIdModifierDirPath rim(5, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
}
{
RegionIdModifierDirPath rim(6, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
ASSERT_STREQ(rim.GetPath(2), L"5/JP/");
}
{
RegionIdModifierDirPath rim(6, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
ASSERT_STREQ(rim.GetPath(2), L"5/US/");
}
{
RegionIdModifierDirPath rim(6, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
ASSERT_STREQ(rim.GetPath(2), L"5/EU/");
}
{
RegionIdModifierDirPath rim(7, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/");
ASSERT_STREQ(rim.GetPath(1), L"2/JP/");
ASSERT_STREQ(rim.GetPath(2), L"5/JP/");
}
{
RegionIdModifierDirPath rim(7, 1);
ASSERT_STREQ(rim.GetPath(0), L"0/US/");
ASSERT_STREQ(rim.GetPath(1), L"2/US/");
ASSERT_STREQ(rim.GetPath(2), L"5/US/");
}
{
RegionIdModifierDirPath rim(7, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/");
ASSERT_STREQ(rim.GetPath(2), L"5/EU/");
}
{
RegionIdModifierDirPath rim(0, 3);
ASSERT_STREQ(rim.GetPath(0), L"");
}
}
class RegionIdModifierPathNum : public RegionIdModifier
{
public:
RegionIdModifierPathNum(u8 nupVersion);
};
RegionIdModifierPathNum::RegionIdModifierPathNum(u8 nupVersion) : RegionIdModifier(0, nupVersion, 0, NULL)
{
}
TEST(testRegionIdModifier, GetDirectoryAndFilePathNum)
{
{
RegionIdModifierPathNum rim(0);
ASSERT_EQ(rim.GetFilePathNum(), 1);
ASSERT_EQ(rim.GetDirectoryPathNum(), 1);
}
{
RegionIdModifierPathNum rim(1);
ASSERT_EQ(rim.GetFilePathNum(), 1);
ASSERT_EQ(rim.GetDirectoryPathNum(), 1);
}
{
RegionIdModifierPathNum rim(2);
ASSERT_EQ(rim.GetFilePathNum(), 2);
ASSERT_EQ(rim.GetDirectoryPathNum(), 2);
}
{
RegionIdModifierPathNum rim(3);
ASSERT_EQ(rim.GetFilePathNum(), 2);
ASSERT_EQ(rim.GetDirectoryPathNum(), 2);
}
{
RegionIdModifierPathNum rim(4);
ASSERT_EQ(rim.GetFilePathNum(), 2);
ASSERT_EQ(rim.GetDirectoryPathNum(), 2);
}
{
RegionIdModifierPathNum rim(5);
ASSERT_EQ(rim.GetFilePathNum(), 3);
ASSERT_EQ(rim.GetDirectoryPathNum(), 3);
}
{
RegionIdModifierPathNum rim(6);
ASSERT_EQ(rim.GetFilePathNum(), 3);
ASSERT_EQ(rim.GetDirectoryPathNum(), 3);
}
{
RegionIdModifierPathNum rim(7);
ASSERT_EQ(rim.GetFilePathNum(), 3);
ASSERT_EQ(rim.GetDirectoryPathNum(), 3);
}
}
TEST(testRegionIdModifier, GetFileName)
{
{
RegionIdModifierId rim(0x0100);
ASSERT_STREQ(rim.GetFileName(), L"1_LZ.bin");
}
{
RegionIdModifierId rim(0x0f00);
ASSERT_STREQ(rim.GetFileName(), L"15_LZ.bin");
}
{
RegionIdModifierId rim(0xff00);
ASSERT_STREQ(rim.GetFileName(), L"255_LZ.bin");
}
{
RegionIdModifierId rim(0x6b0a);
ASSERT_STREQ(rim.GetFileName(), L"107_LZ.bin");
}
}
class RegionIdModifierFilePath : public RegionIdModifier
{
public:
RegionIdModifierFilePath(u16 id, u8 nupVersion, u8 regionCode);
const wchar_t* GetPath(u8 index);
private:
PathList m_FilePath[3];
};
RegionIdModifierFilePath::RegionIdModifierFilePath(u16 id, u8 nupVersion, u8 regionCode) : RegionIdModifier(id, nupVersion, regionCode, NULL)
{
}
const wchar_t* RegionIdModifierFilePath::GetPath(u8 index)
{
std::memset(m_FilePath, 0, sizeof(m_FilePath));
size_t pathNum = GetFilePathNum();
std::memcpy(m_FilePath, GetFilePath(), sizeof(PathList) * pathNum);
return m_FilePath[index].path;
}
TEST(testRegionIdModifier, GetFilePath)
{
{
RegionIdModifierFilePath rim(0x0100, 0, 0);
ASSERT_STREQ(rim.GetPath(0), L"0/JP/1_LZ.bin");
}
{
RegionIdModifierFilePath rim(185 << 8 ,5, 2);
ASSERT_STREQ(rim.GetPath(0), L"0/EU/185_LZ.bin");
ASSERT_STREQ(rim.GetPath(1), L"2/EU/185_LZ.bin");
ASSERT_STREQ(rim.GetPath(2), L"5/EU/185_LZ.bin");
}
// 範囲外
{
RegionIdModifierFilePath rim(0xff00 ,6, 3);
ASSERT_STREQ(rim.GetPath(0), L"");
}
}
class RegionIdModifierGetValidRegionId : public RegionIdModifier
{
public:
RegionIdModifierGetValidRegionId(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName);
const wchar_t* GetPath(u8 index);
private:
PathList m_FilePath[3];
};
RegionIdModifierGetValidRegionId::RegionIdModifierGetValidRegionId(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName) : RegionIdModifier(id, nupVersion, regionCode, regionName)
{
}
const wchar_t* RegionIdModifierGetValidRegionId::GetPath(u8 index)
{
std::memset(m_FilePath, 0, sizeof(m_FilePath));
size_t pathNum = GetFilePathNum();
std::memcpy(m_FilePath, GetFilePath(), sizeof(PathList) * pathNum);
return m_FilePath[index].path;
}
//#define USE_HELPER_MACRO
#ifndef USE_HELPER_MACRO
void GetValidRegionIdHelper(u16 id, u8 nupVersion, u8 regionCode, const wchar_t* regionName, u8 expectedId)
{
void* buf;
size_t size;
u8 modifiedId;
size_t fileNum;
RegionIdModifierGetValidRegionId rim(id, nupVersion, regionCode, regionName);
fileNum = rim.GetFilePathNum();
for(u8 i = 0 ; i < fileNum; i++)
{
ReadFile(rim.GetPath(fileNum - i - 1), &buf, &size);
if(rim.GetValidRegionId(buf, size, &modifiedId))
{
if(modifiedId == expectedId)
{
ASSERT_TRUE(rim.GetValidRegionId(buf, size, &modifiedId));
ASSERT_EQ(modifiedId, expectedId);
delete[] reinterpret_cast<u8*>(buf);
return;
}
}
delete[] reinterpret_cast<u8*>(buf);
}
// ここには来ないはず
ASSERT_TRUE(false);
}
#else
#define GetValidRegionIdHelper(id, nupVersion, regionCode, regionName, expectedId) \
{\
void* buf;\
size_t size;\
u8 modifiedId;\
size_t fileNum;\
\
RegionIdModifierGetValidRegionId rim(id, nupVersion, regionCode, regionName);\
fileNum = rim.GetFilePathNum();\
for(u8 i = 0 ; i < fileNum; i++)\
{\
ReadFile(rim.GetPath(fileNum - i - 1), &buf, &size);\
if(rim.GetValidRegionId(buf, size, &modifiedId))\
{\
if(modifiedId == expectedId)\
{\
ASSERT_TRUE(rim.GetValidRegionId(buf, size, &modifiedId)); \
ASSERT_EQ(modifiedId, expectedId); \
delete[] reinterpret_cast<u8*>(buf); \
return;\
}\
}\
delete[] reinterpret_cast<u8*>(buf);\
}\
ASSERT_TRUE(false);\
\
}\
#endif
TEST(testRegionIdModifier, GetValidRegionIdLaunch)
{
u8 nupVersion;
for(u8 i = 0; i < 6; i++)
{
nupVersion = i;
#include "testdata_Launch_all_valid.txt"
#include "testdata_Launch_all_invalid.txt"
}
}
TEST(testRegionIdModifier, GetValidRegionId1stNUP)
{
u8 nupVersion;
for(u8 i = 2; i < 6; i++)
{
nupVersion = i;
#include "testdata_1stNUP_all_valid.txt"
#include "testdata_1stNUP_all_invalid.txt"
}
}
TEST(testRegionIdModifier, GetValidRegionId2ndNUP)
{
u8 nupVersion;
for(u8 i = 5; i < 6; i++)
{
nupVersion = i;
#include "testdata_2ndNUP_all_valid.txt"
#include "testdata_2ndNUP_all_invalid.txt"
}
}

View File

@ -0,0 +1,170 @@
#include <fstream>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <cstring>
#include "testUtil.h"
namespace internal
{
inline u32 Read32Le(const u8* p)
{
return (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
}
// ################################################################################
u32 GetUncompressedSize(const void* pData)
{
const u8* p = static_cast<const u8*>(pData);
u32 size = internal::Read32Le(p) >> 8;
if (size == 0)
{
size = internal::Read32Le(p + 4);
}
return size;
}
void UncompressLZ( const void *srcp, void *destp )
{
const u8* pSrc = static_cast<const u8*>(srcp);
u8* pDst = static_cast<u8*>(destp);
u32 destCount = internal::Read32Le(pSrc) >> 8;
bool exFormat = (*pSrc & 0x0F)? true : false;
pSrc += 4;
if ( destCount == 0 )
{
destCount = internal::Read32Le(pSrc);
pSrc += 4;
}
while ( destCount > 0 )
{
u32 flags = *pSrc++;
for ( int i = 0; i < 8; ++i )
{
if ( !(flags & 0x80) )
{
*pDst++ = *pSrc++;
destCount--;
}
else
{
u32 length = (*pSrc >> 4);
s32 offset;
if ( ! exFormat )
{
length += 3;
}
else
{
// LZ77拡張フォーマット
if ( length == 1 )
{
length = (*pSrc++ & 0x0F) << 12;
length |= (*pSrc++) << 4;
length |= (*pSrc >> 4);
length += 0xFF + 0xF + 3;
}
else if ( length == 0 )
{
length = (*pSrc++ & 0x0F) << 4;
length |= (*pSrc >> 4);
length += 0xF + 2;
}
else
{
length += 1;
}
}
offset = (*pSrc++ & 0x0f) << 8;
offset = (offset | *pSrc++) + 1;
// 不正なデータを展開した際のバッファオーバーラン対策
length = std::min(length, destCount);
destCount -= length;
u8* pTmp = pDst - offset;
for (int j = 0; j < length; j++)
{
*pDst++ = *pTmp++;
}
}
if ( destCount <= 0 )
{
break;
}
flags <<= 1;
}
}
}
void DumpBuf(void* buf, size_t fileSize)
{
std::cout.setf(std::ios::hex, std::ios::basefield);
for(size_t i = 0; i < fileSize; i++)
{
std::cout << std::setw(2) << std::setfill('0') << static_cast<short>(reinterpret_cast<u8*>(buf)[i]);
if(i % 16 == 15)
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
void ReadFile(const wchar_t* path, void** decode, size_t* size)
{
if(path == NULL)
{
return;
}
char filePath[256];
std::wcstombs(filePath, path, sizeof(filePath));
char prefix[] = "../../../common/romfiles/regionData/";
char fullPath[256];
std::memset(fullPath, 0, sizeof(fullPath));
strlcpy(fullPath, prefix, sizeof(fullPath));
strlcat(fullPath, filePath, 256 - strlen(fullPath));
//std::cout << fullPath << std::endl;
std::ifstream ifs(fullPath, std::ios::in | std::ios::binary);
ifs.seekg(0, std::fstream::end);
size_t eofPos = ifs.tellg();
ifs.clear();
ifs.seekg(0, std::fstream::beg);
size_t begPos = ifs.tellg();
size_t fileSize = eofPos - begPos;
//std::cout << "filesize = " << fileSize << std::endl;
u8* buf = new u8[fileSize];
ifs.read(reinterpret_cast<char*>(buf), fileSize);
ifs.close();
//DumpBuf(buf, fileSize);
size_t uncompressedSize = GetUncompressedSize(buf);
//std::cout.setf(std::ios::dec, std::ios::basefield);
//std::cout << "UncompressedSize = " << uncompressedSize << std::endl;
*decode = new u8[uncompressedSize];
*size = uncompressedSize;
UncompressLZ( buf, *decode);
//DumpBuf(decode, uncompressedSize);
delete[] buf;
}

View File

@ -0,0 +1,13 @@
#ifndef _TEST_UTIL_H_
#define _TEST_UTIL_H_
#include <cstddef>
#include "types.h"
u32 GetUncompressedSize(const void* pData);
void UncompressLZ( const void *srcp, void *destp );
void DumpBuf(void* buf, size_t fileSize);
// PC上のファイルを開くユーティリティ
void ReadFile(const wchar_t* path, void** decode, size_t* size);
#endif

View File

@ -0,0 +1,13 @@
#ifndef _TYPES_H_
#define _TYPES_H_
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef short s16;
typedef unsigned int u32;
typedef int s32;
typedef unsigned long long u64;
typedef long long s64;
#endif