v2.0.0
Loading...
Searching...
No Matches
fiff_id.cpp
Go to the documentation of this file.
1//=============================================================================================================
19
20//=============================================================================================================
21// INCLUDES
22//=============================================================================================================
23
24#include "fiff_id.h"
25#include "fiff_file.h"
26
27#ifndef __EMSCRIPTEN__
28#include <QNetworkInterface>
29#endif
30#include <QDateTime>
31
32#include <ctime>
33#include <QDebug>
34
35//=============================================================================================================
36// USED NAMESPACES
37//=============================================================================================================
38
39using namespace FIFFLIB;
40
41//=============================================================================================================
42// DEFINE MEMBER METHODS
43//=============================================================================================================
44
46: version(-1)
47{
48 machid[0] = -1;
49 machid[1] = -1;
50 time.secs = -1;
51 time.usecs = -1;
52}
53
54//=============================================================================================================
55
56FiffId::FiffId(const FiffId& p_FiffId)
57: version(p_FiffId.version)
58{
59 machid[0] = p_FiffId.machid[0];
60 machid[1] = p_FiffId.machid[1];
61 time.secs = p_FiffId.time.secs;
62 time.usecs = p_FiffId.time.usecs;
63}
64
65//=============================================================================================================
66
70
71//=============================================================================================================
72
74{
75 FiffId id;
76 id.version = FIFFC_VERSION;
77
78 int fixed_id[2];
79 get_machid(fixed_id);
80 /*
81 * Internet address in the first two words
82 */
83 id.machid[0] = fixed_id[0];
84 id.machid[1] = fixed_id[1];
85 /*
86 * Time in the third and fourth words
87 */
88 /*
89 * Time in the third and fourth words
90 * Since practically no system gives times in
91 * true micro seconds, the last three digits
92 * are randomized to insure uniqueness.
93 */
94 {
95 id.time.secs = QDateTime::currentMSecsSinceEpoch() / 1000;
96 id.time.usecs = rand() % 1000;
97 }
98 return id;
99}
100
101//=============================================================================================================
102
104{
105 version = -1;
106 machid[0] = -1;
107 machid[1] = -1;
108 time.secs = -1;
109 time.usecs = -1;
110}
111
112//=============================================================================================================
113
114bool FiffId::get_machid(int* fixed_id)
115{
116 QList<QString> possibleHardwareAdresses;
117 fixed_id[0] = 0;
118 fixed_id[1] = 0;
119
120#ifndef __EMSCRIPTEN__
121 QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
122
123 if (!ifaces.isEmpty()) {
124 for (int i = 0; i < ifaces.size(); ++i) {
125 unsigned int flags = ifaces[i].flags();
126 bool isLoopback = static_cast<bool>(flags & QNetworkInterface::IsLoopBack);
127 bool isP2P = static_cast<bool>(flags & QNetworkInterface::IsPointToPoint);
128 bool isRunning = static_cast<bool>(flags & QNetworkInterface::IsRunning);
129 // If this interface isn't running, we don't care about it
130 if (!isRunning)
131 continue;
132 // We only want valid interfaces that aren't loopback/virtual and not point to point
133 if (!ifaces[i].isValid() || isLoopback || isP2P)
134 continue;
135 possibleHardwareAdresses << ifaces[i].hardwareAddress();
136 }
137 if (possibleHardwareAdresses.size() > 0) {
138 // We take the first address as machine identifier
139 QStringList hexPresentation = possibleHardwareAdresses[0].split(":");
140 if (hexPresentation.size() == 6) {
141 fixed_id[0] = QString(hexPresentation[0] + hexPresentation[1] + hexPresentation[2]).toInt(nullptr, 16);
142 fixed_id[1] = QString(hexPresentation[3] + hexPresentation[4] + hexPresentation[5]).toInt(nullptr, 16);
143 return true;
144 }
145 }
146 }
147#endif
148
149 return false;
150}
151
152//=============================================================================================================
153
154void FiffId::print() const
155{
156 if (!isEmpty()) {
157 qInfo("\t%d.%d 0x%x%x %d %d\n", this->version >> 16, this->version & 0xFFFF, this->machid[0], this->machid[1], this->time.secs, this->time.usecs);
158 }
159}
160
161//=============================================================================================================
162
164{
165 QString strOut = QString("%1%2").arg(machid[0], 8, 16, QChar('0')).arg(machid[1], 8, 16, QChar('0'));
166
167 // to do...
168 // macid is 6 bytes of data->12 chars.
169 // here macid is stored in two integers --> 8 bytes --> 16 chars.
170 // some versions of sinuhe store the significant chars at the beginning of the 16 chars.
171 // other versions sotre the at the end. I don't know on what it depends on.
172 // clue 1: version 1.3 stores it at the beginning. (padding with 4 '0' chars at the end).
173 // clue 2: version 1.2 stores it at the ending chars. (padding with 4 '0' chars at the beginning of the 16).
174 // I've no idea if this behaviour is solid...
175 // int thresholdMayorVersion(1);
176 // int thresholdMinorVersion(2);
177
178 // int thresholdVersionInt(static_cast<int>(thresholdMayorVersion*pow(2.,16))+thresholdMinorVersion);
179 // if(version > thresholdVersionInt) //if this.version > 65538
180 // {
181 // strOut.chop(4);
182 // } else
183 // {
184 // strOut.right(strOut.size()-4);
185 // }
186
187 int step = 2;
188 for (int i = step; i < strOut.size(); i += step + 1) {
189 strOut.insert(i, QChar(':'));
190 }
191
192 return strOut.toUpper();
193}
194
195//=============================================================================================================
196
198{
199 static FiffId defaultFiffId;
200 return defaultFiffId;
201}
202
203//=============================================================================================================
204
205QString FiffId::toString() const
206{
207 time_t secs = time.secs;
208
209 // localtime() returns a pointer to a shared static buffer, so two threads
210 // formatting an id at once can corrupt each other's result. Use the
211 // reentrant variant, which writes into a caller-supplied struct. MSVC
212 // spells it localtime_s and reverses the argument order.
213 struct tm ltime{};
214#ifdef _WIN32
215 const bool bTimeValid = (localtime_s(&ltime, &secs) == 0);
216#else
217 const bool bTimeValid = (localtime_r(&secs, &ltime) != nullptr);
218#endif
219
220 char timebuf[100];
221 if (!bTimeValid || strftime(timebuf, sizeof(timebuf), "%c", &ltime) == 0) {
222 timebuf[0] = '\0';
223 }
224
225 return QString("%1.%2 0x%3%4 %5")
226 .arg(version >> 16)
227 .arg(version & 0xFFFF)
228 .arg(machid[0], 0, 16)
229 .arg(machid[1], 0, 16)
230 .arg(QString::fromLatin1(timebuf));
231}
FIFF tag-kind, block-kind and type-code numerical definitions, authoritative for FIFFLIB.
#define FIFFC_VERSION
Definition fiff_file.h:215
128-bit FIFF identifier record (machine ID + creation time) used to stamp files, blocks and parent re...
FIFF file I/O, in-memory data structures and high-level readers/writers.
fiff_int_t machid[2]
Definition fiff_id.h:193
QString toString() const
Definition fiff_id.cpp:205
bool isEmpty() const
Definition fiff_id.h:201
QString toMachidString() const
Definition fiff_id.cpp:163
FiffTime time
Definition fiff_id.h:194
static bool get_machid(int *fixed_id)
Definition fiff_id.cpp:114
static FiffId new_file_id()
Definition fiff_id.cpp:73
fiff_int_t version
Definition fiff_id.h:192
void print() const
Definition fiff_id.cpp:154
static FiffId & getDefault()
Definition fiff_id.cpp:197