]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/txtstrm.cpp
Applied patch [ 686843 ] File Dialog Wildcard Bug
[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 license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "txtstrm.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20 #pragma hdrstop
21#endif
22
23#if wxUSE_STREAMS
24
25#include "wx/txtstrm.h"
26#include <ctype.h>
27
28
29// ----------------------------------------------------------------------------
30// constants
31// ----------------------------------------------------------------------------
32
33// Unix: "\n"
34// Dos: "\r\n"
35// Mac: "\r"
36
37// ----------------------------------------------------------------------------
38// wxTextInputStream
39// ----------------------------------------------------------------------------
40
41#if wxUSE_UNICODE
42wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep, wxMBConv& conv)
43 : m_input(s), m_separators(sep), m_conv(conv)
44{
45}
46#else
47wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
48 : m_input(s), m_separators(sep)
49{
50}
51#endif
52
53wxTextInputStream::~wxTextInputStream()
54{
55}
56
57wxChar wxTextInputStream::NextNonSeparators()
58{
59 wxChar c = (wxChar) 0;
60 for (;;)
61 {
62 if (!m_input) return (wxChar) 0;
63 c = m_input.GetC();
64
65 if (c != wxT('\n') &&
66 c != wxT('\r') &&
67 !m_separators.Contains(c))
68 return c;
69 }
70
71}
72
73bool wxTextInputStream::EatEOL(const wxChar &c)
74{
75 if (c == wxT('\n')) return TRUE; // eat on UNIX
76
77 if (c == wxT('\r')) // eat on both Mac and DOS
78 {
79 if (!m_input) return TRUE;
80 wxChar c2 = m_input.GetC();
81
82 if (c2 != wxT('\n')) m_input.Ungetch( c2 ); // Don't eat on Mac
83 return TRUE;
84 }
85
86 return FALSE;
87}
88
89void wxTextInputStream::SkipIfEndOfLine( wxChar c )
90{
91 if (EatEOL(c)) return;
92 else m_input.Ungetch( c ); // no line terminator
93}
94
95wxUint32 wxTextInputStream::Read32()
96{
97 /* I only implemented a simple integer parser */
98 // VZ: what about using strtol()?? (TODO)
99
100 int sign;
101 wxInt32 i;
102
103 if (!m_input) return 0;
104 int c = NextNonSeparators();
105 if (c==(wxChar)0) return 0;
106
107 i = 0;
108 if (! (c == wxT('-') || c == wxT('+') || isdigit(c)) )
109 {
110 m_input.Ungetch(c);
111 return 0;
112 }
113
114 if (c == wxT('-'))
115 {
116 sign = -1;
117 c = m_input.GetC();
118 } else
119 if (c == wxT('+'))
120 {
121 sign = 1;
122 c = m_input.GetC();
123 } else
124 {
125 sign = 1;
126 }
127
128 while (isdigit(c))
129 {
130 i = i*10 + (c - (int)wxT('0'));
131 c = m_input.GetC();
132 }
133
134 SkipIfEndOfLine( c );
135
136 i *= sign;
137
138 return (wxUint32)i;
139}
140
141wxUint16 wxTextInputStream::Read16()
142{
143 return (wxUint16)Read32();
144}
145
146wxUint8 wxTextInputStream::Read8()
147{
148 return (wxUint8)Read32();
149}
150
151double wxTextInputStream::ReadDouble()
152{
153 /* I only implemented a simple float parser
154 * VZ: what about using strtod()?? (TODO)
155 */
156
157 double f;
158 int theSign;
159
160 if (!m_input)
161 return 0;
162
163 int c = NextNonSeparators();
164 if (c==(wxChar)0) return 0;
165
166 f = 0.0;
167 if (! (c == wxT('.') || c == wxT(',') || c == wxT('-') || c == wxT('+') || isdigit(c)) )
168 {
169 m_input.Ungetch(c);
170 return 0;
171 }
172
173 if (c == wxT('-'))
174 {
175 theSign = -1;
176 c = m_input.GetC();
177 } else
178 if (c == wxT('+'))
179 {
180 theSign = 1;
181 c = m_input.GetC();
182 }
183 else
184 {
185 theSign = 1;
186 }
187
188 while (isdigit(c))
189 {
190 f = f*10 + (c - wxT('0'));
191 c = m_input.GetC();
192 }
193
194 if (c == wxT('.') || c == wxT(','))
195 {
196 double f_multiplicator = (double) 0.1;
197
198 c = m_input.GetC();
199
200 while (isdigit(c))
201 {
202 f += (c-wxT('0'))*f_multiplicator;
203 f_multiplicator /= 10;
204 c = m_input.GetC();
205 }
206
207 if (c == wxT('e'))
208 {
209 double f_multiplicator = 0.0;
210 int i, e;
211
212 c = m_input.GetC();
213
214 switch (c)
215 {
216 case wxT('-'): f_multiplicator = 0.1; break;
217 case wxT('+'): f_multiplicator = 10.0; break;
218 }
219
220 e = Read8(); // why only max 256 ?
221
222 for (i=0;i<e;i++)
223 f *= f_multiplicator;
224 }
225 else
226 SkipIfEndOfLine( c );
227 }
228 else
229 {
230 m_input.Ungetch(c);
231 }
232
233 f *= theSign;
234 return f;
235}
236
237wxString wxTextInputStream::ReadString()
238{
239 return ReadLine();
240}
241
242wxString wxTextInputStream::ReadLine()
243{
244 wxString line;
245
246 while ( !m_input.Eof() )
247 {
248#if wxUSE_UNICODE
249 // FIXME: this is only works for single byte encodings
250 // How-to read a single char in an unkown encoding???
251 char buf[10];
252 buf[0] = m_input.GetC();
253 buf[1] = 0;
254
255 wxChar wbuf[2];
256 m_conv.MB2WC( wbuf, buf, 2 );
257 wxChar c = wbuf[0];
258#else
259 char c = m_input.GetC();
260#endif
261
262 if ( !m_input )
263 break;
264
265 if (EatEOL(c))
266 break;
267
268 line += c;
269 }
270
271 return line;
272}
273
274wxString wxTextInputStream::ReadWord()
275{
276 wxString word;
277
278 if ( !m_input )
279 return word;
280
281 wxChar c = NextNonSeparators();
282 if ( !c )
283 return word;
284
285 word += c;
286
287 while ( !m_input.Eof() )
288 {
289 c = m_input.GetC();
290
291 if (!m_input)
292 break;
293
294 if (m_separators.Contains(c))
295 break;
296
297 if (EatEOL(c))
298 break;
299
300 word += c;
301 }
302
303 return word;
304}
305
306wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
307{
308 word = ReadWord();
309 return *this;
310}
311
312wxTextInputStream& wxTextInputStream::operator>>(char& c)
313{
314 if (!m_input)
315 {
316 c = 0;
317 return *this;
318 }
319
320 c = m_input.GetC();
321
322 if (EatEOL(c))
323 c = '\n';
324
325 return *this;
326}
327
328wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
329{
330 i = (wxInt16)Read16();
331 return *this;
332}
333
334wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
335{
336 i = (wxInt32)Read32();
337 return *this;
338}
339
340wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
341{
342 i = Read16();
343 return *this;
344}
345
346wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
347{
348 i = Read32();
349 return *this;
350}
351
352wxTextInputStream& wxTextInputStream::operator>>(double& i)
353{
354 i = ReadDouble();
355 return *this;
356}
357
358wxTextInputStream& wxTextInputStream::operator>>(float& f)
359{
360 f = (float)ReadDouble();
361 return *this;
362}
363
364
365
366#if wxUSE_UNICODE
367wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode, wxMBConv& conv)
368 : m_output(s), m_conv(conv)
369#else
370wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
371 : m_output(s)
372#endif
373{
374 m_mode = mode;
375 if (m_mode == wxEOL_NATIVE)
376 {
377#if defined(__WXMSW__) || defined(__WXPM__)
378 m_mode = wxEOL_DOS;
379#elif defined(__WXMAC__) && !defined(__DARWIN__)
380 m_mode = wxEOL_MAC;
381#else
382 m_mode = wxEOL_UNIX;
383#endif
384 }
385}
386
387wxTextOutputStream::~wxTextOutputStream()
388{
389}
390
391void wxTextOutputStream::SetMode(wxEOL mode)
392{
393 m_mode = mode;
394 if (m_mode == wxEOL_NATIVE)
395 {
396#if defined(__WXMSW__) || defined(__WXPM__)
397 m_mode = wxEOL_DOS;
398#elif defined(__WXMAC__) && !defined(__DARWIN__)
399 m_mode = wxEOL_MAC;
400#else
401 m_mode = wxEOL_UNIX;
402#endif
403 }
404}
405
406void wxTextOutputStream::Write32(wxUint32 i)
407{
408 wxString str;
409 str.Printf(wxT("%u"), i);
410
411 WriteString(str);
412}
413
414void wxTextOutputStream::Write16(wxUint16 i)
415{
416 wxString str;
417 str.Printf(wxT("%u"), i);
418
419 WriteString(str);
420}
421
422void wxTextOutputStream::Write8(wxUint8 i)
423{
424 wxString str;
425 str.Printf(wxT("%u"), i);
426
427 WriteString(str);
428}
429
430void wxTextOutputStream::WriteDouble(double d)
431{
432 wxString str;
433
434 str.Printf(wxT("%f"), d);
435 WriteString(str);
436}
437
438void wxTextOutputStream::WriteString(const wxString& string)
439{
440 size_t len = string.length();
441
442 wxString out;
443 out.reserve(len);
444
445 for ( size_t i = 0; i < len; i++ )
446 {
447 const wxChar c = string[i];
448 if ( c == wxT('\n') )
449 {
450 switch ( m_mode )
451 {
452 case wxEOL_DOS:
453 out << _T("\r\n");
454 continue;
455
456 case wxEOL_MAC:
457 out << _T('\r');
458 continue;
459
460 default:
461 wxFAIL_MSG( _T("unknown EOL mode in wxTextOutputStream") );
462 // fall through
463
464 case wxEOL_UNIX:
465 // don't treat '\n' specially
466 ;
467 }
468 }
469
470 out << c;
471 }
472
473 // We must not write the trailing NULL here
474#if wxUSE_UNICODE
475 wxCharBuffer buffer = m_conv.cWC2MB( out );
476 m_output.Write( (const char*) buffer, strlen( (const char*) buffer ) );
477#else
478 m_output.Write(out.c_str(), out.length() );
479#endif
480}
481
482wxTextOutputStream& wxTextOutputStream::operator<<(const wxChar *string)
483{
484 WriteString( wxString(string) );
485 return *this;
486}
487
488wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
489{
490 WriteString( string );
491 return *this;
492}
493
494wxTextOutputStream& wxTextOutputStream::operator<<(char c)
495{
496 WriteString( wxString::FromAscii(c) );
497
498 return *this;
499}
500
501wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
502{
503 wxString str;
504 str.Printf(wxT("%d"), (signed int)c);
505 WriteString(str);
506
507 return *this;
508}
509
510wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
511{
512 wxString str;
513 str.Printf(wxT("%ld"), (signed long)c);
514 WriteString(str);
515
516 return *this;
517}
518
519wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
520{
521 wxString str;
522 str.Printf(wxT("%u"), (unsigned int)c);
523 WriteString(str);
524
525 return *this;
526}
527
528wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
529{
530 wxString str;
531 str.Printf(wxT("%lu"), (unsigned long)c);
532 WriteString(str);
533
534 return *this;
535}
536
537wxTextOutputStream &wxTextOutputStream::operator<<(double f)
538{
539 WriteDouble(f);
540 return *this;
541}
542
543wxTextOutputStream& wxTextOutputStream::operator<<(float f)
544{
545 WriteDouble((double)f);
546 return *this;
547}
548
549wxTextOutputStream &endl( wxTextOutputStream &stream )
550{
551 return stream << wxT('\n');
552}
553
554#endif
555 // wxUSE_STREAMS