MNE-CPP  0.1.9
A Framework for Electrophysiology
fiff_dir_node.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "fiff_dir_node.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 // USED NAMESPACES
50 //=============================================================================================================
51 
52 using namespace FIFFLIB;
53 
54 //=============================================================================================================
55 // DEFINE MEMBER METHODS
56 //=============================================================================================================
57 
59 : type(-1)
60 , nent_tree(-1)
61 , parent(NULL)
62 {
63 }
64 
65 //=============================================================================================================
66 
68 : type(p_FiffDirTree->type)
69 , id(p_FiffDirTree->id)
70 , parent_id(p_FiffDirTree->parent_id)
71 , dir(p_FiffDirTree->dir)
72 , nent_tree(p_FiffDirTree->nent_tree)
73 , parent(p_FiffDirTree->parent)
74 , children(p_FiffDirTree->children)
75 {
76 }
77 
78 //=============================================================================================================
79 
81 {
82  // QList<FiffDirNode*>::iterator i;
83  // for (i = this->children.begin(); i != this->children.end(); ++i)
84  // if (*i)
85  // delete *i;
86 }
87 
88 //=============================================================================================================
89 
90 bool FiffDirNode::copy_tree(FiffStream::SPtr& p_pStreamIn, const FiffId& in_id, const QList<FiffDirNode::SPtr>& p_Nodes, FiffStream::SPtr& p_pStreamOut)
91 {
92  if(p_Nodes.size() <= 0)
93  return false;
94 
95  qint32 k, p;
96 
97  for(k = 0; k < p_Nodes.size(); ++k)
98  {
99  p_pStreamOut->start_block(p_Nodes[k]->type);//8
100  if (p_Nodes[k]->id.version != -1)
101  {
102  if (in_id.version != -1)
103  p_pStreamOut->write_id(FIFF_PARENT_FILE_ID, in_id);//9
104 
105  p_pStreamOut->write_id(FIFF_BLOCK_ID);//10
106  p_pStreamOut->write_id(FIFF_PARENT_BLOCK_ID, p_Nodes[k]->id);//11
107  }
108  for (p = 0; p < p_Nodes[k]->nent(); ++p)
109  {
110  //
111  // Do not copy these tags
112  //
113  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)
114  continue;
115 
116  //
117  // Read and write tags, pass data through transparently
118  //
119  if (!p_pStreamIn->device()->seek(p_Nodes[k]->dir[p]->pos)) //fseek(fidin, nodes(k).dir(p).pos, 'bof') == -1
120  {
121  printf("Could not seek to the tag\n");
122  return false;
123  }
124 
125  //ToDo this is the same like read_tag
126  FiffTag::SPtr tag(new FiffTag());
127  //QDataStream in(fidin);
128  FiffStream::SPtr in = p_pStreamIn;
129  in->setByteOrder(QDataStream::BigEndian);
130 
131  //
132  // Read fiff tag header from stream
133  //
134  *in >> tag->kind;
135  *in >> tag->type;
136  qint32 size;
137  *in >> size;
138  tag->resize(size);
139  *in >> tag->next;
140 
141  //
142  // Read data when available
143  //
144  if (tag->size() > 0)
145  {
146  in->readRawData(tag->data(), tag->size());
147  // Don't do this conversion because it breaks the writing on
148  // little endian systems (i.e., OSX, Linux, Windows...)
149  // FiffTag::convert_tag_data(tag,FIFFV_BIG_ENDIAN,FIFFV_NATIVE_ENDIAN);
150  }
151 
152  //QDataStream out(p_pStreamOut);
153  FiffStream::SPtr out = p_pStreamOut;
154  out->setByteOrder(QDataStream::BigEndian);
155 
156  *out << (qint32)tag->kind;
157  *out << (qint32)tag->type;
158  *out << (qint32)tag->size();
159  *out << (qint32)FIFFV_NEXT_SEQ;
160 
161  out->writeRawData(tag->data(),tag->size());
162  }
163  for(p = 0; p < p_Nodes[k]->nchild(); ++p)
164  {
165  QList<FiffDirNode::SPtr> childList;
166  childList << p_Nodes[k]->children[p];
167  FiffDirNode::copy_tree(p_pStreamIn, in_id, childList, p_pStreamOut);
168  }
169  p_pStreamOut->end_block(p_Nodes[k]->type);
170  }
171  return true;
172 }
173 
174 //=============================================================================================================
175 
176 QList<FiffDirNode::SPtr> FiffDirNode::dir_tree_find(fiff_int_t p_kind) const
177 {
178  QList<FiffDirNode::SPtr> nodes;
179  if(this->type == p_kind)
180  nodes.append(FiffDirNode::SPtr(new FiffDirNode(this)));
181 
182  QList<FiffDirNode::SPtr>::const_iterator i;
183  for (i = this->children.begin(); i != this->children.end(); ++i)
184  nodes.append((*i)->dir_tree_find(p_kind));
185 
186  return nodes;
187 }
188 
189 //=============================================================================================================
190 
191 bool FiffDirNode::find_tag(FiffStream* p_pStream, fiff_int_t findkind, FiffTag::SPtr& p_pTag) const
192 {
193  for (qint32 p = 0; p < this->nent(); ++p)
194  {
195  if (this->dir[p]->kind == findkind)
196  {
197  p_pStream->read_tag(p_pTag,this->dir[p]->pos);
198  return true;
199  }
200  }
201  if (p_pTag)
202  p_pTag.clear();
203 
204  return false;
205 }
206 
207 //=============================================================================================================
208 
209 bool FiffDirNode::has_tag(fiff_int_t findkind)
210 {
211  for(qint32 p = 0; p < this->nent(); ++p)
212  if(this->dir.at(p)->kind == findkind)
213  return true;
214  return false;
215 }
216 
217 //=============================================================================================================
218 
219 bool FiffDirNode::has_kind(fiff_int_t p_kind) const
220 {
221  if(this->type == p_kind)
222  return true;
223 
224  QList<FiffDirNode::SPtr>::const_iterator i;
225  for(i = this->children.begin(); i != this->children.end(); ++i)
226  if((*i)->has_kind(p_kind))
227  return true;
228 
229  return false;
230 }
231 
232 //=============================================================================================================
233 
234 void FiffDirNode::print(int indent) const
235 {
236  int j, prev_kind,count;
237  QList<FiffDirEntry::SPtr> dentry = this->dir;
238 
239  for (int k = 0; k < indent; k++)
240  putchar(' ');
241  explain_block (this->type);
242  printf (" { ");
243  if (!this->id.isEmpty())
244  this->id.print();
245  printf ("\n");
246 
247  for (j = 0, prev_kind = -1, count = 0; j < this->nent(); j++) {
248  if (dentry[j]->kind != prev_kind) {
249  if (count > 1)
250  printf (" [%d]\n",count);
251  else if (j > 0)
252  putchar('\n');
253  for (int k = 0; k < indent+2; k++)
254  putchar(' ');
255  explain (dentry[j]->kind);
256  prev_kind = dentry[j]->kind;
257  count = 1;
258  }
259  else
260  count++;
261  prev_kind = dentry[j]->kind;
262  }
263  if (count > 1)
264  printf (" [%d]\n",count);
265  else if (j > 0)
266  putchar ('\n');
267  for (j = 0; j < this->nchild(); j++)
268  this->children[j]->print(indent+5);
269  for (int k = 0; k < indent; k++)
270  putchar(' ');
271  printf ("}\n");
272 }
273 
274 //=============================================================================================================
275 
277 {
278  for (int k = 0; _fiff_block_explanations[k].kind >= 0; k++) {
279  if (_fiff_block_explanations[k].kind == kind) {
280  printf ("%d = %s",kind,_fiff_block_explanations[k].text);
281  return;
282  }
283  }
284  printf ("Cannot explain: %d",kind);
285 }
286 
287 //=============================================================================================================
288 
289 void FiffDirNode::explain(int kind)
290 {
291  int k;
292  for (k = 0; _fiff_explanations[k].kind >= 0; k++) {
293  if (_fiff_explanations[k].kind == kind) {
294  printf ("%d = %s",kind,_fiff_explanations[k].text);
295  return;
296  }
297  }
298  printf ("Cannot explain: %d",kind);
299 }
300 
301 //=============================================================================================================
302 
303 const char *FiffDirNode::get_tag_explanation(int kind)
304 {
305  int k;
306  for (k = 0; _fiff_explanations[k].kind >= 0; k++) {
307  if (_fiff_explanations[k].kind == kind)
308  return _fiff_explanations[k].text;
309  }
310  return "unknown";
311 }
312 
313 //=============================================================================================================
314 
315 fiff_int_t FiffDirNode::nent() const
316 {
317  return dir.size();
318 }
319 
320 //=============================================================================================================
321 
322 fiff_int_t FiffDirNode::nchild() const
323 {
324  return children.size();
325 }
FiffTag class declaration, which provides fiff tag I/O and processing methods.
bool find_tag(QSharedPointer< FiffStream > &p_pStream, fiff_int_t findkind, QSharedPointer< FiffTag > &p_pTag) const
bool has_kind(fiff_int_t p_kind) const
FiffStream class declaration.
FiffDirNode::SPtr parent
bool isEmpty() const
bool read_tag(QSharedPointer< FiffTag > &p_pTag, fiff_long_t pos=-1)
QSharedPointer< FiffTag > SPtr
Definition: fiff_tag.h:152
bool has_tag(fiff_int_t findkind)
static void explain(int kind)
fiff_int_t nchild() const
QList< FiffDirNode::SPtr > dir_tree_find(fiff_int_t p_kind) const
QList< FiffDirEntry::SPtr > dir
Directory Node structure.
Definition: fiff_dir_node.h:75
FiffDirNode class declaration, which provides fiff dir tree processing methods.
FIFF data tag.
Definition: fiff_tag.h:148
void print(int indent) const
static bool copy_tree(QSharedPointer< FiffStream > &p_pStreamIn, const FiffId &in_id, const QList< QSharedPointer< FiffDirNode > > &p_Nodes, QSharedPointer< FiffStream > &p_pStreamOut)
QSharedPointer< FiffDirNode > SPtr
Definition: fiff_dir_node.h:77
static const char * get_tag_explanation(int kind)
fiff_int_t version
Definition: fiff_id.h:152
Universially unique identifier.
Definition: fiff_id.h:68
QList< FiffDirNode::SPtr > children
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:107
FIFF File I/O routines.
Definition: fiff_stream.h:104
fiff_int_t nent() const
static void explain_block(int kind)