631 lines
13 KiB
C++
631 lines
13 KiB
C++
#include "Precompiled.h"
|
|
|
|
#ifdef RAKI_PLATFORM_PS3
|
|
#include <cell/cell_fs.h>
|
|
#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
|
|
|