Files
wxWidgets/src/common/txtstrm.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

544 lines
11 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: src/common/txtstrm.cpp
// Purpose: Text stream classes
// Author: Guilhem Lavaux
// Modified by:
// Created: 28/06/98
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_STREAMS
#include "wx/txtstrm.h"
#ifndef WX_PRECOMP
#include "wx/crt.h"
#endif
#include <ctype.h>
// ----------------------------------------------------------------------------
// wxTextInputStream
// ----------------------------------------------------------------------------
#if wxUSE_UNICODE
wxTextInputStream::wxTextInputStream(wxInputStream &s,
const wxString &sep,
const wxMBConv& conv)
: m_input(s), m_separators(sep), m_conv(conv.Clone())
{
memset((void*)m_lastBytes, 0, 10);
}
#else
wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
: m_input(s), m_separators(sep)
{
memset((void*)m_lastBytes, 0, 10);
}
#endif
wxTextInputStream::~wxTextInputStream()
{
#if wxUSE_UNICODE
delete m_conv;
#endif // wxUSE_UNICODE
}
void wxTextInputStream::UngetLast()
{
size_t byteCount = 0;
while(m_lastBytes[byteCount]) // pseudo ANSI strlen (even for Unicode!)
byteCount++;
m_input.Ungetch(m_lastBytes, byteCount);
memset((void*)m_lastBytes, 0, 10);
}
wxChar wxTextInputStream::NextChar()
{
#if wxUSE_UNICODE
wxChar wbuf[2];
memset((void*)m_lastBytes, 0, 10);
for(size_t inlen = 0; inlen < 9; inlen++)
{
// actually read the next character
m_lastBytes[inlen] = m_input.GetC();
if(m_input.LastRead() <= 0)
return wxEOT;
switch ( m_conv->ToWChar(wbuf, WXSIZEOF(wbuf), m_lastBytes, inlen + 1) )
{
case 0:
// this is a bug in converter object as it should either fail
// or decode non-empty string to something non-empty
wxFAIL_MSG("ToWChar() can't return 0 for non-empty input");
break;
case wxCONV_FAILED:
// the buffer probably doesn't contain enough bytes to decode
// as a complete character, try with more bytes
break;
default:
// if we couldn't decode a single character during the last
// loop iteration we shouldn't be able to decode 2 or more of
// them with an extra single byte, something fishy is going on
wxFAIL_MSG("unexpected decoding result");
// fall through nevertheless and return at least something
case 1:
// we finally decoded a character
return wbuf[0];
}
}
// there should be no encoding which requires more than nine bytes for one
// character so something must be wrong with our conversion but we have no
// way to signal it from here
return wxEOT;
#else
m_lastBytes[0] = m_input.GetC();
if(m_input.LastRead() <= 0)
return wxEOT;
return m_lastBytes[0];
#endif
}
wxChar wxTextInputStream::NextNonSeparators()
{
for (;;)
{
wxChar c = NextChar();
if (c == wxEOT) return (wxChar) 0;
if (c != wxT('\n') &&
c != wxT('\r') &&
m_separators.Find(c) < 0)
return c;
}
}
bool wxTextInputStream::EatEOL(const wxChar &c)
{
if (c == wxT('\n')) return true; // eat on UNIX
if (c == wxT('\r')) // eat on both Mac and DOS
{
wxChar c2 = NextChar();
if(c2 == wxEOT) return true; // end of stream reached, had enough :-)
if (c2 != wxT('\n')) UngetLast(); // Don't eat on Mac
return true;
}
return false;
}
wxUint32 wxTextInputStream::Read32(int base)
{
wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
if(!m_input) return 0;
wxString word = ReadWord();
if(word.empty())
return 0;
return wxStrtoul(word.c_str(), 0, base);
}
wxUint16 wxTextInputStream::Read16(int base)
{
return (wxUint16)Read32(base);
}
wxUint8 wxTextInputStream::Read8(int base)
{
return (wxUint8)Read32(base);
}
wxInt32 wxTextInputStream::Read32S(int base)
{
wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
if(!m_input) return 0;
wxString word = ReadWord();
if(word.empty())
return 0;
return wxStrtol(word.c_str(), 0, base);
}
wxInt16 wxTextInputStream::Read16S(int base)
{
return (wxInt16)Read32S(base);
}
wxInt8 wxTextInputStream::Read8S(int base)
{
return (wxInt8)Read32S(base);
}
double wxTextInputStream::ReadDouble()
{
if(!m_input) return 0;
wxString word = ReadWord();
if(word.empty())
return 0;
return wxStrtod(word.c_str(), 0);
}
#if WXWIN_COMPATIBILITY_2_6
wxString wxTextInputStream::ReadString()
{
return ReadLine();
}
#endif // WXWIN_COMPATIBILITY_2_6
wxString wxTextInputStream::ReadLine()
{
wxString line;
while ( !m_input.Eof() )
{
wxChar c = NextChar();
if(c == wxEOT)
break;
if (EatEOL(c))
break;
line += c;
}
return line;
}
wxString wxTextInputStream::ReadWord()
{
wxString word;
if ( !m_input )
return word;
wxChar c = NextNonSeparators();
if ( !c )
return word;
word += c;
while ( !m_input.Eof() )
{
c = NextChar();
if(c == wxEOT)
break;
if (m_separators.Find(c) >= 0)
break;
if (EatEOL(c))
break;
word += c;
}
return word;
}
wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
{
word = ReadWord();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(char& c)
{
c = m_input.GetC();
if(m_input.LastRead() <= 0) c = 0;
if (EatEOL(c))
c = '\n';
return *this;
}
#if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
wxTextInputStream& wxTextInputStream::operator>>(wchar_t& wc)
{
wc = GetChar();
return *this;
}
#endif // wxUSE_UNICODE
wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
{
i = (wxInt16)Read16();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
{
i = (wxInt32)Read32();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
{
i = Read16();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
{
i = Read32();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(double& i)
{
i = ReadDouble();
return *this;
}
wxTextInputStream& wxTextInputStream::operator>>(float& f)
{
f = (float)ReadDouble();
return *this;
}
#if wxUSE_UNICODE
wxTextOutputStream::wxTextOutputStream(wxOutputStream& s,
wxEOL mode,
const wxMBConv& conv)
: m_output(s), m_conv(conv.Clone())
#else
wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
: m_output(s)
#endif
{
m_mode = mode;
if (m_mode == wxEOL_NATIVE)
{
#if defined(__WINDOWS__) || defined(__WXPM__)
m_mode = wxEOL_DOS;
#else
m_mode = wxEOL_UNIX;
#endif
}
}
wxTextOutputStream::~wxTextOutputStream()
{
#if wxUSE_UNICODE
delete m_conv;
#endif // wxUSE_UNICODE
}
void wxTextOutputStream::SetMode(wxEOL mode)
{
m_mode = mode;
if (m_mode == wxEOL_NATIVE)
{
#if defined(__WINDOWS__) || defined(__WXPM__)
m_mode = wxEOL_DOS;
#else
m_mode = wxEOL_UNIX;
#endif
}
}
void wxTextOutputStream::Write32(wxUint32 i)
{
wxString str;
str.Printf(wxT("%u"), i);
WriteString(str);
}
void wxTextOutputStream::Write16(wxUint16 i)
{
wxString str;
str.Printf(wxT("%u"), (unsigned)i);
WriteString(str);
}
void wxTextOutputStream::Write8(wxUint8 i)
{
wxString str;
str.Printf(wxT("%u"), (unsigned)i);
WriteString(str);
}
void wxTextOutputStream::WriteDouble(double d)
{
wxString str;
str.Printf(wxT("%f"), d);
WriteString(str);
}
void wxTextOutputStream::WriteString(const wxString& string)
{
size_t len = string.length();
wxString out;
out.reserve(len);
for ( size_t i = 0; i < len; i++ )
{
const wxChar c = string[i];
if ( c == wxT('\n') )
{
switch ( m_mode )
{
case wxEOL_DOS:
out << wxT("\r\n");
continue;
case wxEOL_MAC:
out << wxT('\r');
continue;
default:
wxFAIL_MSG( wxT("unknown EOL mode in wxTextOutputStream") );
// fall through
case wxEOL_UNIX:
// don't treat '\n' specially
;
}
}
out << c;
}
#if wxUSE_UNICODE
// FIXME-UTF8: use wxCharBufferWithLength if/when we have it
wxCharBuffer buffer = m_conv->cWC2MB(out.wc_str(), out.length(), &len);
m_output.Write(buffer, len);
#else
m_output.Write(out.c_str(), out.length() );
#endif
}
wxTextOutputStream& wxTextOutputStream::PutChar(wxChar c)
{
#if wxUSE_UNICODE
WriteString( wxString(&c, *m_conv, 1) );
#else
WriteString( wxString(&c, wxConvLocal, 1) );
#endif
return *this;
}
void wxTextOutputStream::Flush()
{
#if wxUSE_UNICODE
const size_t len = m_conv->FromWChar(NULL, 0, L"", 1);
if ( len > m_conv->GetMBNulLen() )
{
wxCharBuffer buf(len);
m_conv->FromWChar(buf.data(), len, L"", 1);
m_output.Write(buf, len - m_conv->GetMBNulLen());
}
#endif // wxUSE_UNICODE
}
wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
{
WriteString( string );
return *this;
}
wxTextOutputStream& wxTextOutputStream::operator<<(char c)
{
WriteString( wxString::FromAscii(c) );
return *this;
}
#if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
wxTextOutputStream& wxTextOutputStream::operator<<(wchar_t wc)
{
WriteString( wxString(&wc, *m_conv, 1) );
return *this;
}
#endif // wxUSE_UNICODE
wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
{
wxString str;
str.Printf(wxT("%d"), (signed int)c);
WriteString(str);
return *this;
}
wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
{
wxString str;
str.Printf(wxT("%ld"), (signed long)c);
WriteString(str);
return *this;
}
wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
{
wxString str;
str.Printf(wxT("%u"), (unsigned int)c);
WriteString(str);
return *this;
}
wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
{
wxString str;
str.Printf(wxT("%lu"), (unsigned long)c);
WriteString(str);
return *this;
}
wxTextOutputStream &wxTextOutputStream::operator<<(double f)
{
WriteDouble(f);
return *this;
}
wxTextOutputStream& wxTextOutputStream::operator<<(float f)
{
WriteDouble((double)f);
return *this;
}
wxTextOutputStream &endl( wxTextOutputStream &stream )
{
return stream.PutChar(wxT('\n'));
}
#endif
// wxUSE_STREAMS