MNE-CPP  0.1.9
A Framework for Electrophysiology
fiff_id.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "fiff_id.h"
42 #include "fiff_file.h"
43 
44 #include <QNetworkInterface>
45 #include <QDateTime>
46 
47 //=============================================================================================================
48 // USED NAMESPACES
49 //=============================================================================================================
50 
51 using namespace FIFFLIB;
52 
53 //=============================================================================================================
54 // DEFINE MEMBER METHODS
55 //=============================================================================================================
56 
58 : version(-1)
59 {
60  machid[0] = -1;
61  machid[1] = -1;
62  time.secs = -1;
63  time.usecs = -1;
64 }
65 
66 //=============================================================================================================
67 
68 FiffId::FiffId(const FiffId& p_FiffId)
69 : version(p_FiffId.version)
70 {
71  machid[0] = p_FiffId.machid[0];
72  machid[1] = p_FiffId.machid[1];
73  time.secs = p_FiffId.time.secs;
74  time.usecs = p_FiffId.time.usecs;
75 }
76 
77 //=============================================================================================================
78 
80 {
81 }
82 
83 //=============================================================================================================
84 
86 {
87  FiffId id;
88  id.version = FIFFC_VERSION;
89 
90  int fixed_id[2];
91  get_machid(fixed_id);
92  /*
93  * Internet address in the first two words
94  */
95  id.machid[0] = fixed_id[0];
96  id.machid[1] = fixed_id[1];
97  /*
98  * Time in the third and fourth words
99  */
100  /*
101  * Time in the third and fourth words
102  * Since practically no system gives times in
103  * true micro seconds, the last three digits
104  * are randomized to insure uniqueness.
105  */
106  {
107  id.time.secs = QDateTime::currentMSecsSinceEpoch()/1000;
108  id.time.usecs = rand() % 1000;
109  }
110  return id;
111 }
112 
113 //=============================================================================================================
114 
116 {
117  version = -1;
118  machid[0] = -1;
119  machid[1] = -1;
120  time.secs = -1;
121  time.usecs = -1;
122 }
123 
124 //=============================================================================================================
125 
126 bool FiffId::get_machid(int *fixed_id)
127 {
128  QList<QString> possibleHardwareAdresses;
129 
130  #ifndef WASMBUILD
131  QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
132 
133  fixed_id[0] = 0;
134  fixed_id[1] = 0;
135  if ( !ifaces.isEmpty() ) {
136  for(int i = 0; i < ifaces.size(); ++i) {
137  unsigned int flags = ifaces[i].flags();
138  bool isLoopback = (bool)(flags & QNetworkInterface::IsLoopBack);
139  bool isP2P = (bool)(flags & QNetworkInterface::IsPointToPoint);
140  bool isRunning = (bool)(flags & QNetworkInterface::IsRunning);
141  // If this interface isn't running, we don't care about it
142  if ( !isRunning ) continue;
143  // We only want valid interfaces that aren't loopback/virtual and not point to point
144  if ( !ifaces[i].isValid() || isLoopback || isP2P ) continue;
145  possibleHardwareAdresses << ifaces[i].hardwareAddress();
146  }
147  if (possibleHardwareAdresses.size() > 0) {
148  // We take the first address as machine identifier
149  QStringList hexPresentation = possibleHardwareAdresses[0].split(":");
150  if(hexPresentation.size() == 6) {
151  fixed_id[0] = QString(hexPresentation[0] + hexPresentation[1] + hexPresentation[2]).toInt(NULL,16);
152  fixed_id[1] = QString(hexPresentation[3] + hexPresentation[4] + hexPresentation[5]).toInt(NULL,16);
153  return true;
154  }
155  }
156  }
157  #endif
158 
159  return false;
160 }
161 
162 //=============================================================================================================
163 
164 void FiffId::print() const
165 {
166  if(!isEmpty()) {
167  printf ("\t%d.%d ",this->version>>16,this->version & 0xFFFF);
168  printf ("0x%x%x ",this->machid[0],this->machid[1]);
169  printf ("%d %d ",this->time.secs,this->time.usecs);
170  }
171 }
172 
173 //=============================================================================================================
174 
175 QString FiffId::toMachidString() const
176 {
177  QString strOut = QString("%1%2").arg(machid[0],8,16,QChar('0')).arg(machid[1],8,16,QChar('0'));
178 
179 // to do...
180 // macid is 6 bytes of data->12 chars.
181 // here macid is stored in two integers --> 8 bytes --> 16 chars.
182 // some versions of sinuhe store the significant chars at the beginning of the 16 chars.
183 // other versions sotre the at the end. I don't know on what it depends on.
184 // clue 1: version 1.3 stores it at the beginning. (padding with 4 '0' chars at the end).
185 // clue 2: version 1.2 stores it at the ending chars. (padding with 4 '0' chars at the beginning of the 16).
186 // I've no idea if this behaviour is solid...
187 // int thresholdMayorVersion(1);
188 // int thresholdMinorVersion(2);
189 
190 // int thresholdVersionInt(static_cast<int>(thresholdMayorVersion*pow(2.,16))+thresholdMinorVersion);
191 // if(version > thresholdVersionInt) //if this.version > 65538
192 // {
193 // strOut.chop(4);
194 // } else
195 // {
196 // strOut.right(strOut.size()-4);
197 // }
198 
199  int step=2;
200  for(int i=step;i < strOut.size(); i+=step+1)
201  {
202  strOut.insert(i,QChar(':'));
203  }
204 
205  return strOut.toUpper();
206 }
207 
208 //=============================================================================================================
209 
211 {
212  static FiffId defaultFiffId;
213  return defaultFiffId;
214 }
FIFFLIB::FiffId::time
fiffTimeRec time
Definition: fiff_id.h:154
FIFFLIB::FiffId::getDefault
static FiffId & getDefault()
Definition: fiff_id.cpp:210
FIFFLIB::_fiffTimeRec::usecs
fiff_int_t usecs
Definition: fiff_types_mne-c.h:184
FIFFLIB::FiffId
Universially unique identifier.
Definition: fiff_id.h:68
FIFFLIB::FiffId::print
void print() const
Definition: fiff_id.cpp:164
FIFFLIB::FiffId::isEmpty
bool isEmpty() const
Definition: fiff_id.h:175
FIFFLIB::FiffId::FiffId
FiffId()
Definition: fiff_id.cpp:57
FIFFLIB::FiffId::machid
fiff_int_t machid[2]
Definition: fiff_id.h:153
FIFFLIB::FiffId::new_file_id
static FiffId new_file_id()
Definition: fiff_id.cpp:85
FIFFLIB::FiffId::toMachidString
QString toMachidString() const
Definition: fiff_id.cpp:175
FIFFLIB::FiffId::version
fiff_int_t version
Definition: fiff_id.h:152
FIFFLIB::_fiffTimeRec::secs
fiff_int_t secs
Definition: fiff_types_mne-c.h:183
fiff_id.h
FiffId class declaration.
fiff_file.h
Header file describing the numerical values used in fif files.
FIFFLIB::FiffId::get_machid
static bool get_machid(int *fixed_id)
Definition: fiff_id.cpp:126
FIFFLIB::FiffId::clear
void clear()
Definition: fiff_id.cpp:115
FIFFLIB::FiffId::~FiffId
~FiffId()
Definition: fiff_id.cpp:79