Added IMPLEMENT_CLASS, ... about wxStream classes (I hope I didn't make mistakes).
[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 #include <stdlib.h>
17 #include <wx/stream.h>
18 #include <wx/mstream.h>
19
20 #if !USE_SHARED_LIBRARY
21 IMPLEMENT_CLASS(wxMemoryStreamBase, wxStream)
22 IMPLEMENT_CLASS(wxMemoryInputStream, wxMemoryStreamBase)
23 IMPLEMENT_DYNAMIC_CLASS(wxMemoryOutputStream, wxMemoryStreamBase)
24 IMPLEMENT_DYNAMIC_CLASS(wxMemoryStream, wxMemoryStreamBase)
25 #endif
26
27 wxMemoryStreamBase::wxMemoryStreamBase(char *data, size_t length, int iolimit)
28 {
29 m_buffer = data;
30 m_iolimit = iolimit;
31 m_persistent = FALSE;
32 m_length = length;
33 m_position_i = m_position_o = 0;
34 }
35
36 wxMemoryStreamBase::~wxMemoryStreamBase()
37 {
38 free(m_buffer);
39 }
40
41 wxInputStream& wxMemoryStreamBase::Read(void *buffer, size_t size)
42 {
43 if (m_iolimit == 2) {
44 m_eof = TRUE;
45 return *this;
46 }
47 if (m_position_i+size > m_length)
48 size = m_length-m_position_i;
49
50 memcpy((void *)((unsigned long)buffer+m_position_i), m_buffer, size);
51 m_position_i += size;
52 m_lastread = size;
53
54 return *this;
55 }
56
57 size_t wxMemoryStreamBase::SeekI(int pos, wxWhenceType whence)
58 {
59 if (m_iolimit == 2)
60 return 0;
61
62 switch (whence) {
63 case wxBeginPosition:
64 if ((size_t)pos > m_length)
65 return m_position_i;
66 return (m_position_i = pos);
67
68 case wxCurrentPosition:
69 if ((size_t)(m_position_i+pos) > m_length)
70 return m_position_i;
71
72 return (m_position_i += pos);
73
74 case wxEndPosition:
75 if ((size_t)(m_length-pos) > m_length)
76 return m_position_i;
77
78 return (m_position_i = m_length-pos);
79 }
80
81 return m_position_i;
82 }
83
84 wxOutputStream& wxMemoryStreamBase::Write(const void *buffer, size_t size)
85 {
86 if (m_iolimit == 1) {
87 m_bad = TRUE;
88 return *this;
89 }
90
91 if (m_position_o+size > m_length)
92 if (!ChangeBufferSize(m_position_o+size)) {
93 m_bad = TRUE;
94 return *this;
95 }
96
97 memcpy(m_buffer+m_position_o, buffer, size);
98 m_position_o += size;
99 m_lastwrite = size;
100
101 return *this;
102 }
103
104 size_t wxMemoryStreamBase::SeekO(int pos, wxWhenceType whence)
105 {
106 if (m_iolimit == 2)
107 return 0;
108
109 switch (whence) {
110 case wxBeginPosition:
111 if ((size_t)pos > m_length)
112 return m_position_o;
113 return (m_position_o = pos);
114
115 case wxCurrentPosition:
116 if ((size_t)(m_position_o+pos) > m_length)
117 return m_position_o;
118
119 return (m_position_o += pos);
120
121 case wxEndPosition:
122 if ((size_t)(m_length-pos) > m_length)
123 return m_position_o;
124
125 return (m_position_o = m_length-pos);
126 }
127
128 return m_position_o;
129 }
130
131 bool wxMemoryStreamBase::ChangeBufferSize(size_t new_size)
132 {
133 m_length = new_size;
134 if (!m_buffer)
135 m_buffer = (char *)malloc(m_length);
136 else
137 m_buffer = (char *)realloc(m_buffer, m_length);
138
139 return (m_buffer != NULL);
140 }