1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: fslow_IArchive.h 4 5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 29386 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_FSLOW_FSLOW_ARCHIVEMAPFILESYSTEM_H_ 17 #define NN_FSLOW_FSLOW_ARCHIVEMAPFILESYSTEM_H_ 18 19 #include <nn/Result.h> 20 #include <nn/fs/fs_Result.h> 21 #include <nn/util/util_Result.h> 22 23 #pragma push 24 #pragma diag_suppress 2817 25 // #2817-D: temporary used for conditional class rvalue result (C++ core issue #446 resolution) 対策 26 #include <map> 27 #pragma pop 28 29 #include <nn/fslow/fslow_IArchive.h> 30 31 namespace nn { namespace fslow { 32 33 template <class Self, class TFileSystemTypeInfo, class TArchiveHandleTable, class ArchiveName> 34 class ArchiveMapFileSystem 35 { 36 public: 37 // スレッドセーフティ? 38 39 typedef typename TFileSystemTypeInfo::Archive Archive; 40 typedef typename TFileSystemTypeInfo::File File; 41 typedef typename TFileSystemTypeInfo::Directory Directory; 42 typedef typename TFileSystemTypeInfo::FileHandle FileHandle; 43 typedef typename TFileSystemTypeInfo::DirectoryHandle DirectoryHandle; 44 typedef typename TFileSystemTypeInfo::Path Path; 45 typedef typename TFileSystemTypeInfo::DirectoryEntry DirectoryEntry; 46 typedef TArchiveHandleTable ArchiveHandleTable; 47 typedef typename ArchiveHandleTable::Handle ArchiveHandle; 48 49 // Self に CRTP で要求するインターフェイス 50 // ArchiveHandleTable& GetHandleTable(); 51 // Result RegisterToNameMap(ArchiveName, ArchiveHandle); 52 // void UnregisterFromNameMap(ArchiveName); 53 // ArchiveName GetArchiveName(Path); 54 // Path GetPathString(Path); 55 56 private: 57 GetSelf()58 Self& GetSelf() { return static_cast<Self&>(*this); } GetSelf()59 const Self& GetSelf() const { return static_cast<const Self&>(*this); } 60 61 typedef typename ArchiveHandleTable::Accessor Accessor; 62 63 public: 64 AddArchive(const ArchiveName & name,Archive archive)65 Result AddArchive(const ArchiveName& name, Archive archive) 66 { 67 ArchiveHandle handle = GetSelf().GetHandleTable().Register(archive); 68 if (!handle) 69 { 70 return nn::fs::ResultHandleTableFull(); 71 } 72 Result result = GetSelf().RegisterToNameMap(name, handle); 73 if (result.IsFailure()) 74 { 75 GetSelf().GetHandleTable().Unregister(handle); 76 } 77 return result; 78 } 79 RemoveArchive(const ArchiveName & name)80 Result RemoveArchive(const ArchiveName& name) 81 { 82 ArchiveHandle handle; 83 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 84 GetSelf().UnregisterFromNameMap(name); 85 GetSelf().GetHandleTable().Unregister(handle); 86 return nn::ResultSuccess(); 87 } 88 OpenFile(FileHandle * pOut,nn::fs::Transaction transaction,Path path,bit32 mode,nn::fs::Attributes attributes)89 Result OpenFile(FileHandle* pOut, nn::fs::Transaction transaction, Path path, bit32 mode, nn::fs::Attributes attributes) 90 { 91 nn::fs::PathMark pathMark; 92 pathMark.rawPathMark = 0; 93 return OpenFile( pOut, transaction, path, pathMark, mode, attributes); 94 } 95 OpenFile(FileHandle * pOut,nn::fs::Transaction transaction,Path path,nn::fs::PathMark pathMark,bit32 mode,nn::fs::Attributes attributes)96 Result OpenFile(FileHandle* pOut, nn::fs::Transaction transaction, Path path, nn::fs::PathMark pathMark, bit32 mode, nn::fs::Attributes attributes) 97 { 98 ArchiveName name = GetSelf().GetArchiveName(path); 99 if (!name.IsValid()) 100 { 101 return nn::fs::ResultInvalidPathFormat(); 102 } 103 ArchiveHandle handle; 104 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 105 File file; 106 { 107 Accessor acc(GetSelf().GetHandleTable(), handle); 108 if (!acc) 109 { 110 return nn::fs::ResultArchiveInvalidated(); 111 } 112 NN_UTIL_RETURN_IF_FAILED(acc->OpenFile(&file, transaction, GetSelf().GetPathString(Move(path)), pathMark, mode, attributes)); 113 } 114 *pOut = FileHandle(handle, file); 115 return nn::ResultSuccess(); 116 } 117 ReadFile(s32 * pOut,const FileHandle & handle,s64 offset,void * buffer,size_t size)118 Result ReadFile(s32* pOut, const FileHandle& handle, s64 offset, void* buffer, size_t size) 119 { 120 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 121 if (!acc) 122 { 123 return nn::fs::ResultArchiveInvalidated(); 124 } 125 return handle.p->ReadBytes(pOut, offset, buffer, size); 126 } 127 WriteFile(s32 * pOut,const FileHandle & handle,s64 offset,const void * buffer,size_t size)128 Result WriteFile(s32* pOut, const FileHandle& handle, s64 offset, const void* buffer, size_t size) 129 { 130 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 131 if (!acc) 132 { 133 return nn::fs::ResultArchiveInvalidated(); 134 } 135 return handle.p->WriteBytes(pOut, offset, buffer, size, nn::fs::WriteOption(true)); 136 } 137 GetFileSize(s64 * pOut,const FileHandle & handle)138 Result GetFileSize(s64* pOut, const FileHandle& handle) 139 { 140 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 141 if (!acc) 142 { 143 return nn::fs::ResultArchiveInvalidated(); 144 } 145 return handle.p->GetSize(pOut); 146 } 147 SetFileSize(const FileHandle & handle,s64 size)148 Result SetFileSize(const FileHandle& handle, s64 size) 149 { 150 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 151 if (!acc) 152 { 153 return nn::fs::ResultArchiveInvalidated(); 154 } 155 return handle.p->SetSize(size); 156 } 157 CloseFile(const FileHandle & handle)158 Result CloseFile(const FileHandle& handle) 159 { 160 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 161 if (!acc) 162 { 163 return nn::fs::ResultArchiveInvalidated(); 164 } 165 Result result = handle.p->Close(); 166 acc->FreeFileObject(handle.p); 167 return result; 168 } 169 OpenDirectory(DirectoryHandle * pOut,Path path)170 Result OpenDirectory(DirectoryHandle* pOut, Path path) 171 { 172 ArchiveName name = GetSelf().GetArchiveName(path); 173 if (!name.IsValid()) 174 { 175 return nn::fs::ResultInvalidPathFormat(); 176 } 177 ArchiveHandle handle; 178 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 179 Directory directory; 180 { 181 Accessor acc(GetSelf().GetHandleTable(), handle); 182 if (!acc) 183 { 184 return nn::fs::ResultArchiveInvalidated(); 185 } 186 NN_UTIL_RETURN_IF_FAILED(acc->OpenDirectory(&directory, GetSelf().GetPathString(Move(path)))); 187 } 188 *pOut = DirectoryHandle(handle, directory); 189 return nn::ResultSuccess(); 190 } 191 ReadDirectory(s32 * pNumEntriesOut,const DirectoryHandle & handle,DirectoryEntry entries[],s32 numEntries)192 Result ReadDirectory(s32* pNumEntriesOut, const DirectoryHandle& handle, DirectoryEntry entries[], s32 numEntries) 193 { 194 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 195 if (!acc) 196 { 197 return nn::fs::ResultArchiveInvalidated(); 198 } 199 return handle.p->Read(pNumEntriesOut, entries, numEntries); 200 } 201 CloseDirectory(const DirectoryHandle & handle)202 Result CloseDirectory(const DirectoryHandle& handle) 203 { 204 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 205 if (!acc) 206 { 207 return nn::fs::ResultArchiveInvalidated(); 208 } 209 Result result = handle.p->Close(); 210 acc->FreeDirectoryObject(handle.p); 211 return result; 212 } 213 DeleteFile(nn::fs::Transaction transaction,Path path)214 Result DeleteFile(nn::fs::Transaction transaction, Path path) 215 { 216 ArchiveName name = GetSelf().GetArchiveName(path); 217 if (!name.IsValid()) 218 { 219 return nn::fs::ResultInvalidPathFormat(); 220 } 221 ArchiveHandle handle; 222 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 223 { 224 Accessor acc(GetSelf().GetHandleTable(), handle); 225 if (!acc) 226 { 227 return nn::fs::ResultArchiveInvalidated(); 228 } 229 NN_UTIL_RETURN_IF_FAILED(acc->DeleteFile(transaction, GetSelf().GetPathString(Move(path)))); 230 } 231 return nn::ResultSuccess(); 232 } 233 DeleteDirectory(nn::fs::Transaction transaction,Path path)234 Result DeleteDirectory(nn::fs::Transaction transaction, Path path) 235 { 236 ArchiveName name = GetSelf().GetArchiveName(path); 237 if (!name.IsValid()) 238 { 239 return nn::fs::ResultInvalidPathFormat(); 240 } 241 ArchiveHandle handle; 242 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 243 { 244 Accessor acc(GetSelf().GetHandleTable(), handle); 245 if (!acc) 246 { 247 return nn::fs::ResultArchiveInvalidated(); 248 } 249 NN_UTIL_RETURN_IF_FAILED(acc->DeleteDirectory(transaction, GetSelf().GetPathString(Move(path)))); 250 } 251 return nn::ResultSuccess(); 252 } 253 DeleteDirectoryRecursively(nn::fs::Transaction transaction,Path path)254 Result DeleteDirectoryRecursively(nn::fs::Transaction transaction, Path path) 255 { 256 ArchiveName name = GetSelf().GetArchiveName(path); 257 if (!name.IsValid()) 258 { 259 return nn::fs::ResultInvalidPathFormat(); 260 } 261 ArchiveHandle handle; 262 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 263 { 264 Accessor acc(GetSelf().GetHandleTable(), handle); 265 if (!acc) 266 { 267 return nn::fs::ResultArchiveInvalidated(); 268 } 269 NN_UTIL_RETURN_IF_FAILED(acc->DeleteDirectoryRecursively(transaction, GetSelf().GetPathString(Move(path)))); 270 } 271 return nn::ResultSuccess(); 272 } 273 CreateFile(nn::fs::Transaction transaction,Path path,nn::fs::Attributes attributes,s64 size)274 Result CreateFile(nn::fs::Transaction transaction, Path path, nn::fs::Attributes attributes, s64 size) 275 { 276 ArchiveName name = GetSelf().GetArchiveName(path); 277 if (!name.IsValid()) 278 { 279 return nn::fs::ResultInvalidPathFormat(); 280 } 281 ArchiveHandle handle; 282 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 283 { 284 Accessor acc(GetSelf().GetHandleTable(), handle); 285 if (!acc) 286 { 287 return nn::fs::ResultArchiveInvalidated(); 288 } 289 NN_UTIL_RETURN_IF_FAILED(acc->CreateFile(transaction, GetSelf().GetPathString(Move(path)), attributes, size)); 290 } 291 return nn::ResultSuccess(); 292 } 293 CreateDirectory(nn::fs::Transaction transaction,Path path,nn::fs::Attributes attributes)294 Result CreateDirectory(nn::fs::Transaction transaction, Path path, nn::fs::Attributes attributes) 295 { 296 ArchiveName name = GetSelf().GetArchiveName(path); 297 if (!name.IsValid()) 298 { 299 return nn::fs::ResultInvalidPathFormat(); 300 } 301 ArchiveHandle handle; 302 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 303 { 304 Accessor acc(GetSelf().GetHandleTable(), handle); 305 if (!acc) 306 { 307 return nn::fs::ResultArchiveInvalidated(); 308 } 309 NN_UTIL_RETURN_IF_FAILED(acc->CreateDirectory(transaction, GetSelf().GetPathString(Move(path)), attributes)); 310 } 311 return nn::ResultSuccess(); 312 } 313 RenameFile(nn::fs::Transaction transaction,Path oldPath,Path newPath)314 Result RenameFile(nn::fs::Transaction transaction, Path oldPath, Path newPath) 315 { 316 ArchiveHandle handle1, handle2; 317 { 318 ArchiveName name = GetSelf().GetArchiveName(oldPath); 319 if (!name.IsValid()) 320 { 321 return nn::fs::ResultInvalidPathFormat(); 322 } 323 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle1, name)); 324 } 325 { 326 ArchiveName name = GetSelf().GetArchiveName(newPath); 327 if (!name.IsValid()) 328 { 329 return nn::fs::ResultInvalidPathFormat(); 330 } 331 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle2, name)); 332 } 333 if (handle1 != handle2) 334 { 335 return nn::fs::ResultUnsupportedOperation(); 336 } 337 { 338 Accessor acc(GetSelf().GetHandleTable(), handle1); 339 if (!acc) 340 { 341 return nn::fs::ResultArchiveInvalidated(); 342 } 343 NN_UTIL_RETURN_IF_FAILED(acc->RenameFile(transaction, GetSelf().GetPathString(Move(oldPath)), GetSelf().GetPathString(Move(newPath)))); 344 } 345 return nn::ResultSuccess(); 346 } 347 RenameDirectory(nn::fs::Transaction transaction,Path oldPath,Path newPath)348 Result RenameDirectory(nn::fs::Transaction transaction, Path oldPath, Path newPath) 349 { 350 ArchiveHandle handle1, handle2; 351 { 352 ArchiveName name = GetSelf().GetArchiveName(oldPath); 353 if (!name.IsValid()) 354 { 355 return nn::fs::ResultInvalidPathFormat(); 356 } 357 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle1, name)); 358 } 359 { 360 ArchiveName name = GetSelf().GetArchiveName(newPath); 361 if (!name.IsValid()) 362 { 363 return nn::fs::ResultInvalidPathFormat(); 364 } 365 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle2, name)); 366 } 367 if (handle1 != handle2) 368 { 369 return nn::fs::ResultUnsupportedOperation(); 370 } 371 { 372 Accessor acc(GetSelf().GetHandleTable(), handle1); 373 if (!acc) 374 { 375 return nn::fs::ResultArchiveInvalidated(); 376 } 377 NN_UTIL_RETURN_IF_FAILED(acc->RenameDirectory(transaction, GetSelf().GetPathString(Move(oldPath)), GetSelf().GetPathString(Move(newPath)))); 378 } 379 return nn::ResultSuccess(); 380 } 381 GetPathMark(nn::fs::PathMark * pathMark,Path path)382 Result GetPathMark( nn::fs::PathMark* pathMark, Path path) 383 { 384 ArchiveName name = GetSelf().GetArchiveName(path); 385 if (!name.IsValid()) 386 { 387 return nn::fs::ResultInvalidPathFormat(); 388 } 389 ArchiveHandle handle; 390 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 391 { 392 Accessor acc(GetSelf().GetHandleTable(), handle); 393 if (!acc) 394 { 395 return nn::fs::ResultArchiveInvalidated(); 396 } 397 NN_UTIL_RETURN_IF_FAILED(acc->GetPathMark( pathMark, GetSelf().GetPathString(Move(path)))); 398 } 399 return nn::ResultSuccess(); 400 } 401 HasFile(bool * pOut,Path path)402 Result HasFile(bool* pOut, Path path) 403 { 404 FileHandle* p; 405 Result result = OpenFile(p, nn::fs::Transaction(), path, nn::fs::OPEN_MODE_READ, nn::fs::Attributes()); 406 if (result.IsFailure()) 407 { 408 if (result <= nn::fs::ResultNotFound()) 409 { 410 *pOut = false; 411 return ResultSuccess(); 412 } 413 else 414 { 415 return result; 416 } 417 } 418 p->p->Close(); 419 CloseFile(*p); 420 *pOut = true; 421 return ResultSuccess(); 422 }// TORIAEZU 423 HasDirectory(bool * pOut,Path path)424 Result HasDirectory(bool* pOut, Path path) 425 { 426 DirectoryHandle* p; 427 Result result = OpenDirectory(p, path); 428 if (result.IsFailure()) 429 { 430 if (result <= nn::fs::ResultNotFound()) 431 { 432 *pOut = false; 433 return ResultSuccess(); 434 } 435 else 436 { 437 return result; 438 } 439 } 440 p->p->Close(); 441 CloseDirectory(*p); 442 *pOut = true; 443 return ResultSuccess(); 444 }// TORIAEZU 445 }; 446 447 }} 448 449 #endif 450