JD2022-TU1/main/extern/Raki/Source/RakiTests/Stream/ReadFileStream.cpp

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