#include "Precompiled.h" #ifdef RAKI_PLATFORM_PS3 #include #endif // RAKI_PLATFORM_PS3 #include "RakiTests/Stream/ReadFileStream.h" namespace raki { #if defined ( RAKI_PLATFORM_CAFE ) FSCmdBlock g_FSCommandBlock; FSClient g_FS_Client_Handle; s32 g_FSInitRefCount = 0; /*---------------------------------------------------------------------------* Name: stateChangeCallback Description: Handler of state change notification. *---------------------------------------------------------------------------*/ static void stateChangeCallback( FSClient* pClient, FSVolumeState state, void* pContext) { // Report volume state and last error FSError lastError = FSGetLastError(pClient); OSReport("Volume state of client 0x%08x changed to %d\n", pClient, state); OSReport("Last error: %d\n", lastError); if (state == FS_VOLSTATE_FATAL) { OSReport("** Fatal error occured (expected) **"); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static s32 _our_InitFS(void) { if (!g_FSInitRefCount) { FSStateChangeParams stateChangeParams; FSInit(); FSAddClient(&g_FS_Client_Handle, FS_RET_NO_ERROR); // Set state change notification callback. stateChangeParams.userCallback = stateChangeCallback; // Use callback stateChangeParams.userContext = NULL; // user context stateChangeParams.ioMsgQueue = NULL; // Don't use message queue FSSetStateChangeNotification(&g_FS_Client_Handle, &stateChangeParams); } g_FSInitRefCount++; return 0; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ bool DVDOpen(const char * path, FSFileHandle *info) { FSStatus result = FS_STATUS_OK; result = _our_InitFS(); if (FS_STATUS_OK != result) { OSReport("DVDOpen Error: _our_InitFS failed!\n"); return FALSE; } // Init command block. FSInitCmdBlock(&g_FSCommandBlock); result = FSOpenFile(&g_FS_Client_Handle, &g_FSCommandBlock, path, "r", info, FS_RET_NOT_FOUND); if (FS_STATUS_OK != result) { OSReport("DVDOpen Error: FSOpenFile(%s) returned %d!\n", path, result); return false; } return true; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ void DVDClose(FSFileHandle fileInfo) { // Init command block. FSInitCmdBlock(&g_FSCommandBlock); FSCloseFile(&g_FS_Client_Handle, &g_FSCommandBlock, fileInfo, FS_RET_NO_ERROR); } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ s32 DVDRead(FSFileHandle fileInfo, void* addr, u32 length, u32 offset) { // Init command block. FSInitCmdBlock(&g_FSCommandBlock); FSReadFileWithPos(&g_FS_Client_Handle, &g_FSCommandBlock, addr, length, 1, offset, fileInfo, 0, FS_RET_NO_ERROR); return length; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ u32 DVDGetLength(FSFileHandle fileInfo) { FSStat stat; // Init command block. FSInitCmdBlock(&g_FSCommandBlock); FSGetStatFile(&g_FS_Client_Handle, &g_FSCommandBlock, fileInfo, &stat, FS_RET_NO_ERROR); return stat.size; } void * SimpleRead(const char * filename, u32 * len) { RAKI_ASSERT(filename); RAKI_ASSERT(len); *len = 0; FSFileHandle info = { 0 }; if ( !DVDOpen( filename, &info ) ) return NULL; *len = DVDGetLength( info ); void * fileBuf = Memory::mallocAligned64( *len, Memory::data ); if ( !fileBuf ) { *len = 0; return NULL; } if ( !DVDRead(info, fileBuf, *len, 0 ) ) { Memory::freeAligned64( fileBuf ); *len = 0; return NULL; } DVDClose( info ); return fileBuf; } #endif // defined ( RAKI_PLATFORM_CAFE ) ReadFileStream::ReadFileStream() : m_size( 0 ) #if defined ( RAKI_USING_XAUDIO2 ) , m_file (NULL ) #elif defined ( RAKI_PLATFORM_PS3 ) , m_file (NULL ) , m_currentPos( 0 ) #elif defined ( RAKI_PLATFORM_WII ) , m_currentPos( 0 ) , m_fileCopy( NULL ) #elif defined ( RAKI_PLATFORM_CAFE ) , m_currentPos( 0 ) , m_fileCopy( NULL ) #elif defined ( RAKI_PLATFORM_ORBIS ) || defined (RAKI_PLATFORM_PROSPERO) , m_file(NULL) #endif { setIsReading(); } ReadFileStream::~ReadFileStream() { close(); } bool ReadFileStream::open( const char * _path ) { RAKI_ASSERT( _path ); close(); #if defined ( RAKI_USING_XAUDIO2 ) #if defined RAKI_PLATFORM_WIN32 size_t sizeConverted = 0; wchar_t widePath[0x200]; errno_t retValue = mbstowcs_s( &sizeConverted, widePath, 0x1FF, _path, 0x1FF); RAKI_ASSERT( !retValue ); RAKI_ASSERT( sizeConverted ); HANDLE handle = CreateFile( widePath, // lpFileName READ_CONTROL, // dwDesiredAccess 0, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDisposition FILE_FLAG_BACKUP_SEMANTICS, // dwFlagsAndAttributes NULL ); // hTemplateFile #else HANDLE handle = CreateFile( _path, // lpFileName READ_CONTROL, // dwDesiredAccess 0, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDisposition FILE_FLAG_BACKUP_SEMANTICS, // dwFlagsAndAttributes NULL ); // hTemplateFile #endif if ( handle != INVALID_HANDLE_VALUE ) { LARGE_INTEGER fileSize = { 0 }; GetFileSizeEx( handle, &fileSize ); m_size = fileSize.QuadPart; CloseHandle( handle ); } if ( !m_size ) return false; if ( fopen_s( &m_file, _path, "rb" ) ) m_file = NULL; if ( !m_file ) { m_size = 0; } return ( m_file != NULL ); #elif defined RAKI_PLATFORM_PS3 m_currentPos = 0; CellFsErrno ret = cellFsOpen( _path, CELL_FS_O_RDONLY, &m_file, NULL, 0 ); if ( ret != CELL_FS_SUCCEEDED ) return false; RAKI_ASSERT( m_file ); // arf change default value... CellFsStat stats = { 0 }; ret = cellFsFstat( m_file, &stats ); if ( ret != CELL_FS_SUCCEEDED ) { close(); return false; } m_size = stats.st_size; if ( !m_file ) { m_size = 0; } return ( m_file != NULL ); #elif defined ( RAKI_PLATFORM_WII ) m_currentPos = 0; BOOL opened = DVDOpen( _path, &m_fileInfo ); if ( !opened ) { m_fileInfo.startAddr = 0; return false; } m_size = DVDGetLength( &m_fileInfo ); if ( m_size ) { m_fileCopy = Memory::mallocMem2Aligned32( m_size, Memory::data ); if ( m_fileCopy ) { DCFlushRange( m_fileCopy, (u32)m_size ); long round_length = OSRoundUp32B( (u32) m_size ); s32 result = DVDRead( &m_fileInfo, m_fileCopy, round_length, 0 ); // if ( result ) // DCInvalidateRange( m_fileCopy, (u32)result ); if ( result == round_length ) return true; } } return false; #elif defined ( RAKI_PLATFORM_CAFE ) u32 read_length = 0; m_fileCopy = SimpleRead( _path, &read_length ); m_size = read_length; return m_fileCopy != NULL; #elif defined ( RAKI_PLATFORM_ORBIS ) || defined ( RAKI_PLATFORM_PROSPERO ) m_file = fopen(_path, "rb"); if(NULL == m_file) return false; fseek(m_file, 0, SEEK_END); m_size = ftell(m_file); fseek(m_file, 0, SEEK_SET); return true; #else #error #endif } void ReadFileStream::close() { #if defined ( RAKI_USING_XAUDIO2 ) if ( m_file ) fclose( m_file ); m_file = NULL; #elif defined ( RAKI_PLATFORM_PS3 ) if ( m_file ) cellFsClose( m_file ); m_file = 0; m_currentPos = 0; m_file = NULL; #elif defined ( RAKI_PLATFORM_WII ) if ( m_fileCopy ) { Memory::freeMem2Aligned32( m_fileCopy ); m_fileCopy = NULL; DVDClose( &m_fileInfo ); m_fileInfo.startAddr = 0; } m_currentPos = 0; #elif defined ( RAKI_PLATFORM_CAFE ) if ( m_fileCopy ) { Memory::freeAligned64( m_fileCopy ); m_fileCopy = NULL; } m_currentPos = 0; #elif defined ( RAKI_PLATFORM_ORBIS ) || defined ( RAKI_PLATFORM_PROSPERO ) if ( NULL == m_file ) return; fclose( m_file ); m_file = NULL; #else #error #endif m_size = 0; } u64 ReadFileStream::stream( void * _data, const u64 _size ) { RAKI_ASSERT( _data ); RAKI_ASSERT( _size ); #if defined ( RAKI_USING_XAUDIO2 ) if ( m_file ) return (u64) fread( _data, 1, (size_t)_size, m_file ); return 0; #elif defined ( RAKI_PLATFORM_PS3 ) u64 actuallyRead = 0; if ( m_file ) cellFsReadWithOffset( m_file, m_currentPos, (void*)_data, _size, &actuallyRead ); m_currentPos += actuallyRead; return actuallyRead; #elif defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE ) u64 actuallyRead = 0; if ( m_fileCopy ) { actuallyRead = _size; if ( m_currentPos + actuallyRead > m_size ) actuallyRead = ( m_size - m_currentPos ); if ( actuallyRead ) { Memory::memcpy( _data, (void*)( m_currentPos + (char*) m_fileCopy ), actuallyRead ); m_currentPos += actuallyRead; } } return actuallyRead; #elif defined( RAKI_PLATFORM_ORBIS ) || defined ( RAKI_PLATFORM_PROSPERO ) if( m_file ) return (u64)fread( _data, 1, (size_t)_size, m_file ); return 0; #else #error #endif } u64 ReadFileStream::seek( const u64 _size, const SeekType _seekType ) { #if defined ( RAKI_USING_XAUDIO2 ) if ( m_file ) { if ( _seekType == SeekableStream::fromBeginning ) { fseek( m_file, (long)_size, SEEK_SET ); } else if ( _seekType == SeekableStream::fromCurrentPos ) { fseek( m_file, (long)_size, SEEK_CUR ); } else { RAKI_ASSERT_FALSE; } u64 currentPos = (u64) ftell( m_file ); return currentPos; } return 0; #elif defined ( RAKI_PLATFORM_PS3 ) if ( m_file ) { if ( _seekType == SeekableStream::fromBeginning ) { if ( _size < m_size ) m_currentPos = _size; else m_currentPos = m_size; } else if ( _seekType == SeekableStream::fromCurrentPos ) { if ( m_currentPos + _size < m_size ) m_currentPos += _size; else m_currentPos = m_size; } else { RAKI_ASSERT_FALSE; } } return m_currentPos; #elif defined ( RAKI_PLATFORM_WII ) if ( m_fileInfo.startAddr ) { if ( _seekType == SeekableStream::fromBeginning ) { if ( _size < m_size ) m_currentPos = _size; else m_currentPos = m_size; } else if ( _seekType == SeekableStream::fromCurrentPos ) { if ( m_currentPos + _size < m_size ) m_currentPos += _size; else m_currentPos = m_size; } else { RAKI_ASSERT_FALSE; } } return m_currentPos; #elif defined ( RAKI_PLATFORM_CAFE ) if ( m_fileCopy ) { if ( _seekType == SeekableStream::fromBeginning ) { if ( _size < m_size ) m_currentPos = _size; else m_currentPos = m_size; } else if ( _seekType == SeekableStream::fromCurrentPos ) { if ( m_currentPos + _size < m_size ) m_currentPos += _size; else m_currentPos = m_size; } else { RAKI_ASSERT_FALSE; } } return m_currentPos; #elif defined ( RAKI_PLATFORM_ORBIS ) || defined ( RAKI_PLATFORM_PROSPERO ) if ( m_file ) { if ( _seekType == SeekableStream::fromBeginning ) { fseek( m_file, (long)_size, SEEK_SET ); } else if ( _seekType == SeekableStream::fromCurrentPos ) { fseek( m_file, (long)_size, SEEK_CUR ); } else { RAKI_ASSERT_FALSE; } u64 currentPos = (u64) ftell( m_file ); return currentPos; } return 0; #else #error #endif } u64 ReadFileStream::getCurrentPos() const { #if defined ( RAKI_USING_XAUDIO2 ) if ( m_file ) return (u64) ftell( m_file ); return 0; #elif defined ( RAKI_PLATFORM_PS3 ) || defined ( RAKI_PLATFORM_WII ) || defined ( RAKI_PLATFORM_CAFE ) return m_currentPos; #elif defined ( RAKI_PLATFORM_ORBIS ) || defined ( RAKI_PLATFORM_PROSPERO ) if ( m_file ) return (u64) ftell( m_file ); return 0; #else #error #endif } u64 ReadFileStream::getSize() const { return m_size; } } // namespace raki