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