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