MNE-CPP  beta 1.0
fiff_dir_tree.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "fiff_dir_tree.h"
42 #include "fiff_stream.h"
43 #include "fiff_tag.h"
44 //#include "fiff_ctf_comp.h"
45 //#include "fiff_proj.h"
46 //#include "fiff_info.h"
47 
48 
49 //*************************************************************************************************************
50 //=============================================================================================================
51 // USED NAMESPACES
52 //=============================================================================================================
53 
54 using namespace FIFFLIB;
55 
56 
57 //*************************************************************************************************************
58 //=============================================================================================================
59 // DEFINE MEMBER METHODS
60 //=============================================================================================================
61 
63 : block(-1)
64 , nent(-1)
65 , nent_tree(-1)
66 , nchild(-1)
67 {
68 }
69 
70 
71 //*************************************************************************************************************
72 
74 : block(p_FiffDirTree.block)
75 , id(p_FiffDirTree.id)
76 , parent_id(p_FiffDirTree.parent_id)
77 , dir(p_FiffDirTree.dir)
78 , nent(p_FiffDirTree.nent)
79 , nent_tree(p_FiffDirTree.nent_tree)
80 , children(p_FiffDirTree.children)
81 , nchild(p_FiffDirTree.nchild)
82 {
83 
84 }
85 
86 
87 //*************************************************************************************************************
88 
90 {
91 // QList<FiffDirTree*>::iterator i;
92 // for (i = this->children.begin(); i != this->children.end(); ++i)
93 // if (*i)
94 // delete *i;
95 }
96 
97 
98 //*************************************************************************************************************
99 
101 {
102  block = -1;
103  id.clear();
104  parent_id.clear();
105  dir.clear();
106  nent = -1;
107  nent_tree = -1;
108  children.clear();
109  nchild = -1;
110 }
111 
112 
113 //*************************************************************************************************************
114 
115 bool FiffDirTree::copy_tree(FiffStream::SPtr p_pStreamIn, FiffId& in_id, QList<FiffDirTree>& p_Nodes, FiffStream::SPtr p_pStreamOut)
116 {
117  if(p_Nodes.size() <= 0)
118  return false;
119 
120  qint32 k, p;
121 
122  for(k = 0; k < p_Nodes.size(); ++k)
123  {
124  p_pStreamOut->start_block(p_Nodes[k].block);//8
125  if (p_Nodes[k].id.version != -1)
126  {
127  if (in_id.version != -1)
128  p_pStreamOut->write_id(FIFF_PARENT_FILE_ID, in_id);//9
129 
130  p_pStreamOut->write_id(FIFF_BLOCK_ID);//10
131  p_pStreamOut->write_id(FIFF_PARENT_BLOCK_ID, p_Nodes[k].id);//11
132  }
133  for (p = 0; p < p_Nodes[k].nent; ++p)
134  {
135  //
136  // Do not copy these tags
137  //
138  if(p_Nodes[k].dir[p].kind == FIFF_BLOCK_ID || p_Nodes[k].dir[p].kind == FIFF_PARENT_BLOCK_ID || p_Nodes[k].dir[p].kind == FIFF_PARENT_FILE_ID)
139  continue;
140 
141  //
142  // Read and write tags, pass data through transparently
143  //
144  if (!p_pStreamIn->device()->seek(p_Nodes[k].dir[p].pos)) //fseek(fidin, nodes(k).dir(p).pos, 'bof') == -1
145  {
146  printf("Could not seek to the tag\n");
147  return false;
148  }
149 
150 //ToDo this is the same like read_tag
151  FiffTag::SPtr tag(new FiffTag());
152  //QDataStream in(fidin);
153  FiffStream::SPtr in = p_pStreamIn;
154  in->setByteOrder(QDataStream::BigEndian);
155 
156  //
157  // Read fiff tag header from stream
158  //
159  *in >> tag->kind;
160  *in >> tag->type;
161  qint32 size;
162  *in >> size;
163  tag->resize(size);
164  *in >> tag->next;
165 
166  //
167  // Read data when available
168  //
169  if (tag->size() > 0)
170  {
171  in->readRawData(tag->data(), tag->size());
172  FiffTag::convert_tag_data(tag,FIFFV_BIG_ENDIAN,FIFFV_NATIVE_ENDIAN);
173  }
174 
175  //QDataStream out(p_pStreamOut);
176  FiffStream::SPtr out = p_pStreamOut;
177  out->setByteOrder(QDataStream::BigEndian);
178 
179  *out << (qint32)tag->kind;
180  *out << (qint32)tag->type;
181  *out << (qint32)tag->size();
182  *out << (qint32)FIFFV_NEXT_SEQ;
183 
184  out->writeRawData(tag->data(),tag->size());
185  }
186  for(p = 0; p < p_Nodes[k].nchild; ++p)
187  {
188  QList<FiffDirTree> childList;
189  childList << p_Nodes[k].children[p];
190  FiffDirTree::copy_tree(p_pStreamIn, in_id, childList, p_pStreamOut);
191  }
192  p_pStreamOut->end_block(p_Nodes[k].block);
193  }
194  return true;
195 }
196 
197 
198 //*************************************************************************************************************
199 
200 qint32 FiffDirTree::make_dir_tree(FiffStream* p_pStream, QList<FiffDirEntry>& p_Dir, FiffDirTree& p_Tree, qint32 start)
201 {
202 // if (p_pTree != NULL)
203 // delete p_pTree;
204  p_Tree.clear();
205 
206  FiffTag::SPtr t_pTag;
207 
208  qint32 block;
209  if(p_Dir[start].kind == FIFF_BLOCK_START)
210  {
211  FiffTag::read_tag(p_pStream, t_pTag, p_Dir[start].pos);
212  block = *t_pTag->toInt();
213  }
214  else
215  {
216  block = 0;
217  }
218 
219 // qDebug() << "start { " << p_pTree->block;
220 
221  qint32 current = start;
222 
223  p_Tree.block = block;
224  p_Tree.nent = 0;
225  p_Tree.nchild = 0;
226 
227  while (current < p_Dir.size())
228  {
229  if (p_Dir[current].kind == FIFF_BLOCK_START)
230  {
231  if (current != start)
232  {
233  FiffDirTree t_ChildTree;
234  current = FiffDirTree::make_dir_tree(p_pStream,p_Dir,t_ChildTree, current);
235  ++p_Tree.nchild;
236  p_Tree.children.append(t_ChildTree);
237  }
238  }
239  else if(p_Dir[current].kind == FIFF_BLOCK_END)
240  {
241  FiffTag::read_tag(p_pStream, t_pTag, p_Dir[start].pos);
242  if (*t_pTag->toInt() == p_Tree.block)
243  break;
244  }
245  else
246  {
247  ++p_Tree.nent;
248  p_Tree.dir.append(p_Dir[current]);
249 
250  //
251  // Add the id information if available
252  //
253  if (block == 0)
254  {
255  if (p_Dir[current].kind == FIFF_FILE_ID)
256  {
257  FiffTag::read_tag(p_pStream, t_pTag, p_Dir[current].pos);
258  p_Tree.id = t_pTag->toFiffID();
259  }
260  }
261  else
262  {
263  if (p_Dir[current].kind == FIFF_BLOCK_ID)
264  {
265  FiffTag::read_tag(p_pStream, t_pTag, p_Dir[current].pos);
266  p_Tree.id = t_pTag->toFiffID();
267  }
268  else if (p_Dir[current].kind == FIFF_PARENT_BLOCK_ID)
269  {
270  FiffTag::read_tag(p_pStream, t_pTag, p_Dir[current].pos);
271  p_Tree.parent_id = t_pTag->toFiffID();
272  }
273  }
274  }
275  ++current;
276  }
277 
278  //
279  // Eliminate the empty directory
280  //
281  if(p_Tree.nent == 0)
282  p_Tree.dir.clear();
283 
284 // qDebug() << "block =" << p_pTree->block << "nent =" << p_pTree->nent << "nchild =" << p_pTree->nchild;
285 // qDebug() << "end } " << block;
286 
287  return current;
288 }
289 
290 
291 //*************************************************************************************************************
292 
293 QList<FiffDirTree> FiffDirTree::dir_tree_find(fiff_int_t p_kind) const
294 {
295  QList<FiffDirTree> nodes;
296  if(this->block == p_kind)
297  nodes.append(*this);
298 
299  QList<FiffDirTree>::const_iterator i;
300  for (i = this->children.begin(); i != this->children.end(); ++i)
301  nodes.append((*i).dir_tree_find(p_kind));
302 
303  return nodes;
304 }
305 
306 
307 //*************************************************************************************************************
308 
309 bool FiffDirTree::find_tag(FiffStream* p_pStream, fiff_int_t findkind, FiffTag::SPtr& p_pTag) const
310 {
311  for (qint32 p = 0; p < this->nent; ++p)
312  {
313  if (this->dir[p].kind == findkind)
314  {
315  FiffTag::read_tag(p_pStream,p_pTag,this->dir[p].pos);
316  return true;
317  }
318  }
319  if (p_pTag)
320  p_pTag.clear();
321 
322  return false;
323 }
324 
325 
326 //*************************************************************************************************************
327 
328 bool FiffDirTree::has_tag(fiff_int_t findkind)
329 {
330  for(qint32 p = 0; p < this->nent; ++p)
331  if(this->dir.at(p).kind == findkind)
332  return true;
333  return false;
334 }
335 
336 //*************************************************************************************************************
337 
338 bool FiffDirTree::has_kind(fiff_int_t p_kind) const
339 {
340  if(this->block == p_kind)
341  return true;
342 
343  QList<FiffDirTree>::const_iterator i;
344  for(i = this->children.begin(); i != this->children.end(); ++i)
345  if((*i).has_kind(p_kind))
346  return true;
347 
348  return false;
349 }
static bool copy_tree(QSharedPointer< FiffStream > p_pStreamIn, FiffId &in_id, QList< FiffDirTree > &p_Nodes, QSharedPointer< FiffStream > p_pStreamOut)
QList< FiffDirTree > children
bool find_tag(FiffStream *p_pStream, fiff_int_t findkind, QSharedPointer< FiffTag > &p_pTag) const
fiff_int_t version
Definition: fiff_id.h:127
QList< FiffDirTree > dir_tree_find(fiff_int_t p_kind) const
FiffDirTree class declaration, which provides fiff dir tree processing methods.
Universially unique identifier.
Definition: fiff_id.h:78
static qint32 make_dir_tree(FiffStream *p_pStream, QList< FiffDirEntry > &p_Dir, FiffDirTree &p_Tree, qint32 start=0)
QSharedPointer< FiffTag > SPtr
Definition: fiff_tag.h:166
static bool read_tag(FiffStream *p_pStream, FiffTag::SPtr &p_pTag, qint64 pos=-1)
Definition: fiff_tag.cpp:204
static void convert_tag_data(FiffTag::SPtr tag, int from_endian, int to_endian)
Definition: fiff_tag.cpp:617
bool has_kind(fiff_int_t p_kind) const
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:132
FiffStream class declaration.
Directory tree structure.
Definition: fiff_dir_tree.h:80
bool has_tag(fiff_int_t findkind)
QList< FiffDirEntry > dir
Definition: fiff.h:98
FIFF data tag.
Definition: fiff_tag.h:163
FiffTag class declaration, which provides fiff tag I/O and processing methods.
FIFF File I/O routines.
Definition: fiff_stream.h:129
void clear()
Definition: fiff_id.cpp:89