]> git.saurik.com Git - wxWidgets.git/blame - src/common/txtstrm.cpp
support for unicode font names
[wxWidgets.git] / src / common / txtstrm.cpp
CommitLineData
5a96d2f4 1///////////////////////////////////////////////////////////////////////////////
fae05df5
GL
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$
717b9bf2 8// Copyright: (c) Guilhem Lavaux
65571936 9// Licence: wxWindows licence
fae05df5
GL
10/////////////////////////////////////////////////////////////////////////////
11
fae05df5
GL
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"
c980c992 22#include <ctype.h>
fae05df5 23
cd25b18c
RR
24
25// ----------------------------------------------------------------------------
26// constants
27// ----------------------------------------------------------------------------
28
29// Unix: "\n"
30// Dos: "\r\n"
31// Mac: "\r"
32
33// ----------------------------------------------------------------------------
34// wxTextInputStream
35// ----------------------------------------------------------------------------
36
2b5f62a0
VZ
37#if wxUSE_UNICODE
38wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep, wxMBConv& conv)
39 : m_input(s), m_separators(sep), m_conv(conv)
40{
2348a842 41 memset((void*)m_lastBytes, 0, 10);
2b5f62a0
VZ
42}
43#else
191549ed
SB
44wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
45 : m_input(s), m_separators(sep)
fae05df5 46{
2348a842 47 memset((void*)m_lastBytes, 0, 10);
fae05df5 48}
2b5f62a0 49#endif
fae05df5
GL
50
51wxTextInputStream::~wxTextInputStream()
52{
53}
54
2348a842
VZ
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);
cb719f2e 69 for(size_t inlen = 0; inlen < 9; inlen++)
2348a842
VZ
70 {
71 // actually read the next character
72 m_lastBytes[inlen] = m_input.GetC();
73
cb719f2e 74 if(m_input.LastRead() <= 0)
2348a842 75 return wxEOT;
cb719f2e 76
2348a842
VZ
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();
cb719f2e
WS
85
86 if(m_input.LastRead() <= 0)
2348a842 87 return wxEOT;
cb719f2e 88
2348a842
VZ
89 return m_lastBytes[0];
90#endif
cb719f2e 91
2348a842
VZ
92}
93
191549ed 94wxChar wxTextInputStream::NextNonSeparators()
fae05df5 95{
cd25b18c
RR
96 for (;;)
97 {
999836aa 98 wxChar c = NextChar();
2348a842 99 if (c == wxEOT) return (wxChar) 0;
cd6ce4a9
VZ
100
101 if (c != wxT('\n') &&
102 c != wxT('\r') &&
103 !m_separators.Contains(c))
104 return c;
cd25b18c 105 }
717b9bf2 106
cd25b18c 107}
fae05df5 108
f6bcfd97 109bool wxTextInputStream::EatEOL(const wxChar &c)
cd25b18c 110{
cb719f2e 111 if (c == wxT('\n')) return true; // eat on UNIX
cd6ce4a9 112
f6bcfd97 113 if (c == wxT('\r')) // eat on both Mac and DOS
717b9bf2 114 {
2348a842 115 wxChar c2 = NextChar();
cb719f2e 116 if(c2 == wxEOT) return true; // end of stream reached, had enough :-)
cd6ce4a9 117
2348a842 118 if (c2 != wxT('\n')) UngetLast(); // Don't eat on Mac
cb719f2e 119 return true;
cd25b18c 120 }
717b9bf2 121
cb719f2e 122 return false;
191549ed
SB
123}
124
2348a842 125wxUint32 wxTextInputStream::Read32(int base)
191549ed 126{
2348a842
VZ
127 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
128 if(!m_input) return 0;
129
130 wxString word = ReadWord();
7448de8d 131 if(word.empty())
2348a842
VZ
132 return 0;
133 return wxStrtoul(word.c_str(), 0, base);
cd25b18c 134}
fae05df5 135
2348a842 136wxUint16 wxTextInputStream::Read16(int base)
cd25b18c 137{
2348a842
VZ
138 return (wxUint16)Read32(base);
139}
cd6ce4a9 140
2348a842
VZ
141wxUint8 wxTextInputStream::Read8(int base)
142{
143 return (wxUint8)Read32(base);
144}
717b9bf2 145
2348a842
VZ
146wxInt32 wxTextInputStream::Read32S(int base)
147{
148 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
149 if(!m_input) return 0;
cd25b18c 150
2348a842 151 wxString word = ReadWord();
7448de8d 152 if(word.empty())
cd25b18c 153 return 0;
2348a842 154 return wxStrtol(word.c_str(), 0, base);
fae05df5
GL
155}
156
2348a842 157wxInt16 wxTextInputStream::Read16S(int base)
fae05df5 158{
2348a842 159 return (wxInt16)Read32S(base);
fae05df5
GL
160}
161
2348a842 162wxInt8 wxTextInputStream::Read8S(int base)
fae05df5 163{
2348a842 164 return (wxInt8)Read32S(base);
fae05df5
GL
165}
166
167double wxTextInputStream::ReadDouble()
168{
2348a842
VZ
169 if(!m_input) return 0;
170 wxString word = ReadWord();
7448de8d 171 if(word.empty())
f6bcfd97 172 return 0;
2348a842 173 return wxStrtod(word.c_str(), 0);
fae05df5
GL
174}
175
176wxString wxTextInputStream::ReadString()
9853d977 177{
cd6ce4a9 178 return ReadLine();
9853d977
SB
179}
180
181wxString wxTextInputStream::ReadLine()
fae05df5 182{
cd25b18c
RR
183 wxString line;
184
cd6ce4a9 185 while ( !m_input.Eof() )
cd25b18c 186 {
2348a842
VZ
187 wxChar c = NextChar();
188 if(c == wxEOT)
189 break;
cb719f2e 190
cd6ce4a9
VZ
191 if ( !m_input )
192 break;
193
194 if (EatEOL(c))
195 break;
196
cd25b18c
RR
197 line += c;
198 }
717b9bf2 199
cd25b18c 200 return line;
fae05df5 201}
717b9bf2 202
9853d977
SB
203wxString wxTextInputStream::ReadWord()
204{
9853d977 205 wxString word;
9853d977 206
cd6ce4a9
VZ
207 if ( !m_input )
208 return word;
209
210 wxChar c = NextNonSeparators();
211 if ( !c )
212 return word;
213
f6bcfd97 214 word += c;
cb719f2e 215
cd6ce4a9 216 while ( !m_input.Eof() )
9853d977 217 {
2348a842
VZ
218 c = NextChar();
219 if(c == wxEOT)
f6bcfd97 220 break;
cb719f2e 221
cd6ce4a9
VZ
222 if (m_separators.Contains(c))
223 break;
224
225 if (EatEOL(c))
226 break;
227
9853d977 228 word += c;
9853d977
SB
229 }
230
231 return word;
232}
233
234wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
fae05df5 235{
cd6ce4a9
VZ
236 word = ReadWord();
237 return *this;
fae05df5
GL
238}
239
f6bcfd97 240wxTextInputStream& wxTextInputStream::operator>>(char& c)
fae05df5 241{
191549ed 242 c = m_input.GetC();
2348a842 243 if(m_input.LastRead() <= 0) c = 0;
717b9bf2 244
f6bcfd97
BP
245 if (EatEOL(c))
246 c = '\n';
247
cd25b18c 248 return *this;
fae05df5
GL
249}
250
fcbe123e
VZ
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
fae05df5
GL
262wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
263{
cd25b18c
RR
264 i = (wxInt16)Read16();
265 return *this;
fae05df5
GL
266}
267
268wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
269{
cd25b18c
RR
270 i = (wxInt32)Read32();
271 return *this;
fae05df5
GL
272}
273
fae05df5
GL
274wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
275{
cd25b18c
RR
276 i = Read16();
277 return *this;
fae05df5
GL
278}
279
280wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
281{
cd25b18c
RR
282 i = Read32();
283 return *this;
fae05df5
GL
284}
285
286wxTextInputStream& wxTextInputStream::operator>>(double& i)
287{
cd25b18c
RR
288 i = ReadDouble();
289 return *this;
fae05df5
GL
290}
291
292wxTextInputStream& wxTextInputStream::operator>>(float& f)
293{
cd25b18c
RR
294 f = (float)ReadDouble();
295 return *this;
fae05df5
GL
296}
297
2b5f62a0
VZ
298
299
300#if wxUSE_UNICODE
301wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode, wxMBConv& conv)
302 : m_output(s), m_conv(conv)
303#else
c7a9fa36 304wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
191549ed 305 : m_output(s)
2b5f62a0 306#endif
fae05df5 307{
c7a9fa36
RR
308 m_mode = mode;
309 if (m_mode == wxEOL_NATIVE)
310 {
311#if defined(__WXMSW__) || defined(__WXPM__)
312 m_mode = wxEOL_DOS;
f3ff3813 313#elif defined(__WXMAC__) && !defined(__DARWIN__)
c7a9fa36
RR
314 m_mode = wxEOL_MAC;
315#else
316 m_mode = wxEOL_UNIX;
317#endif
318 }
fae05df5
GL
319}
320
321wxTextOutputStream::~wxTextOutputStream()
322{
323}
324
cd0b1709 325void wxTextOutputStream::SetMode(wxEOL mode)
c7a9fa36
RR
326{
327 m_mode = mode;
328 if (m_mode == wxEOL_NATIVE)
329 {
330#if defined(__WXMSW__) || defined(__WXPM__)
331 m_mode = wxEOL_DOS;
f3ff3813 332#elif defined(__WXMAC__) && !defined(__DARWIN__)
c7a9fa36
RR
333 m_mode = wxEOL_MAC;
334#else
335 m_mode = wxEOL_UNIX;
336#endif
337 }
338}
339
fae05df5
GL
340void wxTextOutputStream::Write32(wxUint32 i)
341{
cd25b18c 342 wxString str;
223d09f6 343 str.Printf(wxT("%u"), i);
717b9bf2 344
cd25b18c 345 WriteString(str);
fae05df5
GL
346}
347
348void wxTextOutputStream::Write16(wxUint16 i)
349{
cd25b18c 350 wxString str;
17a1ebd1 351 str.Printf(wxT("%u"), (unsigned)i);
717b9bf2 352
cd25b18c 353 WriteString(str);
fae05df5
GL
354}
355
356void wxTextOutputStream::Write8(wxUint8 i)
357{
cd25b18c 358 wxString str;
17a1ebd1 359 str.Printf(wxT("%u"), (unsigned)i);
717b9bf2 360
cd25b18c 361 WriteString(str);
fae05df5
GL
362}
363
364void wxTextOutputStream::WriteDouble(double d)
365{
cd25b18c 366 wxString str;
fae05df5 367
223d09f6 368 str.Printf(wxT("%f"), d);
cd25b18c 369 WriteString(str);
fae05df5
GL
370}
371
372void wxTextOutputStream::WriteString(const wxString& string)
373{
20ea6894
VZ
374 size_t len = string.length();
375
376 wxString out;
377 out.reserve(len);
378
379 for ( size_t i = 0; i < len; i++ )
cd25b18c 380 {
20ea6894
VZ
381 const wxChar c = string[i];
382 if ( c == wxT('\n') )
cd25b18c 383 {
20ea6894 384 switch ( m_mode )
cd6ce4a9 385 {
20ea6894
VZ
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 ;
c7a9fa36 401 }
cd25b18c 402 }
20ea6894
VZ
403
404 out << c;
7448de8d 405 }
20ea6894 406
2b5f62a0
VZ
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
fae05df5
GL
414}
415
ba854691
RN
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
fae05df5
GL
426wxTextOutputStream& wxTextOutputStream::operator<<(const wxChar *string)
427{
cd25b18c
RR
428 WriteString( wxString(string) );
429 return *this;
fae05df5
GL
430}
431
432wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
433{
cd25b18c
RR
434 WriteString( string );
435 return *this;
fae05df5
GL
436}
437
f6bcfd97 438wxTextOutputStream& wxTextOutputStream::operator<<(char c)
fae05df5 439{
2b5f62a0 440 WriteString( wxString::FromAscii(c) );
cb719f2e 441
cd25b18c 442 return *this;
fae05df5
GL
443}
444
e4940feb 445#if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
3ca1bf5a
VZ
446
447wxTextOutputStream& wxTextOutputStream::operator<<(wchar_t wc)
448{
449 WriteString( wxString(&wc, m_conv, 1) );
65a1bb98
VZ
450
451 return *this;
3ca1bf5a
VZ
452}
453
e4940feb 454#endif // wxUSE_UNICODE
3ca1bf5a 455
fae05df5
GL
456wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
457{
78e848ca
RR
458 wxString str;
459 str.Printf(wxT("%d"), (signed int)c);
460 WriteString(str);
cd6ce4a9 461
cd25b18c 462 return *this;
fae05df5
GL
463}
464
465wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
466{
78e848ca
RR
467 wxString str;
468 str.Printf(wxT("%ld"), (signed long)c);
469 WriteString(str);
cd6ce4a9 470
cd25b18c 471 return *this;
fae05df5
GL
472}
473
fae05df5
GL
474wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
475{
78e848ca
RR
476 wxString str;
477 str.Printf(wxT("%u"), (unsigned int)c);
478 WriteString(str);
cd6ce4a9 479
cd25b18c 480 return *this;
fae05df5
GL
481}
482
483wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
484{
78e848ca
RR
485 wxString str;
486 str.Printf(wxT("%lu"), (unsigned long)c);
487 WriteString(str);
488
cd25b18c 489 return *this;
fae05df5
GL
490}
491
492wxTextOutputStream &wxTextOutputStream::operator<<(double f)
493{
cd25b18c
RR
494 WriteDouble(f);
495 return *this;
fae05df5
GL
496}
497
498wxTextOutputStream& wxTextOutputStream::operator<<(float f)
499{
cd25b18c
RR
500 WriteDouble((double)f);
501 return *this;
fae05df5
GL
502}
503
ed58dbea
RR
504wxTextOutputStream &endl( wxTextOutputStream &stream )
505{
ba854691 506 return stream.PutChar(wxT('\n'));
ed58dbea
RR
507}
508
fae05df5
GL
509#endif
510 // wxUSE_STREAMS