GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CompositeFrame.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_CompositeFrame
24 #include "CompositeFrame.h"
25 #endif
26 
27 using namespace ADF;
28 
30  ConcreteFrame(key),
31  fSubKey(0x0),
32  fSubKeyConst(0x0),
33  fCurrentKeys(),
34  fStackOfKeys()
35 {
36  // clone the key with the help of the main factory
37  fSubKey =
38  MainKeyFactory::theMainFactory().Clone(key);
39  fSubKeyConst =
40  MainKeyFactory::theMainFactory().Clone(key);
41 
42  // only one owns the keys
43  fCurrentKeys.SetOwner(false); fStackOfKeys.SetOwner(true);
44 }
45 
46 CompositeFrame::CompositeFrame(Key *key,const FactoryItem &secondary_key) :
47  ConcreteFrame(key),
48  fSubKey(0x0),
49  fSubKeyConst(0x0),
50  fCurrentKeys(),
51  fStackOfKeys()
52 {
53  fSubKey =
54  MainKeyFactory::theMainFactory().New(secondary_key);
55  fSubKeyConst =
56  MainKeyFactory::theMainFactory().New(secondary_key);
57 
58  // it does not own the keys.
59  fCurrentKeys.SetOwner(false); fStackOfKeys.SetOwner(true);
60 }
61 
63 {
64  if ( fSubKey )
65  { delete fSubKey; fSubKey = 0x0; }
66  if ( fSubKeyConst )
67  { delete fSubKeyConst; fSubKeyConst = 0x0; }
68 
69  fCurrentKeys.Clear(); fStackOfKeys.Delete();
70 }
71 
73 {
74  // to know the current number of keys found in this frame
75  UInt_t nb_current = fCurrentKeys.GetSize();
76 
77  // to get the next key on the stack
78  Key *key = fStackOfKeys.At(nb_current);
79 
80  // no more available, a new one is created by cloning the constant key and added on the top
81  // of the stack to be deleted properly at the end.
82  if ( key == 0x0 ) {
84  if ( key )
85  fStackOfKeys.Add(key);
86  }
87  return key;
88 }
89 
91 {
92  UInt_t sum_data_size = 0u;
93  if ( fSubKey == 0x0 || fSubKeyConst == 0x0 ) return sum_data_size; // should not be necessary
94 
95  // clear the current stack of keys, set the level of the stack of allocated keys to 0
96  // and rewind the buffer to extract the current keys
97  fCurrentKeys.Clear(); fStackOfKeys.SetBottom(); fBuffer->SetOffset();
98  while ( 1 ) {
99  // try to get the next key from the frame
100  if ( ! fSubKey->Link((*fBuffer),fBuffer->Offset(),fSubKeyConst->GetKeyLength()) ) break;
101 
102 // fSubKey->Print(); fSubKeyConst->Print();
103 
104  // check if the current key is of the expected type
105  if ( fSubKeyConst->IsAKey(fSubKey) ) {
106  Key *nextsubkey = NewSubKey();
107  if ( nextsubkey ) {
108  nextsubkey->Link((*fBuffer),fBuffer->Offset(),fSubKeyConst->GetKeyLength());
109  fCurrentKeys.Add(nextsubkey);
110 
111  sum_data_size += nextsubkey->GetDataLength();
112  }
114  }
115  else break; // cannot scan anymore ... unknown type of key
116  }
117  return sum_data_size;
118 }
119 
120 Bool_t CompositeFrame::IsASubFrame(const Frame &frame)
121 {
122  if ( fSubKeyConst->IsAKey(frame.GetKey()) )
123  return true;
124  return false;
125 }
126 
127 Bool_t CompositeFrame::AddSubFrame(const Frame &frame)
128 {
129  Bool_t ok = false;
130 
131  // check if the given Frame is compatible.
132  if ( !IsASubFrame(frame) )
133  return false;
134 
135  // check the size needed to add this sub-frame
136  UInt_t needed = frame.GetKey()->GetDataLength() + fSubKeyConst->GetKeyLength();
137 
138  if ( !fBuffer->Reserve(needed) )
139  return false;
140 
141  // get a new subkey, link it to the inner buffer and fill it by the convertion mechanism
142  Key *nextsubkey = 0x0;
143  nextsubkey =
144  NewSubKey();
145 
146  ok = nextsubkey->Link((*fBuffer),fBuffer->Offset(),fSubKeyConst->GetKeyLength());
147  ok = ok
148  && nextsubkey->Convert(frame.GetKey());
149 
150  // now copy the data part from the given frame into this (Export moves the cursor into fBuffer)
152  ok = ok
153  && frame.ExportData((*fBuffer));
154 
155  // if ok, change the data size in the current buffer, add the newkey to the list of current subkey
156  if ( ok ) {
157  fKey->SetDataLength(fKey->GetDataLength()+needed);
158  fCurrentKeys.Add(nextsubkey);
159  }
160  return ok;
161 }
162 
163 Bool_t CompositeFrame::LinkSubFrame(UInt_t whichsubkey, Frame *subframe)
164 {
165  Key *subkey = fCurrentKeys.At(whichsubkey);
166  if ( subkey == 0x0 )
167  return false;
168 
169  // export only the data part, the key is converted.
170  UInt_t off =
171  fBuffer->Offset();
173 
174  Bool_t ok;
175  ok = subframe->GetKey()->Convert(subkey);
176  ok = ok &&
177  subframe->Link(fBuffer->CurrentAddress(),subkey->GetDataLength(),'f');
178 
179  fBuffer->SetOffset(off); // back to previous position
180 
181  return ok;
182 }
183 
184 Bool_t CompositeFrame::TransfertSubFrame(const Frame &from, UInt_t whichsub)
185 {
186  // both frames must be composite
187  if ( from.IsComposite() == false )
188  return false;
189 
190  const Key *subkey = from.GetSubKey(whichsub);
191  if ( subkey == from.GetKey() ) {
192  return false;
193  } // in case the subkey does not exist
194 
195  Bool_t ok = true;
196  UInt_t needed =
197  subkey->GetFrameLength();
198 
199  // check if enough place in the destination buffer
200  RealBuffer()->SetOffset(GetKey()->GetDataLength());
201  if ( needed > RealBuffer()->FreeSize() )
202  if ( !RealBuffer()->Reserve(needed) )
203  return false;
204 
205  // copy the subframe in the destination frame
206  UInt_t pos_subframe;
207  if ( (*from.GetRealBuffer()).IsAnOffset(subkey->GetAddress(),pos_subframe) )
208  ok = ok &&
209  BufferIO::Copy((*from.GetRealBuffer()),(*RealBuffer()),needed,pos_subframe);
210  else
211  ok = false;
212 
213  // change the key content
214  if ( ok )
215  GetKey()->SetDataLength(GetKey()->GetDataLength()+needed);
216 
217  return ok;
218 }
219 
220 /*
221 Bool_t CompositeFrame::ChangeFrame(const Version &version)
222 {
223  if ( IsZombie() )
224  return false;
225 
226  // define the new key and check it is a valid key
227  FactoryItem newkeyitem;
228  newkeyitem =
229  fSubKeyConst->GetSignature();
230  newkeyitem.SetVersion(version);
231 
232  Key *newkey =
233  KeyFactory::New(newkeyitem);
234  if ( newkey == 0x0 )
235  return false;
236 
237  // allocation of new keys
238  Key *sub, *subcst;
239 
240  sub = KeyFactory::theMainFactory().Clone(newkey);
241  subcst = KeyFactory::theMainFactory().Clone(newkey);
242 
243  delete newkey;
244 
245  if ( sub && subcst ) {
246  if ( fSubKeyConst )
247  delete fSubKeyConst;
248  if ( fSubKey)
249  delete fSubKey;
250 
251  fSubKey = sub; fSubKeyConst = subcst;
252 
253  fStackOfKeys.Delete();
254  fCurrentKeys.Clear();
255 
256  return true;
257  }
258  else {
259  if ( sub )
260  delete sub;
261  if ( subcst )
262  delete subcst;
263 
264  return false;
265  }
266 }
267 */
268 
269 
270 
271 
272 
273 
virtual const Key * GetSubKey(UInt_t) const =0
Returns one of the sub-key in case this is a composite frame.
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
virtual BufferIO * RealBuffer()
Definition: Frame.h:314
virtual Key * GetKey()=0
To get the Key associated to this frame.
Base class for a Key.
Definition: Key.h:56
Base class for a Frame.
Definition: Frame.h:73
Char_t * CurrentAddress()
for classes that needs it to write directly data into it.
Definition: BufferIO.h:101
virtual const BufferIO * GetRealBuffer() const =0
give access to the underlying buffer of the data part
virtual Key * GetKey()
To get the Key associated to this frame.
Definition: Frame.h:344
virtual Bool_t IsASubFrame(const Frame &)
to check if a subframe could be added to the composite frame
virtual UInt_t GetDataLength() const
Definition: Key.h:134
Key * fSubKeyConst
ConstKey remains unchanged (unlinked) to be sure the comparison IsAKey is always good.
virtual Bool_t ExportData(BufferIO &buf) const =0
Export the content of the frame (data part only) in a buffer.
UInt_t Offset() const
it returns the current position in the buffer
Definition: BufferIO.h:240
BufferIO * fBuffer
Definition: Frame.h:310
virtual Bool_t IsComposite() const
tells if this frame is a composite frame i.e. if it is composed of sub-frames
Definition: Frame.h:212
virtual Bool_t AddSubFrame(const Frame &)
Add a subframe to that frame (only if composite)
virtual UInt_t GetKeyLength() const
Unique number corresponding to a type of Key.
Definition: Key.h:210
virtual const Char_t * GetAddress() const
Definition: Key.h:139
virtual Bool_t Copy(const Char_t *from, UInt_t from_size)
copy an external buffer to this.
Definition: BufferIO.cpp:248
virtual UInt_t Scan()
Scan this CompositeFrame. If it is a composite frame, it looks for the keys of sub-frames.
virtual Bool_t Link(const Char_t *, UInt_t)
Link an external buffer to this key.
Definition: Key.cpp:74
virtual Bool_t Convert(const Key *akey)
convert a key to another key ... not an easy task ... use it carefully
Definition: Key.h:226
Key * NewSubKey()
to get a new subkey
virtual Bool_t LinkSubFrame(UInt_t, Frame *)
Attach the sub-frame corresponding to the given subkey to the Frame given in the second argument...
virtual Bool_t Link(const Char_t *, UInt_t, const char= 'b')=0
Link a buffer to this Frame.
virtual Bool_t TransfertSubFrame(const Frame &from, UInt_t whichsub)
copy the sub-frame #i to the CompositeFrame given in the second argument
Key * fSubKey
Key used to scan the main frame (link to parts of the main frame)
static MainKeyFactory & theMainFactory()
the main (global) keyfactory
Definition: KeyFactory.cpp:150
virtual Key * New(const FactoryItem &)
build a key using item.
Definition: KeyFactory.cpp:155
virtual Bool_t IsAKey(const Key *akey) const
Compares two keys.
Definition: Key.h:217
virtual UInt_t GetFrameLength() const
Definition: Key.h:136
Base class that described an item in a Factory.
Definition: FactoryItem.h:52
UInt_t SetOffset(UInt_t off=0u) const
change the current position.
Definition: BufferIO.cpp:122