v2.0.0
Loading...
Searching...
No Matches
fiff_dir_node.cpp
Go to the documentation of this file.
1//=============================================================================================================
21
22//=============================================================================================================
23// INCLUDES
24//=============================================================================================================
25
26#include "fiff_dir_node.h"
27#include "fiff_stream.h"
28#include "fiff_tag.h"
29#include "fiff_explain.h"
30#include <QDebug>
31//#include "fiff_ctf_comp.h"
32//#include "fiff_proj.h"
33//#include "fiff_info.h"
34
35//=============================================================================================================
36// USED NAMESPACES
37//=============================================================================================================
38
39using namespace FIFFLIB;
40
41//=============================================================================================================
42// DEFINE MEMBER METHODS
43//=============================================================================================================
44
46: type(-1)
47, nent_tree(-1)
48, parent(nullptr)
49{
50}
51
52//=============================================================================================================
53
55: type(p_FiffDirTree->type)
56, id(p_FiffDirTree->id)
57, dir(p_FiffDirTree->dir)
58, nent_tree(p_FiffDirTree->nent_tree)
59, parent(p_FiffDirTree->parent)
60, parent_id(p_FiffDirTree->parent_id)
61, children(p_FiffDirTree->children)
62{
63}
64
65//=============================================================================================================
66
68{
69 // QList<FiffDirNode*>::iterator i;
70 // for (i = this->children.begin(); i != this->children.end(); ++i)
71 // if (*i)
72 // delete *i;
73}
74
75//=============================================================================================================
76
77bool FiffDirNode::copy_tree(FiffStream::SPtr& p_pStreamIn, const FiffId& in_id, const QList<FiffDirNode::SPtr>& p_Nodes, FiffStream::SPtr& p_pStreamOut)
78{
79 if (p_Nodes.size() <= 0)
80 return false;
81
82 qint32 k, p;
83
84 for (k = 0; k < p_Nodes.size(); ++k) {
85 p_pStreamOut->start_block(p_Nodes[k]->type); //8
86 if (p_Nodes[k]->id.version != -1) {
87 if (in_id.version != -1)
88 p_pStreamOut->write_id(FIFF_PARENT_FILE_ID, in_id); //9
89
90 p_pStreamOut->write_id(FIFF_BLOCK_ID); //10
91 p_pStreamOut->write_id(FIFF_PARENT_BLOCK_ID, p_Nodes[k]->id); //11
92 }
93 for (p = 0; p < p_Nodes[k]->nent(); ++p) {
94 //
95 // Do not copy these tags
96 //
97 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)
98 continue;
99
100 //
101 // Read and write tags, pass data through transparently
102 //
103 if (!p_pStreamIn->device()->seek(p_Nodes[k]->dir[p]->pos)) //fseek(fidin, nodes(k).dir(p).pos, 'bof') == -1
104 {
105 qWarning("Could not seek to the tag\n");
106 return false;
107 }
108
109 //ToDo this is the same like read_tag
110 auto tag = std::make_unique<FiffTag>();
111 //QDataStream in(fidin);
112 FiffStream::SPtr in = p_pStreamIn;
113 in->setByteOrder(QDataStream::BigEndian);
114
115 //
116 // Read fiff tag header from stream
117 //
118 *in >> tag->kind;
119 *in >> tag->type;
120 qint32 size;
121 *in >> size;
122 tag->resize(size);
123 *in >> tag->next;
124
125 //
126 // Read data when available
127 //
128 if (tag->size() > 0) {
129 in->readRawData(tag->data(), tag->size());
130 // Don't do this conversion because it breaks the writing on
131 // little endian systems (i.e., OSX, Linux, Windows...)
132 // FiffTag::convert_tag_data(tag.get(),FIFFV_BIG_ENDIAN,FIFFV_NATIVE_ENDIAN);
133 }
134
135 //QDataStream out(p_pStreamOut);
136 FiffStream::SPtr out = p_pStreamOut;
137 out->setByteOrder(QDataStream::BigEndian);
138
139 *out << (qint32)tag->kind;
140 *out << (qint32)tag->type;
141 *out << (qint32)tag->size();
142 *out << (qint32)FIFFV_NEXT_SEQ;
143
144 out->writeRawData(tag->data(), tag->size());
145 }
146 for (p = 0; p < p_Nodes[k]->nchild(); ++p) {
147 QList<FiffDirNode::SPtr> childList;
148 childList << p_Nodes[k]->children[p];
149 FiffDirNode::copy_tree(p_pStreamIn, in_id, childList, p_pStreamOut);
150 }
151 p_pStreamOut->end_block(p_Nodes[k]->type);
152 }
153 return true;
154}
155
156//=============================================================================================================
157
158QList<FiffDirNode::SPtr> FiffDirNode::dir_tree_find(fiff_int_t p_kind) const
159{
160 QList<FiffDirNode::SPtr> nodes;
161 if (this->type == p_kind)
162 nodes.append(FiffDirNode::SPtr(new FiffDirNode(this)));
163
164 QList<FiffDirNode::SPtr>::const_iterator i;
165 for (i = this->children.begin(); i != this->children.end(); ++i)
166 nodes.append((*i)->dir_tree_find(p_kind));
167
168 return nodes;
169}
170
171//=============================================================================================================
172
173bool FiffDirNode::find_tag(FiffStream* p_pStream, fiff_int_t findkind, FiffTag::UPtr& p_pTag) const
174{
175 for (qint32 p = 0; p < this->nent(); ++p) {
176 if (this->dir[p]->kind == findkind) {
177 p_pStream->read_tag(p_pTag, this->dir[p]->pos);
178 return true;
179 }
180 }
181 if (p_pTag)
182 p_pTag.reset();
183
184 return false;
185}
186
187//=============================================================================================================
188
190{
191 for (qint32 p = 0; p < this->nent(); ++p)
192 if (this->dir.at(p)->kind == findkind)
193 return true;
194 return false;
195}
196
197//=============================================================================================================
198
200{
201 if (this->type == p_kind)
202 return true;
203
204 QList<FiffDirNode::SPtr>::const_iterator i;
205 for (i = this->children.begin(); i != this->children.end(); ++i)
206 if ((*i)->has_kind(p_kind))
207 return true;
208
209 return false;
210}
211
212//=============================================================================================================
213
214void FiffDirNode::print(int indent) const
215{
216 int j, prev_kind, count;
217 QList<FiffDirEntry::SPtr> dentry = this->dir;
218
219 for (int k = 0; k < indent; k++)
220 putchar(' ');
221 explain_block(this->type);
222 qDebug(" { ");
223 if (!this->id.isEmpty())
224 this->id.print();
225 qDebug("\n");
226
227 for (j = 0, prev_kind = -1, count = 0; j < this->nent(); j++) {
228 if (dentry[j]->kind != prev_kind) {
229 if (count > 1)
230 qDebug(" [%d]\n", count);
231 else if (j > 0)
232 putchar('\n');
233 for (int k = 0; k < indent + 2; k++)
234 putchar(' ');
235 explain(dentry[j]->kind);
236 prev_kind = dentry[j]->kind;
237 count = 1;
238 } else
239 count++;
240 prev_kind = dentry[j]->kind;
241 }
242 if (count > 1)
243 qDebug(" [%d]\n", count);
244 else if (j > 0)
245 putchar('\n');
246 for (j = 0; j < this->nchild(); j++)
247 this->children[j]->print(indent + 5);
248 for (int k = 0; k < indent; k++)
249 putchar(' ');
250 qDebug("}\n");
251}
252
253//=============================================================================================================
254
256{
257 for (int k = 0; _fiff_block_explanations[k].kind >= 0; k++) {
258 if (_fiff_block_explanations[k].kind == kind) {
259 qDebug("%d = %s", kind, _fiff_block_explanations[k].text);
260 return;
261 }
262 }
263 qWarning("Cannot explain: %d", kind);
264}
265
266//=============================================================================================================
267
269{
270 int k;
271 for (k = 0; _fiff_explanations[k].kind >= 0; k++) {
272 if (_fiff_explanations[k].kind == kind) {
273 qDebug("%d = %s", kind, _fiff_explanations[k].text);
274 return;
275 }
276 }
277 qWarning("Cannot explain: %d", kind);
278}
279
280//=============================================================================================================
281
283{
284 int k;
285 for (k = 0; _fiff_explanations[k].kind >= 0; k++) {
286 if (_fiff_explanations[k].kind == kind)
287 return _fiff_explanations[k].text;
288 }
289 return "unknown";
290}
291
292//=============================================================================================================
293
294const char* FiffDirNode::get_unit_name(int unit)
295{
296 for (int k = 0; _fiff_unit_explanations[k].kind >= 0; k++) {
297 if (_fiff_unit_explanations[k].kind == unit)
298 return _fiff_unit_explanations[k].text;
299 }
300 return "NA";
301}
302
303//=============================================================================================================
304
306{
307 return dir.size();
308}
309
310//=============================================================================================================
311
313{
314 return children.size();
315}
#define FIFFV_NEXT_SEQ
FIFF tag: the 16-byte tag header (kind, type, size, next) plus its decoded payload.
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
Static lookup table mapping every documented FIFF tag kind to a fixed-width human-readable label,...
#define FIFF_PARENT_BLOCK_ID
Definition fiff_file.h:326
#define FIFF_BLOCK_ID
Definition fiff_file.h:319
#define FIFF_PARENT_FILE_ID
Definition fiff_file.h:325
Recursive node of the parsed FIFF block tree (FIFFB_* hierarchy with directory entries and children).
FIFF file I/O, in-memory data structures and high-level readers/writers.
qint32 fiff_int_t
Definition fiff_types.h:86
fiff_int_t nchild() const
QList< FiffDirNode::SPtr > children
static const char * get_unit_name(int unit)
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)
128-bit FIFF identifier: hardware machine ID plus creation time, stamped on every file and block.
Definition fiff_id.h:69
fiff_int_t version
Definition fiff_id.h:192
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
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:165