]> git.saurik.com Git - wxWidgets.git/commitdiff
added support for 64 bit ints in wx stream classes (patch 1203970)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Feb 2006 16:51:34 +0000 (16:51 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 11 Feb 2006 16:51:34 +0000 (16:51 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37497 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/longlong.tex
include/wx/datstrm.h
include/wx/defs.h
include/wx/longlong.h
src/common/datstrm.cpp
src/common/longlong.cpp
tests/longlong/longlongtest.cpp
tests/streams/datastreamtest.cpp
tests/streams/textstreamtest.cpp

index 53c813b2060e14a2ed5b246babc3a16e988c373c..c286f988a1bb486e82639bde0619081bd23cd4ef 100644 (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):
 
index 68ed4dfa6a2d9dfec72fa376593b8eef85110650..e34f3672b26687280bfcee1d2c1f257b82f81f42 100644 (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}
index 7551c3c24b9ddf9f638f5f51ba4a242490ca0abc..f49620a6aef16bf72355c8022dd7e634784cfe68 100644 (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);
 
index 0738eb4ec8ee432f6ebcfc6e06b03459f0f9a1cc..a15d8de78cd89adfd26350da197ba5345d5145ca 100644 (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
 
 /*  ---------------------------------------------------------------------------- */
index 0fdf22973ab25d62e6c88932c991ac2043e4dcd5..69b6c4ca477154ab70877313b1b783fd9661a3bd 100644 (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
     // 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
index 0a02f17e8f677dd2843a5ab9d672f9b8695ceec7..656b628b35faa1d5ef437d65dcf21e14b75cc698 100644 (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)
+#if wxUSE_LONGLONG
+
+template <class T>
+static
+void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order)
 {
-  m_input->Read(buffer, size * 8);
+    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 )
+    {
+        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;
+}
 
-  if (m_be_order)
+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 (wxUint32 i=0; i<size; i++)
+    for ( size_t i = 0; i < size; i++ )
     {
-      wxUint64 v = wxUINT64_SWAP_ON_LE(*buffer);
-      *(buffer++) = v;
+      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,16 +454,17 @@ wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
 {
 }
 
+#if wxHAS_INT64
 void wxDataOutputStream::Write64(wxUint64 i)
 {
-  wxUint64 i64;
+  Write64(&i, 1);
+}
 
-  if (m_be_order)
-    i64 = wxUINT64_SWAP_ON_LE(i);
-  else
-    i64 = wxUINT64_SWAP_ON_BE(i);
-  m_output->Write(&i64, 8);
+void wxDataOutputStream::Write64(wxInt64 i)
+{
+  Write64(&i, 1);
 }
+#endif // wxHAS_INT64
 
 void wxDataOutputStream::Write32(wxUint32 i)
 {
@@ -334,27 +522,59 @@ 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)
 {
@@ -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);
index b61b13d159a9f62398572a7ece70e8a5df3268e7..b8364d85799ace4a069e05bd6a508ad57cbac2b2 100644 (file)
 #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
index 3d4815db0958732bcea2874aeb852b344fce76d6..fdeb5fdd716774476373d3160f36acf35b8f3378 100644 (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
index 37778693523e3899151e1e22499dacc6c4066956..efe700336ca51a7ffb7fe678c59f7f42b4e06404 100644 (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?
index 6139092965d721e527077c4b4e080ece2156c3ee..239b37aaa406bac7f2a857eb9c60abcae70b1ce2 100644 (file)
 #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
+