ctr_Repair/trunk/ConsoleDataMigration/sources/tests/googletest/RegionIdModifier/testUtil.cpp
N2614 372d4d759a 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
2012-01-13 08:10:32 +00:00

171 lines
4.4 KiB
C++

#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;
}