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