GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BufferIO.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004 by Olivier Stezowski *
3  * stezow(AT)ipnl.in2p3.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
23 #ifndef ADF_BufferIO
24 #include "BufferIO.h"
25 #endif
26 
27 using namespace ADF;
28 
29 BufferIO::BufferIO(UInt_t s):
30  fStatus(BaseBuffer::kGood),
31  fEndian(BaseBuffer::kLittle),
32  fInner(0),
33  fOuter(0),
34  fRealInnerSize(0u),
35  fRealOuterSize(0u),
36  fBufferIO(0),
37  fSize(0u),
38  fRealSize(0u),
39  fCurrent(0u)
40 {
43 
44  SetCurrent('i');
45 }
46 
47 void BufferIO::SetCurrent(const char which)
48 {
49  char realw = which;
50 
51  // if outer does not exist, keep inner one
52  if ( which == 'o' )
53  if ( fOuter == NULL ) realw = 'i';
54 
55  if ( realw == 'o' ) {
56  fBufferIO = fOuter;
57  fSize = fRealOuterSize;
58  fRealSize = fRealOuterSize;
59  }
60  else {
61  fBufferIO = fInner;
62  fSize = fRealInnerSize;
63  fRealSize = fRealInnerSize;
64  }
65 }
66 
68 {
69  if ( fInner != NULL )
70  { BaseBuffer::Delete(fInner); }
71 
72  fInner = fOuter = fBufferIO = 0;
73  fCurrent = fSize = fRealSize = fRealInnerSize = fRealOuterSize = 0u;
74 
76 }
77 
78 void BufferIO::AllocInner(UInt_t s)
79 {
80  UInt_t lsize = s > 0u ? s : 1u ; // to prevent allocation of a NULL buffer
81 
82  // delete the previous one and allocate a new one that is fill with 0
83  if ( fInner != NULL )
84  BaseBuffer::Delete(fInner);
85  fInner = BaseBuffer::New(fInner,lsize);
86 
87  // cannot allocate memory ... probably to much has been asked, allocates the mimimum = 1 byte
88  if ( fInner == NULL ) {
89  lsize = 1u; fInner = BaseBuffer::New(fInner,lsize);
90  }
91  fRealInnerSize = lsize;
92 }
93 
95 {
96  BufferIO *b = NULL;
97 
98  // allocates the right buffer depending of the system.
99  if ( e == BaseBuffer::SysEndian() ) { /* printf("Buffer allocated \n"); */ b = new BufferIO(s); }
100  else { /* printf("EndianBuffer allocated \n");*/ b = new EndianBufferIO(s); }
101 
102  // change endian since default is to init with the endian of the system.
103  if ( b )
104  b->SetEndian(e);
105 
106  return b;
107 }
108 
110 {
111  if ( fRealSize > 0u )
113 
115 }
116 
118 {
120 }
121 
122 UInt_t BufferIO::SetOffset(UInt_t off) const
123 {
124  if ( off > fSize )
125  fCurrent = fSize;
126  else
127  fCurrent = off;
128 
129  return fCurrent;
130 }
131 
132 UInt_t BufferIO::SetOffset(const Char_t *off) const
133 {
134  if ( off < fBufferIO )
135  return BufferIO::SetOffset(0u);
136  if ( off > fBufferIO+fSize )
137  return BufferIO::SetOffset(fSize);
138 
139  return BufferIO::SetOffset(UInt_t(off-fBufferIO));
140 }
141 
142 Bool_t BufferIO::IsAnOffset(const Char_t *off, UInt_t &pos) const
143 {
144  if ( off < fBufferIO )
145  return false;
146  if ( off > fBufferIO+fSize )
147  return false;
148 
149  pos = UInt_t(off - fBufferIO); return true;
150 }
151 
152 UInt_t BufferIO::SetEffectiveSize(UInt_t new_size)
153 {
154  if ( new_size < fRealSize )
155  fSize = new_size;
156  else
157  fSize = fRealSize;
158 
159  return fSize;
160 }
161 
162 Bool_t BufferIO::Expand(UInt_t new_size)
163 {
164  // the Real size is enought, so just change the current size
165  if ( new_size <= fRealSize ) {
167  fSize = new_size;
168 
169  return true;
170  }
171 
172  // The current buffer is not the inner buffer, so the expand method is not applied
173  // since the outer buffer is not owned by BufferIO
174  if ( fBufferIO != fInner )
175  return false;
176 
177  // now the current buffer is the inner one without a size large enough
178  // so allocates a new buffer
179  Char_t *newbuf = NULL; newbuf = BaseBuffer::New(newbuf,new_size);
180 
181  // cannot allocate the corresponding memory
182  if ( newbuf == NULL )
183  return false;
184 
185  // copy the content of the old buffer before deleting the old one
186  ::memcpy(newbuf,fBufferIO,Offset());
187  //
188  BaseBuffer::Delete(fInner);
189 
190  // set the characterictics of the new inner and current buffer
191  fInner = newbuf;
192  fRealInnerSize = new_size;
193 
194  SetCurrent('i');
195 
196  return true;
197 }
198 
199 Bool_t BufferIO::Reserve(UInt_t add)
200 {
201  // enough place
202  if ( fCurrent + add <= fSize )
203  return true;
204 
205  // enough place just by changing the size
206  if ( fCurrent + add <= fRealSize ) {
207  fSize = fRealSize;
208  return true;
209  }
210  // try to expand
211  return Expand(fCurrent + add);
212 }
213 
214 Bool_t BufferIO::Link(const Char_t *extbuf, UInt_t size_ext_buf)
215 {
216  Bool_t ok = true;
217 
218  if ( extbuf == NULL )
219  return false;
220 
221  if ( extbuf == fInner ) { // try to link again the inner
222  if ( size_ext_buf < fRealInnerSize ) {
223  SetCurrent('i');
224  fCurrent = 0u; fSize = size_ext_buf; fStatus = BaseBuffer::kGood; // the new attached buffer is ready to be processed
225  }
226  else { ok = false; }
227  }
228  else {
229  fOuter = const_cast<Char_t *>(extbuf); fRealOuterSize = size_ext_buf;
230  if ( fOuter ) {
231  SetCurrent('o');
232  fCurrent = 0u; fSize = size_ext_buf; fStatus = BaseBuffer::kGood; // the new attached buffer is ready to be processed
233  }
234  else { ok = false; }
235  }// new buffer attached
236 
237  return ok;
238 }
239 
240 Bool_t BufferIO::Link(const BufferIO &extbuf, UInt_t p1, UInt_t p2)
241 {
242  if ( (p1+p2) > extbuf.Size() )
243  return false;
244 
245  return Link(extbuf.GetAddress()+p1,p2);
246 }
247 
248 Bool_t BufferIO::Copy(const Char_t *extbuf, UInt_t size_ext_buf)
249 {
250  // if the inner buffer is not large enought, try to expand it
251  Bool_t ok = true;
252 
253  if ( fRealInnerSize < size_ext_buf ) { // inner is too small
254 
255  Char_t *newbuf
256  = NULL;
257  newbuf = BaseBuffer::New(newbuf,size_ext_buf);
258 
259  // can allocate the corresponding memory
260  if ( newbuf != NULL ) {
261 
262  // delete current buffer
263  BaseBuffer::Delete(fInner);
264 
265  // set the characterictics of the new inner buffer
266  fInner = newbuf;
267  fRealInnerSize = size_ext_buf;
268  }
269  else ok = false;
270  }
271 
272  if ( ok ) { // the size of the current buffer is large enought for a full copy
273 
274  BaseBuffer::Copy(extbuf,fInner,size_ext_buf);
275  SetCurrent('i');
276  SetEffectiveSize(size_ext_buf);
277 
278  // the new attached buffer is ready to be processed
280  }
281 
282  return ok;
283 }
284 
285 UInt_t BufferIO::Import(FILE *fd, UInt_t size_ext_buf)
286 {
287  UInt_t btoread = size_ext_buf;
288 
289  if ( Reserve(size_ext_buf) ) { // the size of the current buffer is large enought for a full copy
290  btoread = size_ext_buf;
291  btoread = (UInt_t)::fread(fBufferIO+fCurrent,1,btoread,fd); fCurrent += btoread;
292  }
293  else btoread = 0u;
294 
295  return btoread;
296 }
297 
298 UInt_t BufferIO::Import(const Char_t *from, UInt_t size_ext_buf)
299 {
300  UInt_t btoread = size_ext_buf;
301 
302  if ( Reserve(size_ext_buf) ) { // the size of the current buffer is large enought for a full copy
303  BaseBuffer::Copy(from,fBufferIO+fCurrent,btoread);
304  }
305  else btoread = 0u;
306 
307  fCurrent += btoread; return btoread;
308 }
309 
310 UInt_t BufferIO::Import(const BufferIO &from, UInt_t size_ext_buf)
311 {
312  // check if the given size does not overestimate the real size of the passed buffer
313  UInt_t btoread = size_ext_buf <= from.Size() ? size_ext_buf : from.Size() ;
314 
315  if ( Reserve(size_ext_buf) ) { // the size of the current buffer is large enought for a full copy
316  BaseBuffer::Copy(from.GetAddress(),CurrentAddress(),btoread);
317  }
318  else btoread = 0u;
319 
320  fCurrent += btoread; return btoread;
321 }
322 
323 
324 /*
325 UInt_t BufferIO::PeakUpFast(FILE *fd, UInt_t size_ext_buf)
326 {
327  UInt_t btoread = size_ext_buf, bread;
328  Long_t fpos = ::ftell(fd);bread = ::fread(fBufferIO+fCurrent,1,btoread,fd); ::fseek(fd,fpos,SEEK_SET);
329 
330  fCurrent += bread; return bread;
331 }
332 */
333 
334 UInt_t BufferIO::Export(FILE *fd, UInt_t size_buf) const
335 {
336  // if size asked is too high, reduce it to the effective size
337  UInt_t bwritten = size_buf;
338 
339  if ( size_buf > Size() )
340  bwritten = Size();
341 
342  bwritten = (UInt_t)::fwrite(fBufferIO,1,bwritten,fd); fCurrent += bwritten; return bwritten;
343 }
344 
345 UInt_t BufferIO::Import(std::istream &in, UInt_t size_ext_buf)
346 {
347  UInt_t btoread = size_ext_buf;
348 
349  // if the current buffer is not large enought, try to expand it
350  Bool_t oksize = true;
351  if ( FreeSize() < size_ext_buf )
352  oksize = Expand(size_ext_buf-FreeSize());
353 
354  if ( oksize ) { // the size of the current buffer is large enought for a full copy
355  btoread = size_ext_buf;
356  in.read(CurrentAddress(),btoread); btoread = UInt_t(in.gcount()); fCurrent += btoread;
357  }
358  else btoread = 0u;
359 
360  return btoread;
361 }
362 
363 UInt_t BufferIO::Export(std::ostream &out, UInt_t size_buf) const
364 {
365  UInt_t bwritten = size_buf;
366 
367  if ( size_buf > Size() )
368  bwritten = Size();
369 
370  out.write(fBufferIO,bwritten); fCurrent += bwritten; return bwritten;
371 }
372 
374 {
375  Char_t *old = fOuter; fOuter = NULL; fRealOuterSize = 0u;
376 
377  // the inner buffer is ready to be processed
378  SetCurrent('i');
380 
381  return old;
382 }
383 
385 {
386 // printf("endian buffer allocated \n");
388  else fEndian = BaseBuffer::kBig;
389 }
390 
392 
393 
virtual Bool_t Reserve(UInt_t size)
to reserve a given size (from the current position) to be sure one are able to write something ...
Definition: BufferIO.cpp:199
TBrowser * b
Char_t * fBufferIO
current buffer in which data are read/written
Definition: BufferIO.h:73
Char_t * CurrentAddress()
for classes that needs it to write directly data into it.
Definition: BufferIO.h:101
virtual Bool_t Link(const Char_t *from, UInt_t from_size)
Link an external buffer to this class.
Definition: BufferIO.cpp:214
virtual void Reset()
Reset means set all elements to 0 and the current position is 0.
Definition: BufferIO.cpp:109
static void Delete(Char_t *p)
Definition: BaseBuffer.h:151
BufferIO(UInt_t s=aByte)
Default size for a BufferIO is one byte just because it could be used only with an external buffer...
Definition: BufferIO.cpp:29
Bool_t IsAnOffset(const Char_t *off, UInt_t &pos) const
check if this address belongs to this buffer
Definition: BufferIO.cpp:142
static void Zero(Char_t *p, Int_t nb)
Definition: BaseBuffer.h:108
A Endianbuffer is used to read/write raw data buffers from/on files.
Definition: BufferIO.h:843
virtual Char_t * Unlink()
Unlink the external buffer to this class.
Definition: BufferIO.cpp:373
UInt_t fRealSize
Real size of the current buffer.
Definition: BufferIO.h:77
UInt_t Offset() const
it returns the current position in the buffer
Definition: BufferIO.h:240
UInt_t Size() const
it returns the maximum number of bytes in this buffer
Definition: BufferIO.h:220
UInt_t fCurrent
current position in the buffer (mutable so that reading are allowed for constant) ...
Definition: BufferIO.h:80
Base class for a buffer.
Definition: BaseBuffer.h:48
static bool IsSysEndian(BaseBuffer::EEndian e)
check out the endian type of the running system
Definition: BaseBuffer.h:94
static EEndian SysEndian()
Definition: BaseBuffer.h:96
header file for BufferIO.cpp
UInt_t FreeSize() const
it returns the number of free bytes to the end
Definition: BufferIO.h:236
void SetCurrent(const char= 'i')
to switch between inner and outer
Definition: BufferIO.cpp:47
const Char_t * GetAddress() const
Pointer to the current underlying array of bytes.
Definition: BufferIO.h:216
virtual UInt_t Export(Char_t *, UInt_t) const
Export this buffer to an array.
Definition: BufferIO.h:694
void AllocInner(UInt_t)
Definition: BufferIO.cpp:78
static void Copy(const void *from, void *to, Int_t size)
copy the content from -> to
Definition: BaseBuffer.h:172
EndianBufferIO(UInt_t s=aKByte)
Definition: BufferIO.cpp:384
virtual Bool_t Copy(const Char_t *from, UInt_t from_size)
copy an external buffer to this.
Definition: BufferIO.cpp:248
static BufferIO * New(BaseBuffer::EEndian e, UInt_t s=aByte)
return the right buffer taking Into account the endian argument compared to the underlying endian sys...
Definition: BufferIO.cpp:94
virtual Bool_t Expand(UInt_t new_size)
Expand the size of the current buffer.
Definition: BufferIO.cpp:162
static Char_t * New(Char_t *p, Int_t nb=32 *aKByte)
Definition: BaseBuffer.h:209
UInt_t SetEffectiveSize(UInt_t size=kMaxUInt_t)
in case the buffer is partly filled and you would like to read it again
Definition: BufferIO.cpp:152
void SetEndian(BaseBuffer::EEndian e)
Definition: BufferIO.h:84
UInt_t Import(const Char_t *from, UInt_t size_ext_buf)
Import the given array in this buffer.
Definition: BufferIO.cpp:298
virtual ~EndianBufferIO()
Definition: BufferIO.cpp:391
virtual void FastReset()
Definition: BufferIO.cpp:117
EStatus fStatus
current status
Definition: BufferIO.h:57
UInt_t fSize
effective size of the current buffer
Definition: BufferIO.h:75
EEndian fEndian
current endian
Definition: BufferIO.h:59
virtual ~BufferIO()
Definition: BufferIO.cpp:67
UInt_t SetOffset(UInt_t off=0u) const
change the current position.
Definition: BufferIO.cpp:122