X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/61eb6bb67389fdb59484ee710d20d8689f2cd3f6..76015a6bb79156d8af1b5e8b4b8e46b4e192d18f:/src/common/datstrm.cpp?ds=inline diff --git a/src/common/datstrm.cpp b/src/common/datstrm.cpp index c15d0af639..c55f2134fb 100644 --- a/src/common/datstrm.cpp +++ b/src/common/datstrm.cpp @@ -24,6 +24,24 @@ #include "wx/math.h" #endif //WX_PRECOMP +namespace +{ + +// helper unions used to swap bytes of floats and doubles +union Float32Data +{ + wxFloat32 f; + wxUint32 i; +}; + +union Float64Data +{ + wxFloat64 f; + wxUint32 i[2]; +}; + +} // anonymous namespace + // ---------------------------------------------------------------------------- // wxDataStreamBase // ---------------------------------------------------------------------------- @@ -37,6 +55,12 @@ wxDataStreamBase::wxDataStreamBase(const wxMBConv& conv) wxUnusedVar(conv); m_be_order = false; + + // For compatibility with the existing data files, we use extended + // precision if it is available, i.e. if wxUSE_APPLE_IEEE is on. +#if wxUSE_APPLE_IEEE + m_useExtendedPrecision = true; +#endif // wxUSE_APPLE_IEEE } #if wxUSE_UNICODE @@ -108,13 +132,48 @@ wxUint8 wxDataInputStream::Read8() double wxDataInputStream::ReadDouble() { #if wxUSE_APPLE_IEEE - char buf[10]; + if ( m_useExtendedPrecision ) + { + char buf[10]; - m_input->Read(buf, 10); - return wxConvertFromIeeeExtended((const wxInt8 *)buf); -#else - return 0.0; -#endif + m_input->Read(buf, 10); + return wxConvertFromIeeeExtended((const wxInt8 *)buf); + } + else +#endif // wxUSE_APPLE_IEEE + { + Float64Data floatData; + + if ( m_be_order == (wxBYTE_ORDER == wxBIG_ENDIAN) ) + { + floatData.i[0] = Read32(); + floatData.i[1] = Read32(); + } + else + { + floatData.i[1] = Read32(); + floatData.i[0] = Read32(); + } + + return static_cast(floatData.f); + } +} + +float wxDataInputStream::ReadFloat() +{ +#if wxUSE_APPLE_IEEE + if ( m_useExtendedPrecision ) + { + return (float)ReadDouble(); + } + else +#endif // wxUSE_APPLE_IEEE + { + Float32Data floatData; + + floatData.i = Read32(); + return static_cast(floatData.f); + } } wxString wxDataInputStream::ReadString() @@ -388,6 +447,14 @@ void wxDataInputStream::ReadDouble(double *buffer, size_t size) } } +void wxDataInputStream::ReadFloat(float *buffer, size_t size) +{ + for (wxUint32 i=0; i>(wxString& s) { s = ReadString(); @@ -458,15 +525,15 @@ wxDataInputStream& wxDataInputStream::operator>>(wxLongLong& i) } #endif // wxLongLong_t -wxDataInputStream& wxDataInputStream::operator>>(double& i) +wxDataInputStream& wxDataInputStream::operator>>(double& d) { - i = ReadDouble(); + d = ReadDouble(); return *this; } wxDataInputStream& wxDataInputStream::operator>>(float& f) { - f = (float)ReadDouble(); + f = ReadFloat(); return *this; } @@ -535,22 +602,49 @@ void wxDataOutputStream::WriteString(const wxString& string) void wxDataOutputStream::WriteDouble(double d) { - char buf[10]; +#if wxUSE_APPLE_IEEE + if ( m_useExtendedPrecision ) + { + char buf[10]; + + wxConvertToIeeeExtended(d, (wxInt8 *)buf); + m_output->Write(buf, 10); + } + else +#endif // wxUSE_APPLE_IEEE + { + Float64Data floatData; + floatData.f = (wxFloat64)d; + + if ( m_be_order == (wxBYTE_ORDER == wxBIG_ENDIAN) ) + { + Write32(floatData.i[0]); + Write32(floatData.i[1]); + } + else + { + Write32(floatData.i[1]); + Write32(floatData.i[0]); + } + } +} + +void wxDataOutputStream::WriteFloat(float f) +{ #if wxUSE_APPLE_IEEE - wxConvertToIeeeExtended(d, (wxInt8 *)buf); -#else - wxUnusedVar(d); -#if !defined(__VMS__) && !defined(__GNUG__) -#ifdef _MSC_VER -# pragma message("wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!") -#else -# pragma warning "wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!" -#endif -#endif - buf[0] = '\0'; -#endif - m_output->Write(buf, 10); + if ( m_useExtendedPrecision ) + { + WriteDouble((double)f); + } + else +#endif // wxUSE_APPLE_IEEE + { + Float32Data floatData; + + floatData.f = (wxFloat32)f; + Write32(floatData.i); + } } #if wxHAS_INT64 @@ -664,6 +758,14 @@ void wxDataOutputStream::WriteDouble(const double *buffer, size_t size) } } +void wxDataOutputStream::WriteFloat(const float *buffer, size_t size) +{ + for (wxUint32 i=0; i