ctr_Repair/trunk/ConsoleDataMigration/common/FileTransfer.cpp
N2614 eaa3853461 ファイル転送量表示の初期化をまとめる
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@45 385bec56-5757-e545-9c3a-d8741f4650f1
2011-02-10 02:31:24 +00:00

250 lines
8.0 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: FileTransfer.cpp
Copyright 2009 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 "FileTransfer.h"
#include <vector>
namespace common
{
namespace
{
u64 s_TotalFileSize;
u64 s_FinishedFileSize = 0;
u64 s_Progress = 0;
}
nn::Result CalculateFileNum(std::wstring currentDirectory, u32& fileNum, u32& fileSize)
{
nn::fs::FileInputStream fis;
nn::fs::Directory dir;
nn::Result result;
std::vector<nn::fs::DirectoryEntry> entryList; //カレントディレクトリのエントリ一覧を格納
std::vector<nn::fs::DirectoryEntry>::iterator entryIndex;
result = dir.TryInitialize(currentDirectory.c_str());
if(result.IsSuccess())
{
nn::fs::DirectoryEntry entry;
s32 numEntry;
for(;;)
{
result = dir.TryRead(&numEntry, &entry, 1);
if(result.IsFailure())
{
dir.Finalize();
return result;
}
if(numEntry == 0)
{
// カレントディレクトリを閉じる
dir.Finalize();
// カレントディレクトリの子を開く
for(entryIndex = entryList.begin(); entryIndex != entryList.end(); entryIndex++)
{
if(entryIndex->attributes.isDirectory)
{
CalculateFileNum(currentDirectory + std::wstring(entryIndex->entryName) + std::wstring(L"/"), fileNum, fileSize);
}
}
return nn::ResultSuccess();
}
entryList.push_back(entry);
fileNum++;
fileSize+= entry.entrySize;
}
}
else
{
NN_LOG("failed initialize directory\n");
dir.Finalize();
return result;
}
}
// ディレクトリ間のコピー
// アーカイブ越しのコピーが可能
// アーカイブにマウントした状態で呼び出す必要あり
// 書き込み先のディレクトリはあらかじめ消去しておくこと。
// 引数はスラッシュ付き
bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf, const size_t bufSize)
{
nn::fs::Directory from_dir;
nn::fs::DirectoryEntry entry;
s32 numread = 0;
std::wostringstream target_from;
std::wostringstream target_to;
bool ret_value = true;
nn::Result result = from_dir.TryInitialize(from_path);
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
return false;
}
while (1)
{
result = from_dir.TryRead(&numread, &entry, 1);
if (result.IsFailure() || numread != 1)
{
break;
}
if (std::wcscmp(entry.entryName, L".") == 0 || std::wcscmp(entry.entryName, L"..") == 0)
{
continue;
}
target_from.str(L"");
target_from.clear(std::stringstream::goodbit);
target_from << from_path << entry.entryName;
target_to.str(L"");
target_to.clear(std::stringstream::goodbit);
target_to << to_path << entry.entryName;
// ディレクトリの場合
if (entry.attributes.isDirectory)
{
// ディレクトリ作成
NN_LOG("Create Directory %ls\n", target_to.str().c_str());
result = nn::fs::TryCreateDirectory(target_to.str().c_str());
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
else
{
target_from << L"/";
target_to << L"/";
// 再帰処理
if (!CopyDirectory(target_from.str().c_str(), target_to.str().c_str(), buf, bufSize))
{
ret_value = false;
}
}
}
// ファイルの場合
else
{
// ファイル作成
nn::fs::FileInputStream from_file;
nn::fs::FileOutputStream to_file;
s64 filesize;
s32 readsize;
s32 writesize;
NN_LOG("Copy File %ls\n", target_from.str().c_str());
// 読み込み対象ファイル開く
result = from_file.TryInitialize(target_from.str().c_str());
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
else
{
// 読み込み対象ファイルのサイズ取得
result = from_file.TryGetSize(&filesize);
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
else
{
// 書き込み対象ファイル作成
result = nn::fs::TryCreateFile(target_to.str().c_str(), filesize);
result = to_file.TryInitialize(target_to.str().c_str(), false);
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
else
{
while (1)
{
result = from_file.TryRead(&readsize, buf, bufSize);
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
break;
}
else
{
if (readsize == 0)
{
result = to_file.TryFlush();
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
break;
}
else
{
result = to_file.TryWrite(&writesize, buf, readsize, false);
s_FinishedFileSize += readsize;
s_Progress = s_FinishedFileSize * 100/ s_TotalFileSize;
NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress);
if (result.IsFailure())
{
nn::dbg::PrintResult(result);
ret_value = false;
}
}
}
}
}
to_file.Finalize();
}
}
from_file.Finalize();
}
}
from_dir.Finalize();
return ret_value;
}
u32 GetProgress()
{
return s_Progress;
}
void InitializeTransferProgress(u64 totalSize)
{
s_TotalFileSize = totalSize;
s_FinishedFileSize = 0;
}
}