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