1 : //=============================================================================
2 : // File <$/src/cpp/prod/protocol/cdr/cdr_fragment.cpp>
3 : // This file is part of YaOrb : Yet Another Object Request Broker,
4 : // Copyright (c) 2000-2003, Marc Alff.
5 : //
6 : // This program is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU General Public License
8 : // as published by the Free Software Foundation; either version 2
9 : // of the License, or (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 : //
20 : //=============================================================================
21 :
22 : // Portability
23 : #include "yaorb/config.h"
24 : #include "src/cpp/prod/port/port_stdc.h"
25 :
26 : #include <yaorb/CORBA.h>
27 : #include <yaorb/YAORB.h>
28 :
29 : #include "src/cpp/prod/protocol/cdr/msg.h"
30 : #include "src/cpp/prod/protocol/cdr/cdr_fragment.h"
31 : #include "src/cpp/prod/tool/Assert.h"
32 :
33 : Fragment::Fragment(
34 : int headerSize,
35 8 : int dataSize)
36 : : _headerSize(headerSize),
37 : _dataSize(dataSize),
38 : _data(NULL),
39 8 : _next(NULL)
40 : {
41 : ASSERT((_headerSize % 8) == 0) ;
42 : ASSERT((_dataSize % 8) == 0) ;
43 : ASSERT((_headerSize + _dataSize) != 0) ;
44 :
45 8 : _data = new CORBA::Octet[_headerSize + _dataSize] ;
46 : }
47 :
48 : Fragment::Fragment(
49 : int headerSize,
50 : int dataSize,
51 0 : const CORBA::Octet *data)
52 : : _headerSize(headerSize),
53 : _dataSize(dataSize),
54 : _data(NULL),
55 0 : _next(NULL)
56 : {
57 : ASSERT((_headerSize % 8) == 0) ;
58 : ASSERT((_dataSize % 8) == 0) ;
59 : ASSERT((_headerSize + _dataSize) != 0) ;
60 :
61 0 : _data = new CORBA::Octet[_headerSize + _dataSize] ;
62 :
63 0 : memcpy(_data + _headerSize, data, _dataSize) ;
64 : }
65 :
66 8 : Fragment::~Fragment()
67 : {
68 8 : delete [] _data ;
69 :
70 8 : if (_next)
71 : {
72 4 : delete _next ;
73 : }
74 4 : }
75 :
76 : Fragment*
77 8 : Fragment::GetNext(void) const
78 : {
79 : return _next ;
80 : }
81 :
82 : void
83 4 : Fragment::SetNext(Fragment* next)
84 : {
85 4 : _next = next ;
86 : }
87 :
88 : int
89 0 : Fragment::GetHeaderSize(void) const
90 : {
91 : return _headerSize ;
92 : }
93 :
94 : int
95 108 : Fragment::GetDataSize(void) const
96 : {
97 : return _dataSize ;
98 : }
99 :
100 : CORBA::Octet*
101 0 : Fragment::GetHeader(void)
102 : {
103 : return _data ;
104 : }
105 :
106 : CORBA::Octet*
107 108 : Fragment::GetData(void)
108 : {
109 : return _data + _headerSize ;
110 : }
111 :
112 : CDRFragment::CDRFragment(
113 : int firstHeaderSize,
114 : int firstDataSize,
115 : int nextHeaderSize,
116 4 : int nextDataSize)
117 : : CDR(YAORB::CDR_WRITE),
118 : _first(NULL),
119 : _current(NULL),
120 : _localPosition(0),
121 : _nextHeaderSize(nextHeaderSize),
122 4 : _nextDataSize(nextDataSize)
123 : {
124 : ASSERT((firstHeaderSize % 8) == 0) ;
125 : ASSERT((firstDataSize % 8) == 0) ;
126 : ASSERT((nextHeaderSize % 8) == 0) ;
127 : ASSERT((nextDataSize % 8) == 0) ;
128 :
129 4 : _first = new Fragment(firstHeaderSize, firstDataSize) ;
130 4 : _current = _first ;
131 4 : }
132 :
133 0 : CDRFragment::CDRFragment(Fragment *first)
134 : : CDR(YAORB::CDR_READ),
135 : _first(first),
136 : _current(first),
137 : _localPosition(0),
138 : _nextHeaderSize(0),
139 0 : _nextDataSize(0)
140 : {
141 : ASSERT(first != NULL) ;
142 : }
143 :
144 4 : CDRFragment::~CDRFragment()
145 : {
146 4 : delete _first ;
147 0 : }
148 :
149 : Fragment*
150 0 : CDRFragment::GetFirstFragment(void)
151 : {
152 : return _first ;
153 : }
154 :
155 : void
156 : CDRFragment::GetBytes(
157 : CORBA::Octet *buffer,
158 : int size)
159 4 : throw (CORBA::SystemException)
160 : {
161 : CORBA::Octet *buf = buffer ;
162 : int s = size ;
163 :
164 : int localSize = 0 ;
165 : int partialSize = 0 ;
166 : CORBA::Octet *localBuffer = NULL ;
167 :
168 : //--------------------------------------------------------------------------
169 : // While there is still data to read,
170 : //--------------------------------------------------------------------------
171 :
172 8 : while (s >0)
173 : {
174 8 : localSize = _current->GetDataSize() ;
175 8 : localBuffer = _current->GetData() ;
176 :
177 : //-----------------------------------------------------------------------
178 : // See if all can be read from the current fragment
179 : //-----------------------------------------------------------------------
180 :
181 8 : if ((_localPosition + s) > localSize)
182 : {
183 : //--------------------------------------------------------------------
184 : // If no, read all the content from the current fragment ...
185 : //--------------------------------------------------------------------
186 :
187 4 : partialSize = localSize - _localPosition ;
188 :
189 4 : if (partialSize >0)
190 : {
191 4 : (void) memcpy(buf, & localBuffer[_localPosition], partialSize) ;
192 4 : _localPosition += partialSize ;
193 4 : _position += partialSize ;
194 4 : buf += partialSize ;
195 4 : s -= partialSize ;
196 : }
197 :
198 : ASSERT(_localPosition == localSize) ;
199 :
200 : //--------------------------------------------------------------------
201 : // ... and move to the next fragment.
202 : //--------------------------------------------------------------------
203 :
204 4 : _current = _current->GetNext() ;
205 :
206 4 : if (_current == NULL)
207 : {
208 0 : ThrowMarshal(this) ;
209 : }
210 :
211 4 : _localPosition = 0 ;
212 : localSize = _current->GetDataSize() ;
213 : localBuffer = _current->GetData() ;
214 : }
215 : else
216 : {
217 : //--------------------------------------------------------------------
218 : // If yes, read all the remaining data from the current fragment.
219 : //--------------------------------------------------------------------
220 :
221 4 : (void) memcpy(buf, & localBuffer[_localPosition], s) ;
222 4 : _localPosition += s ;
223 4 : _position += s ;
224 : s = 0 ;
225 : }
226 : }
227 : }
228 :
229 : void
230 : CDRFragment::PutBytes(
231 : CORBA::Octet *buffer,
232 : int size)
233 96 : throw (CORBA::SystemException)
234 : {
235 : CORBA::Octet *buf = buffer ;
236 : int s = size ;
237 :
238 : int localSize = 0 ;
239 : int partialSize = 0 ;
240 : CORBA::Octet *localBuffer =NULL ;
241 : Fragment *next = NULL ;
242 :
243 : //--------------------------------------------------------------------------
244 : // While there is still data to write,
245 : //--------------------------------------------------------------------------
246 :
247 100 : while (s >0)
248 : {
249 100 : localSize = _current->GetDataSize() ;
250 100 : localBuffer = _current->GetData() ;
251 :
252 : //-----------------------------------------------------------------------
253 : // See if the current fragment has enough space
254 : //-----------------------------------------------------------------------
255 :
256 100 : if ((_localPosition + s) > localSize)
257 : {
258 : //--------------------------------------------------------------------
259 : // If no, fill the current fragment ...
260 : //--------------------------------------------------------------------
261 :
262 4 : partialSize = localSize - _localPosition ;
263 :
264 4 : if (partialSize >0)
265 : {
266 4 : (void) memcpy(& localBuffer[_localPosition], buf, partialSize) ;
267 4 : _localPosition += partialSize ;
268 4 : _position += partialSize ;
269 4 : buf += partialSize ;
270 4 : s -= partialSize ;
271 : }
272 :
273 : ASSERT(_localPosition == localSize) ;
274 :
275 : //--------------------------------------------------------------------
276 : // ... and move to the next fragment.
277 : //--------------------------------------------------------------------
278 :
279 4 : next = _current->GetNext() ;
280 :
281 4 : if (next == NULL)
282 : {
283 4 : next = new Fragment(_nextHeaderSize, _nextDataSize) ;
284 4 : _current->SetNext(next) ;
285 4 : _current = next ;
286 : }
287 :
288 4 : _localPosition = 0 ;
289 : localSize = _current->GetDataSize() ;
290 : localBuffer = _current->GetData() ;
291 : }
292 : else
293 : {
294 : //--------------------------------------------------------------------
295 : // If yes, write all the remaining data to the current fragment.
296 : //--------------------------------------------------------------------
297 :
298 96 : (void) memcpy(& localBuffer[_localPosition], buf, s) ;
299 96 : _localPosition += s ;
300 96 : _position += s ;
301 : s = 0 ;
302 : }
303 : }
304 : }
305 :
306 : void
307 8 : CDRFragment::reset(YAORB::CDR_Op op)
308 : {
309 8 : if ( (_op == YAORB::CDR_WRITE)
310 : && ( op == YAORB::CDR_WRITE)
311 : )
312 : {
313 4 : _current = _first ;
314 4 : _position = 0 ;
315 4 : _localPosition = 0 ;
316 :
317 4 : return ;
318 : }
319 :
320 4 : if (op == YAORB::CDR_READ)
321 : {
322 4 : _op = op ;
323 4 : _current = _first ;
324 4 : _position = 0 ;
325 4 : _localPosition = 0 ;
326 :
327 4 : return ;
328 : }
329 :
330 0 : NON_DEV("Read to Write reset") ;
331 : }
332 :
|