mirror of https://github.com/PCSX2/pcsx2.git
wxIsoFile: ... and some more fixes.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxIsoFile@3944 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ca9e250837
commit
e30892cf34
|
@ -176,14 +176,3 @@ extern u64 GetTickFrequency();
|
|||
extern u64 GetCPUTicks();
|
||||
|
||||
extern wxString GetOSVersionString();
|
||||
|
||||
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
|
||||
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
|
||||
extern void pcsx2_aligned_free(void* pmem);
|
||||
|
||||
// aligned_malloc: Implement/declare linux equivalents here!
|
||||
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
|
||||
# define _aligned_malloc pcsx2_aligned_malloc
|
||||
# define _aligned_free pcsx2_aligned_free
|
||||
# define _aligned_realloc pcsx2_aligned_realloc
|
||||
#endif
|
||||
|
|
|
@ -1,220 +1,233 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Exceptions.h"
|
||||
|
||||
// pxUSE_SECURE_MALLOC - enables bounds checking on scoped malloc allocations.
|
||||
|
||||
#ifndef pxUSE_SECURE_MALLOC
|
||||
#define pxUSE_SECURE_MALLOC 0
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
|
||||
// pointer to null after deallocation.
|
||||
|
||||
#define safe_delete( ptr ) \
|
||||
((void) (delete (ptr)), (ptr) = NULL)
|
||||
|
||||
#define safe_delete_array( ptr ) \
|
||||
((void) (delete[] (ptr)), (ptr) = NULL)
|
||||
|
||||
// No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
|
||||
// just about every compiler and libc implementation of any recentness.
|
||||
#define safe_free( ptr ) \
|
||||
( (void) (free( ptr ), !!0), (ptr) = NULL )
|
||||
//((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
|
||||
|
||||
#define safe_fclose( ptr ) \
|
||||
((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL))
|
||||
|
||||
// Implementation note: all known implementations of _aligned_free check the pointer for
|
||||
// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
|
||||
// do it here.
|
||||
#define safe_aligned_free( ptr ) \
|
||||
((void) ( _aligned_free( ptr ), (ptr) = NULL ))
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseScopedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base class that allows various ScopedMalloc types to be passed to functions that act
|
||||
// on them.
|
||||
//
|
||||
// Rationale: This class and the derived varieties are provided as a simple autonomous self-
|
||||
// destructing container for malloc. The entire class is almost completely dependency free,
|
||||
// and thus can be included everywhere and anywhere without dependency hassles.
|
||||
//
|
||||
template< typename T >
|
||||
class BaseScopedAlloc
|
||||
{
|
||||
protected:
|
||||
T* m_buffer;
|
||||
uint m_size;
|
||||
|
||||
public:
|
||||
BaseScopedAlloc()
|
||||
{
|
||||
m_buffer = NULL;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
virtual ~BaseScopedAlloc() throw()
|
||||
{
|
||||
//pxAssume(m_buffer==NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
size_t GetSize() const { return m_size; }
|
||||
size_t GetLength() const { return m_size; }
|
||||
|
||||
// Allocates the object to the specified size. If an existing allocation is in
|
||||
// place, it is freed and replaced with the new allocation, and all data is lost.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Alloc( size_t newsize )=0;
|
||||
|
||||
// Re-sizes the allocation to the requested size, without any data loss.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Resize( size_t newsize )=0;
|
||||
|
||||
void Free()
|
||||
{
|
||||
Alloc( 0 );
|
||||
}
|
||||
|
||||
// Makes enough room for the requested size. Existing data in the array is retained.
|
||||
void MakeRoomFor( uint size )
|
||||
{
|
||||
if (size <= m_size) return;
|
||||
Resize( size );
|
||||
}
|
||||
|
||||
T* GetPtr( uint idx=0 ) const
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return &m_buffer[idx];
|
||||
}
|
||||
|
||||
T& operator[]( uint idx )
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return m_buffer[idx];
|
||||
}
|
||||
|
||||
const T& operator[]( uint idx ) const
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return m_buffer[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// A simple container class for a standard malloc allocation. By default, no bounds checking
|
||||
// is performed, and there is no option for enabling bounds checking. If bounds checking and
|
||||
// other features are needed, use the more robust SafeArray<> instead.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template< typename T >
|
||||
class ScopedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
public:
|
||||
ScopedAlloc( size_t size=0 ) : BaseScopedAlloc<T>()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlloc() throw()
|
||||
{
|
||||
Alloc(0);
|
||||
}
|
||||
|
||||
virtual void Alloc( size_t newsize )
|
||||
{
|
||||
safe_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size) return;
|
||||
|
||||
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory("ScopedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize( size_t newsize )
|
||||
{
|
||||
this->m_size = newsize;
|
||||
this->m_buffer = (T*)realloc(this->m_buffer * sizeof(T), newsize);
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory("ScopedAlloc::Resize");
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlignedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// A simple container class for an aligned allocation. By default, no bounds checking is
|
||||
// performed, and there is no option for enabling bounds checking. If bounds checking and
|
||||
// other features are needed, use the more robust SafeArray<> instead.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template< typename T, uint align >
|
||||
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
public:
|
||||
ScopedAlignedAlloc( size_t size=0 ) : BaseScopedAlloc()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlignedAlloc() throw()
|
||||
{
|
||||
Alloc(0);
|
||||
}
|
||||
|
||||
virtual void Alloc( size_t newsize )
|
||||
{
|
||||
safe_aligned_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size) return;
|
||||
|
||||
this->m_buffer = (T*)_aligned_malloc( this->m_size * sizeof(T), align );
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize( size_t newsize )
|
||||
{
|
||||
this->m_size = newsize;
|
||||
this->m_buffer = (T*)_aligned_realloc(this->m_buffer, newsize * sizeof(T), align);
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
|
||||
}
|
||||
};
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Exceptions.h"
|
||||
|
||||
// pxUSE_SECURE_MALLOC - enables bounds checking on scoped malloc allocations.
|
||||
|
||||
#ifndef pxUSE_SECURE_MALLOC
|
||||
#define pxUSE_SECURE_MALLOC 0
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
|
||||
// pointer to null after deallocation.
|
||||
|
||||
#define safe_delete( ptr ) \
|
||||
((void) (delete (ptr)), (ptr) = NULL)
|
||||
|
||||
#define safe_delete_array( ptr ) \
|
||||
((void) (delete[] (ptr)), (ptr) = NULL)
|
||||
|
||||
// No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
|
||||
// just about every compiler and libc implementation of any recentness.
|
||||
#define safe_free( ptr ) \
|
||||
( (void) (free( ptr ), !!0), (ptr) = NULL )
|
||||
//((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
|
||||
|
||||
#define safe_fclose( ptr ) \
|
||||
((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL))
|
||||
|
||||
// Implementation note: all known implementations of _aligned_free check the pointer for
|
||||
// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
|
||||
// do it here.
|
||||
#define safe_aligned_free( ptr ) \
|
||||
((void) ( _aligned_free( ptr ), (ptr) = NULL ))
|
||||
|
||||
|
||||
extern void* __fastcall pcsx2_aligned_malloc(size_t size, size_t align);
|
||||
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t size, size_t align);
|
||||
extern void pcsx2_aligned_free(void* pmem);
|
||||
|
||||
// aligned_malloc: Implement/declare linux equivalents here!
|
||||
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
|
||||
# define _aligned_malloc pcsx2_aligned_malloc
|
||||
# define _aligned_free pcsx2_aligned_free
|
||||
# define _aligned_realloc pcsx2_aligned_realloc
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseScopedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Base class that allows various ScopedMalloc types to be passed to functions that act
|
||||
// on them.
|
||||
//
|
||||
// Rationale: This class and the derived varieties are provided as a simple autonomous self-
|
||||
// destructing container for malloc. The entire class is almost completely dependency free,
|
||||
// and thus can be included everywhere and anywhere without dependency hassles.
|
||||
//
|
||||
template< typename T >
|
||||
class BaseScopedAlloc
|
||||
{
|
||||
protected:
|
||||
T* m_buffer;
|
||||
uint m_size;
|
||||
|
||||
public:
|
||||
BaseScopedAlloc()
|
||||
{
|
||||
m_buffer = NULL;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
virtual ~BaseScopedAlloc() throw()
|
||||
{
|
||||
//pxAssume(m_buffer==NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
size_t GetSize() const { return m_size; }
|
||||
size_t GetLength() const { return m_size; }
|
||||
|
||||
// Allocates the object to the specified size. If an existing allocation is in
|
||||
// place, it is freed and replaced with the new allocation, and all data is lost.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Alloc( size_t newsize )=0;
|
||||
|
||||
// Re-sizes the allocation to the requested size, without any data loss.
|
||||
// Parameter:
|
||||
// newSize - size of the new allocation, in elements (not bytes!). If the specified
|
||||
// size is 0, the the allocation is freed, same as calling Free().
|
||||
virtual void Resize( size_t newsize )=0;
|
||||
|
||||
void Free()
|
||||
{
|
||||
Alloc( 0 );
|
||||
}
|
||||
|
||||
// Makes enough room for the requested size. Existing data in the array is retained.
|
||||
void MakeRoomFor( uint size )
|
||||
{
|
||||
if (size <= m_size) return;
|
||||
Resize( size );
|
||||
}
|
||||
|
||||
T* GetPtr( uint idx=0 ) const
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return &m_buffer[idx];
|
||||
}
|
||||
|
||||
T& operator[]( uint idx )
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return m_buffer[idx];
|
||||
}
|
||||
|
||||
const T& operator[]( uint idx ) const
|
||||
{
|
||||
#if pxUSE_SECURE_MALLOC
|
||||
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size );
|
||||
#endif
|
||||
return m_buffer[idx];
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// A simple container class for a standard malloc allocation. By default, no bounds checking
|
||||
// is performed, and there is no option for enabling bounds checking. If bounds checking and
|
||||
// other features are needed, use the more robust SafeArray<> instead.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template< typename T >
|
||||
class ScopedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
public:
|
||||
ScopedAlloc( size_t size=0 ) : BaseScopedAlloc<T>()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlloc() throw()
|
||||
{
|
||||
Alloc(0);
|
||||
}
|
||||
|
||||
virtual void Alloc( size_t newsize )
|
||||
{
|
||||
safe_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size) return;
|
||||
|
||||
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory("ScopedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize( size_t newsize )
|
||||
{
|
||||
this->m_size = newsize;
|
||||
this->m_buffer = (T*)realloc(this->m_buffer * sizeof(T), newsize);
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory("ScopedAlloc::Resize");
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// ScopedAlignedAlloc
|
||||
// --------------------------------------------------------------------------------------
|
||||
// A simple container class for an aligned allocation. By default, no bounds checking is
|
||||
// performed, and there is no option for enabling bounds checking. If bounds checking and
|
||||
// other features are needed, use the more robust SafeArray<> instead.
|
||||
//
|
||||
// See docs for BaseScopedAlloc for details and rationale.
|
||||
//
|
||||
template< typename T, uint align >
|
||||
class ScopedAlignedAlloc : public BaseScopedAlloc<T>
|
||||
{
|
||||
public:
|
||||
ScopedAlignedAlloc( size_t size=0 ) : BaseScopedAlloc<T>()
|
||||
{
|
||||
Alloc(size);
|
||||
}
|
||||
|
||||
virtual ~ScopedAlignedAlloc() throw()
|
||||
{
|
||||
Alloc(0);
|
||||
}
|
||||
|
||||
virtual void Alloc( size_t newsize )
|
||||
{
|
||||
safe_aligned_free(this->m_buffer);
|
||||
this->m_size = newsize;
|
||||
if (!this->m_size) return;
|
||||
|
||||
this->m_buffer = (T*)_aligned_malloc( this->m_size * sizeof(T), align );
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
|
||||
}
|
||||
|
||||
virtual void Resize( size_t newsize )
|
||||
{
|
||||
this->m_size = newsize;
|
||||
this->m_buffer = (T*)_aligned_realloc(this->m_buffer, newsize * sizeof(T), align);
|
||||
|
||||
if (!this->m_buffer)
|
||||
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,204 +1,205 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "wxBaseTools.h"
|
||||
#include "pxStreams.h"
|
||||
|
||||
#include <wx/stream.h>
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamReader (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Interface for reading data from a gzip stream.
|
||||
//
|
||||
|
||||
pxStreamReader::pxStreamReader(const wxString& filename, ScopedPtr<wxInputStream>& input)
|
||||
: m_filename( filename )
|
||||
, m_stream( input.DetachPtr() )
|
||||
{
|
||||
}
|
||||
|
||||
pxStreamReader::pxStreamReader(const wxString& filename, wxInputStream* input)
|
||||
: m_filename( filename )
|
||||
, m_stream( input )
|
||||
{
|
||||
}
|
||||
|
||||
void pxStreamReader::SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_stream = stream.DetachPtr();
|
||||
}
|
||||
|
||||
void pxStreamReader::SetStream( const wxString& filename, wxInputStream* stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_stream = stream;
|
||||
}
|
||||
|
||||
void pxStreamReader::Read( void* dest, size_t size )
|
||||
{
|
||||
m_stream->Read(dest, size);
|
||||
if (m_stream->GetLastError() == wxSTREAM_READ_ERROR)
|
||||
{
|
||||
int err = errno;
|
||||
if (!err)
|
||||
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)");
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(m_filename, err));
|
||||
ex->SetDiagMsg( L"cannot read from file: " + ex->DiagMsg() );
|
||||
ex->Rethrow();
|
||||
}
|
||||
|
||||
// IMPORTANT! The underlying file/source Eof() stuff is not really reliable, so we
|
||||
// must always use the explicit check against the number of bytes read to determine
|
||||
// end-of-stream conditions.
|
||||
|
||||
if ((size_t)m_stream->LastRead() < size)
|
||||
throw Exception::EndOfStream( m_filename );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamWriter
|
||||
// --------------------------------------------------------------------------------------
|
||||
pxStreamWriter::pxStreamWriter(const wxString& filename, ScopedPtr<wxOutputStream>& output)
|
||||
: m_filename( filename )
|
||||
, m_outstream( output.DetachPtr() )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pxStreamWriter::pxStreamWriter(const wxString& filename, wxOutputStream* output)
|
||||
: m_filename( filename )
|
||||
, m_outstream( output )
|
||||
{
|
||||
}
|
||||
|
||||
void pxStreamWriter::SetStream( const wxString& filename, ScopedPtr<wxOutputStream>& stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_outstream = stream.DetachPtr();
|
||||
}
|
||||
|
||||
void pxStreamWriter::SetStream( const wxString& filename, wxOutputStream* stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_outstream = stream;
|
||||
}
|
||||
|
||||
|
||||
void pxStreamWriter::Write( const void* src, size_t size )
|
||||
{
|
||||
m_outstream->Write(src, size);
|
||||
if(m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
|
||||
{
|
||||
int err = errno;
|
||||
if (!err)
|
||||
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream.");
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(m_filename, err));
|
||||
ex->SetDiagMsg( L"Cannot write to file: " + ex->DiagMsg() );
|
||||
ex->Rethrow();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxTextStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
// Returns TRUE if the source is UTF8, or FALSE if it's just ASCII crap.
|
||||
bool pxReadLine( wxInputStream& input, std::string& dest )
|
||||
{
|
||||
dest.clear();
|
||||
bool isUTF8 = false;
|
||||
while ( true )
|
||||
{
|
||||
char c;
|
||||
input.Read(&c, sizeof(c));
|
||||
if( c == 0 ) break;
|
||||
if( input.Eof() ) break;
|
||||
if( c == '\n' ) break; // eat on UNIX
|
||||
if( c == '\r' )
|
||||
{
|
||||
input.Read(&c, sizeof(c));
|
||||
if( c == 0 ) break;
|
||||
if( input.Eof() ) break;
|
||||
if( c == '\n' ) break;
|
||||
|
||||
input.Ungetch(c);
|
||||
break;
|
||||
}
|
||||
dest += c;
|
||||
if( c & 0x80 ) isUTF8 = true;
|
||||
}
|
||||
|
||||
return isUTF8;
|
||||
}
|
||||
|
||||
void pxReadLine( wxInputStream& input, wxString& dest, std::string& intermed )
|
||||
{
|
||||
dest.clear();
|
||||
if( pxReadLine( input, intermed ) )
|
||||
dest = fromUTF8(intermed.c_str());
|
||||
else
|
||||
{
|
||||
// Optimized ToAscii conversion.
|
||||
// wx3.0 : NOT COMPATIBLE!! (on linux anyway)
|
||||
const char* ascii = intermed.c_str();
|
||||
while( *ascii != 0 ) dest += (wchar_t)(unsigned char)*ascii++;
|
||||
}
|
||||
}
|
||||
|
||||
void pxReadLine( wxInputStream& input, wxString& dest )
|
||||
{
|
||||
std::string line;
|
||||
pxReadLine( input, dest, line );
|
||||
}
|
||||
|
||||
wxString pxReadLine( wxInputStream& input )
|
||||
{
|
||||
wxString result;
|
||||
pxReadLine( input, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
void pxWriteLine( wxOutputStream& output )
|
||||
{
|
||||
output.Write( "\n", 1 );
|
||||
}
|
||||
|
||||
void pxWriteLine( wxOutputStream& output, const wxString& text )
|
||||
{
|
||||
if( !text.IsEmpty() )
|
||||
{
|
||||
pxToUTF8 utf8(text);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
pxWriteLine( output );
|
||||
}
|
||||
|
||||
void pxWriteMultiline( wxOutputStream& output, const wxString& src )
|
||||
{
|
||||
if( src.IsEmpty() ) return;
|
||||
|
||||
wxString result( src );
|
||||
result.Replace( L"\r\n", L"\n" );
|
||||
result.Replace( L"\r", L"\n" );
|
||||
|
||||
pxToUTF8 utf8(result);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "wxBaseTools.h"
|
||||
#include "pxStreams.h"
|
||||
|
||||
#include <wx/stream.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamReader (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Interface for reading data from a gzip stream.
|
||||
//
|
||||
|
||||
pxStreamReader::pxStreamReader(const wxString& filename, ScopedPtr<wxInputStream>& input)
|
||||
: m_filename( filename )
|
||||
, m_stream( input.DetachPtr() )
|
||||
{
|
||||
}
|
||||
|
||||
pxStreamReader::pxStreamReader(const wxString& filename, wxInputStream* input)
|
||||
: m_filename( filename )
|
||||
, m_stream( input )
|
||||
{
|
||||
}
|
||||
|
||||
void pxStreamReader::SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_stream = stream.DetachPtr();
|
||||
}
|
||||
|
||||
void pxStreamReader::SetStream( const wxString& filename, wxInputStream* stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_stream = stream;
|
||||
}
|
||||
|
||||
void pxStreamReader::Read( void* dest, size_t size )
|
||||
{
|
||||
m_stream->Read(dest, size);
|
||||
if (m_stream->GetLastError() == wxSTREAM_READ_ERROR)
|
||||
{
|
||||
int err = errno;
|
||||
if (!err)
|
||||
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)");
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(m_filename, err));
|
||||
ex->SetDiagMsg( L"cannot read from file: " + ex->DiagMsg() );
|
||||
ex->Rethrow();
|
||||
}
|
||||
|
||||
// IMPORTANT! The underlying file/source Eof() stuff is not really reliable, so we
|
||||
// must always use the explicit check against the number of bytes read to determine
|
||||
// end-of-stream conditions.
|
||||
|
||||
if ((size_t)m_stream->LastRead() < size)
|
||||
throw Exception::EndOfStream( m_filename );
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxStreamWriter
|
||||
// --------------------------------------------------------------------------------------
|
||||
pxStreamWriter::pxStreamWriter(const wxString& filename, ScopedPtr<wxOutputStream>& output)
|
||||
: m_filename( filename )
|
||||
, m_outstream( output.DetachPtr() )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pxStreamWriter::pxStreamWriter(const wxString& filename, wxOutputStream* output)
|
||||
: m_filename( filename )
|
||||
, m_outstream( output )
|
||||
{
|
||||
}
|
||||
|
||||
void pxStreamWriter::SetStream( const wxString& filename, ScopedPtr<wxOutputStream>& stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_outstream = stream.DetachPtr();
|
||||
}
|
||||
|
||||
void pxStreamWriter::SetStream( const wxString& filename, wxOutputStream* stream )
|
||||
{
|
||||
m_filename = filename;
|
||||
m_outstream = stream;
|
||||
}
|
||||
|
||||
|
||||
void pxStreamWriter::Write( const void* src, size_t size )
|
||||
{
|
||||
m_outstream->Write(src, size);
|
||||
if(m_outstream->GetLastError() == wxSTREAM_WRITE_ERROR)
|
||||
{
|
||||
int err = errno;
|
||||
if (!err)
|
||||
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream.");
|
||||
|
||||
ScopedExcept ex(Exception::FromErrno(m_filename, err));
|
||||
ex->SetDiagMsg( L"Cannot write to file: " + ex->DiagMsg() );
|
||||
ex->Rethrow();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxTextStream
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
// Returns TRUE if the source is UTF8, or FALSE if it's just ASCII crap.
|
||||
bool pxReadLine( wxInputStream& input, std::string& dest )
|
||||
{
|
||||
dest.clear();
|
||||
bool isUTF8 = false;
|
||||
while ( true )
|
||||
{
|
||||
char c;
|
||||
input.Read(&c, sizeof(c));
|
||||
if( c == 0 ) break;
|
||||
if( input.Eof() ) break;
|
||||
if( c == '\n' ) break; // eat on UNIX
|
||||
if( c == '\r' )
|
||||
{
|
||||
input.Read(&c, sizeof(c));
|
||||
if( c == 0 ) break;
|
||||
if( input.Eof() ) break;
|
||||
if( c == '\n' ) break;
|
||||
|
||||
input.Ungetch(c);
|
||||
break;
|
||||
}
|
||||
dest += c;
|
||||
if( c & 0x80 ) isUTF8 = true;
|
||||
}
|
||||
|
||||
return isUTF8;
|
||||
}
|
||||
|
||||
void pxReadLine( wxInputStream& input, wxString& dest, std::string& intermed )
|
||||
{
|
||||
dest.clear();
|
||||
if( pxReadLine( input, intermed ) )
|
||||
dest = fromUTF8(intermed.c_str());
|
||||
else
|
||||
{
|
||||
// Optimized ToAscii conversion.
|
||||
// wx3.0 : NOT COMPATIBLE!! (on linux anyway)
|
||||
const char* ascii = intermed.c_str();
|
||||
while( *ascii != 0 ) dest += (wchar_t)(unsigned char)*ascii++;
|
||||
}
|
||||
}
|
||||
|
||||
void pxReadLine( wxInputStream& input, wxString& dest )
|
||||
{
|
||||
std::string line;
|
||||
pxReadLine( input, dest, line );
|
||||
}
|
||||
|
||||
wxString pxReadLine( wxInputStream& input )
|
||||
{
|
||||
wxString result;
|
||||
pxReadLine( input, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
void pxWriteLine( wxOutputStream& output )
|
||||
{
|
||||
output.Write( "\n", 1 );
|
||||
}
|
||||
|
||||
void pxWriteLine( wxOutputStream& output, const wxString& text )
|
||||
{
|
||||
if( !text.IsEmpty() )
|
||||
{
|
||||
pxToUTF8 utf8(text);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
pxWriteLine( output );
|
||||
}
|
||||
|
||||
void pxWriteMultiline( wxOutputStream& output, const wxString& src )
|
||||
{
|
||||
if( src.IsEmpty() ) return;
|
||||
|
||||
wxString result( src );
|
||||
result.Replace( L"\r\n", L"\n" );
|
||||
result.Replace( L"\r", L"\n" );
|
||||
|
||||
pxToUTF8 utf8(result);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue