added support for 64 bit ints in wx stream classes (patch 1203970)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37497 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2006-02-11 16:51:34 +00:00
parent 87152bb53d
commit 216a72f3b9
10 changed files with 883 additions and 52 deletions

View File

@ -40,6 +40,7 @@ All:
- Fixed wxODBC buffer overflow problem in Unicode builds.
- Fixed wxSocketBase::InterruptWait on wxBase.
- Important code cleanup (Paul Cornett)
- Added support for wxLongLong in wx stream classes (Mark Junker)
All (GUI):

View File

@ -76,6 +76,31 @@ wxLongLong.
Assignment operator from native long long (only for compilers supporting it).
\membersection{wxLongLong::operator=}\label{wxlonglongoperatorassignull}
\func{wxLongLong\& operator}{operator=}{\param{wxULongLong\_t }{ll}}
Assignment operator from native unsigned long long (only for compilers
supporting it).
\membersection{wxLongLong::operator=}\label{wxlonglongoperatorassignlong}
\func{wxLongLong\& operator}{operator=}{\param{long }{l}}
Assignment operator from long.
\membersection{wxLongLong::operator=}\label{wxlonglongoperatorassignulong}
\func{wxLongLong\& operator}{operator=}{\param{unsigned long }{l}}
Assignment operator from unsigned long.
\membersection{wxLongLong::operator=}\label{wxlonglongoperatorassignulonglong}
\func{wxLongLong\& operator}{operator=}{\param{const wxULongLong \& }{ll}}
Assignment operator from unsigned long long. The sign bit will be copied too.
\membersection{wxLongLong::Abs}\label{wxlonglongabs}
\constfunc{wxLongLong}{Abs}{\void}

View File

@ -30,14 +30,30 @@ public:
bool IsOk() { return m_input->IsOk(); }
#if wxHAS_INT64
wxUint64 Read64();
#endif
#if wxUSE_LONGLONG
wxLongLong ReadLL();
#endif
wxUint32 Read32();
wxUint16 Read16();
wxUint8 Read8();
double ReadDouble();
wxString ReadString();
#if wxHAS_INT64
void Read64(wxUint64 *buffer, size_t size);
void Read64(wxInt64 *buffer, size_t size);
#endif
#if defined(wxLongLong_t) && wxUSE_LONGLONG
void Read64(wxULongLong *buffer, size_t size);
void Read64(wxLongLong *buffer, size_t size);
#endif
#if wxUSE_LONGLONG
void ReadLL(wxULongLong *buffer, size_t size);
void ReadLL(wxLongLong *buffer, size_t size);
#endif
void Read32(wxUint32 *buffer, size_t size);
void Read16(wxUint16 *buffer, size_t size);
void Read8(wxUint8 *buffer, size_t size);
@ -50,7 +66,14 @@ public:
wxDataInputStream& operator>>(wxUint8& c);
wxDataInputStream& operator>>(wxUint16& i);
wxDataInputStream& operator>>(wxUint32& i);
#if wxHAS_INT64
wxDataInputStream& operator>>(wxUint64& i);
wxDataInputStream& operator>>(wxInt64& i);
#endif
#if defined(wxLongLong_t) && wxUSE_LONGLONG
wxDataInputStream& operator>>(wxULongLong& i);
wxDataInputStream& operator>>(wxLongLong& i);
#endif
wxDataInputStream& operator>>(double& i);
wxDataInputStream& operator>>(float& f);
@ -78,14 +101,32 @@ public:
bool IsOk() { return m_output->IsOk(); }
#if wxHAS_INT64
void Write64(wxUint64 i);
void Write64(wxInt64 i);
#endif
#if wxUSE_LONGLONG
void WriteLL(const wxLongLong &ll);
void WriteLL(const wxULongLong &ll);
#endif
void Write32(wxUint32 i);
void Write16(wxUint16 i);
void Write8(wxUint8 i);
void WriteDouble(double d);
void WriteString(const wxString& string);
#if wxHAS_INT64
void Write64(const wxUint64 *buffer, size_t size);
void Write64(const wxInt64 *buffer, size_t size);
#endif
#if defined(wxLongLong_t) && wxUSE_LONGLONG
void Write64(const wxULongLong *buffer, size_t size);
void Write64(const wxLongLong *buffer, size_t size);
#endif
#if wxUSE_LONGLONG
void WriteLL(const wxULongLong *buffer, size_t size);
void WriteLL(const wxLongLong *buffer, size_t size);
#endif
void Write32(const wxUint32 *buffer, size_t size);
void Write16(const wxUint16 *buffer, size_t size);
void Write8(const wxUint8 *buffer, size_t size);
@ -99,7 +140,14 @@ public:
wxDataOutputStream& operator<<(wxUint8 c);
wxDataOutputStream& operator<<(wxUint16 i);
wxDataOutputStream& operator<<(wxUint32 i);
#if wxHAS_INT64
wxDataOutputStream& operator<<(wxUint64 i);
wxDataOutputStream& operator<<(wxInt64 i);
#endif
#if defined(wxLongLong_t) && wxUSE_LONGLONG
wxDataOutputStream& operator<<(const wxULongLong &i);
wxDataOutputStream& operator<<(const wxLongLong &i);
#endif
wxDataOutputStream& operator<<(double f);
wxDataOutputStream& operator<<(float f);

View File

@ -1013,6 +1013,23 @@ inline void *wxUIntToPtr(wxUIntPtr p)
typedef wxLongLong_t wxInt64;
typedef wxULongLong_t wxUint64;
#define wxHAS_INT64 1
#elif wxUSE_LONGLONG
/* these macros allow to definea 64 bit constants in a portable way */
#define wxLL(x) wxLongLong(x)
#define wxULL(x) wxULongLong(x)
#define wxInt64 wxLongLong
#define wxUint64 wxULongLong
#define wxHAS_INT64 1
#else // !wxUSE_LONGLONG
#define wxHAS_INT64 0
#endif
@ -1174,7 +1191,7 @@ typedef float wxFloat32;
(((wxUint64) (val) & (wxUint64) wxULL(0x0000ff0000000000)) >> 24) | \
(((wxUint64) (val) & (wxUint64) wxULL(0x00ff000000000000)) >> 40) | \
(((wxUint64) (val) & (wxUint64) wxULL(0xff00000000000000)) >> 56)))
#else /* !wxLongLong_t */
#elif wxUSE_LONGLONG /* !wxLongLong_t */
#define wxUINT64_SWAP_ALWAYS(val) \
((wxUint64) ( \
((wxULongLong(val) & wxULongLong(0L, 0x000000ffU)) << 56) | \
@ -1207,8 +1224,10 @@ typedef float wxFloat32;
#define wxINT32_SWAP_ON_BE(val) wxINT32_SWAP_ALWAYS(val)
#define wxUINT32_SWAP_ON_LE(val) (val)
#define wxINT32_SWAP_ON_LE(val) (val)
#define wxUINT64_SWAP_ON_BE(val) wxUINT64_SWAP_ALWAYS(val)
#define wxUINT64_SWAP_ON_LE(val) (val)
#if wxHAS_INT64
#define wxUINT64_SWAP_ON_BE(val) wxUINT64_SWAP_ALWAYS(val)
#define wxUINT64_SWAP_ON_LE(val) (val)
#endif
#else
#define wxUINT16_SWAP_ON_LE(val) wxUINT16_SWAP_ALWAYS(val)
#define wxINT16_SWAP_ON_LE(val) wxINT16_SWAP_ALWAYS(val)
@ -1218,8 +1237,10 @@ typedef float wxFloat32;
#define wxINT32_SWAP_ON_LE(val) wxINT32_SWAP_ALWAYS(val)
#define wxUINT32_SWAP_ON_BE(val) (val)
#define wxINT32_SWAP_ON_BE(val) (val)
#define wxUINT64_SWAP_ON_LE(val) wxUINT64_SWAP_ALWAYS(val)
#define wxUINT64_SWAP_ON_BE(val) (val)
#if wxHAS_INT64
#define wxUINT64_SWAP_ON_LE(val) wxUINT64_SWAP_ALWAYS(val)
#define wxUINT64_SWAP_ON_BE(val) (val)
#endif
#endif
/* ---------------------------------------------------------------------------- */

View File

@ -14,6 +14,9 @@
#define _WX_LONGLONG_H
#include "wx/defs.h"
#if wxUSE_LONGLONG
#include "wx/string.h"
#include <limits.h> // for LONG_MAX
@ -39,7 +42,12 @@
// unknown pragma should never be an error -- except that, actually, some
// broken compilers don't like it, so we have to disable it in this case
// <sigh>
#if !(defined(__WATCOMC__) || defined(__VISAGECPP__))
#ifdef __GNUC__
#warning "Your compiler does not appear to support 64 bit "\
"integers, using emulation class instead.\n" \
"Please report your compiler version to " \
"wx-dev@lists.wxwidgets.org!"
#elif !(defined(__WATCOMC__) || defined(__VISAGECPP__))
#pragma warning "Your compiler does not appear to support 64 bit "\
"integers, using emulation class instead.\n" \
"Please report your compiler version to " \
@ -123,8 +131,16 @@ public:
// from native 64 bit integer
wxLongLongNative& operator=(wxLongLong_t ll)
{ m_ll = ll; return *this; }
wxLongLongNative& operator=(wxULongLong_t ll)
{ m_ll = ll; return *this; }
wxLongLongNative& operator=(const wxULongLongNative &ll);
wxLongLongNative& operator=(long l)
{ m_ll = l; return *this; }
wxLongLongNative& operator=(unsigned long l)
{ m_ll = l; return *this; }
#if wxUSE_LONGLONG_WX
wxLongLongNative& operator=(wxLongLongWx ll);
wxLongLongNative& operator=(const class wxULongLongWx &ll);
#endif
@ -307,6 +323,13 @@ public:
friend WXDLLIMPEXP_BASE
wxString& operator<<(wxString&, const wxLongLongNative&);
#if wxUSE_STREAMS
friend WXDLLIMPEXP_BASE
class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongNative&);
friend WXDLLIMPEXP_BASE
class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongNative&);
#endif
private:
wxLongLong_t m_ll;
};
@ -328,6 +351,10 @@ public:
m_ll |= (wxULongLong_t) lo;
}
#if wxUSE_LONGLONG_WX
wxULongLongNative(const class wxULongLongWx &ll);
#endif
// default copy ctor is ok
// no dtor
@ -336,6 +363,18 @@ public:
// from native 64 bit integer
wxULongLongNative& operator=(wxULongLong_t ll)
{ m_ll = ll; return *this; }
wxULongLongNative& operator=(wxLongLong_t ll)
{ m_ll = ll; return *this; }
wxULongLongNative& operator=(long l)
{ m_ll = l; return *this; }
wxULongLongNative& operator=(unsigned long l)
{ m_ll = l; return *this; }
wxULongLongNative& operator=(const wxLongLongNative &ll)
{ m_ll = ll.GetValue(); return *this; }
#if wxUSE_LONGLONG_WX
wxULongLongNative& operator=(wxLongLongWx ll);
wxULongLongNative& operator=(const class wxULongLongWx &ll);
#endif
// assignment operators from wxULongLongNative is ok
@ -494,10 +533,24 @@ public:
friend WXDLLIMPEXP_BASE
wxString& operator<<(wxString&, const wxULongLongNative&);
#if wxUSE_STREAMS
friend WXDLLIMPEXP_BASE
class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongNative&);
friend WXDLLIMPEXP_BASE
class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongNative&);
#endif
private:
wxULongLong_t m_ll;
};
inline
wxLongLongNative& wxLongLongNative::operator=(const wxULongLongNative &ll)
{
m_ll = ll.GetValue();
return *this;
}
#endif // wxUSE_LONGLONG_NATIVE
#if wxUSE_LONGLONG_WX
@ -553,7 +606,22 @@ public:
return *this;
}
// from double
wxLongLongWx& operator=(unsigned long l)
{
m_lo = l;
m_hi = 0;
#ifdef wxLONGLONG_TEST_MODE
m_ll = l;
Check();
#endif // wxLONGLONG_TEST_MODE
return *this;
}
wxLongLongWx& operator=(const class wxULongLongWx &ll);
// from double
wxLongLongWx& Assign(double d);
// can't have assignment operator from 2 longs
@ -693,6 +761,13 @@ public:
friend WXDLLIMPEXP_BASE
wxString& operator<<(wxString&, const wxLongLongWx&);
#if wxUSE_STREAMS
friend WXDLLIMPEXP_BASE
class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongWx&);
friend WXDLLIMPEXP_BASE
class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongWx&);
#endif
private:
// long is at least 32 bits, so represent our 64bit number as 2 longs
@ -769,6 +844,26 @@ public:
return *this;
}
wxULongLongWx& operator=(long l)
{
m_lo = l;
m_hi = (unsigned long) ((l<0) ? -1l : 0);
#ifdef wxLONGLONG_TEST_MODE
m_ll = (wxULongLong_t) (wxLongLong_t) l;
Check();
#endif // wxLONGLONG_TEST_MODE
return *this;
}
wxULongLongWx& operator=(const class wxLongLongWx &ll) {
// Should we use an assert like it was before in the constructor?
// wxASSERT(ll.GetHi() >= 0);
m_hi = (unsigned long)ll.GetHi();
m_lo = ll.GetLo();
return *this;
}
// can't have assignment operator from 2 longs
@ -879,6 +974,13 @@ public:
friend WXDLLIMPEXP_BASE
wxString& operator<<(wxString&, const wxULongLongWx&);
#if wxUSE_STREAMS
friend WXDLLIMPEXP_BASE
class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongWx&);
friend WXDLLIMPEXP_BASE
class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongWx&);
#endif
private:
// long is at least 32 bits, so represent our 64bit number as 2 longs
@ -929,4 +1031,16 @@ inline wxLongLong operator-(unsigned long l, const wxULongLong& ull)
return wxLongLong((long)ret.GetHi(),ret.GetLo());
}
#if wxUSE_LONGLONG_NATIVE && wxUSE_STREAMS
WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value);
WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value);
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value);
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxLongLong_t &value);
#endif
#endif // wxUSE_LONGLONG
#endif // _WX_LONGLONG_H

View File

@ -35,17 +35,14 @@ wxDataInputStream::wxDataInputStream(wxInputStream& s)
{
}
#if wxHAS_INT64
wxUint64 wxDataInputStream::Read64()
{
wxUint64 i64;
m_input->Read(&i64, 8);
if (m_be_order)
return wxUINT64_SWAP_ON_LE(i64);
else
return wxUINT64_SWAP_ON_BE(i64);
wxUint64 tmp;
Read64(&tmp, 1);
return tmp;
}
#endif // wxHAS_INT64
wxUint32 wxDataInputStream::Read32()
{
@ -114,28 +111,196 @@ wxString wxDataInputStream::ReadString()
return wxEmptyString;
}
void wxDataInputStream::Read64(wxUint64 *buffer, size_t size)
{
m_input->Read(buffer, size * 8);
#if wxUSE_LONGLONG
if (m_be_order)
{
for (wxUint32 i=0; i<size; i++)
template <class T>
static
void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order)
{
typedef T DataType;
unsigned char *pchBuffer = new unsigned char[size * 8];
// TODO: Check for overflow when size is of type uint and is > than 512m
input->Read(pchBuffer, size * 8);
size_t idx_base = 0;
if ( be_order )
{
wxUint64 v = wxUINT64_SWAP_ON_LE(*buffer);
*(buffer++) = v;
for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex )
{
buffer[uiIndex] = 0l;
for ( unsigned ui = 0; ui != 8; ++ui )
{
buffer[uiIndex] = buffer[uiIndex] * 256l +
DataType((unsigned long) pchBuffer[idx_base + ui]);
}
idx_base += 8;
}
}
else // little endian
{
for ( size_t uiIndex=0; uiIndex!=size; ++uiIndex )
{
buffer[uiIndex] = 0l;
for ( unsigned ui=0; ui!=8; ++ui )
buffer[uiIndex] = buffer[uiIndex] * 256l +
DataType((unsigned long) pchBuffer[idx_base + 7 - ui]);
idx_base += 8;
}
}
delete[] pchBuffer;
}
template <class T>
static void DoWriteLL(const T *buffer, size_t size, wxOutputStream *output, bool be_order)
{
typedef T DataType;
unsigned char *pchBuffer = new unsigned char[size * 8];
size_t idx_base = 0;
if ( be_order )
{
for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex )
{
DataType i64 = buffer[uiIndex];
for ( unsigned ui = 0; ui != 8; ++ui )
{
pchBuffer[idx_base + 7 - ui] =
(unsigned char) (i64.GetLo() & 255l);
i64 >>= 8l;
}
idx_base += 8;
}
}
else // little endian
{
for ( size_t uiIndex=0; uiIndex != size; ++uiIndex )
{
DataType i64 = buffer[uiIndex];
for (unsigned ui=0; ui!=8; ++ui)
{
pchBuffer[idx_base + ui] =
(unsigned char) (i64.GetLo() & 255l);
i64 >>= 8l;
}
idx_base += 8;
}
}
// TODO: Check for overflow when size is of type uint and is > than 512m
output->Write(pchBuffer, size * 8);
delete[] pchBuffer;
}
#endif // wxUSE_LONGLONG
#ifdef wxLongLong_t
template <class T>
static
void DoReadI64(T *buffer, size_t size, wxInputStream *input, bool be_order)
{
typedef T DataType;
unsigned char *pchBuffer = (unsigned char*) buffer;
// TODO: Check for overflow when size is of type uint and is > than 512m
input->Read(pchBuffer, size * 8);
if ( be_order )
{
for ( wxUint32 i = 0; i < size; i++ )
{
DataType v = wxUINT64_SWAP_ON_LE(*buffer);
*(buffer++) = v;
}
}
else // little endian
{
for ( wxUint32 i=0; i<size; i++ )
{
DataType v = wxUINT64_SWAP_ON_BE(*buffer);
*(buffer++) = v;
}
}
}
template <class T>
static
void DoWriteI64(const T *buffer, size_t size, wxOutputStream *output, bool be_order)
{
typedef T DataType;
if ( be_order )
{
for ( size_t i = 0; i < size; i++ )
{
DataType i64 = wxUINT64_SWAP_ON_LE(*buffer);
buffer++;
output->Write(&i64, 8);
}
}
else
else // little endian
{
for (wxUint32 i=0; i<size; i++)
for ( size_t i=0; i < size; i++ )
{
wxUint64 v = wxUINT64_SWAP_ON_BE(*buffer);
*(buffer++) = v;
DataType i64 = wxUINT64_SWAP_ON_BE(*buffer);
buffer++;
output->Write(&i64, 8);
}
}
}
#endif // wxLongLong_t
#if wxHAS_INT64
void wxDataInputStream::Read64(wxUint64 *buffer, size_t size)
{
#ifndef wxLongLong_t
DoReadLL(buffer, size, m_input, m_be_order);
#else
DoReadI64(buffer, size, m_input, m_be_order);
#endif
}
void wxDataInputStream::Read64(wxInt64 *buffer, size_t size)
{
#ifndef wxLongLong_t
DoReadLL(buffer, size, m_input, m_be_order);
#else
DoReadI64(buffer, size, m_input, m_be_order);
#endif
}
#endif // wxHAS_INT64
#if defined(wxLongLong_t) && wxUSE_LONGLONG
void wxDataInputStream::Read64(wxULongLong *buffer, size_t size)
{
DoReadLL(buffer, size, m_input, m_be_order);
}
void wxDataInputStream::Read64(wxLongLong *buffer, size_t size)
{
DoReadLL(buffer, size, m_input, m_be_order);
}
#endif // wxLongLong_t
#if wxUSE_LONGLONG
void wxDataInputStream::ReadLL(wxULongLong *buffer, size_t size)
{
DoReadLL(buffer, size, m_input, m_be_order);
}
void wxDataInputStream::ReadLL(wxLongLong *buffer, size_t size)
{
DoReadLL(buffer, size, m_input, m_be_order);
}
wxLongLong wxDataInputStream::ReadLL(void)
{
wxLongLong ll;
DoReadLL(&ll, 1, m_input, m_be_order);
return ll;
}
#endif // wxUSE_LONGLONG
void wxDataInputStream::Read32(wxUint32 *buffer, size_t size)
{
m_input->Read(buffer, size * 4);
@ -235,12 +400,34 @@ wxDataInputStream& wxDataInputStream::operator>>(wxUint32& i)
return *this;
}
#if wxHAS_INT64
wxDataInputStream& wxDataInputStream::operator>>(wxUint64& i)
{
i = Read64();
return *this;
}
wxDataInputStream& wxDataInputStream::operator>>(wxInt64& i)
{
i = Read64();
return *this;
}
#endif // wxHAS_INT64
#if defined(wxLongLong_t) && wxUSE_LONGLONG
wxDataInputStream& wxDataInputStream::operator>>(wxULongLong& i)
{
i = ReadLL();
return *this;
}
wxDataInputStream& wxDataInputStream::operator>>(wxLongLong& i)
{
i = ReadLL();
return *this;
}
#endif // wxLongLong_t
wxDataInputStream& wxDataInputStream::operator>>(double& i)
{
i = ReadDouble();
@ -267,17 +454,18 @@ wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
{
}
#if wxHAS_INT64
void wxDataOutputStream::Write64(wxUint64 i)
{
wxUint64 i64;
if (m_be_order)
i64 = wxUINT64_SWAP_ON_LE(i);
else
i64 = wxUINT64_SWAP_ON_BE(i);
m_output->Write(&i64, 8);
Write64(&i, 1);
}
void wxDataOutputStream::Write64(wxInt64 i)
{
Write64(&i, 1);
}
#endif // wxHAS_INT64
void wxDataOutputStream::Write32(wxUint32 i)
{
wxUint32 i32;
@ -334,28 +522,60 @@ void wxDataOutputStream::WriteDouble(double d)
m_output->Write(buf, 10);
}
#if wxHAS_INT64
void wxDataOutputStream::Write64(const wxUint64 *buffer, size_t size)
{
if (m_be_order)
{
for (wxUint32 i=0; i<size ;i++)
{
wxUint64 i64 = wxUINT64_SWAP_ON_LE(*buffer);
buffer++;
m_output->Write(&i64, 8);
}
}
else
{
for (wxUint32 i=0; i<size ;i++)
{
wxUint64 i64 = wxUINT64_SWAP_ON_BE(*buffer);
buffer++;
m_output->Write(&i64, 8);
}
}
#ifndef wxLongLong_t
DoWriteLL(buffer, size, m_output, m_be_order);
#else
DoWriteI64(buffer, size, m_output, m_be_order);
#endif
}
void wxDataOutputStream::Write64(const wxInt64 *buffer, size_t size)
{
#ifndef wxLongLong_t
DoWriteLL(buffer, size, m_output, m_be_order);
#else
DoWriteI64(buffer, size, m_output, m_be_order);
#endif
}
#endif // wxHAS_INT64
#if defined(wxLongLong_t) && wxUSE_LONGLONG
void wxDataOutputStream::Write64(const wxULongLong *buffer, size_t size)
{
DoWriteLL(buffer, size, m_output, m_be_order);
}
void wxDataOutputStream::Write64(const wxLongLong *buffer, size_t size)
{
DoWriteLL(buffer, size, m_output, m_be_order);
}
#endif // wxLongLong_t
#if wxUSE_LONGLONG
void wxDataOutputStream::WriteLL(const wxULongLong *buffer, size_t size)
{
DoWriteLL(buffer, size, m_output, m_be_order);
}
void wxDataOutputStream::WriteLL(const wxLongLong *buffer, size_t size)
{
DoWriteLL(buffer, size, m_output, m_be_order);
}
void wxDataOutputStream::WriteLL(const wxLongLong &ll)
{
WriteLL(&ll, 1);
}
void wxDataOutputStream::WriteLL(const wxULongLong &ll)
{
WriteLL(&ll, 1);
}
#endif // wxUSE_LONGLONG
void wxDataOutputStream::Write32(const wxUint32 *buffer, size_t size)
{
if (m_be_order)
@ -462,12 +682,34 @@ wxDataOutputStream& wxDataOutputStream::operator<<(wxUint32 i)
return *this;
}
#if wxHAS_INT64
wxDataOutputStream& wxDataOutputStream::operator<<(wxUint64 i)
{
Write64(i);
return *this;
}
wxDataOutputStream& wxDataOutputStream::operator<<(wxInt64 i)
{
Write64(i);
return *this;
}
#endif // wxHAS_INT64
#if defined(wxLongLong_t) && wxUSE_LONGLONG
wxDataOutputStream& wxDataOutputStream::operator<<(const wxULongLong &i)
{
WriteLL(i);
return *this;
}
wxDataOutputStream& wxDataOutputStream::operator<<(const wxLongLong &i)
{
WriteLL(i);
return *this;
}
#endif // wxLongLong_t
wxDataOutputStream& wxDataOutputStream::operator<<(double f)
{
WriteDouble(f);

View File

@ -25,6 +25,10 @@
#include "wx/longlong.h"
#include "wx/math.h" // for fabs()
#if wxUSE_STREAMS
#include "wx/txtstrm.h"
#endif
#if defined(__MWERKS__) && defined(__WXMSW__)
#include <string.h> // for memset()
#else
@ -92,6 +96,41 @@ wxLongLongNative& wxLongLongNative::operator=(wxLongLongWx ll)
m_ll |= ll.GetLo();
return *this;
}
wxLongLongNative& wxLongLongNative::operator=(const class wxULongLongWx &ll)
{
// assign first to avoid precision loss!
m_ll = ll.GetHi();
m_ll <<= 32;
m_ll |= ll.GetLo();
return *this;
}
wxULongLongNative::wxULongLongNative(const class wxULongLongWx &ll)
{
// assign first to avoid precision loss!
m_ll = ll.GetHi();
m_ll <<= 32;
m_ll |= ((unsigned long) ll.GetLo());
}
wxULongLongNative& wxULongLongNative::operator=(wxLongLongWx ll)
{
// assign first to avoid precision loss!
m_ll = ll.GetHi();
m_ll <<= 32;
m_ll |= ((unsigned long) ll.GetLo());
return *this;
}
wxULongLongNative& wxULongLongNative::operator=(const class wxULongLongWx &ll)
{
// assign first to avoid precision loss!
m_ll = ll.GetHi();
m_ll <<= 32;
m_ll |= ((unsigned long) ll.GetLo());
return *this;
}
#endif
#endif // wxUSE_LONGLONG_NATIVE
@ -102,6 +141,14 @@ wxLongLongNative& wxLongLongNative::operator=(wxLongLongWx ll)
#if wxUSE_LONGLONG_WX
// Set value from unsigned wxULongLongWx
wxLongLongWx &wxLongLongWx::operator=(const class wxULongLongWx &ll)
{
m_hi = (unsigned long) ll.GetHi();
m_lo = ll.GetLo();
return *this;
}
// assignment
wxLongLongWx& wxLongLongWx::Assign(double d)
{
@ -1191,4 +1238,113 @@ WXDLLIMPEXP_BASE wxString& operator<< (wxString& s, const wxULongLong& ll)
return s << ll.ToString();
}
#if wxUSE_STREAMS
WXDLLIMPEXP_BASE wxTextOutputStream& operator<< (wxTextOutputStream& o, const wxULongLong& ll)
{
return o << ll.ToString();
}
WXDLLIMPEXP_BASE wxTextOutputStream& operator<< (wxTextOutputStream& o, const wxLongLong& ll)
{
return o << ll.ToString();
}
#define READ_STRING_CHAR(s, idx, len) ((wxChar) ((idx!=len) ? s[idx++] : 0))
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &o, wxULongLong &ll)
{
wxString s = o.ReadWord();
ll = wxULongLong(0l, 0l);
size_t length = s.Length();
size_t idx = 0;
wxChar ch = READ_STRING_CHAR(s, idx, length);
// Skip WS
while (ch==wxT(' ') || ch==wxT('\t'))
ch = READ_STRING_CHAR(s, idx, length);
// Read number
wxULongLong multiplier(0l, 10l);
while (ch>=wxT('0') && ch<=wxT('9')) {
long lValue = (unsigned) (ch - wxT('0'));
ll = ll * multiplier + wxULongLong(0l, lValue);
ch = READ_STRING_CHAR(s, idx, length);
}
return o;
}
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &o, wxLongLong &ll)
{
wxString s = o.ReadWord();
ll = wxLongLong(0l, 0l);
size_t length = s.Length();
size_t idx = 0;
wxChar ch = READ_STRING_CHAR(s, idx, length);
// Skip WS
while (ch==wxT(' ') || ch==wxT('\t'))
ch = READ_STRING_CHAR(s, idx, length);
// Ask for sign
int iSign = 1;
if (ch==wxT('-') || ch==wxT('+')) {
iSign = ((ch==wxT('-')) ? -1 : 1);
ch = READ_STRING_CHAR(s, idx, length);
}
// Read number
wxLongLong multiplier(0l, 10l);
while (ch>=wxT('0') && ch<=wxT('9')) {
long lValue = (unsigned) (ch - wxT('0'));
ll = ll * multiplier + wxLongLong(0l, lValue);
ch = READ_STRING_CHAR(s, idx, length);
}
#if wxUSE_LONGLONG_NATIVE
ll = ll * wxLongLong((wxLongLong_t) iSign);
#else
ll = ll * wxLongLong((long) iSign);
#endif
return o;
}
#if wxUSE_LONGLONG_NATIVE
WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &o, wxULongLong_t value)
{
return o << wxULongLong(value).ToString();
}
WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &o, wxLongLong_t value)
{
return o << wxLongLong(value).ToString();
}
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &o, wxULongLong_t &value)
{
wxULongLong ll;
o >> ll;
value = ll.GetValue();
return o;
}
WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &o, wxLongLong_t &value)
{
wxLongLong ll;
o >> ll;
value = ll.GetValue();
return o;
}
#endif // wxUSE_LONGLONG_NATIVE
#endif // wxUSE_STREAMS
#endif // wxUSE_LONGLONG

View File

@ -24,6 +24,8 @@
#include "wx/longlong.h"
#include "wx/timer.h"
#if wxUSE_LONGLONG
// ----------------------------------------------------------------------------
// helpers for testing
// ----------------------------------------------------------------------------
@ -322,3 +324,4 @@ void LongLongTestCase::ToString()
}
#endif // wxUSE_LONGLONG

View File

@ -21,6 +21,8 @@
#include "wx/wx.h"
#endif // WX_PRECOMP
#include <vector>
#include "wx/datstrm.h"
#include "wx/wfstream.h"
#include "wx/math.h"
@ -38,11 +40,23 @@ private:
CPPUNIT_TEST_SUITE( DataStreamTestCase );
CPPUNIT_TEST( FloatRW );
CPPUNIT_TEST( DoubleRW );
#if wxUSE_LONGLONG
CPPUNIT_TEST( LongLongRW );
#endif
#if wxHAS_INT64
CPPUNIT_TEST( Int64RW );
#endif
CPPUNIT_TEST( NaNRW );
CPPUNIT_TEST_SUITE_END();
void FloatRW();
void DoubleRW();
#if wxUSE_LONGLONG
void LongLongRW();
#endif
#if wxHAS_INT64
void Int64RW();
#endif
void NaNRW();
DECLARE_NO_COPY_CLASS(DataStreamTestCase)
@ -58,6 +72,7 @@ DataStreamTestCase::DataStreamTestCase()
{
}
static
wxFloat64 TestFloatRW(wxFloat64 fValue)
{
wxFileOutputStream* pFileOutput = new wxFileOutputStream( _T("mytext.dat") );
@ -81,6 +96,91 @@ wxFloat64 TestFloatRW(wxFloat64 fValue)
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);
{
wxFileOutputStream FileOutput( _T("mytext.dat") );
wxDataOutputStream DataOutput( FileOutput );
(DataOutput.*pfnWriter)(Values, Size);
}
{
wxFileInputStream FileInput( _T("mytext.dat") );
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 Ok(void) const {
return m_ok;
}
};
template <class T>
static
T TestRW(const T &Value)
{
T InValue;
{
wxFileOutputStream FileOutput( _T("mytext.dat") );
wxDataOutputStream DataOutput( FileOutput );
DataOutput << Value;
}
{
wxFileInputStream FileInput( _T("mytext.dat") );
wxDataInputStream DataInput( FileInput );
DataInput >> InValue;
}
return InValue;
}
void DataStreamTestCase::FloatRW()
{
CPPUNIT_ASSERT( TestFloatRW(5.5) == 5.5 );
@ -95,6 +195,54 @@ void DataStreamTestCase::DoubleRW()
CPPUNIT_ASSERT( TestFloatRW(21321343431.1232143432) == 21321343431.1232143432 );
}
#if wxUSE_LONGLONG
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).Ok() );
CPPUNIT_ASSERT( TestMultiRW<wxULongLong>(ValuesULL, &wxDataOutputStream::WriteLL, &wxDataInputStream::ReadLL).Ok() );
}
#endif
#if wxHAS_INT64
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).Ok() );
CPPUNIT_ASSERT( TestMultiRW<wxUint64>(ValuesUI64, &wxDataOutputStream::Write64, &wxDataInputStream::Read64).Ok() );
}
#endif
void DataStreamTestCase::NaNRW()
{
//TODO?

View File

@ -24,6 +24,10 @@
#include "wx/txtstrm.h"
#include "wx/wfstream.h"
#if wxUSE_LONGLONG
#include "wx/longlong.h"
#endif
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
@ -36,9 +40,17 @@ public:
private:
CPPUNIT_TEST_SUITE( TextStreamTestCase );
CPPUNIT_TEST( Endline );
#if wxUSE_LONGLONG
CPPUNIT_TEST( TestLongLong );
CPPUNIT_TEST( TestLongLong );
#endif
CPPUNIT_TEST_SUITE_END();
void Endline();
#if wxUSE_LONGLONG
void TestLongLong();
void TestULongLong();
#endif // wxUSE_LONGLONG
DECLARE_NO_COPY_CLASS(TextStreamTestCase)
@ -85,3 +97,64 @@ void TextStreamTestCase::Endline()
delete pInFile;
}
#if wxUSE_LONGLONG
template <typename T>
static void DoTestRoundTrip(const T *values, size_t numValues)
{
{
wxFileOutputStream fileOut(_T("test.txt"));
wxTextOutputStream textOut(fileOut);
for ( size_t n = 0; n < numValues; n++ )
{
textOut << values[n] << endl;
}
}
{
wxFileInputStream fileIn(_T("test.txt"));
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));
}
#endif // wxUSE_LONGLONG