* wxStream: I've rewritten the inheritance
[wxWidgets.git] / src / common / mstream.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mstream.cpp
3 // Purpose: "Memory stream" classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "mstream.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18 #include <stdlib.h>
19 #include <wx/stream.h>
20 #include <wx/mstream.h>
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if !USE_SHARED_LIBRARY
27 IMPLEMENT_CLASS(wxMemoryInputStream, wxInputStream)
28 IMPLEMENT_CLASS(wxMemoryOutputStream, wxOutputStream)
29 IMPLEMENT_CLASS2(wxMemoryStream, wxInputStream, wxOutputStream)
30 #endif
31
32 // ----------------------------------------------------------------------------
33 // wxMemoryStreamBase
34 // ----------------------------------------------------------------------------
35 wxMemoryStreamBase::wxMemoryStreamBase()
36 {
37 m_buffer = NULL;
38 m_iolimit = 0;
39 m_persistent = FALSE;
40 m_length = 0;
41 }
42
43 wxMemoryStreamBase::~wxMemoryStreamBase()
44 {
45 if (!m_persistent && m_buffer)
46 free(m_buffer);
47 }
48
49 bool wxMemoryStreamBase::ChangeBufferSize(size_t new_size)
50 {
51 if (m_iolimit == 1)
52 return FALSE;
53
54 m_length = new_size;
55 if (!m_buffer)
56 m_buffer = (char *)malloc(m_length);
57 else
58 m_buffer = (char *)realloc(m_buffer, m_length);
59
60 return (m_buffer != NULL);
61 }
62
63 // ----------------------------------------------------------------------------
64 // wxMemoryInputStream
65 // ----------------------------------------------------------------------------
66
67 wxMemoryInputStream::wxMemoryInputStream(const char *data, size_t len)
68 {
69 m_persistent = TRUE;
70 m_length = len;
71 m_buffer = (char *)data; // It's bad.
72 m_position_i = 0;
73 m_lastread = 0;
74 m_eof = FALSE;
75 m_iolimit = 1;
76 }
77
78 wxInputStream& wxMemoryInputStream::Read(void *buffer, size_t size)
79 {
80 if (m_iolimit == 2) {
81 m_eof = TRUE;
82 return *this;
83 }
84 if (m_position_i+size > m_length)
85 size = m_length-m_position_i;
86
87 memcpy((void *)((unsigned long)buffer+m_position_i), m_buffer, size);
88 m_position_i += size;
89 m_lastread = size;
90
91 return *this;
92 }
93
94 off_t wxMemoryInputStream::SeekI(off_t pos, wxSeekMode mode)
95 {
96 if (m_iolimit == 2)
97 return 0;
98
99 switch (mode) {
100 case wxFromStart:
101 if ((size_t)pos > m_length)
102 return m_position_i;
103 return (m_position_i = pos);
104
105 case wxFromCurrent:
106 if ((size_t)(m_position_i+pos) > m_length)
107 return m_position_i;
108
109 return (m_position_i += pos);
110
111 case wxFromEnd:
112 if ((size_t)(m_length-pos) > m_length)
113 return m_position_i;
114
115 return (m_position_i = m_length-pos);
116 }
117
118 return m_position_i;
119 }
120
121 // ----------------------------------------------------------------------------
122 // wxMemoryOutputStream
123 // ----------------------------------------------------------------------------
124
125 wxMemoryOutputStream::wxMemoryOutputStream(char *data, size_t len)
126 {
127 m_persistent = FALSE;
128 m_buffer = data;
129 m_length = len;
130 m_position_o = 0;
131 m_lastwrite = 0;
132 m_bad = FALSE;
133 m_iolimit = 2;
134 }
135
136 wxOutputStream& wxMemoryOutputStream::Write(const void *buffer, size_t size)
137 {
138 if (m_iolimit == 1) {
139 m_bad = TRUE;
140 return *this;
141 }
142
143 if (m_position_o+size > m_length)
144 if (!ChangeBufferSize(m_position_o+size)) {
145 m_bad = TRUE;
146 return *this;
147 }
148
149 memcpy(m_buffer+m_position_o, buffer, size);
150 m_position_o += size;
151 m_lastwrite = size;
152
153 return *this;
154 }
155
156 off_t wxMemoryOutputStream::SeekO(off_t pos, wxSeekMode mode)
157 {
158 if (m_iolimit == 1)
159 return 0;
160
161 switch (mode) {
162 case wxFromStart:
163 if ((size_t)pos > m_length)
164 return m_position_o;
165 return (m_position_o = pos);
166
167 case wxFromCurrent:
168 if ((size_t)(m_position_o+pos) > m_length)
169 return m_position_o;
170
171 return (m_position_o += pos);
172
173 case wxFromEnd:
174 if ((size_t)(m_length-pos) > m_length)
175 return m_position_o;
176
177 return (m_position_o = m_length-pos);
178 }
179
180 return m_position_o;
181 }
182
183 // ----------------------------------------------------------------------------
184 // wxMemoryStream
185 // ----------------------------------------------------------------------------
186
187 wxMemoryStream::wxMemoryStream(char *data, size_t len)
188 : wxMemoryInputStream(NULL, 0), wxMemoryOutputStream(NULL, 0)
189 {
190 m_persistent = FALSE;
191 m_buffer = data;
192 m_length = len;
193 m_iolimit = 0;
194 }
195
196 wxMemoryStream::~wxMemoryStream()
197 {
198 }