initial commit

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
2025-10-31 23:37:30 +01:00
commit 7228269764
9653 changed files with 4034514 additions and 0 deletions

View File

@@ -0,0 +1,478 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/bstream.h
// Purpose: Template class for testing base stream functions.
// Author: Hans Van Leemputten
// Copyright: (c) 2004 Hans Van Leemputten
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_TESTBSTREAM_H__
#define _WX_TESTBSTREAM_H__
///////////////////////////////////////////////////////////////////////////////
// Some macros preventing us from typing too much ;-)
//
#define STREAM_TEST_NAME "Streams"
#define COMPOSE_TEST_NAME(Name) \
STREAM_TEST_NAME "." #Name
#define STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(Name) \
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Name, COMPOSE_TEST_NAME(Name) );
///////////////////////////////////////////////////////////////////////////////
// Template class that implements a test for all base stream functions.
//
template <class TStreamIn, class TStreamOut> class BaseStreamTestCase : public CppUnit::TestCase
{
protected:
typedef BaseStreamTestCase<TStreamIn, TStreamOut> StreamTestCase;
class CleanupHelper
{
public:
CleanupHelper(StreamTestCase *value)
:m_pCleanup(value)
{}
~CleanupHelper()
{
m_pCleanup->DeleteInStream();
m_pCleanup->DeleteOutStream();
}
private:
StreamTestCase *m_pCleanup;
};
friend class CleanupHelper;
public:
BaseStreamTestCase()
:m_bSimpleTellITest(false),
m_bSimpleTellOTest(false),
m_bSeekInvalidBeyondEnd(true),
m_bEofAtLastRead(true),
m_pCurrentIn(nullptr),
m_pCurrentOut(nullptr)
{ /* Nothing extra */ }
virtual ~BaseStreamTestCase()
{
// Prevent mem leaks!
delete m_pCurrentIn;
delete m_pCurrentOut;
}
protected:
/*
* Input stream tests.
*/
// Just try to perform a GetSize() on the input stream.
void Input_GetSize()
{
CleanupHelper cleanup(this);
const TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
// Size should be greater than zero.
CPPUNIT_ASSERT(stream_in.GetSize() != 0);
}
// The variant for non-seekable streams.
void Input_GetSizeFail()
{
CleanupHelper cleanup(this);
const TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(stream_in.GetSize() == 0);
}
// Just try to perform a GetC() on the input stream.
void Input_GetC()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
// If no exception occurs the test is successful.
(void)stream_in.GetC();
}
// Just try to perform a Read() on the input stream.
void Input_Read()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
// Note: the input stream should at least be of min size +10!
char buf[10];
(void)stream_in.Read(buf, 10);
CPPUNIT_ASSERT(!stream_in.Eof());
DoCheckInputStream(stream_in);
// Test the stream version as well.
TStreamOut &stream_out = CreateOutStream();
(void)stream_in.Read(stream_out);
// The output stream should have read the input stream till the end.
CPPUNIT_ASSERT(stream_in.Eof());
}
// Test and see what happens to the EOF when we
// read after EOF was encountered.
void Input_Eof()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
// Double check to see if Eof it self doesn't changes the Eof status.
CPPUNIT_ASSERT(!stream_in.Eof());
// Travel to the end of the stream.
while(!stream_in.Eof())
{
CPPUNIT_ASSERT_MESSAGE( "unexpected non-EOF stream error",
stream_in.IsOk() );
// Read, we move one byte along.
(void)stream_in.GetC();
#if 0
// EOF behaviour is different in streams, disabled (for now?)
if (m_bEofAtLastRead)
// EOF should only occur after the last successful get.
CPPUNIT_ASSERT_MESSAGE("Eof is detected too late.", !(stream_in.LastRead() != 1 && stream_in.Eof()));
else
// EOF should only occur after a failed get.
CPPUNIT_ASSERT_MESSAGE("Eof is detected too soon.", !(stream_in.LastRead() == 1 && stream_in.Eof()));
#endif
}
// Check EOF stream state.
CPPUNIT_ASSERT_MESSAGE("EOF is not EOF?", stream_in.Eof());
// Ok we found the end, let's see if we can go past it.
for (size_t i = 0; i < 100; i++)
(void)stream_in.GetC();
// Check for EOF correctness.
CPPUNIT_ASSERT_MESSAGE("EOF is wrong when we read past EOF!", stream_in.Eof());
CPPUNIT_ASSERT_MESSAGE("Last error is not EOF while stream_in.Eof() is true", stream_in.GetLastError() == wxSTREAM_EOF);
}
// Just try to perform a LastRead() on the input stream.
void Input_LastRead()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
char buf[5];
(void)stream_in.Read(buf, 5);
REQUIRE( stream_in.GetLastError() == wxSTREAM_NO_ERROR );
CHECK( stream_in.LastRead() == 5 );
(void)stream_in.GetC();
REQUIRE( stream_in.GetLastError() == wxSTREAM_NO_ERROR );
CHECK( stream_in.LastRead() == 1 );
}
void Input_CanRead()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT( stream_in.CanRead() );
// read the entire contents
(void)stream_in.Read(CreateOutStream());
CPPUNIT_ASSERT( !stream_in.CanRead() );
}
// Just try to perform a SeekI() on the input stream.
void Input_SeekI()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT( stream_in.IsSeekable() );
CPPUNIT_ASSERT(!stream_in.Eof());
// Try to Seek in the stream...
CPPUNIT_ASSERT_EQUAL(2, stream_in.SeekI(2, wxFromStart));
CPPUNIT_ASSERT_EQUAL(4, stream_in.SeekI(2, wxFromCurrent));
// Not sure the following line is correct, so test it differently.
//CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_in.SeekI(-2, wxFromEnd));
CPPUNIT_ASSERT(stream_in.SeekI(-2, wxFromEnd) != wxInvalidOffset);
// Go beyond the stream size.
CPPUNIT_ASSERT((stream_in.SeekI(10, wxFromCurrent) == wxInvalidOffset) == m_bSeekInvalidBeyondEnd);
}
void Input_SeekIFail()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT( !stream_in.IsSeekable() );
}
// Just try to perform a TellI() on the input stream.
void Input_TellI()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
// Try to Get the location in the stream...
CPPUNIT_ASSERT_EQUAL(0, stream_in.TellI());
(void)stream_in.GetC();
CPPUNIT_ASSERT_EQUAL(1, stream_in.TellI());
if (!m_bSimpleTellITest)
{
wxFileOffset pos = stream_in.SeekI(5, wxFromStart);
CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
(void)stream_in.GetC();
CPPUNIT_ASSERT_EQUAL(6, stream_in.TellI());
pos = stream_in.SeekI(2, wxFromCurrent);
CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
pos = stream_in.SeekI(5, wxFromStart);
CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
}
}
// Just try to perform a Peek() on the input stream.
void Input_Peek()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
// Test the full stream
while (stream_in.IsOk())
{
char peekChar = stream_in.Peek();
size_t peekLastRead = stream_in.LastRead();
char getChar = stream_in.GetC();
// Peek and GetC should retrieve the same 0 or 1 characters.
CPPUNIT_ASSERT_EQUAL(peekLastRead, stream_in.LastRead());
if (stream_in.LastRead() == 1)
{
CPPUNIT_ASSERT_EQUAL(getChar, peekChar);
}
}
}
// Just try to perform a Ungetch() on the input stream.
void Input_Ungetch()
{
CleanupHelper cleanup(this);
TStreamIn &stream_in = CreateInStream();
CPPUNIT_ASSERT(!stream_in.Eof());
const char *ungetstr = "test";
size_t ungetsize = stream_in.Ungetch(ungetstr, strlen(ungetstr) + 1);
if (ungetsize != 0)
{
CPPUNIT_ASSERT_EQUAL(strlen(ungetstr) + 1, ungetsize);
char buf[10];
(void)stream_in.Read(buf, ungetsize);
CPPUNIT_ASSERT(strcmp(buf, ungetstr) == 0);
}
if (stream_in.Ungetch('a'))
{
CPPUNIT_ASSERT_EQUAL(int('a'), stream_in.GetC());
}
}
/*
* Output stream tests.
*/
// Just try to perform a PutC() on the output stream.
void Output_PutC()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
const char *buf = "Some text";
const wxFileOffset len = strlen(buf);
for ( int i = 0; i < len; i++ )
stream_out.PutC(buf[i]);
if ( stream_out.IsSeekable() )
CPPUNIT_ASSERT_EQUAL(len, stream_out.TellO());
}
// Just try to perform a Write() on the output stream.
void Output_Write()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
// Do the buffer version.
const char *buf = "Some text";
const wxFileOffset len = strlen(buf);
(void)stream_out.Write(buf, len);
if ( stream_out.IsSeekable() )
CPPUNIT_ASSERT_EQUAL( len, stream_out.TellO() );
// Do the Stream version.
TStreamIn &stream_in = CreateInStream();
(void)stream_out.Write(stream_in);
if ( stream_out.IsSeekable() )
CPPUNIT_ASSERT(stream_out.TellO() > len);
}
// Just try to perform a LastWrite() on the output stream.
void Output_LastWrite()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
const char *buf = "12345";
(void)stream_out.Write(buf, 5);
CPPUNIT_ASSERT_EQUAL(5, stream_out.LastWrite());
(void)stream_out.PutC('1');
CPPUNIT_ASSERT_EQUAL(1, stream_out.LastWrite());
}
// Just try to perform a SeekO() on the output stream.
void Output_SeekO()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
CPPUNIT_ASSERT( stream_out.IsSeekable() );
// First put some data in the stream, so it is not empty.
const char *buf = "1234567890";
(void)stream_out.Write(buf, 10);
// Try to Seek in the stream...
CPPUNIT_ASSERT_EQUAL(2, stream_out.SeekO(2, wxFromStart));
CPPUNIT_ASSERT_EQUAL(4, stream_out.SeekO(2, wxFromCurrent));
// Not sure the following line is correct, so test it differently.
//CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_out.SeekO(-2, wxFromEnd));
CPPUNIT_ASSERT(stream_out.SeekO(-2, wxFromEnd) != wxInvalidOffset);
// Go beyond the stream size.
CPPUNIT_ASSERT((stream_out.SeekO(10, wxFromCurrent) == wxInvalidOffset) == m_bSeekInvalidBeyondEnd);
}
void Output_SeekOFail()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
CPPUNIT_ASSERT( !stream_out.IsSeekable() );
}
// Just try to perform a TellO() on the output stream.
void Output_TellO()
{
CleanupHelper cleanup(this);
TStreamOut &stream_out = CreateOutStream();
// Try to Get the location in the stream...
CPPUNIT_ASSERT_EQUAL(0, stream_out.TellO());
(void)stream_out.PutC('1');
CPPUNIT_ASSERT_EQUAL(1, stream_out.TellO());
if (!m_bSimpleTellOTest)
{
// First put some extra data in the stream, so it's not empty.
const char *buf = "1234567890";
(void)stream_out.Write(buf, 10);
wxFileOffset pos = stream_out.SeekO(5, wxFromStart);
CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
(void)stream_out.PutC('1');
CPPUNIT_ASSERT_EQUAL(6, stream_out.TellO());
pos = stream_out.SeekO(2, wxFromCurrent);
CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
pos = stream_out.SeekO(5, wxFromStart);
CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
}
}
protected:
// Some tests can be configured... here you can find the config settings
bool m_bSimpleTellITest; // if true, no SeekI will be used by the TellI test.
// Default false.
bool m_bSimpleTellOTest; // if true, no SeekO will be used by the TellI test.
// Default false.
bool m_bSeekInvalidBeyondEnd; // if true a SeekI|O beyond the end of the stream should return wxInvalidOffset
// Default true.
bool m_bEofAtLastRead; // Does EOF occur at the moment the last byte is read or when read past the last byte.
// Default true.
protected:
TStreamIn &CreateInStream()
{
if (m_pCurrentIn)
{
wxFAIL_MSG(wxT("Error in test case, the previous input stream needs to be delete first!"));
}
m_pCurrentIn = DoCreateInStream();
wxASSERT(m_pCurrentIn != nullptr);
return *m_pCurrentIn;
}
TStreamOut &CreateOutStream()
{
if (m_pCurrentOut)
{
wxFAIL_MSG(wxT("Error in test case, the previous output stream needs to be delete first!"));
}
m_pCurrentOut = DoCreateOutStream();
wxASSERT(m_pCurrentOut != nullptr);
return *m_pCurrentOut;
}
void DeleteInStream()
{
if (m_pCurrentIn == nullptr)
return;
delete m_pCurrentIn;
m_pCurrentIn = nullptr;
// In case something extra needs to be done.
DoDeleteInStream();
}
void DeleteOutStream()
{
if (m_pCurrentOut == nullptr)
return;
CPPUNIT_ASSERT(m_pCurrentOut->Close());
delete m_pCurrentOut;
m_pCurrentOut = nullptr;
// In case something extra needs to be done.
DoDeleteOutStream();
}
protected:
// Items that need to be implemented by a derived class!
virtual TStreamIn *DoCreateInStream() = 0;
virtual TStreamOut *DoCreateOutStream() = 0;
virtual void DoCheckInputStream(TStreamIn& stream_in)
{
CPPUNIT_ASSERT(stream_in.IsOk());
}
virtual void DoDeleteInStream() { /* Depends on the base class */ }
virtual void DoDeleteOutStream() { /* Depends on the base class */ }
private:
TStreamIn *m_pCurrentIn;
TStreamOut *m_pCurrentOut;
};
#endif

View File

@@ -0,0 +1,300 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/datastreamtest.cpp
// Purpose: wxDataXXXStream Unit Test
// Author: Ryan Norton
// Created: 2004-08-14
// Copyright: (c) 2004 Ryan Norton
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif // WX_PRECOMP
#include <vector>
#include "wx/datstrm.h"
#include "wx/wfstream.h"
#include "wx/math.h"
#include "testfile.h"
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class DataStreamTestCase : public CppUnit::TestCase
{
public:
DataStreamTestCase();
private:
CPPUNIT_TEST_SUITE( DataStreamTestCase );
CPPUNIT_TEST( FloatRW );
CPPUNIT_TEST( DoubleRW );
CPPUNIT_TEST( StringRW );
CPPUNIT_TEST( LongLongRW );
CPPUNIT_TEST( Int64RW );
CPPUNIT_TEST( NaNRW );
CPPUNIT_TEST( PseudoTest_UseBigEndian );
CPPUNIT_TEST( FloatRW );
CPPUNIT_TEST( DoubleRW );
// Only test standard IEEE 754 formats if we're using IEEE extended
// format by default, otherwise the tests above already covered them.
#if wxUSE_APPLE_IEEE
CPPUNIT_TEST( PseudoTest_UseIEEE754 );
CPPUNIT_TEST( FloatRW );
CPPUNIT_TEST( DoubleRW );
// Also retest little endian version with standard formats.
CPPUNIT_TEST( PseudoTest_UseLittleEndian );
CPPUNIT_TEST( FloatRW );
CPPUNIT_TEST( DoubleRW );
#endif // wxUSE_APPLE_IEEE
CPPUNIT_TEST_SUITE_END();
wxFloat64 TestFloatRW(wxFloat64 fValue);
void FloatRW();
void DoubleRW();
void StringRW();
void LongLongRW();
void Int64RW();
void NaNRW();
void PseudoTest_UseBigEndian() { ms_useBigEndianFormat = true; }
void PseudoTest_UseLittleEndian() { ms_useBigEndianFormat = false; }
#if wxUSE_APPLE_IEEE
void PseudoTest_UseIEEE754() { ms_useIEEE754 = true; }
#endif // wxUSE_APPLE_IEEE
static bool ms_useBigEndianFormat;
#if wxUSE_APPLE_IEEE
static bool ms_useIEEE754;
#endif // wxUSE_APPLE_IEEE
wxDECLARE_NO_COPY_CLASS(DataStreamTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( DataStreamTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( DataStreamTestCase, "DataStreamTestCase" );
bool DataStreamTestCase::ms_useBigEndianFormat = false;
#if wxUSE_APPLE_IEEE
bool DataStreamTestCase::ms_useIEEE754 = false;
#endif // wxUSE_APPLE_IEEE
DataStreamTestCase::DataStreamTestCase()
{
}
wxFloat64 DataStreamTestCase::TestFloatRW(wxFloat64 fValue)
{
TempFile f("mytext.dat");
{
wxFileOutputStream pFileOutput( f.GetName() );
wxDataOutputStream pDataOutput( pFileOutput );
if ( ms_useBigEndianFormat )
pDataOutput.BigEndianOrdered(true);
#if wxUSE_APPLE_IEEE
if ( ms_useIEEE754 )
pDataOutput.UseBasicPrecisions();
#endif // wxUSE_APPLE_IEEE
pDataOutput << fValue;
}
wxFileInputStream pFileInput( f.GetName() );
wxDataInputStream pDataInput( pFileInput );
if ( ms_useBigEndianFormat )
pDataInput.BigEndianOrdered(true);
#if wxUSE_APPLE_IEEE
if ( ms_useIEEE754 )
pDataInput.UseBasicPrecisions();
#endif // wxUSE_APPLE_IEEE
wxFloat64 fInFloat;
pDataInput >> fInFloat;
return fInFloat;
}
template <class T>
class TestMultiRW {
public:
typedef std::vector<T> ValueArray;
typedef void (wxDataOutputStream::*FnWriter)(const T *buffer, size_t size);
typedef void (wxDataInputStream::*FnReader)(T *buffer, size_t size);
private:
bool m_ok;
private:
void ProcessData(const T *Values,
typename ValueArray::size_type Size,
FnWriter pfnWriter,
FnReader pfnReader)
{
ValueArray InValues(Size);
TempFile f("mytext.dat");
{
wxFileOutputStream FileOutput( f.GetName() );
wxDataOutputStream DataOutput( FileOutput );
(DataOutput.*pfnWriter)(Values, Size);
}
{
wxFileInputStream FileInput( f.GetName() );
wxDataInputStream DataInput( FileInput );
(DataInput.*pfnReader)(&*InValues.begin(), InValues.size());
}
m_ok = true;
for (typename ValueArray::size_type idx=0; idx!=Size; ++idx) {
if (InValues[idx]!=Values[idx]) {
m_ok = false;
break;
}
}
}
public:
TestMultiRW(const T *Values,
size_t Size,
FnWriter pfnWriter,
FnReader pfnReader)
{
ProcessData(Values, (typename ValueArray::size_type) Size, pfnWriter, pfnReader);
}
TestMultiRW(const ValueArray &Values,
FnWriter pfnWriter,
FnReader pfnReader)
{
ProcessData(&*Values.begin(), Values.size(), pfnWriter, pfnReader);
}
bool IsOk() const
{
return m_ok;
}
};
template <class T>
static
T TestRW(const T &Value)
{
T InValue;
TempFile f("mytext.dat");
{
wxFileOutputStream FileOutput( f.GetName() );
wxDataOutputStream DataOutput( FileOutput );
DataOutput << Value;
}
{
wxFileInputStream FileInput( f.GetName() );
wxDataInputStream DataInput( FileInput );
DataInput >> InValue;
}
return InValue;
}
void DataStreamTestCase::FloatRW()
{
CPPUNIT_ASSERT( TestFloatRW(5.5) == 5.5 );
CPPUNIT_ASSERT( TestFloatRW(5) == 5 );
CPPUNIT_ASSERT( TestFloatRW(5.55) == 5.55 );
CPPUNIT_ASSERT( TestFloatRW(55555.555555) == 55555.555555 );
}
void DataStreamTestCase::DoubleRW()
{
CPPUNIT_ASSERT( TestFloatRW(2132131.1232132) == 2132131.1232132 );
CPPUNIT_ASSERT( TestFloatRW(21321343431.1232143432) == 21321343431.1232143432 );
}
void DataStreamTestCase::StringRW()
{
wxString s(wxT("Test1"));
CPPUNIT_ASSERT_EQUAL( TestRW(s), s );
s.append(2, wxT('\0'));
s.append(wxT("Test2"));
CPPUNIT_ASSERT_EQUAL( TestRW(s), s );
s = wxString::FromUTF8("ü");
CPPUNIT_ASSERT_EQUAL( TestRW(s), s );
}
void DataStreamTestCase::LongLongRW()
{
TestMultiRW<wxLongLong>::ValueArray ValuesLL;
TestMultiRW<wxULongLong>::ValueArray ValuesULL;
ValuesLL.push_back(wxLongLong(0l));
ValuesLL.push_back(wxLongLong(1l));
ValuesLL.push_back(wxLongLong(-1l));
ValuesLL.push_back(wxLongLong(0x12345678l));
ValuesLL.push_back(wxLongLong(0x12345678l, 0xabcdef01l));
ValuesULL.push_back(wxULongLong(0l));
ValuesULL.push_back(wxULongLong(1l));
ValuesULL.push_back(wxULongLong(0x12345678l));
ValuesULL.push_back(wxULongLong(0x12345678l, 0xabcdef01l));
CPPUNIT_ASSERT( TestRW(wxLongLong(0x12345678l)) == wxLongLong(0x12345678l) );
CPPUNIT_ASSERT( TestRW(wxLongLong(0x12345678l, 0xabcdef01l)) == wxLongLong(0x12345678l, 0xabcdef01l) );
CPPUNIT_ASSERT( TestMultiRW<wxLongLong>(ValuesLL, &wxDataOutputStream::WriteLL, &wxDataInputStream::ReadLL).IsOk() );
CPPUNIT_ASSERT( TestMultiRW<wxULongLong>(ValuesULL, &wxDataOutputStream::WriteLL, &wxDataInputStream::ReadLL).IsOk() );
}
void DataStreamTestCase::Int64RW()
{
TestMultiRW<wxInt64>::ValueArray ValuesI64;
TestMultiRW<wxUint64>::ValueArray ValuesUI64;
ValuesI64.push_back(wxInt64(0l));
ValuesI64.push_back(wxInt64(1l));
ValuesI64.push_back(wxInt64(-1l));
ValuesI64.push_back(wxInt64(0x12345678l));
ValuesI64.push_back((wxInt64(0x12345678l) << 32) + wxInt64(0xabcdef01l));
ValuesUI64.push_back(wxUint64(0l));
ValuesUI64.push_back(wxUint64(1l));
ValuesUI64.push_back(wxUint64(0x12345678l));
ValuesUI64.push_back((wxUint64(0x12345678l) << 32) + wxUint64(0xabcdef01l));
CPPUNIT_ASSERT( TestRW(wxUint64(0x12345678l)) == wxUint64(0x12345678l) );
CPPUNIT_ASSERT( TestRW((wxUint64(0x12345678l) << 32) + wxUint64(0xabcdef01l)) == (wxUint64(0x12345678l) << 32) + wxUint64(0xabcdef01l) );
CPPUNIT_ASSERT( TestMultiRW<wxInt64>(ValuesI64, &wxDataOutputStream::Write64, &wxDataInputStream::Read64).IsOk() );
CPPUNIT_ASSERT( TestMultiRW<wxUint64>(ValuesUI64, &wxDataOutputStream::Write64, &wxDataInputStream::Read64).IsOk() );
}
void DataStreamTestCase::NaNRW()
{
//TODO?
}

View File

@@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/ffilestream.cpp
// Purpose: Test wxFFileInputStream/wxFFileOutputStream
// Author: Hans Van Leemputten
// Copyright: (c) 2004 Hans Van Leemputten
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/wfstream.h"
#include "bstream.h"
#define DATABUFFER_SIZE 1024
static const wxString FILENAME_FFILEINSTREAM = wxT("ffileinstream.test");
static const wxString FILENAME_FFILEOUTSTREAM = wxT("ffileoutstream.test");
///////////////////////////////////////////////////////////////////////////////
// The test case
//
// Try to fully test wxFFileInputStream and wxFFileOutputStream
class ffileStream : public BaseStreamTestCase<wxFFileInputStream, wxFFileOutputStream>
{
public:
ffileStream();
CPPUNIT_TEST_SUITE(ffileStream);
// Base class stream tests the ffileStream supports.
CPPUNIT_TEST(Input_GetSize);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekI);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
CPPUNIT_TEST(Output_SeekO);
CPPUNIT_TEST(Output_TellO);
// Other test specific for File stream test case.
CPPUNIT_TEST_SUITE_END();
protected:
// Add own test here.
private:
// Implement base class functions.
virtual wxFFileInputStream *DoCreateInStream() override;
virtual wxFFileOutputStream *DoCreateOutStream() override;
virtual void DoDeleteOutStream() override;
private:
wxString GetInFileName() const;
};
ffileStream::ffileStream()
{
m_bSeekInvalidBeyondEnd = false;
m_bEofAtLastRead = false;
}
wxFFileInputStream *ffileStream::DoCreateInStream()
{
wxFFileInputStream *pFileInStream = new wxFFileInputStream(GetInFileName());
CPPUNIT_ASSERT(pFileInStream->IsOk());
return pFileInStream;
}
wxFFileOutputStream *ffileStream::DoCreateOutStream()
{
wxFFileOutputStream *pFileOutStream = new wxFFileOutputStream(FILENAME_FFILEOUTSTREAM);
CPPUNIT_ASSERT(pFileOutStream->IsOk());
return pFileOutStream;
}
void ffileStream::DoDeleteOutStream()
{
::wxRemoveFile(FILENAME_FFILEOUTSTREAM);
}
wxString ffileStream::GetInFileName() const
{
class AutoRemoveFile
{
public:
AutoRemoveFile()
{
m_created = false;
}
~AutoRemoveFile()
{
if ( m_created )
wxRemoveFile(FILENAME_FFILEINSTREAM);
}
bool ShouldCreate()
{
if ( m_created )
return false;
m_created = true;
return true;
}
private:
bool m_created;
};
static AutoRemoveFile autoFile;
if ( autoFile.ShouldCreate() )
{
// Make sure we have a input file...
char buf[DATABUFFER_SIZE];
wxFFileOutputStream out(FILENAME_FFILEINSTREAM);
// Init the data buffer.
for (size_t i = 0; i < DATABUFFER_SIZE; i++)
buf[i] = (i % 0xFF);
// Save the data
out.Write(buf, DATABUFFER_SIZE);
}
return FILENAME_FFILEINSTREAM;
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(ffileStream)

View File

@@ -0,0 +1,193 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/backfile.cpp
// Purpose: Test wxBackingFile
// Author: Mike Wetherell
// Copyright: (c) 2006 Mike Wetherell
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/mstream.h"
#include "wx/private/fileback.h"
#include "bstream.h"
const size_t TESTSIZE = 256;
const size_t BUFSIZE = 100;
///////////////////////////////////////////////////////////////////////////////
// Parent stream for testing
class TestStream : public wxMemoryInputStream
{
public:
TestStream(const void *buf, size_t size)
: wxMemoryInputStream(buf, size) { }
wxFileOffset GetLength() const override { return wxInvalidOffset; }
};
///////////////////////////////////////////////////////////////////////////////
// The test case
class backStream : public CppUnit::TestCase
{
public:
backStream();
CPPUNIT_TEST_SUITE(backStream);
CPPUNIT_TEST(ReadLenSeek);
CPPUNIT_TEST(LenSeekRead);
CPPUNIT_TEST(SeekReadLen);
CPPUNIT_TEST(ReadAll);
CPPUNIT_TEST(ReadTooMuch);
CPPUNIT_TEST(EmptyStream);
CPPUNIT_TEST_SUITE_END();
void ReadLenSeek();
void LenSeekRead();
void SeekReadLen();
void ReadAll();
void ReadTooMuch();
void EmptyStream();
private:
void Read(wxInputStream& in, size_t size1, size_t size2, size_t size3);
void Len(wxBackedInputStream& in);
void Seek(wxInputStream& in);
char m_testdata[TESTSIZE];
};
backStream::backStream()
{
for (unsigned i = 0; i < TESTSIZE; i++)
m_testdata[i] = i;
}
void backStream::ReadLenSeek()
{
wxBackingFile bf(new TestStream(m_testdata, TESTSIZE), BUFSIZE);
wxBackedInputStream in(bf);
Read(in, BUFSIZE, BUFSIZE / 2, 2 * BUFSIZE / 3);
Len(in);
Seek(in);
}
void backStream::LenSeekRead()
{
wxBackingFile bf(new TestStream(m_testdata, TESTSIZE), BUFSIZE);
wxBackedInputStream in(bf);
Len(in);
Seek(in);
Read(in, BUFSIZE, BUFSIZE / 2, 2 * BUFSIZE / 3);
}
void backStream::SeekReadLen()
{
wxBackingFile bf(new TestStream(m_testdata, TESTSIZE), BUFSIZE);
wxBackedInputStream in(bf);
Seek(in);
Read(in, BUFSIZE, BUFSIZE / 2, 2 * BUFSIZE / 3);
Len(in);
}
void backStream::ReadAll()
{
wxBackingFile bf(new TestStream(m_testdata, TESTSIZE), BUFSIZE);
wxBackedInputStream in(bf);
Read(in, TESTSIZE, 0, 0);
}
void backStream::ReadTooMuch()
{
wxBackingFile bf(new TestStream(m_testdata, TESTSIZE), BUFSIZE);
wxBackedInputStream in(bf);
char buf[TESTSIZE * 2];
CPPUNIT_ASSERT_EQUAL(TESTSIZE, in.Read(buf, TESTSIZE * 2).LastRead());
CPPUNIT_ASSERT(in.Eof());
CPPUNIT_ASSERT(memcmp(buf, m_testdata, TESTSIZE) == 0);
}
void backStream::EmptyStream()
{
wxBackingFile bf(new TestStream(m_testdata, 0), BUFSIZE);
wxBackedInputStream in(bf);
char buf[1];
CPPUNIT_ASSERT_EQUAL(size_t(0), in.Read(buf, 1).LastRead());
CPPUNIT_ASSERT(in.Eof());
}
void backStream::Read(wxInputStream& in,
size_t size1,
size_t size2,
size_t size3)
{
const size_t remainder = TESTSIZE - size1 - size2 - size3;
char buf[TESTSIZE];
char *testdata = m_testdata;
in.SeekI(0);
CPPUNIT_ASSERT_EQUAL(size1, in.Read(buf, size1).LastRead());
CPPUNIT_ASSERT(in.IsOk());
CPPUNIT_ASSERT(memcmp(buf, testdata, size1) == 0);
testdata += size1;
CPPUNIT_ASSERT_EQUAL(size2, in.Read(buf, size2).LastRead());
CPPUNIT_ASSERT(in.IsOk());
CPPUNIT_ASSERT(memcmp(buf, testdata, size2) == 0);
testdata += size2;
CPPUNIT_ASSERT_EQUAL(size3, in.Read(buf, size3).LastRead());
CPPUNIT_ASSERT(in.IsOk());
CPPUNIT_ASSERT(memcmp(buf, testdata, size3) == 0);
testdata += size3;
CPPUNIT_ASSERT_EQUAL(remainder, in.Read(buf, TESTSIZE).LastRead());
CPPUNIT_ASSERT(in.Eof());
CPPUNIT_ASSERT(memcmp(buf, testdata, remainder) == 0);
CPPUNIT_ASSERT_EQUAL(size_t(0), in.Read(buf, TESTSIZE).LastRead());
CPPUNIT_ASSERT(in.Eof());
}
void backStream::Len(wxBackedInputStream& in)
{
CPPUNIT_ASSERT_EQUAL(wxFileOffset(TESTSIZE), in.FindLength());
}
void backStream::Seek(wxInputStream& in)
{
CPPUNIT_ASSERT_EQUAL(wxFileOffset(TESTSIZE), in.SeekI(TESTSIZE));
in.GetC();
CPPUNIT_ASSERT_EQUAL(size_t(0), in.LastRead());
CPPUNIT_ASSERT(in.Eof());
for (wxFileOffset i = TESTSIZE - 1; i >= 0; i--) {
CPPUNIT_ASSERT_EQUAL(i, in.SeekI(i));
CPPUNIT_ASSERT_EQUAL(i, in.TellI());
CPPUNIT_ASSERT_EQUAL(int(i), in.GetC());
CPPUNIT_ASSERT_EQUAL(size_t(1), in.LastRead());
CPPUNIT_ASSERT(in.IsOk());
}
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(backStream)

View File

@@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/filestream.cpp
// Purpose: Test wxFileInputStream/wxFileOutputStream
// Author: Hans Van Leemputten
// Copyright: (c) 2004 Hans Van Leemputten
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/wfstream.h"
#include "bstream.h"
#define DATABUFFER_SIZE 1024
static const wxString FILENAME_FILEINSTREAM = wxT("fileinstream.test");
static const wxString FILENAME_FILEOUTSTREAM = wxT("fileoutstream.test");
///////////////////////////////////////////////////////////////////////////////
// The test case
//
// Try to fully test wxFileInputStream and wxFileOutputStream
class fileStream : public BaseStreamTestCase<wxFileInputStream, wxFileOutputStream>
{
public:
fileStream();
CPPUNIT_TEST_SUITE(fileStream);
// Base class stream tests the fileStream supports.
CPPUNIT_TEST(Input_GetSize);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekI);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
CPPUNIT_TEST(Output_SeekO);
CPPUNIT_TEST(Output_TellO);
// Other test specific for File stream test case.
CPPUNIT_TEST_SUITE_END();
protected:
// Add own test here.
private:
// Implement base class functions.
virtual wxFileInputStream *DoCreateInStream() override;
virtual wxFileOutputStream *DoCreateOutStream() override;
virtual void DoDeleteOutStream() override;
private:
wxString GetInFileName() const;
};
fileStream::fileStream()
{
m_bSeekInvalidBeyondEnd = false;
}
wxFileInputStream *fileStream::DoCreateInStream()
{
wxFileInputStream *pFileInStream = new wxFileInputStream(GetInFileName());
CPPUNIT_ASSERT(pFileInStream->IsOk());
return pFileInStream;
}
wxFileOutputStream *fileStream::DoCreateOutStream()
{
wxFileOutputStream *pFileOutStream = new wxFileOutputStream(FILENAME_FILEOUTSTREAM);
CPPUNIT_ASSERT(pFileOutStream->IsOk());
return pFileOutStream;
}
void fileStream::DoDeleteOutStream()
{
::wxRemoveFile(FILENAME_FILEOUTSTREAM);
}
wxString fileStream::GetInFileName() const
{
class AutoRemoveFile
{
public:
AutoRemoveFile()
{
m_created = false;
}
~AutoRemoveFile()
{
if ( m_created )
wxRemoveFile(FILENAME_FILEINSTREAM);
}
bool ShouldCreate()
{
if ( m_created )
return false;
m_created = true;
return true;
}
private:
bool m_created;
};
static AutoRemoveFile autoFile;
if ( autoFile.ShouldCreate() )
{
// Make sure we have a input file...
char buf[DATABUFFER_SIZE];
wxFileOutputStream out(FILENAME_FILEINSTREAM);
// Init the data buffer.
for (size_t i = 0; i < DATABUFFER_SIZE; i++)
buf[i] = (i % 0xFF);
// Save the data
out.Write(buf, DATABUFFER_SIZE);
}
return FILENAME_FILEINSTREAM;
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(fileStream)

View File

@@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/iostreams.cpp
// Purpose: unit test for input/output streams
// Author: Vadim Zeitlin
// Created: 2008-06-15
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#if wxUSE_STREAMS
#include "wx/filename.h"
#include "wx/wfstream.h"
// --------------------------------------------------------------------------
// test class
// --------------------------------------------------------------------------
class IOStreamsTestCase : public CppUnit::TestCase
{
public:
IOStreamsTestCase() { }
virtual void tearDown() override
{
if ( !m_fnTemp.empty() )
{
wxRemoveFile(m_fnTemp);
m_fnTemp.clear();
}
}
private:
CPPUNIT_TEST_SUITE( IOStreamsTestCase );
CPPUNIT_TEST( FStream );
CPPUNIT_TEST( FFStream );
CPPUNIT_TEST_SUITE_END();
void FStream() { wxFileStream s(GetTempFName()); DoTest(s); }
void FFStream() { wxFFileStream s(GetTempFName()); DoTest(s); }
wxString GetTempFName()
{
m_fnTemp = wxFileName::CreateTempFileName("wxtest");
return m_fnTemp;
}
template <class Stream>
void DoTest(Stream& s)
{
s.PutC('x');
CPPUNIT_ASSERT_EQUAL( 1, s.LastWrite() );
s.SeekI(0);
CPPUNIT_ASSERT_EQUAL( int('x'), s.GetC() );
}
wxString m_fnTemp;
wxDECLARE_NO_COPY_CLASS(IOStreamsTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( IOStreamsTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IOStreamsTestCase, "IOStreamsTestCase" );
#endif // wxUSE_STREAMS

View File

@@ -0,0 +1,437 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/largefile.cpp
// Purpose: Tests for large file support
// Author: Mike Wetherell
// Copyright: (c) 2004 Mike Wetherell
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
//
// We're interested in what happens around offsets 0x7fffffff and 0xffffffff
// so the test writes a small chunk of test data just before and just after
// these offsets, then reads them back.
//
// The tests can be run with:
//
// test --verbose largeFile
//
// On systems supporting sparse files they will also be registered in the
// Streams subsuite so that they run by default.
//
// For compilers that support precompilation, includes "wx/wx.h".
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/filename.h"
#include "wx/wfstream.h"
#include <memory>
#ifdef __WINDOWS__
#include "wx/msw/wrapwin.h"
#ifdef __VISUALC__
// 'nonstandard extension used : nameless struct/union' occurs inside
// winioctl.h
#pragma warning(disable:4201)
#endif
#include <winioctl.h>
#ifdef __VISUALC__
#pragma warning(default:4201)
#endif
#endif
#ifdef __VISUALC__
#define fileno _fileno
#endif
///////////////////////////////////////////////////////////////////////////////
// Helpers
bool IsFAT(const wxString& path);
void MakeSparse(const wxString& path, int fd);
///////////////////////////////////////////////////////////////////////////////
// Base class for the test cases - common code
class LargeFileTest : public CppUnit::TestCase
{
public:
LargeFileTest(std::string name) : CppUnit::TestCase(name) { }
virtual ~LargeFileTest() { }
protected:
void runTest() override;
virtual wxInputStream *MakeInStream(const wxString& name) const = 0;
virtual wxOutputStream *MakeOutStream(const wxString& name) const = 0;
virtual bool HasLFS() const = 0;
};
void LargeFileTest::runTest()
{
// self deleting temp file
struct TmpFile {
TmpFile() : m_name(wxFileName::CreateTempFileName(wxT("wxlfs-"))) { }
~TmpFile() { if (!m_name.empty()) wxRemoveFile(m_name); }
wxString m_name;
} tmpfile;
CPPUNIT_ASSERT(!tmpfile.m_name.empty());
bool haveLFS = true;
bool fourGigLimit = false;
if (!HasLFS()) {
haveLFS = false;
wxString n(getName().c_str(), *wxConvCurrent);
wxLogInfo(n + wxT(": No large file support, testing up to 2GB only"));
}
else if (IsFAT(tmpfile.m_name)) {
fourGigLimit = true;
wxString n(getName().c_str(), *wxConvCurrent);
wxLogInfo(n + wxT(": FAT volumes are limited to 4GB files"));
}
// size of the test blocks
const size_t size = 0x40;
// the test blocks
char upto2Gig[size];
char past2Gig[size];
char upto4Gig[size];
char past4Gig[size];
memset(upto2Gig, 'A', size);
memset(past2Gig, 'B', size);
memset(upto4Gig, 'X', size);
memset(past4Gig, 'Y', size);
wxFileOffset pos;
// write a large file
{
std::unique_ptr<wxOutputStream> out(MakeOutStream(tmpfile.m_name));
// write 'A's at [ 0x7fffffbf, 0x7fffffff [
pos = 0x7fffffff - size;
CPPUNIT_ASSERT(out->SeekO(pos) == pos);
CPPUNIT_ASSERT(out->Write(upto2Gig, size).LastWrite() == size);
pos += size;
if (haveLFS) {
// write 'B's at [ 0x7fffffff, 0x8000003f [
CPPUNIT_ASSERT(out->Write(past2Gig, size).LastWrite() == size);
pos += size;
CPPUNIT_ASSERT(out->TellO() == pos);
// write 'X's at [ 0xffffffbf, 0xffffffff [
pos = 0xffffffff - size;
CPPUNIT_ASSERT(out->SeekO(pos) == pos);
CPPUNIT_ASSERT(out->Write(upto4Gig, size).LastWrite() == size);
pos += size;
if (!fourGigLimit) {
// write 'Y's at [ 0xffffffff, 0x10000003f [
CPPUNIT_ASSERT(out->Write(past4Gig, size).LastWrite() == size);
pos += size;
}
}
// check the file seems to be the right length
CPPUNIT_ASSERT(out->TellO() == pos);
CPPUNIT_ASSERT(out->GetLength() == pos);
}
// read the large file back
{
std::unique_ptr<wxInputStream> in(MakeInStream(tmpfile.m_name));
char buf[size];
if (haveLFS) {
CPPUNIT_ASSERT(in->GetLength() == pos);
pos = 0xffffffff;
if (!fourGigLimit) {
CPPUNIT_ASSERT(in->GetLength() > pos);
// read back the 'Y's at [ 0xffffffff, 0x10000003f [
CPPUNIT_ASSERT(in->SeekI(pos) == pos);
CPPUNIT_ASSERT(in->Read(buf, size).LastRead() == size);
CPPUNIT_ASSERT(memcmp(buf, past4Gig, size) == 0);
CPPUNIT_ASSERT(in->TellI() == in->GetLength());
}
// read back the 'X's at [ 0xffffffbf, 0xffffffff [
pos -= size;
CPPUNIT_ASSERT(in->SeekI(pos) == pos);
CPPUNIT_ASSERT(in->Read(buf, size).LastRead() == size);
CPPUNIT_ASSERT(memcmp(buf, upto4Gig, size) == 0);
pos += size;
CPPUNIT_ASSERT(in->TellI() == pos);
// read back the 'B's at [ 0x7fffffff, 0x8000003f [
pos = 0x7fffffff;
CPPUNIT_ASSERT(in->SeekI(pos) == pos);
CPPUNIT_ASSERT(in->Read(buf, size).LastRead() == size);
CPPUNIT_ASSERT(memcmp(buf, past2Gig, size) == 0);
}
else {
CPPUNIT_ASSERT(in->GetLength() == 0x7fffffff);
pos = 0x7fffffff;
}
// read back the 'A's at [ 0x7fffffbf, 0x7fffffff [
pos -= size;
CPPUNIT_ASSERT(in->SeekI(pos) == pos);
CPPUNIT_ASSERT(in->Read(buf, size).LastRead() == size);
CPPUNIT_ASSERT(memcmp(buf, upto2Gig, size) == 0);
pos += size;
CPPUNIT_ASSERT(in->TellI() == pos);
}
}
///////////////////////////////////////////////////////////////////////////////
// wxFile test case
class LargeFileTest_wxFile : public LargeFileTest
{
public:
LargeFileTest_wxFile() : LargeFileTest("wxFile streams") { }
protected:
wxInputStream *MakeInStream(const wxString& name) const override;
wxOutputStream *MakeOutStream(const wxString& name) const override;
bool HasLFS() const override { return (wxFileOffset)0xffffffff > 0; }
};
wxInputStream *LargeFileTest_wxFile::MakeInStream(const wxString& name) const
{
std::unique_ptr<wxFileInputStream> in(new wxFileInputStream(name));
CPPUNIT_ASSERT(in->IsOk());
return in.release();
}
wxOutputStream *LargeFileTest_wxFile::MakeOutStream(const wxString& name) const
{
wxFile file(name, wxFile::write);
CPPUNIT_ASSERT(file.IsOpened());
int fd = file.fd();
file.Detach();
MakeSparse(name, fd);
return new wxFileOutputStream(fd);
}
///////////////////////////////////////////////////////////////////////////////
// wxFFile test case
class LargeFileTest_wxFFile : public LargeFileTest
{
public:
LargeFileTest_wxFFile() : LargeFileTest("wxFFile streams") { }
protected:
wxInputStream *MakeInStream(const wxString& name) const override;
wxOutputStream *MakeOutStream(const wxString& name) const override;
bool HasLFS() const override;
};
wxInputStream *LargeFileTest_wxFFile::MakeInStream(const wxString& name) const
{
std::unique_ptr<wxFFileInputStream> in(new wxFFileInputStream(name));
CPPUNIT_ASSERT(in->IsOk());
return in.release();
}
wxOutputStream *LargeFileTest_wxFFile::MakeOutStream(const wxString& name) const
{
wxFFile file(name, wxT("w"));
CPPUNIT_ASSERT(file.IsOpened());
FILE *fp = file.fp();
file.Detach();
MakeSparse(name, fileno(fp));
return new wxFFileOutputStream(fp);
}
bool LargeFileTest_wxFFile::HasLFS() const
{
#ifdef wxHAS_LARGE_FFILES
return true;
#else
return false;
#endif
}
///////////////////////////////////////////////////////////////////////////////
// The suite
class largeFile : public CppUnit::TestSuite
{
public:
largeFile() : CppUnit::TestSuite("largeFile") { }
static CppUnit::Test *suite();
};
CppUnit::Test *largeFile::suite()
{
largeFile *suite = new largeFile;
suite->addTest(new LargeFileTest_wxFile);
suite->addTest(new LargeFileTest_wxFFile);
return suite;
}
///////////////////////////////////////////////////////////////////////////////
// Implement the helpers
//
// Ideally these tests will be part of the default suite so that regressions
// are picked up. However this is only possible when sparse files are
// supported otherwise the tests require too much disk space.
#ifdef __WINDOWS__
#ifndef FILE_SUPPORTS_SPARSE_FILES
#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
#endif
#ifndef FSCTL_SET_SPARSE
# ifndef FILE_SPECIAL_ACCESS
# define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS
# endif
# define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, \
METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#endif
static DWORD volumeFlags;
static wxChar volumeType[64];
static bool volumeInfoInit;
void GetVolumeInfo(const wxString& path)
{
// extract the volume 'C:\' or '\\tooter\share\' from the path
wxString vol;
if (path.substr(1, 2) == wxT(":\\")) {
vol = path.substr(0, 3);
} else {
if (path.substr(0, 2) == wxT("\\\\")) {
size_t i = path.find(wxT('\\'), 2);
if (i != wxString::npos && i > 2) {
size_t j = path.find(wxT('\\'), ++i);
if (j != i)
vol = path.substr(0, j) + wxT("\\");
}
}
}
// nullptr means the current volume
const wxChar *pVol = vol.empty() ? (const wxChar *)nullptr
: vol.c_str();
if (!::GetVolumeInformation(pVol, nullptr, 0, nullptr, nullptr,
&volumeFlags,
volumeType,
WXSIZEOF(volumeType)))
{
wxLogSysError(wxT("GetVolumeInformation() failed"));
}
volumeInfoInit = true;
}
bool IsFAT(const wxString& path)
{
if (!volumeInfoInit)
GetVolumeInfo(path);
return wxString(volumeType).Upper().find(wxT("FAT")) != wxString::npos;
}
void MakeSparse(const wxString& path, int fd)
{
DWORD cb;
if (!volumeInfoInit)
GetVolumeInfo(path);
if ((volumeFlags & FILE_SUPPORTS_SPARSE_FILES) != 0)
if (!::DeviceIoControl((HANDLE)_get_osfhandle(fd),
FSCTL_SET_SPARSE,
nullptr, 0, nullptr, 0, &cb, nullptr))
volumeFlags &= ~FILE_SUPPORTS_SPARSE_FILES;
}
// return the suite if sparse files are supported, otherwise return nullptr
//
CppUnit::Test* GetlargeFileSuite()
{
if (!volumeInfoInit) {
wxString path;
{
wxFile file;
path = wxFileName::CreateTempFileName(wxT("wxlfs-"), &file);
MakeSparse(path, file.fd());
}
wxRemoveFile(path);
}
if ((volumeFlags & FILE_SUPPORTS_SPARSE_FILES) != 0)
return largeFile::suite();
else
return nullptr;
}
#else // __WINDOWS__
bool IsFAT(const wxString& WXUNUSED(path)) { return false; }
void MakeSparse(const wxString& WXUNUSED(path), int WXUNUSED(fd)) { }
// return the suite if sparse files are supported, otherwise return nullptr
//
CppUnit::Test* GetlargeFileSuite()
{
wxString path;
struct stat st1, st2;
memset(&st1, 0, sizeof(st1));
memset(&st2, 0, sizeof(st2));
{
wxFile file;
path = wxFileName::CreateTempFileName(wxT("wxlfs-"), &file);
fstat(file.fd(), &st1);
file.Seek(st1.st_blksize);
file.Write("x", 1);
fstat(file.fd(), &st1);
file.Seek(0);
file.Write("x", 1);
fstat(file.fd(), &st2);
}
wxRemoveFile(path);
if (st1.st_blocks != st2.st_blocks)
return largeFile::suite();
else
return nullptr;
}
#endif // __WINDOWS__
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(largeFile, "Streams.largeFile");

View File

@@ -0,0 +1,87 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/lzmastream.cpp
// Purpose: Unit tests for LZMA stream classes
// Author: Vadim Zeitlin
// Created: 2018-03-30
// Copyright: (c) 2018 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "testprec.h"
#if wxUSE_LIBLZMA && wxUSE_STREAMS
#include "wx/mstream.h"
#include "wx/lzmastream.h"
#include "bstream.h"
class LZMAStream : public BaseStreamTestCase<wxLZMAInputStream, wxLZMAOutputStream>
{
public:
LZMAStream();
CPPUNIT_TEST_SUITE(zlibStream);
// Base class stream tests.
CPPUNIT_TEST(Input_GetSizeFail);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekIFail);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
CPPUNIT_TEST(Output_SeekOFail);
CPPUNIT_TEST(Output_TellO);
CPPUNIT_TEST_SUITE_END();
protected:
wxLZMAInputStream *DoCreateInStream() override;
wxLZMAOutputStream *DoCreateOutStream() override;
private:
wxDECLARE_NO_COPY_CLASS(LZMAStream);
};
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(LZMAStream)
LZMAStream::LZMAStream()
{
// Disable TellI() and TellO() tests in the base class which don't work
// with the compressed streams.
m_bSimpleTellITest =
m_bSimpleTellOTest = true;
}
wxLZMAInputStream *LZMAStream::DoCreateInStream()
{
// Compress some data.
const char data[] = "This is just some test data for LZMA streams unit test";
const size_t len = sizeof(data);
wxMemoryOutputStream outmem;
wxLZMAOutputStream outz(outmem);
outz.Write(data, len);
REQUIRE( outz.LastWrite() == len );
REQUIRE( outz.Close() );
wxMemoryInputStream* const inmem = new wxMemoryInputStream(outmem);
REQUIRE( inmem->IsOk() );
// Give ownership of the memory input stream to the LZMA stream.
return new wxLZMAInputStream(inmem);
}
wxLZMAOutputStream *LZMAStream::DoCreateOutStream()
{
return new wxLZMAOutputStream(new wxMemoryOutputStream());
}
#endif // wxUSE_LIBLZMA && wxUSE_STREAMS

View File

@@ -0,0 +1,158 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/memstream.cpp
// Purpose: Test wxMemoryInputStream/wxMemoryOutputStream
// Author: Hans Van Leemputten
// Copyright: (c) 2004 Hans Van Leemputten
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/mstream.h"
#include "bstream.h"
#define DATABUFFER_SIZE 256
///////////////////////////////////////////////////////////////////////////////
// The test case
//
// Try to fully test wxMemoryInputStream and wxMemoryOutputStream
class memStream : public BaseStreamTestCase<wxMemoryInputStream, wxMemoryOutputStream>
{
public:
memStream();
virtual ~memStream();
CPPUNIT_TEST_SUITE(memStream);
// Base class stream tests the memStream supports.
CPPUNIT_TEST(Input_GetSize);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekI);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
CPPUNIT_TEST(Output_SeekO);
CPPUNIT_TEST(Output_TellO);
// Other test specific for Memory stream test case.
CPPUNIT_TEST(Ctor_InFromIn);
CPPUNIT_TEST(Ctor_InFromOut);
CPPUNIT_TEST_SUITE_END();
protected:
// Add own test here.
void Ctor_InFromIn();
void Ctor_InFromOut();
private:
const char *GetDataBuffer();
private:
// Implement base class functions.
virtual wxMemoryInputStream *DoCreateInStream() override;
virtual wxMemoryOutputStream *DoCreateOutStream() override;
private:
char m_DataBuffer[DATABUFFER_SIZE];
};
memStream::memStream()
{
// Init the data buffer.
for (size_t i = 0; i < DATABUFFER_SIZE; i++)
m_DataBuffer[i] = (i % 0xFF);
}
memStream::~memStream()
{
/* Nothing extra for now. */
}
const char *memStream::GetDataBuffer()
{
return m_DataBuffer;
}
wxMemoryInputStream *memStream::DoCreateInStream()
{
wxMemoryInputStream *pMemInStream = new wxMemoryInputStream(GetDataBuffer(), DATABUFFER_SIZE);
CPPUNIT_ASSERT(pMemInStream->IsOk());
return pMemInStream;
}
wxMemoryOutputStream *memStream::DoCreateOutStream()
{
wxMemoryOutputStream *pMemOutStream = new wxMemoryOutputStream();
CPPUNIT_ASSERT(pMemOutStream->IsOk());
return pMemOutStream;
}
void memStream::Ctor_InFromIn()
{
wxMemoryInputStream *pMemInStream1 = DoCreateInStream();
wxMemoryInputStream *pMemInStream2 = new wxMemoryInputStream(*pMemInStream1);
CPPUNIT_ASSERT(pMemInStream2->IsOk());
CPPUNIT_ASSERT_EQUAL(pMemInStream1->GetLength(), pMemInStream2->GetLength());
wxFileOffset len = pMemInStream2->GetLength();
char *dat = new char[len];
pMemInStream2->Read(dat, len);
CPPUNIT_ASSERT_EQUAL(len, (wxFileOffset)pMemInStream2->LastRead());
wxStreamBuffer *buf = pMemInStream1->GetInputStreamBuffer();
void *pIn = buf->GetBufferStart();
CPPUNIT_ASSERT(memcmp(pIn, dat, len) == 0);
delete pMemInStream2;
wxFileOffset len2 = len / 2;
CPPUNIT_ASSERT(len2);
CPPUNIT_ASSERT(pMemInStream1->SeekI(-len2, wxFromCurrent) != wxInvalidOffset);
pIn = buf->GetBufferPos();
pMemInStream2 = new wxMemoryInputStream(*pMemInStream1, len2);
CPPUNIT_ASSERT(pMemInStream2->IsOk());
CPPUNIT_ASSERT_EQUAL((wxFileOffset)len2, pMemInStream2->GetLength());
pMemInStream2->Read(dat, len2);
CPPUNIT_ASSERT_EQUAL(len2, (wxFileOffset)pMemInStream2->LastRead());
CPPUNIT_ASSERT(memcmp(pIn, dat, len2) == 0);
delete[] dat;
delete pMemInStream2;
delete pMemInStream1;
}
void memStream::Ctor_InFromOut()
{
wxMemoryOutputStream *pMemOutStream = DoCreateOutStream();
pMemOutStream->Write(GetDataBuffer(), DATABUFFER_SIZE);
wxMemoryInputStream *pMemInStream = new wxMemoryInputStream(*pMemOutStream);
CPPUNIT_ASSERT(pMemInStream->IsOk());
CPPUNIT_ASSERT_EQUAL(pMemInStream->GetLength(), pMemOutStream->GetLength());
size_t len = pMemInStream->GetLength();
wxStreamBuffer *in = pMemInStream->GetInputStreamBuffer();
wxStreamBuffer *out = pMemOutStream->GetOutputStreamBuffer();
void *pIn = in->GetBufferStart();
void *pOut = out->GetBufferStart();
CPPUNIT_ASSERT(pIn != pOut);
CPPUNIT_ASSERT(memcmp(pIn, pOut, len) == 0);
delete pMemInStream;
delete pMemOutStream;
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(memStream)

View File

@@ -0,0 +1,245 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/socketstream.cpp
// Purpose: Test wxSocketInputStream/wxSocketOutputStream
// Author: Vadim Zeitlin
// Copyright: (c) 2008 Vadim Zeitlin
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/log.h"
#endif
#include "wx/socket.h"
#include "wx/sckstrm.h"
#include "wx/thread.h"
#include "bstream.h"
namespace
{
const int TEST_PORT_READ = 0x7778; // arbitrary, chosen because == "wx"
const int TEST_PORT_WRITE = 0x7779; // well, "wy"
// these cond and mutex are used to minimize the risk of the main thread
// Connect()-ing before this thread starts Accept()-ing connections but
// unfortunately we can't make this truly safe, see comment in
// SocketServerThread::Entry()
wxMutex gs_mutex;
wxCondition gs_cond(gs_mutex);
} // anonymous namespace
// return address for the given port on local host
static inline wxIPV4address LocalAddress(int port)
{
wxIPV4address addr;
addr.LocalHost();
addr.Service(port);
return addr;
}
// A thread which creates a listening socket on the specified port and executes
// the given function with each socket which connects to it
class SocketServerThread : public wxThread
{
public:
// port is the port to listen on and function will be called on each
// accepted socket
SocketServerThread(int port, void (*accept)(wxSocketBase&))
: wxThread(wxTHREAD_JOINABLE),
m_port(port),
m_accept(accept)
{
Create();
Run();
}
protected:
virtual void *Entry() override
{
wxSocketServer srv(LocalAddress(m_port), wxSOCKET_REUSEADDR);
CPPUNIT_ASSERT( srv.IsOk() );
// FIXME: this is still not atomic, of course and the main thread could
// call Connect() before we have time to Accept() but there is
// no way to fix it with current API
{
wxMutexLocker lock(gs_mutex);
gs_cond.Signal();
}
wxSocketBase *socket = srv.Accept();
if ( socket )
{
(*m_accept)(*socket);
delete socket;
}
return nullptr;
}
int m_port;
void (*m_accept)(wxSocketBase&);
wxDECLARE_NO_COPY_CLASS(SocketServerThread);
};
// The test case for socket streams
class socketStream :
public BaseStreamTestCase<wxSocketInputStream, wxSocketOutputStream>
{
public:
socketStream();
virtual void setUp() override;
virtual void tearDown() override;
// repeat all socket tests several times with different socket flags, so we
// define this macro which is used several times in the test suite
//
// there must be some more elegant way to do this but I didn't find it...
#define ALL_SOCKET_TESTS() \
CPPUNIT_TEST(Input_GetC); \
CPPUNIT_TEST(Input_Eof); \
CPPUNIT_TEST(Input_Read); \
CPPUNIT_TEST(Input_LastRead); \
CPPUNIT_TEST(Input_CanRead); \
CPPUNIT_TEST(Input_Peek); \
CPPUNIT_TEST(Input_Ungetch); \
\
CPPUNIT_TEST(Output_PutC); \
CPPUNIT_TEST(Output_Write); \
CPPUNIT_TEST(Output_LastWrite)
CPPUNIT_TEST_SUITE(socketStream);
ALL_SOCKET_TESTS();
// some tests don't pass with NOWAIT flag but this is probably not a
// bug (TODO: check this)
#if 0
CPPUNIT_TEST( PseudoTest_SetNoWait );
ALL_SOCKET_TESTS();
#endif
CPPUNIT_TEST( PseudoTest_SetWaitAll );
ALL_SOCKET_TESTS();
CPPUNIT_TEST_SUITE_END();
private:
// Implement base class functions.
virtual wxSocketInputStream *DoCreateInStream() override;
virtual wxSocketOutputStream *DoCreateOutStream() override;
virtual void DoCheckInputStream(wxSocketInputStream& stream_in) override;
// socket thread functions
static void WriteSocket(wxSocketBase& socket)
{
socket.Write("hello, world!", 13);
}
static void ReadSocket(wxSocketBase& socket)
{
char ch;
while ( socket.Read(&ch, 1).LastCount() == 1 )
;
}
void PseudoTest_SetNoWait() { ms_flags = wxSOCKET_NOWAIT; }
void PseudoTest_SetWaitAll() { ms_flags = wxSOCKET_WAITALL; }
wxSocketClient *m_readSocket,
*m_writeSocket;
wxThread *m_writeThread,
*m_readThread;
wxSocketInitializer m_socketInit;
static wxSocketFlags ms_flags;
};
wxSocketFlags socketStream::ms_flags = wxSOCKET_NONE;
socketStream::socketStream()
{
m_readSocket =
m_writeSocket = nullptr;
m_writeThread =
m_readThread = nullptr;
}
void socketStream::setUp()
{
// create the socket threads and wait until they are ready to accept
// connections (if we called Connect() before this happens, it would fail)
{
wxMutexLocker lock(gs_mutex);
m_writeThread =
new SocketServerThread(TEST_PORT_READ, &socketStream::WriteSocket);
CPPUNIT_ASSERT_EQUAL( wxCOND_NO_ERROR, gs_cond.Wait() );
m_readThread =
new SocketServerThread(TEST_PORT_WRITE, &socketStream::ReadSocket);
CPPUNIT_ASSERT_EQUAL( wxCOND_NO_ERROR, gs_cond.Wait() );
}
m_readSocket = new wxSocketClient(ms_flags);
CPPUNIT_ASSERT( m_readSocket->Connect(LocalAddress(TEST_PORT_READ)) );
m_writeSocket = new wxSocketClient(ms_flags);
CPPUNIT_ASSERT( m_writeSocket->Connect(LocalAddress(TEST_PORT_WRITE)) );
}
void socketStream::tearDown()
{
wxDELETE(m_readSocket);
wxDELETE(m_writeSocket);
m_writeThread->Wait();
wxDELETE(m_writeThread);
m_readThread->Wait();
wxDELETE(m_readThread);
}
wxSocketInputStream *socketStream::DoCreateInStream()
{
wxSocketInputStream *pStrInStream = new wxSocketInputStream(*m_readSocket);
CPPUNIT_ASSERT(pStrInStream->IsOk());
return pStrInStream;
}
wxSocketOutputStream *socketStream::DoCreateOutStream()
{
wxSocketOutputStream *pStrOutStream = new wxSocketOutputStream(*m_writeSocket);
CPPUNIT_ASSERT(pStrOutStream->IsOk());
return pStrOutStream;
}
void socketStream::DoCheckInputStream(wxSocketInputStream& stream_in)
{
// This check sometimes fails in the AppVeyor CI environment for unknown
// reason, so just log it there but don't fail the entire test suite run.
if ( wxGetEnv("APPVEYOR", nullptr) )
{
if ( !stream_in.IsOk() )
{
WARN("Socket input stream test failed.\n"
<< "Socket error = " << m_readSocket->Error()
<< ", last count = " << m_readSocket->LastCount());
return;
}
}
CPPUNIT_ASSERT(stream_in.IsOk());
}
// Register the stream sub suite, by using some stream helper macro.
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(socketStream)

View File

@@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/sstream.cpp
// Purpose: Test wxStringInputStream/wxStringOutputStream
// Author: Vadim Zeitlin
// Copyright: (c) 2004 Vadim Zeitlin
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#endif
#include "wx/sstream.h"
#include "bstream.h"
///////////////////////////////////////////////////////////////////////////////
// The test case
//
// Try to fully test wxStringInputStream and wxStringOutputStream
class strStream :
public BaseStreamTestCase<wxStringInputStream, wxStringOutputStream>
{
public:
strStream();
virtual ~strStream();
CPPUNIT_TEST_SUITE(strStream);
// Base class stream tests the strStream supports.
CPPUNIT_TEST(Input_GetSize);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekI);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
// seeking currently not supported by output string stream
//CPPUNIT_TEST(Output_SeekO);
//CPPUNIT_TEST(Output_TellO);
// Other test specific for String stream test case.
CPPUNIT_TEST(Output_Check);
CPPUNIT_TEST_SUITE_END();
protected:
void Output_Check();
private:
// Implement base class functions.
virtual wxStringInputStream *DoCreateInStream() override;
virtual wxStringOutputStream *DoCreateOutStream() override;
// output the given string to wxStringOutputStream and check that its
// contents is exactly the same string
void CheckString(const wxString& text);
wxString m_str;
};
strStream::strStream()
{
static const size_t LEN = 256;
m_str.reserve(LEN);
for ( size_t n = 0; n < LEN; n++ )
{
m_str += wxChar(wxT('A') + n % (wxT('Z') - wxT('A') + 1));
}
}
strStream::~strStream()
{
}
wxStringInputStream *strStream::DoCreateInStream()
{
wxStringInputStream *pStrInStream = new wxStringInputStream(m_str);
CPPUNIT_ASSERT(pStrInStream->IsOk());
return pStrInStream;
}
wxStringOutputStream *strStream::DoCreateOutStream()
{
wxStringOutputStream *pStrOutStream = new wxStringOutputStream();
CPPUNIT_ASSERT(pStrOutStream->IsOk());
return pStrOutStream;
}
void strStream::CheckString(const wxString& text)
{
wxStringOutputStream sos;
const wxCharBuffer buf(text.To8BitData());
sos.Write(buf, buf.length());
CPPUNIT_ASSERT_EQUAL( text, sos.GetString() );
}
void strStream::Output_Check()
{
CheckString("Hello world!");
CheckString(wxString("hi\0dden", 8));
}
// Register the stream sub suite, by using some stream helper macro.
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(strStream)
TEST_CASE("wxStringOutputStream::Tell", "[stream]")
{
wxStringOutputStream ss;
CHECK( ss.TellO() == 0 );
const char* const s = "Hello world";
const wxFileOffset len = strlen(s);
ss.Write(s, len);
CHECK( ss.TellO() == len );
wxString str(s);
CHECK( wxStringOutputStream(&str).TellO() == len );
wxMBConvUTF16 convUTF16;
wxStringOutputStream ss16(nullptr, convUTF16);
CHECK( ss16.TellO() == 0 );
const wxCharBuffer s16 = convUTF16.cWC2MB(wxWCharBuffer(str.wc_str()));
ss16.Write(s16, s16.length());
CHECK( ss16.TellO() == 2*len );
CHECK( wxStringOutputStream(&str, convUTF16).TellO() == 2*len );
// The U+2070D character is represented by a surrogate pair in UTF-16.
wxString u2070D = wxString::FromUTF8("\xF0\xA0\x9C\x8D");
CHECK( wxStringOutputStream(&u2070D, convUTF16).TellO() == 4 );
}

View File

@@ -0,0 +1,434 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/stdstream.cpp
// Purpose: Test wxStdInputStreamBuffer/wxStdOutputStreamBuffer
// Author: Jonathan Liu <net147@gmail.com>
// Copyright: (c) 2009 Jonathan Liu
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if wxUSE_STD_IOSTREAM
#include "wx/stdstream.h"
#include <string.h>
#include "wx/mstream.h"
// ==========================================================================
// Definitions
// ==========================================================================
const int TEST_SIZE = 384;
// ==========================================================================
// Test class
// ==========================================================================
class StdStreamTestCase : public CppUnit::TestCase
{
public:
StdStreamTestCase();
private:
CPPUNIT_TEST_SUITE( StdStreamTestCase );
// Input buffer management and positioning
CPPUNIT_TEST( InputBuffer_pubsetbuf );
CPPUNIT_TEST( InputBuffer_pubseekoff );
CPPUNIT_TEST( InputBuffer_pubseekpos );
CPPUNIT_TEST( InputBuffer_pubsync );
// Input functions
CPPUNIT_TEST( InputBuffer_in_avail );
CPPUNIT_TEST( InputBuffer_snextc );
CPPUNIT_TEST( InputBuffer_sbumpc );
CPPUNIT_TEST( InputBuffer_sgetc );
CPPUNIT_TEST( InputBuffer_sgetn );
CPPUNIT_TEST( InputBuffer_sputbackc );
CPPUNIT_TEST( InputBuffer_sungetc );
// Output buffer management and positioning
CPPUNIT_TEST( OutputBuffer_pubsetbuf );
CPPUNIT_TEST( OutputBuffer_pubseekoff );
CPPUNIT_TEST( OutputBuffer_pubseekpos );
CPPUNIT_TEST( OutputBuffer_pubsync );
// Output functions
CPPUNIT_TEST( OutputBuffer_sputc );
CPPUNIT_TEST( OutputBuffer_sputn );
CPPUNIT_TEST_SUITE_END();
// Input buffer management and positioning
void InputBuffer_pubsetbuf();
void InputBuffer_pubseekoff();
void InputBuffer_pubseekpos();
void InputBuffer_pubsync();
// Input functions
void InputBuffer_in_avail();
void InputBuffer_snextc();
void InputBuffer_sbumpc();
void InputBuffer_sgetc();
void InputBuffer_sgetn();
void InputBuffer_sputbackc();
void InputBuffer_sungetc();
// Output buffer management and positioning
void OutputBuffer_pubsetbuf();
void OutputBuffer_pubseekoff();
void OutputBuffer_pubseekpos();
void OutputBuffer_pubsync();
// Output functions
void OutputBuffer_sputc();
void OutputBuffer_sputn();
char m_testData[TEST_SIZE];
wxDECLARE_NO_COPY_CLASS(StdStreamTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( StdStreamTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( StdStreamTestCase,
"StdStreamTestCase" );
// ==========================================================================
// Implementation
// ==========================================================================
StdStreamTestCase::StdStreamTestCase()
{
for (int i = 0; i < TEST_SIZE; ++i)
m_testData[i] = (i & 0xFF);
}
// --------------------------------------------------------------------------
// Input buffer management and positioning
// --------------------------------------------------------------------------
void StdStreamTestCase::InputBuffer_pubsetbuf()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
char testBuffer[TEST_SIZE];
CPPUNIT_ASSERT(buffer.pubsetbuf(testBuffer, TEST_SIZE) == nullptr);
}
void StdStreamTestCase::InputBuffer_pubseekoff()
{
const char *testData = "0123456789";
wxMemoryInputStream stream(testData, 10);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT_EQUAL(2,
buffer.pubseekoff(2, std::ios_base::beg,
std::ios_base::in));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(2, std::ios_base::beg,
std::ios_base::out));
CPPUNIT_ASSERT_EQUAL(4,
buffer.pubseekoff(2, std::ios_base::cur));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(2, std::ios_base::cur,
std::ios_base::out));
CPPUNIT_ASSERT_EQUAL(8,
buffer.pubseekoff(-2, std::ios_base::end));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(-2, std::ios_base::end,
std::ios_base::out));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(3, std::ios_base::cur));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(3, std::ios_base::cur,
std::ios_base::out));
}
void StdStreamTestCase::InputBuffer_pubseekpos()
{
const char *testData = "0123456789";
wxMemoryInputStream stream(testData, 10);
wxStdInputStreamBuffer buffer(stream);
for (int i = 9; i >= 0; --i)
{
if (i % 2 == 0)
CPPUNIT_ASSERT_EQUAL(i, buffer.pubseekpos(i));
else
CPPUNIT_ASSERT_EQUAL(i, buffer.pubseekpos(i, std::ios_base::in));
CPPUNIT_ASSERT_EQUAL('0' + i, buffer.sgetc());
}
}
void StdStreamTestCase::InputBuffer_pubsync()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.pubsync() == 0);
}
// --------------------------------------------------------------------------
// Input functions
// --------------------------------------------------------------------------
void StdStreamTestCase::InputBuffer_in_avail()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE / 2];
buffer.sgetn(data, TEST_SIZE / 2);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE - TEST_SIZE / 2, buffer.in_avail());
}
void StdStreamTestCase::InputBuffer_snextc()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE];
data[0] = buffer.sgetc();
for (int i = 1; i < TEST_SIZE; ++i)
data[i] = buffer.snextc();
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT_EQUAL((int)(unsigned char) (m_testData[TEST_SIZE - 1]),
buffer.sbumpc());
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
void StdStreamTestCase::InputBuffer_sbumpc()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE];
for (int i = 0; i < TEST_SIZE; ++i)
data[i] = buffer.sbumpc();
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
void StdStreamTestCase::InputBuffer_sgetc()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE];
for (int i = 0; i < TEST_SIZE; ++i) {
data[i] = buffer.sgetc();
buffer.sbumpc();
}
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
void StdStreamTestCase::InputBuffer_sgetn()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE * 2];
std::streamsize read = buffer.sgetn(data, TEST_SIZE * 2);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, read);
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
void StdStreamTestCase::InputBuffer_sputbackc()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE];
std::streamsize read = buffer.sgetn(data, TEST_SIZE);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, read);
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
char putBackChar = m_testData[TEST_SIZE - 1] + 147;
CPPUNIT_ASSERT_EQUAL((int) putBackChar, buffer.sputbackc(putBackChar));
CPPUNIT_ASSERT_EQUAL((int) putBackChar, buffer.sgetc());
CPPUNIT_ASSERT_EQUAL((int) putBackChar, buffer.sbumpc());
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
void StdStreamTestCase::InputBuffer_sungetc()
{
wxMemoryInputStream stream(m_testData, TEST_SIZE);
wxStdInputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.sgetc() != EOF);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, buffer.in_avail());
char data[TEST_SIZE];
std::streamsize read = buffer.sgetn(data, TEST_SIZE);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, read);
CPPUNIT_ASSERT(memcmp(data, m_testData, TEST_SIZE) == 0);
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
CPPUNIT_ASSERT_EQUAL((int) m_testData[TEST_SIZE - 1], buffer.sungetc());
CPPUNIT_ASSERT_EQUAL((int) m_testData[TEST_SIZE - 1], buffer.sgetc());
CPPUNIT_ASSERT_EQUAL((int) m_testData[TEST_SIZE - 1], buffer.sbumpc());
CPPUNIT_ASSERT(buffer.sgetc() == EOF);
}
// --------------------------------------------------------------------------
// Output buffer management and positioning
// --------------------------------------------------------------------------
void StdStreamTestCase::OutputBuffer_pubsetbuf()
{
wxMemoryOutputStream stream;
wxStdOutputStreamBuffer buffer(stream);
char testBuffer[TEST_SIZE];
CPPUNIT_ASSERT(buffer.pubsetbuf(testBuffer, TEST_SIZE) == nullptr);
}
void StdStreamTestCase::OutputBuffer_pubseekoff()
{
char testData[] = "0123456789";
wxMemoryOutputStream stream(testData, 10);
wxStdOutputStreamBuffer buffer(stream);
CPPUNIT_ASSERT_EQUAL(2,
buffer.pubseekoff(2, std::ios_base::beg,
std::ios_base::out));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(2, std::ios_base::beg,
std::ios_base::in));
CPPUNIT_ASSERT_EQUAL(4,
buffer.pubseekoff(2, std::ios_base::cur));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(2, std::ios_base::cur,
std::ios_base::in));
CPPUNIT_ASSERT_EQUAL(8,
buffer.pubseekoff(-2, std::ios_base::end));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(-2, std::ios_base::end,
std::ios_base::in));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(3, std::ios_base::cur));
CPPUNIT_ASSERT_EQUAL(-1,
buffer.pubseekoff(3, std::ios_base::cur,
std::ios_base::in));
}
void StdStreamTestCase::OutputBuffer_pubseekpos()
{
char testData[] = "0123456789";
wxMemoryOutputStream stream(testData, 10);
wxStdOutputStreamBuffer buffer(stream);
for (int i = 9; i >= 0; --i)
{
if (i % 2 == 0)
{
CPPUNIT_ASSERT_EQUAL(i, buffer.pubseekpos(i));
}
else
{
CPPUNIT_ASSERT_EQUAL(i,
buffer.pubseekpos(i, std::ios_base::out));
}
CPPUNIT_ASSERT_EQUAL('0' + (9 - i), buffer.sputc('0' + (9 - i)));
}
CPPUNIT_ASSERT(memcmp(testData, "9876543210", 10) == 0);
CPPUNIT_ASSERT_EQUAL(-1, buffer.pubseekpos(5, std::ios_base::in));
}
void StdStreamTestCase::OutputBuffer_pubsync()
{
wxMemoryOutputStream stream;
wxStdOutputStreamBuffer buffer(stream);
CPPUNIT_ASSERT(buffer.pubsync() == 0);
}
// --------------------------------------------------------------------------
// Output functions
// --------------------------------------------------------------------------
void StdStreamTestCase::OutputBuffer_sputc()
{
wxMemoryOutputStream stream;
wxStdOutputStreamBuffer buffer(stream);
for (int i = 0; i < TEST_SIZE; ++i)
buffer.sputc(m_testData[i]);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, stream.GetSize());
char result[TEST_SIZE];
stream.CopyTo(result, TEST_SIZE);
CPPUNIT_ASSERT(memcmp(result, m_testData, TEST_SIZE) == 0);
}
void StdStreamTestCase::OutputBuffer_sputn()
{
wxMemoryOutputStream stream;
wxStdOutputStreamBuffer buffer(stream);
buffer.sputn(m_testData, TEST_SIZE);
CPPUNIT_ASSERT_EQUAL(TEST_SIZE, stream.GetSize());
char result[TEST_SIZE];
stream.CopyTo(result, TEST_SIZE);
CPPUNIT_ASSERT(memcmp(result, m_testData, TEST_SIZE) == 0);
}
#endif // wxUSE_STD_IOSTREAM

View File

@@ -0,0 +1,81 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/tempfile.cpp
// Purpose: Test wxTempFileOutputStream
// Author: Mike Wetherell
// Copyright: (c) 2005 Mike Wetherell
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/wfstream.h"
#include "wx/filename.h"
#include "bstream.h"
#if wxUSE_STREAMS && wxUSE_FILE
#include "testfile.h"
///////////////////////////////////////////////////////////////////////////////
// The test case
class tempStream : public CppUnit::TestCase
{
CPPUNIT_TEST_SUITE(tempStream);
CPPUNIT_TEST(DoNothing);
CPPUNIT_TEST(Close);
CPPUNIT_TEST(Commit);
CPPUNIT_TEST(Discard);
CPPUNIT_TEST_SUITE_END();
void DoNothing() { DoTest(DONOTHING, false); }
void Close() { DoTest(CLOSE, true); }
void Commit() { DoTest(COMMIT, true); }
void Discard() { DoTest(DISCARD, false); }
enum Action { DONOTHING, CLOSE, COMMIT, DISCARD };
void DoTest(Action action, bool shouldHaveCommited);
};
// the common test code
//
void tempStream::DoTest(Action action, bool shouldHaveCommited)
{
TestFile temp;
{
wxTempFileOutputStream out(temp.GetName());
out.Write("Affer", 5);
CPPUNIT_ASSERT(out.SeekO(2) == 2);
out.Write("t", 1);
CPPUNIT_ASSERT(out.IsSeekable());
CPPUNIT_ASSERT(out.GetLength() == 5);
CPPUNIT_ASSERT(out.TellO() == 3);
switch (action) {
case DONOTHING: break;
case COMMIT: out.Commit(); break;
case DISCARD: out.Discard(); break;
case CLOSE: out.Close();
}
}
wxFileInputStream in(temp.GetName());
char buf[32];
in.Read(buf, sizeof(buf));
buf[in.LastRead()] = 0;
CPPUNIT_ASSERT(strcmp(buf, shouldHaveCommited ? "After" : "Before") == 0);
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(tempStream)
#endif // wxUSE_STREAMS && wxUSE_FILE

View File

@@ -0,0 +1,345 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/textstreamtest.cpp
// Purpose: wxTextXXXStream unit test
// Author: Ryan Norton, Vince Harron
// Created: 2004-08-14
// Copyright: (c) 2004 Ryan Norton, (c) 2006 Vince Harron
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif // WX_PRECOMP
#include "wx/txtstrm.h"
#include "wx/wfstream.h"
#include "wx/longlong.h"
#include "wx/mstream.h"
#include "testfile.h"
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class TextStreamTestCase : public CppUnit::TestCase
{
public:
TextStreamTestCase();
private:
CPPUNIT_TEST_SUITE( TextStreamTestCase );
CPPUNIT_TEST( Endline );
CPPUNIT_TEST( MiscTests );
CPPUNIT_TEST( TestLongLong );
CPPUNIT_TEST( TestULongLong );
CPPUNIT_TEST( TestUTF8Input );
CPPUNIT_TEST( TestEmbeddedZerosUTF16LEInput );
CPPUNIT_TEST( TestEmbeddedZerosUTF16BEInput );
CPPUNIT_TEST( TestEmbeddedZerosUTF32LEInput );
CPPUNIT_TEST( TestEmbeddedZerosUTF32BEInput );
CPPUNIT_TEST_SUITE_END();
void Endline();
void MiscTests();
void TestLongLong();
void TestULongLong();
void TestUTF8Input();
void TestEmbeddedZerosUTF16LEInput();
void TestEmbeddedZerosUTF16BEInput();
void TestEmbeddedZerosUTF32LEInput();
void TestEmbeddedZerosUTF32BEInput();
void TestInput(const wxMBConv& conv,
const void* encodedText,
size_t encodedSize );
wxDECLARE_NO_COPY_CLASS(TextStreamTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( TextStreamTestCase );
// also include in its own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TextStreamTestCase, "TextStreamTestCase" );
TextStreamTestCase::TextStreamTestCase()
{
}
#if defined(__WINDOWS__)
# define NEWLINE "\r\n"
# define NEWLINELEN 2
#elif defined(__WXMAC__) && !defined(__DARWIN__)
# define NEWLINE "\r"
# define NEWLINELEN 1
#else
# define NEWLINE "\n"
# define NEWLINELEN 1
#endif
void TextStreamTestCase::Endline()
{
TempFile f("test.txt");
{
wxFileOutputStream pOutFile(f.GetName());
wxTextOutputStream pOutText(pOutFile);
pOutText << wxT("Test text") << endl
<< wxT("More Testing Text (There should be newline before this)");
}
wxFileInputStream pInFile(f.GetName());
char szIn[9 + NEWLINELEN];
pInFile.Read(szIn, 9 + NEWLINELEN);
CPPUNIT_ASSERT( memcmp(&szIn[9], NEWLINE, NEWLINELEN) == 0 );
}
void TextStreamTestCase::MiscTests()
{
wxString filename = wxT("testdata.conf");
wxFileInputStream fsIn(filename);
if ( !fsIn.IsOk() )
{
return;
}
wxTextInputStream tis(fsIn);
CPPUNIT_ASSERT_EQUAL("# this is the test data file for wxFileConfig tests", tis.ReadLine());
CPPUNIT_ASSERT_EQUAL("value1=one", tis.ReadLine());
CPPUNIT_ASSERT_EQUAL("# a comment here", tis.ReadLine());
CPPUNIT_ASSERT_EQUAL("value2=two", tis.ReadLine());
CPPUNIT_ASSERT_EQUAL("value\\ with\\ spaces\\ inside\\ it=nothing special", tis.ReadLine());
CPPUNIT_ASSERT_EQUAL("path=$PATH", tis.ReadLine());
}
template <typename T>
static void DoTestRoundTrip(const T *values, size_t numValues)
{
TempFile f("test.txt");
{
wxFileOutputStream fileOut(f.GetName());
wxTextOutputStream textOut(fileOut);
for ( size_t n = 0; n < numValues; n++ )
{
textOut << values[n] << endl;
}
}
{
wxFileInputStream fileIn(f.GetName());
wxTextInputStream textIn(fileIn);
T value;
for ( size_t n = 0; n < numValues; n++ )
{
textIn >> value;
CPPUNIT_ASSERT( value == values[n] );
}
}
}
void TextStreamTestCase::TestLongLong()
{
static const wxLongLong llvalues[] =
{
0,
1,
-1,
0x12345678l,
-0x12345678l,
wxLL(0x123456789abcdef0),
wxLL(-0x123456789abcdef0),
};
DoTestRoundTrip(llvalues, WXSIZEOF(llvalues));
}
void TextStreamTestCase::TestULongLong()
{
static const wxULongLong ullvalues[] =
{
0,
1,
0x12345678l,
wxULL(0x123456789abcdef0),
};
DoTestRoundTrip(ullvalues, WXSIZEOF(ullvalues));
}
static const wchar_t txtWchar[4] =
{
0x0041, // LATIN CAPITAL LETTER A
0x0100, // A WITH BREVE, LATIN SMALL LETTER
0x0041, // LATIN CAPITAL LETTER A
0x0100, // A WITH BREVE, LATIN SMALL LETTER
};
static const unsigned char txtUtf8[6] =
{
0x41, 0xc4, 0x80, 0x41, 0xc4, 0x80,
};
static const unsigned char txtUtf16le[8] =
{
0x41, 0x00, 0x00, 0x01, 0x41, 0x00, 0x00, 0x01,
};
static const unsigned char txtUtf16be[8] =
{
0x00, 0x41, 0x01, 0x00, 0x00, 0x41, 0x01, 0x00,
};
static const unsigned char txtUtf32le[16] =
{
0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
};
static const unsigned char txtUtf32be[16] =
{
0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x01, 0x00,
};
void TextStreamTestCase::TestUTF8Input()
{
TestInput(wxConvUTF8, txtUtf8, sizeof(txtUtf8));
TestInput(wxCSConv(wxFONTENCODING_UTF8), txtUtf8, sizeof(txtUtf8));
}
void TextStreamTestCase::TestEmbeddedZerosUTF16LEInput()
{
TestInput(wxMBConvUTF16LE(), txtUtf16le, sizeof(txtUtf16le));
TestInput(wxCSConv(wxFONTENCODING_UTF16LE), txtUtf16le, sizeof(txtUtf16le));
}
void TextStreamTestCase::TestEmbeddedZerosUTF16BEInput()
{
TestInput(wxMBConvUTF16BE(), txtUtf16be, sizeof(txtUtf16be));
TestInput(wxCSConv(wxFONTENCODING_UTF16BE), txtUtf16be, sizeof(txtUtf16be));
}
void TextStreamTestCase::TestEmbeddedZerosUTF32LEInput()
{
TestInput(wxMBConvUTF32LE(), txtUtf32le, sizeof(txtUtf32le));
TestInput(wxCSConv(wxFONTENCODING_UTF32LE), txtUtf32le, sizeof(txtUtf32le));
}
void TextStreamTestCase::TestEmbeddedZerosUTF32BEInput()
{
TestInput(wxMBConvUTF32BE(), txtUtf32be, sizeof(txtUtf32be));
TestInput(wxCSConv(wxFONTENCODING_UTF32BE), txtUtf32be, sizeof(txtUtf32be));
}
void TextStreamTestCase::TestInput(const wxMBConv& conv,
const void *encodedText,
size_t encodedSize)
{
wxMemoryInputStream byteIn(encodedText, encodedSize);
wxTextInputStream textIn(byteIn, wxT("\n"), conv);
wxString temp;
while ( wxChar c = textIn.GetChar() )
{
temp.Append(c);
}
CPPUNIT_ASSERT_EQUAL( WXSIZEOF(txtWchar), temp.length() );
CPPUNIT_ASSERT_EQUAL( 0, memcmp(txtWchar, temp.wc_str(), sizeof(txtWchar)) );
}
TEST_CASE("wxTextInputStream::GetChar", "[text][input][stream][char]")
{
// This is the simplest possible test that used to trigger assertion in
// wxTextInputStream::GetChar().
SECTION("starts-with-nul")
{
const wxUint8 buf[] = { 0x00, 0x01, };
wxMemoryInputStream mis(buf, sizeof(buf));
wxTextInputStream tis(mis);
REQUIRE( tis.GetChar() == 0x00 );
REQUIRE( tis.GetChar() == 0x01 );
REQUIRE( tis.GetChar() == 0x00 );
CHECK( tis.GetInputStream().Eof() );
}
// This exercises a problematic path in GetChar() as the first 3 bytes of
// this stream look like the start of UTF-32BE BOM, but this is not
// actually a BOM because the 4th byte is 0xFE and not 0xFF, so the stream
// should decode the buffer as Latin-1 once it gets there.
SECTION("almost-UTF-32-BOM")
{
const wxUint8 buf[] = { 0x00, 0x00, 0xFE, 0xFE, 0x01 };
wxMemoryInputStream mis(buf, sizeof(buf));
wxTextInputStream tis(mis);
REQUIRE( tis.GetChar() == 0x00 );
REQUIRE( tis.GetChar() == 0x00 );
REQUIRE( tis.GetChar() == 0xFE );
REQUIRE( tis.GetChar() == 0xFE );
REQUIRE( tis.GetChar() == 0x01 );
REQUIRE( tis.GetChar() == 0x00 );
CHECK( tis.GetInputStream().Eof() );
}
// Two null bytes that look like the start of UTF-32BE BOM,
// followed by 4 byte UTF-8 sequence.
// Needs wxConvAuto to not switch to fallback on <6 bytes.
SECTION("UTF8-with-nulls")
{
const wxUint8 buf[] = { 0x00, 0x00, 0xf0, 0x90, 0x8c, 0x98 };
wxMemoryInputStream mis(buf, sizeof(buf));
wxTextInputStream tis(mis);
wxCharTypeBuffer<wxChar> e = wxString::FromUTF8((const char*)buf, sizeof(buf))
.tchar_str<wxChar>();
for ( size_t i = 0; i < e.length(); ++i )
{
INFO("i = " << i);
REQUIRE( tis.GetChar() == e[i] );
}
REQUIRE( tis.GetChar() == 0x00 );
CHECK( tis.GetInputStream().Eof() );
}
// Two null bytes that look like the start of UTF-32BE BOM,
// then 3 bytes that look like the start of UTF-8 sequence.
// Needs 6 character output buffer in GetChar().
SECTION("almost-UTF8-with-nulls")
{
const wxUint8 buf[] = { 0x00, 0x00, 0xf0, 0x90, 0x8c, 0xe0 };
wxMemoryInputStream mis(buf, sizeof(buf));
wxTextInputStream tis(mis);
wxCharTypeBuffer<wxChar> e = wxString((const char*)buf, wxCSConv(wxFONTENCODING_ISO8859_1),
sizeof(buf)).tchar_str<wxChar>();
for ( size_t i = 0; i < e.length(); ++i )
{
INFO("i = " << i);
REQUIRE( tis.GetChar() == e[i] );
}
REQUIRE( tis.GetChar() == 0x00 );
CHECK( tis.GetInputStream().Eof() );
}
}

View File

@@ -0,0 +1,550 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/streams/zlibstream.cpp
// Purpose: Test wxZlibInputStream/wxZlibOutputStream
// Author: Hans Van Leemputten
// Copyright: (c) 2004 Hans Van Leemputten
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/zstream.h"
#include "wx/wfstream.h"
#include "wx/mstream.h"
#include "wx/txtstrm.h"
#include "wx/buffer.h"
#include "bstream.h"
using std::string;
#define DATABUFFER_SIZE 1024
static const wxString FILENAME_GZ = wxT("zlibtest.gz");
///////////////////////////////////////////////////////////////////////////////
// The test case
//
// Try to fully test wxZlibInputStream and wxZlibOutputStream
class zlibStream : public BaseStreamTestCase<wxZlibInputStream, wxZlibOutputStream>
{
public:
zlibStream();
virtual ~zlibStream();
CPPUNIT_TEST_SUITE(zlibStream);
// Base class stream tests the zlibstream supports.
CPPUNIT_TEST(Input_GetSizeFail);
CPPUNIT_TEST(Input_GetC);
CPPUNIT_TEST(Input_Read);
CPPUNIT_TEST(Input_Eof);
CPPUNIT_TEST(Input_LastRead);
CPPUNIT_TEST(Input_CanRead);
CPPUNIT_TEST(Input_SeekIFail);
CPPUNIT_TEST(Input_TellI);
CPPUNIT_TEST(Input_Peek);
CPPUNIT_TEST(Input_Ungetch);
CPPUNIT_TEST(Output_PutC);
CPPUNIT_TEST(Output_Write);
CPPUNIT_TEST(Output_LastWrite);
CPPUNIT_TEST(Output_SeekOFail);
CPPUNIT_TEST(Output_TellO);
// Other test specific for zlib stream test case.
CPPUNIT_TEST(TestStream_NoHeader_Default);
CPPUNIT_TEST(TestStream_NoHeader_NoComp);
CPPUNIT_TEST(TestStream_NoHeader_SpeedComp);
CPPUNIT_TEST(TestStream_NoHeader_BestComp);
CPPUNIT_TEST(TestStream_NoHeader_Dictionary);
CPPUNIT_TEST(TestStream_ZLib_Default);
CPPUNIT_TEST(TestStream_ZLib_NoComp);
CPPUNIT_TEST(TestStream_ZLib_SpeedComp);
CPPUNIT_TEST(TestStream_ZLib_BestComp);
CPPUNIT_TEST(TestStream_GZip_Default);
CPPUNIT_TEST(TestStream_GZip_NoComp);
CPPUNIT_TEST(TestStream_GZip_SpeedComp);
CPPUNIT_TEST(TestStream_GZip_BestComp);
CPPUNIT_TEST(TestStream_GZip_Dictionary);
CPPUNIT_TEST(TestStream_ZLibGZip);
CPPUNIT_TEST(Decompress_BadData);
CPPUNIT_TEST(Decompress_wx251_zlib114_Data_NoHeader);
CPPUNIT_TEST(Decompress_wx251_zlib114_Data_ZLib);
CPPUNIT_TEST(Decompress_gzip135Data);
CPPUNIT_TEST_SUITE_END();
protected:
// Test different stream construct settings.
void TestStream_NoHeader_Default();
void TestStream_NoHeader_NoComp();
void TestStream_NoHeader_SpeedComp();
void TestStream_NoHeader_BestComp();
void TestStream_NoHeader_Dictionary();
void TestStream_ZLib_Default();
void TestStream_ZLib_NoComp();
void TestStream_ZLib_SpeedComp();
void TestStream_ZLib_BestComp();
void TestStream_GZip_Default();
void TestStream_GZip_NoComp();
void TestStream_GZip_SpeedComp();
void TestStream_GZip_BestComp();
void TestStream_GZip_Dictionary();
void TestStream_ZLibGZip();
// Try to decompress bad data.
void Decompress_BadData();
// Decompress data that was compress by an external app.
// (like test wx 2.4.2, 2.5.1 and gzip data)
// Note: This test is limited in testing range!
void Decompress_wx251_zlib114_Data_NoHeader();
void Decompress_wx251_zlib114_Data_ZLib();
void Decompress_gzip135Data();
private:
const char *GetDataBuffer();
const unsigned char *GetCompressedData();
void doTestStreamData(int input_flag, int output_flag, int compress_level, const wxMemoryBuffer *buf = nullptr);
void doDecompress_ExternalData(const unsigned char *data, const char *value, size_t data_size, size_t value_size, int flag = wxZLIB_AUTO);
private:
// Implement base class functions.
virtual wxZlibInputStream *DoCreateInStream() override;
virtual wxZlibOutputStream *DoCreateOutStream() override;
virtual void DoDeleteInStream() override;
virtual void DoDeleteOutStream() override;
// Helper that can be used to create new wx compatibility tests...
// Otherwise not used by the tests.
void genExtTestData(wxTextOutputStream &out, const char *buf, int flag);
private:
char m_DataBuffer[DATABUFFER_SIZE];
size_t m_SizeCompressedData;
unsigned char *m_pCompressedData;
wxMemoryBuffer m_Dictionary;
// Used by the base Creat[In|Out]Stream and Delete[In|Out]Stream.
wxMemoryInputStream *m_pTmpMemInStream;
wxMemoryOutputStream *m_pTmpMemOutStream;
};
zlibStream::zlibStream()
:m_SizeCompressedData(0),
m_pCompressedData(nullptr),
m_pTmpMemInStream(nullptr),
m_pTmpMemOutStream(nullptr)
{
// Init the data buffer.
for (size_t i = 0; i < DATABUFFER_SIZE; i++)
m_DataBuffer[i] = (i % 0xFF);
m_Dictionary.AppendData(m_DataBuffer, sizeof(m_DataBuffer) / 2);
// Set extra base config settings.
m_bSimpleTellITest = true;
m_bSimpleTellOTest = true;
/* Example code on how to produce test data...
{
wxFFileOutputStream fstream_out(wxT("gentest.cpp"));
wxTextOutputStream out( fstream_out );
genExtTestData(out, "zlib data created with wxWidgets 2.5.x [March 27], wxZLIB_NO_HEADER, zlib 1.1.4", wxZLIB_NO_HEADER);
genExtTestData(out, "zlib data created with wxWidgets 2.5.x [March 27], wxZLIB_ZLIB, zlib 1.1.4", wxZLIB_ZLIB);
}
*/
}
zlibStream::~zlibStream()
{
delete[] m_pCompressedData;
delete m_pTmpMemInStream;
delete m_pTmpMemOutStream;
}
void zlibStream::TestStream_NoHeader_Default()
{
doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_DEFAULT_COMPRESSION);
}
void zlibStream::TestStream_NoHeader_NoComp()
{
doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_NO_COMPRESSION);
}
void zlibStream::TestStream_NoHeader_SpeedComp()
{
doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_BEST_SPEED);
}
void zlibStream::TestStream_NoHeader_BestComp()
{
doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_BEST_COMPRESSION);
}
void zlibStream::TestStream_NoHeader_Dictionary()
{
doTestStreamData(wxZLIB_NO_HEADER, wxZLIB_NO_HEADER, wxZ_DEFAULT_COMPRESSION, &m_Dictionary);
}
void zlibStream::TestStream_ZLib_Default()
{
doTestStreamData(wxZLIB_ZLIB, wxZLIB_ZLIB, wxZ_DEFAULT_COMPRESSION);
}
void zlibStream::TestStream_ZLib_NoComp()
{
doTestStreamData(wxZLIB_ZLIB, wxZLIB_ZLIB, wxZ_NO_COMPRESSION);
}
void zlibStream::TestStream_ZLib_SpeedComp()
{
doTestStreamData(wxZLIB_ZLIB, wxZLIB_ZLIB, wxZ_BEST_SPEED);
}
void zlibStream::TestStream_ZLib_BestComp()
{
doTestStreamData(wxZLIB_ZLIB, wxZLIB_ZLIB, wxZ_BEST_COMPRESSION);
}
void zlibStream::TestStream_GZip_Default()
{
doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_DEFAULT_COMPRESSION);
}
void zlibStream::TestStream_GZip_NoComp()
{
doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_NO_COMPRESSION);
}
void zlibStream::TestStream_GZip_SpeedComp()
{
doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_BEST_SPEED);
}
void zlibStream::TestStream_GZip_BestComp()
{
doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_BEST_COMPRESSION);
}
void zlibStream::TestStream_GZip_Dictionary()
{
doTestStreamData(wxZLIB_GZIP, wxZLIB_GZIP, wxZ_DEFAULT_COMPRESSION, &m_Dictionary);
}
void zlibStream::TestStream_ZLibGZip()
{
// Only use default compression level, as this test is
// for testing if the streams can determine the stream type info them self...
doTestStreamData(wxZLIB_AUTO, wxZLIB_ZLIB, wxZ_DEFAULT_COMPRESSION);
doTestStreamData(wxZLIB_AUTO, wxZLIB_GZIP, wxZ_DEFAULT_COMPRESSION);
}
void zlibStream::Decompress_BadData()
{
// Setup the bad data stream and the zlib stream.
wxMemoryInputStream memstream_in(GetDataBuffer(), DATABUFFER_SIZE);
CPPUNIT_ASSERT(memstream_in.IsOk());
wxZlibInputStream zstream_in(memstream_in);
CPPUNIT_ASSERT(zstream_in.IsOk()); // We did not yet read from the stream
// so it should still be OK.
// Try to force the stream to go to bad status.
CPPUNIT_ASSERT(!zstream_in.Eof());
if (zstream_in.IsOk())
zstream_in.GetC();
// Because of the bad data in the input stream the zlib
// stream should be marked as NOT OK.
CPPUNIT_ASSERT(!zstream_in.IsOk());
}
void zlibStream::Decompress_wx251_zlib114_Data_NoHeader()
{
const unsigned char data[] = {171,202,201,76,82,72,73,44,73,84,72,46,74,77,44,73,77,81,40,207,44,201,80,40,175,8,207,76,73,79,45,41,86,48,210,51,213,171,80,136,246,77,44,74,206,80,48,50,143,213,1,202,69,249,120,58,197,251,249,199,123,184,58,186,184,6,233,40,84,129,12,49,212,51,212,51,1,0,32};
const char *value = "zlib data created with wxWidgets 2.5.x [March 27], wxZLIB_NO_HEADER, zlib 1.1.4";
const size_t data_size = sizeof(data);
const size_t value_size = strlen(value);
// We need to specify wxZLIB_NO_HEADER because wxZLIB_AUTO can't find it his self.
doDecompress_ExternalData(data, value, data_size, value_size, wxZLIB_NO_HEADER);
}
void zlibStream::Decompress_wx251_zlib114_Data_ZLib()
{
const unsigned char data[] = {120,156,171,202,201,76,82,72,73,44,73,84,72,46,74,77,44,73,77,81,40,207,44,201,80,40,175,8,207,76,73,79,45,41,86,48,210,51,213,171,80,136,246,77,44,74,206,80,48,50,143,213,1,202,69,249,120,58,197,131,8,29,133,42,144,126,67,61,67,61,19,0,191,86,23,216};
const char *value = "zlib data created with wxWidgets 2.5.x [March 27], wxZLIB_ZLIB, zlib 1.1.4";
const size_t data_size = sizeof(data);
const size_t value_size = strlen(value);
doDecompress_ExternalData(data, value, data_size, value_size);
}
void zlibStream::Decompress_gzip135Data()
{
// Compressed data was on the command line with gzip 1.3.5.
const unsigned char gzip135_data[] = {31,139,8,0,177,248,112,64,4,3,115,206,207,45,40,74,45,46,78,77,81,72,73,44,73,84,72,46,74,77,44,1,114,202,51,75,50,20,220,253,66,21,210,171,50,11,20,12,245,140,245,76,185,0,1,107,16,80,44,0,0,0,0};
const char *gzip135_value = "Compressed data created with GNU gzip 1.3.5\n";
// Size of the value and date items.
const size_t data_size = sizeof(gzip135_data);
const size_t value_size = strlen(gzip135_value);
// Perform a generic data test on the data.
doDecompress_ExternalData(gzip135_data, gzip135_value, data_size, value_size);
}
const char *zlibStream::GetDataBuffer()
{
return m_DataBuffer;
}
const unsigned char *zlibStream::GetCompressedData()
{
if (!m_pCompressedData)
{
// Construct the compressed data live.
wxMemoryOutputStream memstream_out;
{
const char *buf = "01234567890123456789012345678901234567890123456789"; /* = 50 */
wxZlibOutputStream zstream_out(memstream_out);
zstream_out.Write(buf, strlen(buf));
}
// Copy the to the
m_SizeCompressedData = memstream_out.GetSize();
m_pCompressedData = new unsigned char[m_SizeCompressedData];
memstream_out.CopyTo(m_pCompressedData, m_SizeCompressedData);
}
CPPUNIT_ASSERT(m_pCompressedData != nullptr);
return m_pCompressedData;
}
void zlibStream::doTestStreamData(int input_flag, int output_flag, int compress_level, const wxMemoryBuffer *buf)
{
size_t fail_pos;
char last_value = 0;
bool bWasEOF;
{ // Part one: Create a compressed file.
wxFileOutputStream fstream_out(FILENAME_GZ);
CPPUNIT_ASSERT(fstream_out.IsOk());
{
wxZlibOutputStream zstream_out(fstream_out, compress_level, output_flag);
CPPUNIT_ASSERT_MESSAGE("Could not create the output stream", zstream_out.IsOk());
if (buf)
zstream_out.SetDictionary(*buf);
// Next: Compress some data so the file is containing something.
zstream_out.Write(GetDataBuffer(), DATABUFFER_SIZE);
}
// Next thing is required by zlib versions pre 1.2.0.
if (input_flag == wxZLIB_NO_HEADER)
fstream_out.PutC(' ');
}
{ // Part two: Verify that the compressed data when uncompressed
// matches the original data.
wxFileInputStream fstream_in(FILENAME_GZ);
CPPUNIT_ASSERT(fstream_in.IsOk());
wxZlibInputStream zstream_in(fstream_in, input_flag);
CPPUNIT_ASSERT_MESSAGE("Could not create the input stream", zstream_in.IsOk());
if (buf)
zstream_in.SetDictionary(*buf);
// Next: Check char per char if the returned data is valid.
const char *pbuf = GetDataBuffer();
for (fail_pos = 0; !zstream_in.Eof(); fail_pos++)
{
last_value = zstream_in.GetC();
if (zstream_in.LastRead() != 1 ||
last_value != pbuf[fail_pos])
break;
}
bWasEOF = zstream_in.Eof();
}
// Remove the temp file...
::wxRemoveFile(FILENAME_GZ);
// Check state of the verify action.
if (fail_pos != DATABUFFER_SIZE || !bWasEOF)
{
wxString msg;
msg << wxT("Wrong data item at pos ") << fail_pos
<< wxT(" (Org_val ") << GetDataBuffer()[fail_pos]
<< wxT(" != Zlib_val ") << last_value
<< wxT("), with compression level ") << compress_level;
CPPUNIT_FAIL(string(msg.mb_str()));
}
}
void zlibStream::doDecompress_ExternalData(const unsigned char *data, const char *value, size_t data_size, size_t value_size, int flag)
{
// See that the input is ok.
wxASSERT(data != nullptr);
wxASSERT(value != nullptr);
wxASSERT(data_size > 0);
wxASSERT(value_size > 0);
// Quickly try to see if the data is valid.
switch (flag)
{
case wxZLIB_NO_HEADER:
break;
case wxZLIB_ZLIB:
if (!(data_size >= 1 && data[0] == 0x78))
{
wxLogError(wxT("zlib data seems to not be zlib data!"));
}
break;
case wxZLIB_GZIP:
if (!(data_size >= 2 && data[0] == 0x1F && data[1] == 0x8B))
{
wxLogError(wxT("gzip data seems to not be gzip data!"));
}
break;
case wxZLIB_AUTO:
if (!(data_size >= 1 && data[0] == 0x78) ||
!(data_size >= 2 && data[0] == 0x1F && data[1] == 0x8B))
{
wxLogError(wxT("Data seems to not be zlib or gzip data!"));
}
break;
default:
wxLogError(wxT("Unknown flag, skipping quick test."));
};
// Creat the needed streams.
wxMemoryInputStream memstream_in(data, data_size);
CPPUNIT_ASSERT(memstream_in.IsOk());
wxZlibInputStream zstream_in(memstream_in, flag);
CPPUNIT_ASSERT(zstream_in.IsOk());
bool bValueEq = true;
size_t i;
for (i = 0; !zstream_in.Eof(); i++)
{
char last_value = zstream_in.GetC();
// First check if it is a valid read.
if (zstream_in.LastRead() == 1)
{
// Check the values
if (last_value != value[i])
{
bValueEq = false;
break;
}
}
else
{
// If the read failed and turned the stream to Eof we stop reading.
if (zstream_in.Eof())
break;
CPPUNIT_ASSERT_MESSAGE("Stream is no longer ok!", zstream_in.IsOk());
}
// Don't go over the end of the value buffer...
if (i == value_size)
{
// And if we do then try to see how long the stream actually is.
while (!zstream_in.Eof())
{
// Move one item along in the stream.
(void)zstream_in.GetC();
i++;
// Check if we are in an infinite loop by multiplying value_size
// by 5 to have a *much* bigger range then the real range.
// Note: In case you ask yourself, why 5, the answer is no reason...
// it is not too big and not to small a size, nothing more
// nothing less to it.
if (i > (value_size*5))
{
// Note: Please make sure Input_Eof test passed.
CPPUNIT_FAIL("Infinite stream detected, breaking the infinite loop");
return;
}
}
}
}
CPPUNIT_ASSERT_EQUAL( i, value_size );
CPPUNIT_ASSERT( bValueEq );
}
wxZlibInputStream *zlibStream::DoCreateInStream()
{
const unsigned char *buf = GetCompressedData();
m_pTmpMemInStream = new wxMemoryInputStream(buf, m_SizeCompressedData);
CPPUNIT_ASSERT(m_pTmpMemInStream->IsOk());
wxZlibInputStream *pzstream_in = new wxZlibInputStream(*m_pTmpMemInStream);
CPPUNIT_ASSERT(pzstream_in->IsOk());
return pzstream_in;
}
wxZlibOutputStream *zlibStream::DoCreateOutStream()
{
m_pTmpMemOutStream = new wxMemoryOutputStream();
CPPUNIT_ASSERT(m_pTmpMemOutStream->IsOk());
wxZlibOutputStream *pzstream_out = new wxZlibOutputStream(*m_pTmpMemOutStream);
CPPUNIT_ASSERT(pzstream_out->IsOk());
return pzstream_out;
}
void zlibStream::DoDeleteInStream()
{
delete m_pTmpMemInStream;
m_pTmpMemInStream = nullptr;
}
void zlibStream::DoDeleteOutStream()
{
delete m_pTmpMemOutStream;
m_pTmpMemOutStream = nullptr;
}
void zlibStream::genExtTestData(wxTextOutputStream &out, const char *buf, int flag)
{
unsigned char *data;
size_t size;
{ // Gen data
wxMemoryOutputStream memstream_out;
{
wxZlibOutputStream zstream_out(memstream_out, wxZ_DEFAULT_COMPRESSION, flag);
zstream_out.Write(buf, strlen(buf));
}
if (flag == wxZLIB_NO_HEADER)
memstream_out.PutC(' ');
size = memstream_out.GetSize();
data = new unsigned char[size];
memstream_out.CopyTo(data, size);
}
out << wxT("void zlibStream::Decompress_wxXXXData()") << wxT("\n");
out << wxT("{") << wxT("\n") << wxT(" const unsigned char data[] = {");
size_t i;
for (i = 0; i < size; i++)
{
if (i+1 != size)
out << wxString::Format(wxT("%d,"), data[i]);
else
out << wxString::Format(wxT("%d"), data[i]);
}
delete [] data;
out << wxT("};") << wxT("\n");
out << wxT(" const char *value = \"") << wxString(buf, wxConvUTF8) << wxT("\";") << wxT("\n");
out << wxT(" const size_t data_size = sizeof(data);") << wxT("\n");
out << wxT(" const size_t value_size = strlen(value);") << wxT("\n");
out << wxT(" doDecompress_ExternalData(data, value, data_size, value_size);") << wxT("\n");
out << wxT("}") << wxT("\n");
}
// Register the stream sub suite, by using some stream helper macro.
// Note: Don't forget to connect it to the base suite (See: bstream.cpp => StreamCase::suite())
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(zlibStream)