ctr_Repair/trunk/CardSaveData/common/savefile/exsave.cpp

300 lines
8.6 KiB
C++

#include <wchar.h>
#include <string.h>
#include <nn/fs.h>
#include <../fs/fs_ResultPrivate.h>
#include "exsave.h"
#define OWN_UID 0xf8014
const char *exsaveName = "exsave:";
const wchar_t *exsaveRoot_w = L"exsave:/save/";
const char *exsaveRoot = "exsave:/save/";
#define ROOTLENGTH_EX 8
const wchar_t *exsaveSys_w = L"exsave:/ncl_sysdata.ncl";//暫定
wchar_t expath_w[PATHLENGTH_MAX];//パス名
wchar_t expathu_w[100][PATHLENGTH_MAX];//上層パス名
wchar_t expathw_w[PATHLENGTH_MAX];//パス名ワーク
static nn::fs::DirectoryEntry exdcEntry[MAX_LEVEL];
static nn::fs::Directory exdc[MAX_LEVEL];
//拡張セーブデータ
//存在確認
bool ExSave::IsExist()
{
LastNnResult = nn::fs::MountExtSaveData(exsaveName,OWN_UID);
nn::fs::Unmount(exsaveName);
return LastNnResult.IsSuccess();
}
//パス検索位置のリセット
void ExSave::ResetPath()
{
s_lv=0;
s_serch = false;
wcscpy(expath_w,exsaveRoot_w);
//wcscpy(expathu_w,expath_w);
}
myResult ExSave::GetPath(wchar_t *path)
{
int n;
while(1){
if (s_serch==false){
LastNnResult = exdc[s_lv].TryInitialize(expath_w);//Open
if (LastNnResult.IsFailure()){
return RESULT_FAIL;
}
}
while(1){
n = (exdc[s_lv].Read(&exdcEntry[s_lv],1));
if ( n==0 )//終端
{
exdc[s_lv].Finalize();
if (s_lv == 0){path[0]=0;return RESULT_OK;}// ---- rootなら終了
s_lv--;//上の層に戻る
wcscpy(expath_w,expathu_w[s_lv]);//パス戻す
}else{
if(exdcEntry[s_lv].attributes.isDirectory){//ディレクトリ
//m_info.DirCount++;
wcscpy(expathu_w[s_lv],expath_w);//パス保存
wcscat(expath_w,exdcEntry[s_lv].entryName);//次のディレクトリパス
wcscat(expath_w,L"/");
if (++s_lv == MAX_LEVEL)return RESULT_DIR_LEVEL_OVER;
s_serch = false;
break;
}else{//ファイル
//m_info.FileCount++;
s_serch = true;
wcscpy(path,pPathTop);
wcscat(path,exdcEntry[s_lv].entryName);
return RESULT_OK;
}
}
}
}
}
//削除
bool ExSave::Delete()
{
LastNnResult = nn::fs::DeleteExtSaveData(OWN_UID);
//if (nn::fs::ResultNotFound().Includes(LastNnResult))return RESULT_NOT_FOUND;
return LastNnResult.IsSuccess();
}
//セーブ作成、成功時はマウント状態
myResult ExSave::Create(const void* icon,size_t iconSize,u32 entryDir,u32 entryFile)
{
if ( IsMounted )return RESULT_ALREADY_MOUNT;
LastNnResult = nn::fs::CreateExtSaveData(OWN_UID,icon,iconSize,entryDir,entryFile);
if (LastNnResult.IsFailure())return RESULT_FAIL_CREATE;
LastNnResult = nn::fs::MountExtSaveData(exsaveName,OWN_UID);
if (LastNnResult.IsFailure())return RESULT_FAIL_MOUNT;
LastNnResult = nn::fs::TryCreateDirectory(exsaveRoot_w);
if (LastNnResult.IsFailure()){
nn::fs::Unmount(exsaveName);
return RESULT_FAIL_MOUNT;
}
IsMounted = true;
return RESULT_OK;
}
//マウント
myResult ExSave::Mount()
{
if ( IsMounted )return RESULT_ALREADY_MOUNT;
LastNnResult = nn::fs::MountExtSaveData(exsaveName,OWN_UID);
if (LastNnResult.IsFailure()){
return RESULT_FAIL_MOUNT;
}
IsMounted = true;
return RESULT_OK;
}
void ExSave::Unmount()
{
IsMounted = false;
nn::fs::Unmount(exsaveName);
}
//ライト属性ファイルを閉じる
void ExSave::CloseW()
{
writer.Finalize();
}
//ファイルライト
s32 ExSave::Write(char *buffer,size_t size)
{
s32 ct;
LastNnResult = writer.TryWrite(&ct,(void*)buffer,size);
if(LastNnResult.IsFailure())ct=0;
return ct;
}
//管理用ファイル
//ライト属性で開く
bool ExSave::OpenSysW()
{
LastNnResult = nn::fs::TryCreateFile(exsaveSys_w,sizeof(tArcInfo));
LastNnResult = writerSys.TryInitialize(exsaveSys_w,false);
return LastNnResult.IsSuccess();
}
//ライト属性ファイルを閉じる
void ExSave::CloseSysW()
{
writerSys.Finalize();
}
//システムファイルライト
bool ExSave::WriteSys(tArcInfo *pinfo)
{
s32 ct;
pinfo->Ver = INFO_VERSION;
LastNnResult = writerSys.TryWrite(&ct,(void*)pinfo,sizeof(tArcInfo));
return LastNnResult.IsSuccess();
}
//リード属性で開く
bool ExSave::OpenSysR()
{
LastNnResult = readerSys.TryInitialize(exsaveSys_w);
return LastNnResult.IsSuccess();
}
//ライト属性ファイルを閉じる
void ExSave::CloseSysR()
{
readerSys.Finalize();
}
//ファイルリード
bool ExSave::ReadSys(tArcInfo *pinfo)
{
s32 ct;
LastNnResult = readerSys.TryRead(&ct,(void*)pinfo,sizeof(tArcInfo));
return LastNnResult.IsSuccess();
}
//ライト属性ファイルを開く
bool ExSave::OpenW(wchar_t *path,s64 size)
{
int pos,pos2;
wcscpy(expath_w,exsaveRoot_w);
wcscat(expath_w,path);
while(1){
LastNnResult = nn::fs::TryCreateFile(expath_w,size);
if(LastNnResult.IsSuccess())break;
//ディレクトリがなければディレクトリを作成
pos = GetPosDelmLast(expath_w,ROOTLENGTH_EX);//ファイルが存在するディレクトリ
if (pos <= 0)return false;//rootかパスが不正
//while (1){
wcscpy(expathw_w,expath_w);//ワークにコピー
while (LastNnResult.IsFailure()){//ディレクトリ作成できるまで遡る
if(LastNnResult.GetDescription()!=nn::fs::DESCRIPTION_DBM_DIRECTORY_NOT_FOUND)return false;
pos2 = GetPosDelmLast(expathw_w,ROOTLENGTH_EX);//境界位置を探す
if (pos2 == 0)return false;//root到達
expathw_w[pos2] = 0;//境界まで削除 (例) dir1/dir2/file -> dir1/dir2 -> dir1
LastNnResult = nn::fs::TryCreateDirectory(expathw_w);
}
//if (pos2 == pos)break;//配置ディレクトリなら抜ける
//todo:ディレクトリが深いとき時間がかかるなら、無駄なTryCreateを省く
//案)直上から最初の成功までのデリミタ位置を記録
//先に全ディレクトリ作っておくのがよさげ
//}
}
LastNnResult = writer.TryInitialize(expath_w,false);
return LastNnResult.IsSuccess();
}
//ファイルリード
s32 ExSave::Read(char *buffer,size_t size)
{
// if (IsMounted==false)return 0;
s32 ct;
LastNnResult = reader.TryRead(&ct,(void*)buffer,size);
if(LastNnResult.IsFailure())ct=0;
return ct;
}
void ExSave::Close()
{
reader.Finalize();
}
//ファイルを開く
//パス指定はルート以降
//(ex)data:/dir/file -> dir/file
bool ExSave::Open(wchar_t *path)
{
wcscpy(expathw_w,exsaveRoot_w);
wcscat(expathw_w,path);
LastNnResult = reader.TryInitialize(expathw_w);
if (LastNnResult.IsSuccess())
{
LastNnResult = reader.TryGetSize(&FileSize);
if (LastNnResult.IsSuccess())return true;
else Close();
}
return false;
}
//アーカイブ情報の取得
bool ExSave::GetInfo(tArcInfo *pinfo)
{
if(Mount()==RESULT_FAIL_MOUNT)return false;
//システムデータからフォーマット情報
if (OpenSysR())
{
if(ReadSys(pinfo) == false){
pinfo->Pcode[0]=0;
CloseSysR();//クローズ
Unmount();
return false;
}
}else{
Unmount();
return false;
}
CloseSysR();//クローズ
// Unmount();
//#ifdef INFO_API_USE
//API情報と比較
// LastNnResult = nn::fs::GetExtSaveDataFormatInfo(OWN_UID,&m_info.FileEntry,&m_info.DirEntry);
// if (m_info.FileEntry != pinfo->FileEntry)return false;
// if (m_info.DirEntry != pinfo->DirEntry)return false;
// //if (m_info.Dup != pinfo->Dup)return false; //ExSaveには無い
//#endif
return true;
}
//コンストラクタ
ExSave::ExSave()
{
IsMounted = false;
s_lv=0;
m_info.DirCount = 0;
m_info.FileCount = 0;
m_info.DirEntry = 0;
m_info.FileEntry = 0;
wcscpy(expath_w,exsaveRoot_w);
//wcscpy(expathu_w,expath_w);
pPathTop = (wchar_t*)((u32)&expath_w+strlen(exsaveRoot)*2);
}
void ExSave::Finalize()
{
Close();
Unmount();
}
//デストラクタ
ExSave::~ExSave()
{
Finalize();
}