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