]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/txtstrm.cpp
Applied patch [ 1378183 ] Mac: wxNotebook::HitTest off by one
[wxWidgets.git] / src / common / txtstrm.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: txtstrm.cpp
3// Purpose: Text stream classes
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 28/06/98
7// RCS-ID: $Id$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#if wxUSE_STREAMS
20
21#include "wx/txtstrm.h"
22#include <ctype.h>
23
24
25// ----------------------------------------------------------------------------
26// constants
27// ----------------------------------------------------------------------------
28
29// Unix: "\n"
30// Dos: "\r\n"
31// Mac: "\r"
32
33// ----------------------------------------------------------------------------
34// wxTextInputStream
35// ----------------------------------------------------------------------------
36
37#if wxUSE_UNICODE
38wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep, wxMBConv& conv)
39 : m_input(s), m_separators(sep), m_conv(conv)
40{
41 memset((void*)m_lastBytes, 0, 10);
42}
43#else
44wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
45 : m_input(s), m_separators(sep)
46{
47 memset((void*)m_lastBytes, 0, 10);
48}
49#endif
50
51wxTextInputStream::~wxTextInputStream()
52{
53}
54
55void wxTextInputStream::UngetLast()
56{
57 size_t byteCount = 0;
58 while(m_lastBytes[byteCount]) // pseudo ANSI strlen (even for Unicode!)
59 byteCount++;
60 m_input.Ungetch(m_lastBytes, byteCount);
61 memset((void*)m_lastBytes, 0, 10);
62}
63
64wxChar wxTextInputStream::NextChar()
65{
66#if wxUSE_UNICODE
67 wxChar wbuf[2];
68 memset((void*)m_lastBytes, 0, 10);
69 for(size_t inlen = 0; inlen < 9; inlen++)
70 {
71 // actually read the next character
72 m_lastBytes[inlen] = m_input.GetC();
73
74 if(m_input.LastRead() <= 0)
75 return wxEOT;
76
77 int retlen = (int) m_conv.MB2WC(wbuf, m_lastBytes, 2); // returns -1 for failure
78 if(retlen >= 0) // res == 0 could happen for '\0' char
79 return wbuf[0];
80 }
81 // there should be no encoding which requires more than nine bytes for one character...
82 return wxEOT;
83#else
84 m_lastBytes[0] = m_input.GetC();
85
86 if(m_input.LastRead() <= 0)
87 return wxEOT;
88
89 return m_lastBytes[0];
90#endif
91
92}
93
94wxChar wxTextInputStream::NextNonSeparators()
95{
96 for (;;)
97 {
98 wxChar c = NextChar();
99 if (c == wxEOT) return (wxChar) 0;
100
101 if (c != wxT('\n') &&
102 c != wxT('\r') &&
103 !m_separators.Contains(c))
104 return c;
105 }
106
107}
108
109bool wxTextInputStream::EatEOL(const wxChar &c)
110{
111 if (c == wxT('\n')) return true; // eat on UNIX
112
113 if (c == wxT('\r')) // eat on both Mac and DOS
114 {
115 wxChar c2 = NextChar();
116 if(c2 == wxEOT) return true; // end of stream reached, had enough :-)
117
118 if (c2 != wxT('\n')) UngetLast(); // Don't eat on Mac
119 return true;
120 }
121
122 return false;
123}
124
125wxUint32 wxTextInputStream::Read32(int base)
126{
127 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
128 if(!m_input) return 0;
129
130 wxString word = ReadWord();
131 if(word.empty())
132 return 0;
133 return wxStrtoul(word.c_str(), 0, base);
134}
135
136wxUint16 wxTextInputStream::Read16(int base)
137{
138 return (wxUint16)Read32(base);
139}
140
141wxUint8 wxTextInputStream::Read8(int base)
142{
143 return (wxUint8)Read32(base);
144}
145
146wxInt32 wxTextInputStream::Read32S(int base)
147{
148 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
149 if(!m_input) return 0;
150
151 wxString word = ReadWord();
152 if(word.empty())
153 return 0;
154 return wxStrtol(word.c_str(), 0, base);
155}
156
157wxInt16 wxTextInputStream::Read16S(int base)
158{
159 return (wxInt16)Read32S(base);
160}
161
162wxInt8 wxTextInputStream::Read8S(int base)
163{
164 return (wxInt8)Read32S(base);
165}
166
167double wxTextInputStream::ReadDouble()
168{
169 if(!m_input) return 0;
170 wxString word = ReadWord();
171 if(word.empty())
172 return 0;
173 return wxStrtod(word.c_str(), 0);
174}
175
176wxString wxTextInputStream::ReadString()
177{
178 return ReadLine();
179}
180
181wxString wxTextInputStream::ReadLine()
182{
183 wxString line;
184
185 while ( !m_input.Eof() )
186 {
187 wxChar c = NextChar();
188 if(c == wxEOT)
189 break;
190
191 if ( !m_input )
192 break;
193
194 if (EatEOL(c))
195 break;
196
197 line += c;
198 }
199
200 return line;
201}
202
203wxString wxTextInputStream::ReadWord()
204{
205 wxString word;
206
207 if ( !m_input )
208 return word;
209
210 wxChar c = NextNonSeparators();
211 if ( !c )
212 return word;
213
214 word += c;
215
216 while ( !m_input.Eof() )
217 {
218 c = NextChar();
219 if(c == wxEOT)
220 break;
221
222 if (m_separators.Contains(c))
223 break;
224
225 if (EatEOL(c))
226 break;
227
228 word += c;
229 }
230
231 return word;
232}
233
234wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
235{
236 word = ReadWord();
237 return *this;
238}
239
240wxTextInputStream& wxTextInputStream::operator>>(char& c)
241{
242 c = m_input.GetC();
243 if(m_input.LastRead() <= 0) c = 0;
244
245 if (EatEOL(c))
246 c = '\n';
247
248 return *this;
249}
250
251#if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
252
253wxTextInputStream& wxTextInputStream::operator>>(wchar_t& wc)
254{
255 wc = GetChar();
256
257 return *this;
258}
259
260#endif // wxUSE_UNICODE
261
262wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
263{
264 i = (wxInt16)Read16();
265 return *this;
266}
267
268wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
269{
270 i = (wxInt32)Read32();
271 return *this;
272}
273
274wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
275{
276 i = Read16();
277 return *this;
278}
279
280wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
281{
282 i = Read32();
283 return *this;
284}
285
286wxTextInputStream& wxTextInputStream::operator>>(double& i)
287{
288 i = ReadDouble();
289 return *this;
290}
291
292wxTextInputStream& wxTextInputStream::operator>>(float& f)
293{
294 f = (float)ReadDouble();
295 return *this;
296}
297
298
299
300#if wxUSE_UNICODE
301wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode, wxMBConv& conv)
302 : m_output(s), m_conv(conv)
303#else
304wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
305 : m_output(s)
306#endif
307{
308 m_mode = mode;
309 if (m_mode == wxEOL_NATIVE)
310 {
311#if defined(__WXMSW__) || defined(__WXPM__)
312 m_mode = wxEOL_DOS;
313#elif defined(__WXMAC__) && !defined(__DARWIN__)
314 m_mode = wxEOL_MAC;
315#else
316 m_mode = wxEOL_UNIX;
317#endif
318 }
319}
320
321wxTextOutputStream::~wxTextOutputStream()
322{
323}
324
325void wxTextOutputStream::SetMode(wxEOL mode)
326{
327 m_mode = mode;
328 if (m_mode == wxEOL_NATIVE)
329 {
330#if defined(__WXMSW__) || defined(__WXPM__)
331 m_mode = wxEOL_DOS;
332#elif defined(__WXMAC__) && !defined(__DARWIN__)
333 m_mode = wxEOL_MAC;
334#else
335 m_mode = wxEOL_UNIX;
336#endif
337 }
338}
339
340void wxTextOutputStream::Write32(wxUint32 i)
341{
342 wxString str;
343 str.Printf(wxT("%u"), i);
344
345 WriteString(str);
346}
347
348void wxTextOutputStream::Write16(wxUint16 i)
349{
350 wxString str;
351 str.Printf(wxT("%u"), (unsigned)i);
352
353 WriteString(str);
354}
355
356void wxTextOutputStream::Write8(wxUint8 i)
357{
358 wxString str;
359 str.Printf(wxT("%u"), (unsigned)i);
360
361 WriteString(str);
362}
363
364void wxTextOutputStream::WriteDouble(double d)
365{
366 wxString str;
367
368 str.Printf(wxT("%f"), d);
369 WriteString(str);
370}
371
372void wxTextOutputStream::WriteString(const wxString& string)
373{
374 size_t len = string.length();
375
376 wxString out;
377 out.reserve(len);
378
379 for ( size_t i = 0; i < len; i++ )
380 {
381 const wxChar c = string[i];
382 if ( c == wxT('\n') )
383 {
384 switch ( m_mode )
385 {
386 case wxEOL_DOS:
387 out << _T("\r\n");
388 continue;
389
390 case wxEOL_MAC:
391 out << _T('\r');
392 continue;
393
394 default:
395 wxFAIL_MSG( _T("unknown EOL mode in wxTextOutputStream") );
396 // fall through
397
398 case wxEOL_UNIX:
399 // don't treat '\n' specially
400 ;
401 }
402 }
403
404 out << c;
405 }
406
407 // We must not write the trailing NULL here
408#if wxUSE_UNICODE
409 wxCharBuffer buffer = m_conv.cWC2MB( out );
410 m_output.Write( (const char*) buffer, strlen( (const char*) buffer ) );
411#else
412 m_output.Write(out.c_str(), out.length() );
413#endif
414}
415
416wxTextOutputStream& wxTextOutputStream::PutChar(wxChar c)
417{
418#if wxUSE_UNICODE
419 WriteString( wxString(&c, m_conv, 1) );
420#else
421 WriteString( wxString(&c, wxConvLocal, 1) );
422#endif
423 return *this;
424}
425
426wxTextOutputStream& wxTextOutputStream::operator<<(const wxChar *string)
427{
428 WriteString( wxString(string) );
429 return *this;
430}
431
432wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
433{
434 WriteString( string );
435 return *this;
436}
437
438wxTextOutputStream& wxTextOutputStream::operator<<(char c)
439{
440 WriteString( wxString::FromAscii(c) );
441
442 return *this;
443}
444
445#if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
446
447wxTextOutputStream& wxTextOutputStream::operator<<(wchar_t wc)
448{
449 WriteString( wxString(&wc, m_conv, 1) );
450
451 return *this;
452}
453
454#endif // wxUSE_UNICODE
455
456wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
457{
458 wxString str;
459 str.Printf(wxT("%d"), (signed int)c);
460 WriteString(str);
461
462 return *this;
463}
464
465wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
466{
467 wxString str;
468 str.Printf(wxT("%ld"), (signed long)c);
469 WriteString(str);
470
471 return *this;
472}
473
474wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
475{
476 wxString str;
477 str.Printf(wxT("%u"), (unsigned int)c);
478 WriteString(str);
479
480 return *this;
481}
482
483wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
484{
485 wxString str;
486 str.Printf(wxT("%lu"), (unsigned long)c);
487 WriteString(str);
488
489 return *this;
490}
491
492wxTextOutputStream &wxTextOutputStream::operator<<(double f)
493{
494 WriteDouble(f);
495 return *this;
496}
497
498wxTextOutputStream& wxTextOutputStream::operator<<(float f)
499{
500 WriteDouble((double)f);
501 return *this;
502}
503
504wxTextOutputStream &endl( wxTextOutputStream &stream )
505{
506 return stream.PutChar(wxT('\n'));
507}
508
509#endif
510 // wxUSE_STREAMS