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: 25433 $ 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 "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 // TODO: 適切な Result 71 return nn::fs::ResultOutOfMemory(); 72 } 73 Result result = GetSelf().RegisterToNameMap(name, handle); 74 if (result.IsFailure()) 75 { 76 GetSelf().GetHandleTable().Unregister(handle); 77 } 78 return result; 79 } 80 RemoveArchive(const ArchiveName & name)81 Result RemoveArchive(const ArchiveName& name) 82 { 83 ArchiveHandle handle; 84 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 85 GetSelf().UnregisterFromNameMap(name); 86 GetSelf().GetHandleTable().Unregister(handle); 87 return nn::ResultSuccess(); 88 } 89 OpenFile(FileHandle * pOut,nn::fs::Transaction transaction,Path path,bit32 mode,nn::fs::Attributes attributes)90 Result OpenFile(FileHandle* pOut, nn::fs::Transaction transaction, Path path, bit32 mode, nn::fs::Attributes attributes) 91 { 92 nn::fs::PathMark pathMark; 93 pathMark.rawPathMark = 0; 94 return OpenFile( pOut, transaction, path, pathMark, mode, attributes); 95 } 96 OpenFile(FileHandle * pOut,nn::fs::Transaction transaction,Path path,nn::fs::PathMark pathMark,bit32 mode,nn::fs::Attributes attributes)97 Result OpenFile(FileHandle* pOut, nn::fs::Transaction transaction, Path path, nn::fs::PathMark pathMark, bit32 mode, nn::fs::Attributes attributes) 98 { 99 ArchiveName name = GetSelf().GetArchiveName(path); 100 if (!name.IsValid()) 101 { 102 return nn::fs::ResultInvalidPathFormat(); 103 } 104 ArchiveHandle handle; 105 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 106 File file; 107 { 108 Accessor acc(GetSelf().GetHandleTable(), handle); 109 if (!acc) 110 { 111 // TODO: この Result でいい? 112 return nn::fs::ResultArchiveNotFound(); 113 } 114 NN_UTIL_RETURN_IF_FAILED(acc->OpenFile(&file, transaction, GetSelf().GetPathString(Move(path)), pathMark, mode, attributes)); 115 } 116 *pOut = FileHandle(handle, file); 117 return nn::ResultSuccess(); 118 } 119 ReadFile(s32 * pOut,const FileHandle & handle,s64 offset,void * buffer,size_t size)120 Result ReadFile(s32* pOut, const FileHandle& handle, s64 offset, void* buffer, size_t size) 121 { 122 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 123 if (!acc) 124 { 125 // TODO: この Result でいい? 126 return nn::fs::ResultArchiveNotFound(); 127 } 128 return handle.p->ReadBytes(pOut, offset, buffer, size); 129 } 130 WriteFile(s32 * pOut,const FileHandle & handle,s64 offset,const void * buffer,size_t size)131 Result WriteFile(s32* pOut, const FileHandle& handle, s64 offset, const void* buffer, size_t size) 132 { 133 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 134 if (!acc) 135 { 136 // TODO: この Result でいい? 137 return nn::fs::ResultArchiveNotFound(); 138 } 139 return handle.p->WriteBytes(pOut, offset, buffer, size, true); 140 } 141 GetFileSize(s64 * pOut,const FileHandle & handle)142 Result GetFileSize(s64* pOut, const FileHandle& handle) 143 { 144 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 145 if (!acc) 146 { 147 // TODO: この Result でいい? 148 return nn::fs::ResultArchiveNotFound(); 149 } 150 return handle.p->GetSize(pOut); 151 } 152 SetFileSize(const FileHandle & handle,s64 size)153 Result SetFileSize(const FileHandle& handle, s64 size) 154 { 155 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 156 if (!acc) 157 { 158 // TODO: この Result でいい? 159 return nn::fs::ResultArchiveNotFound(); 160 } 161 return handle.p->SetSize(size); 162 } 163 CloseFile(const FileHandle & handle)164 Result CloseFile(const FileHandle& handle) 165 { 166 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 167 if (!acc) 168 { 169 // TODO: この Result でいい? 170 return nn::fs::ResultArchiveNotFound(); 171 } 172 Result result = handle.p->Close(); 173 acc->FreeFileObject(handle.p); 174 return result; 175 } 176 OpenDirectory(DirectoryHandle * pOut,Path path)177 Result OpenDirectory(DirectoryHandle* pOut, Path path) 178 { 179 ArchiveName name = GetSelf().GetArchiveName(path); 180 if (!name.IsValid()) 181 { 182 return nn::fs::ResultInvalidPathFormat(); 183 } 184 ArchiveHandle handle; 185 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 186 Directory directory; 187 { 188 Accessor acc(GetSelf().GetHandleTable(), handle); 189 if (!acc) 190 { 191 // TODO: この Result でいい? 192 return nn::fs::ResultArchiveNotFound(); 193 } 194 NN_UTIL_RETURN_IF_FAILED(acc->OpenDirectory(&directory, GetSelf().GetPathString(Move(path)))); 195 } 196 *pOut = DirectoryHandle(handle, directory); 197 return nn::ResultSuccess(); 198 } 199 ReadDirectory(s32 * pNumEntriesOut,const DirectoryHandle & handle,DirectoryEntry entries[],s32 numEntries)200 Result ReadDirectory(s32* pNumEntriesOut, const DirectoryHandle& handle, DirectoryEntry entries[], s32 numEntries) 201 { 202 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 203 if (!acc) 204 { 205 // TODO: この Result でいい? 206 return nn::fs::ResultArchiveNotFound(); 207 } 208 return handle.p->Read(pNumEntriesOut, entries, numEntries); 209 } 210 CloseDirectory(const DirectoryHandle & handle)211 Result CloseDirectory(const DirectoryHandle& handle) 212 { 213 Accessor acc(GetSelf().GetHandleTable(), handle.archiveHandle); 214 if (!acc) 215 { 216 // TODO: この Result でいい? 217 return nn::fs::ResultArchiveNotFound(); 218 } 219 Result result = handle.p->Close(); 220 acc->FreeDirectoryObject(handle.p); 221 return result; 222 } 223 DeleteFile(nn::fs::Transaction transaction,Path path)224 Result DeleteFile(nn::fs::Transaction transaction, Path path) 225 { 226 ArchiveName name = GetSelf().GetArchiveName(path); 227 if (!name.IsValid()) 228 { 229 return nn::fs::ResultInvalidPathFormat(); 230 } 231 ArchiveHandle handle; 232 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 233 { 234 Accessor acc(GetSelf().GetHandleTable(), handle); 235 if (!acc) 236 { 237 // TODO: この Result でいい? 238 return nn::fs::ResultArchiveNotFound(); 239 } 240 NN_UTIL_RETURN_IF_FAILED(acc->DeleteFile(transaction, GetSelf().GetPathString(Move(path)))); 241 } 242 return nn::ResultSuccess(); 243 } 244 DeleteDirectory(nn::fs::Transaction transaction,Path path)245 Result DeleteDirectory(nn::fs::Transaction transaction, Path path) 246 { 247 ArchiveName name = GetSelf().GetArchiveName(path); 248 if (!name.IsValid()) 249 { 250 return nn::fs::ResultInvalidPathFormat(); 251 } 252 ArchiveHandle handle; 253 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 254 { 255 Accessor acc(GetSelf().GetHandleTable(), handle); 256 if (!acc) 257 { 258 // TODO: この Result でいい? 259 return nn::fs::ResultArchiveNotFound(); 260 } 261 NN_UTIL_RETURN_IF_FAILED(acc->DeleteDirectory(transaction, GetSelf().GetPathString(Move(path)))); 262 } 263 return nn::ResultSuccess(); 264 } 265 DeleteDirectoryRecursively(nn::fs::Transaction transaction,Path path)266 Result DeleteDirectoryRecursively(nn::fs::Transaction transaction, Path path) 267 { 268 ArchiveName name = GetSelf().GetArchiveName(path); 269 if (!name.IsValid()) 270 { 271 return nn::fs::ResultInvalidPathFormat(); 272 } 273 ArchiveHandle handle; 274 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 275 { 276 Accessor acc(GetSelf().GetHandleTable(), handle); 277 if (!acc) 278 { 279 // TODO: この Result でいい? 280 return nn::fs::ResultArchiveNotFound(); 281 } 282 NN_UTIL_RETURN_IF_FAILED(acc->DeleteDirectoryRecursively(transaction, GetSelf().GetPathString(Move(path)))); 283 } 284 return nn::ResultSuccess(); 285 } 286 CreateDirectory(nn::fs::Transaction transaction,Path path,nn::fs::Attributes attributes)287 Result CreateDirectory(nn::fs::Transaction transaction, Path path, nn::fs::Attributes attributes) 288 { 289 ArchiveName name = GetSelf().GetArchiveName(path); 290 if (!name.IsValid()) 291 { 292 return nn::fs::ResultInvalidPathFormat(); 293 } 294 ArchiveHandle handle; 295 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 296 { 297 Accessor acc(GetSelf().GetHandleTable(), handle); 298 if (!acc) 299 { 300 // TODO: この Result でいい? 301 return nn::fs::ResultArchiveNotFound(); 302 } 303 NN_UTIL_RETURN_IF_FAILED(acc->CreateDirectory(transaction, GetSelf().GetPathString(Move(path)), attributes)); 304 } 305 return nn::ResultSuccess(); 306 } 307 RenameFile(nn::fs::Transaction transaction,Path oldPath,Path newPath)308 Result RenameFile(nn::fs::Transaction transaction, Path oldPath, Path newPath) 309 { 310 ArchiveHandle handle1, handle2; 311 { 312 ArchiveName name = GetSelf().GetArchiveName(oldPath); 313 if (!name.IsValid()) 314 { 315 return nn::fs::ResultInvalidPathFormat(); 316 } 317 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle1, name)); 318 } 319 { 320 ArchiveName name = GetSelf().GetArchiveName(newPath); 321 if (!name.IsValid()) 322 { 323 return nn::fs::ResultInvalidPathFormat(); 324 } 325 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle2, name)); 326 } 327 if (handle1 != handle2) 328 { 329 return nn::fs::ResultUnsupportedOperation(); 330 } 331 { 332 Accessor acc(GetSelf().GetHandleTable(), handle1); 333 if (!acc) 334 { 335 // TODO: この Result でいい? 336 return nn::fs::ResultArchiveNotFound(); 337 } 338 NN_UTIL_RETURN_IF_FAILED(acc->RenameFile(transaction, GetSelf().GetPathString(Move(oldPath)), GetSelf().GetPathString(Move(newPath)))); 339 } 340 return nn::ResultSuccess(); 341 } 342 RenameDirectory(nn::fs::Transaction transaction,Path oldPath,Path newPath)343 Result RenameDirectory(nn::fs::Transaction transaction, Path oldPath, Path newPath) 344 { 345 ArchiveHandle handle1, handle2; 346 { 347 ArchiveName name = GetSelf().GetArchiveName(oldPath); 348 if (!name.IsValid()) 349 { 350 return nn::fs::ResultInvalidPathFormat(); 351 } 352 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle1, name)); 353 } 354 { 355 ArchiveName name = GetSelf().GetArchiveName(newPath); 356 if (!name.IsValid()) 357 { 358 return nn::fs::ResultInvalidPathFormat(); 359 } 360 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle2, name)); 361 } 362 if (handle1 != handle2) 363 { 364 return nn::fs::ResultUnsupportedOperation(); 365 } 366 { 367 Accessor acc(GetSelf().GetHandleTable(), handle1); 368 if (!acc) 369 { 370 // TODO: この Result でいい? 371 return nn::fs::ResultArchiveNotFound(); 372 } 373 NN_UTIL_RETURN_IF_FAILED(acc->RenameDirectory(transaction, GetSelf().GetPathString(Move(oldPath)), GetSelf().GetPathString(Move(newPath)))); 374 } 375 return nn::ResultSuccess(); 376 } 377 GetPathMark(nn::fs::PathMark * pathMark,Path path)378 Result GetPathMark( nn::fs::PathMark* pathMark, Path path) 379 { 380 ArchiveName name = GetSelf().GetArchiveName(path); 381 if (!name.IsValid()) 382 { 383 return nn::fs::ResultInvalidPathFormat(); 384 } 385 ArchiveHandle handle; 386 NN_UTIL_RETURN_IF_FAILED(GetSelf().GetArchiveHandle(&handle, name)); 387 { 388 Accessor acc(GetSelf().GetHandleTable(), handle); 389 if (!acc) 390 { 391 // TODO: この Result でいい? 392 return nn::fs::ResultArchiveNotFound(); 393 } 394 NN_UTIL_RETURN_IF_FAILED(acc->GetPathMark( pathMark, GetSelf().GetPathString(Move(path)))); 395 } 396 return nn::ResultSuccess(); 397 } 398 399 }; 400 401 }} 402 403 #endif 404