]>
git.saurik.com Git - wxWidgets.git/blob - src/common/txtstrm.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/txtstrm.cpp
3 // Purpose: Text stream classes
4 // Author: Guilhem Lavaux
7 // Copyright: (c) Guilhem Lavaux
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
20 #include "wx/txtstrm.h"
28 // ----------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
33 wxTextInputStream::wxTextInputStream(wxInputStream
&s
,
36 : m_input(s
), m_separators(sep
), m_conv(conv
.Clone())
38 memset((void*)m_lastBytes
, 0, 10);
41 wxTextInputStream::wxTextInputStream(wxInputStream
&s
, const wxString
&sep
)
42 : m_input(s
), m_separators(sep
)
44 memset((void*)m_lastBytes
, 0, 10);
48 wxTextInputStream::~wxTextInputStream()
52 #endif // wxUSE_UNICODE
55 void wxTextInputStream::UngetLast()
58 while(m_lastBytes
[byteCount
]) // pseudo ANSI strlen (even for Unicode!)
60 m_input
.Ungetch(m_lastBytes
, byteCount
);
61 memset((void*)m_lastBytes
, 0, 10);
64 wxChar
wxTextInputStream::NextChar()
68 memset((void*)m_lastBytes
, 0, 10);
69 for(size_t inlen
= 0; inlen
< 9; inlen
++)
71 // actually read the next character
72 m_lastBytes
[inlen
] = m_input
.GetC();
74 if(m_input
.LastRead() <= 0)
77 switch ( m_conv
->ToWChar(wbuf
, WXSIZEOF(wbuf
), m_lastBytes
, inlen
+ 1) )
80 // this is a bug in converter object as it should either fail
81 // or decode non-empty string to something non-empty
82 wxFAIL_MSG("ToWChar() can't return 0 for non-empty input");
86 // the buffer probably doesn't contain enough bytes to decode
87 // as a complete character, try with more bytes
91 // if we couldn't decode a single character during the last
92 // loop iteration we shouldn't be able to decode 2 or more of
93 // them with an extra single byte, something fishy is going on
94 wxFAIL_MSG("unexpected decoding result");
95 // fall through nevertheless and return at least something
98 // we finally decoded a character
103 // there should be no encoding which requires more than nine bytes for one
104 // character so something must be wrong with our conversion but we have no
105 // way to signal it from here
108 m_lastBytes
[0] = m_input
.GetC();
110 if(m_input
.LastRead() <= 0)
113 return m_lastBytes
[0];
118 wxChar
wxTextInputStream::NextNonSeparators()
122 wxChar c
= NextChar();
123 if (c
== wxEOT
) return (wxChar
) 0;
125 if (c
!= wxT('\n') &&
127 m_separators
.Find(c
) < 0)
133 bool wxTextInputStream::EatEOL(const wxChar
&c
)
135 if (c
== wxT('\n')) return true; // eat on UNIX
137 if (c
== wxT('\r')) // eat on both Mac and DOS
139 wxChar c2
= NextChar();
140 if(c2
== wxEOT
) return true; // end of stream reached, had enough :-)
142 if (c2
!= wxT('\n')) UngetLast(); // Don't eat on Mac
149 wxUint32
wxTextInputStream::Read32(int base
)
151 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
152 if(!m_input
) return 0;
154 wxString word
= ReadWord();
157 return wxStrtoul(word
.c_str(), 0, base
);
160 wxUint16
wxTextInputStream::Read16(int base
)
162 return (wxUint16
)Read32(base
);
165 wxUint8
wxTextInputStream::Read8(int base
)
167 return (wxUint8
)Read32(base
);
170 wxInt32
wxTextInputStream::Read32S(int base
)
172 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
173 if(!m_input
) return 0;
175 wxString word
= ReadWord();
178 return wxStrtol(word
.c_str(), 0, base
);
181 wxInt16
wxTextInputStream::Read16S(int base
)
183 return (wxInt16
)Read32S(base
);
186 wxInt8
wxTextInputStream::Read8S(int base
)
188 return (wxInt8
)Read32S(base
);
191 double wxTextInputStream::ReadDouble()
193 if(!m_input
) return 0;
194 wxString word
= ReadWord();
197 return wxStrtod(word
.c_str(), 0);
200 #if WXWIN_COMPATIBILITY_2_6
202 wxString
wxTextInputStream::ReadString()
207 #endif // WXWIN_COMPATIBILITY_2_6
209 wxString
wxTextInputStream::ReadLine()
213 while ( !m_input
.Eof() )
215 wxChar c
= NextChar();
228 wxString
wxTextInputStream::ReadWord()
235 wxChar c
= NextNonSeparators();
241 while ( !m_input
.Eof() )
247 if (m_separators
.Find(c
) >= 0)
259 wxTextInputStream
& wxTextInputStream::operator>>(wxString
& word
)
265 wxTextInputStream
& wxTextInputStream::operator>>(char& c
)
268 if(m_input
.LastRead() <= 0) c
= 0;
276 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
278 wxTextInputStream
& wxTextInputStream::operator>>(wchar_t& wc
)
285 #endif // wxUSE_UNICODE
287 wxTextInputStream
& wxTextInputStream::operator>>(wxInt16
& i
)
289 i
= (wxInt16
)Read16();
293 wxTextInputStream
& wxTextInputStream::operator>>(wxInt32
& i
)
295 i
= (wxInt32
)Read32();
299 wxTextInputStream
& wxTextInputStream::operator>>(wxUint16
& i
)
305 wxTextInputStream
& wxTextInputStream::operator>>(wxUint32
& i
)
311 wxTextInputStream
& wxTextInputStream::operator>>(double& i
)
317 wxTextInputStream
& wxTextInputStream::operator>>(float& f
)
319 f
= (float)ReadDouble();
326 wxTextOutputStream::wxTextOutputStream(wxOutputStream
& s
,
328 const wxMBConv
& conv
)
329 : m_output(s
), m_conv(conv
.Clone())
331 wxTextOutputStream::wxTextOutputStream(wxOutputStream
& s
, wxEOL mode
)
336 if (m_mode
== wxEOL_NATIVE
)
338 #if defined(__WINDOWS__) || defined(__WXPM__)
346 wxTextOutputStream::~wxTextOutputStream()
350 #endif // wxUSE_UNICODE
353 void wxTextOutputStream::SetMode(wxEOL mode
)
356 if (m_mode
== wxEOL_NATIVE
)
358 #if defined(__WINDOWS__) || defined(__WXPM__)
366 void wxTextOutputStream::Write32(wxUint32 i
)
369 str
.Printf(wxT("%u"), i
);
374 void wxTextOutputStream::Write16(wxUint16 i
)
377 str
.Printf(wxT("%u"), (unsigned)i
);
382 void wxTextOutputStream::Write8(wxUint8 i
)
385 str
.Printf(wxT("%u"), (unsigned)i
);
390 void wxTextOutputStream::WriteDouble(double d
)
394 str
.Printf(wxT("%f"), d
);
398 void wxTextOutputStream::WriteString(const wxString
& string
)
400 size_t len
= string
.length();
405 for ( size_t i
= 0; i
< len
; i
++ )
407 const wxChar c
= string
[i
];
408 if ( c
== wxT('\n') )
421 wxFAIL_MSG( wxT("unknown EOL mode in wxTextOutputStream") );
425 // don't treat '\n' specially
434 // FIXME-UTF8: use wxCharBufferWithLength if/when we have it
435 wxCharBuffer buffer
= m_conv
->cWC2MB(out
.wc_str(), out
.length(), &len
);
436 m_output
.Write(buffer
, len
);
438 m_output
.Write(out
.c_str(), out
.length() );
442 wxTextOutputStream
& wxTextOutputStream::PutChar(wxChar c
)
445 WriteString( wxString(&c
, *m_conv
, 1) );
447 WriteString( wxString(&c
, wxConvLocal
, 1) );
452 void wxTextOutputStream::Flush()
455 const size_t len
= m_conv
->FromWChar(NULL
, 0, L
"", 1);
456 if ( len
> m_conv
->GetMBNulLen() )
458 wxCharBuffer
buf(len
);
459 m_conv
->FromWChar(buf
.data(), len
, L
"", 1);
460 m_output
.Write(buf
, len
- m_conv
->GetMBNulLen());
462 #endif // wxUSE_UNICODE
465 wxTextOutputStream
& wxTextOutputStream::operator<<(const wxString
& string
)
467 WriteString( string
);
471 wxTextOutputStream
& wxTextOutputStream::operator<<(char c
)
473 WriteString( wxString::FromAscii(c
) );
478 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
480 wxTextOutputStream
& wxTextOutputStream::operator<<(wchar_t wc
)
482 WriteString( wxString(&wc
, *m_conv
, 1) );
487 #endif // wxUSE_UNICODE
489 wxTextOutputStream
& wxTextOutputStream::operator<<(wxInt16 c
)
492 str
.Printf(wxT("%d"), (signed int)c
);
498 wxTextOutputStream
& wxTextOutputStream::operator<<(wxInt32 c
)
501 str
.Printf(wxT("%ld"), (signed long)c
);
507 wxTextOutputStream
& wxTextOutputStream::operator<<(wxUint16 c
)
510 str
.Printf(wxT("%u"), (unsigned int)c
);
516 wxTextOutputStream
& wxTextOutputStream::operator<<(wxUint32 c
)
519 str
.Printf(wxT("%lu"), (unsigned long)c
);
525 wxTextOutputStream
&wxTextOutputStream::operator<<(double f
)
531 wxTextOutputStream
& wxTextOutputStream::operator<<(float f
)
533 WriteDouble((double)f
);
537 wxTextOutputStream
&endl( wxTextOutputStream
&stream
)
539 return stream
.PutChar(wxT('\n'));