EZC3D
Parameters.cpp
Go to the documentation of this file.
1 #define EZC3D_API_EXPORTS
2 
10 #include "Parameters.h"
11 #include "Header.h"
12 
14  _parametersStart(1),
15  _checksum(0x50),
16  _nbParamBlock(0),
17  _processorType(PROCESSOR_TYPE::NO_PROCESSOR_TYPE)
18 {
20 }
21 
23  _parametersStart(0),
24  _checksum(0),
25  _nbParamBlock(0),
26  _processorType(PROCESSOR_TYPE::NO_PROCESSOR_TYPE)
27 {
29 
30  // Read the Parameters Header (assuming Intel processor)
31  _parametersStart = c3d.readUint(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE, static_cast<int>(256*ezc3d::DATA_TYPE::WORD*(c3d.header().parametersAddress()-1) + c3d.header().nbOfZerosBeforeHeader()), std::ios::beg);
32  _checksum = c3d.readUint(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE);
33  _nbParamBlock = c3d.readUint(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE);
34  size_t processorTypeId = c3d.readUint(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE);
35  if (_checksum == 0 && _parametersStart == 0){
36  // In theory, if this happens, this is a bad c3d formatting and should return an error, but for some reason
37  // Qualisys decided that they would not comply to the standard. Therefore set put "_parameterStart" and "_checksum" to 0
38  // This is a patch for Qualisys bad formatting c3d
39  _parametersStart = 1;
40  _checksum = 0x50;
41  }
42  if (_checksum != 0x50) // If checkbyte is wrong
43  throw std::ios_base::failure("File must be a valid c3d file");
44 
45  if (processorTypeId == 84)
46  _processorType = ezc3d::PROCESSOR_TYPE::INTEL;
47  else if (processorTypeId == 85)
48  _processorType = ezc3d::PROCESSOR_TYPE::DEC;
49  else if (processorTypeId == 86){
50  _processorType = ezc3d::PROCESSOR_TYPE::MIPS;
51  throw std::runtime_error("MIPS processor type not supported yet, please open a GitHub issue to report that you want this feature!");
52  }
53  else
54  throw std::runtime_error("Could not read the processor type");
55 
56  // Read parameter or group
57  std::streampos nextParamByteInFile(static_cast<int>(file.tellg()) + static_cast<int>(_parametersStart) - ezc3d::DATA_TYPE::BYTE);
58  while (nextParamByteInFile)
59  {
60  // Check if we spontaneously got to the next parameter. Otherwise c3d is messed up
61  if (file.tellg() != nextParamByteInFile)
62  throw std::ios_base::failure("Bad c3d formatting");
63 
64  // Nb of char in the group name, locked if negative, 0 if we finished the section
65  int nbCharInName(c3d.readInt(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE));
66  if (nbCharInName == 0)
67  break;
68  int id(c3d.readInt(processorType(), file, 1*ezc3d::DATA_TYPE::BYTE));
69 
70  // Make sure there at least enough group
71  for (size_t i = _groups.size(); i < static_cast<size_t>(abs(id)); ++i)
73 
74  // Group ID always negative for groups and positive parameter of group ID
75  if (id < 0)
76  nextParamByteInFile = group_nonConst(static_cast<size_t>(abs(id)-1)).read(c3d, *this, file, nbCharInName);
77  else
78  nextParamByteInFile = group_nonConst(static_cast<size_t>(id-1)).parameter(c3d, *this, file, nbCharInName);
79  }
80 }
81 
83 {
84  // Mandatory groups
85  {
86  ezc3d::ParametersNS::GroupNS::Group grp("POINT", "");
87  {
89  p.set(0);
90  p.lock();
91  grp.parameter(p);
92  }
93  {
95  p.set(-1.0);
96  p.lock();
97  grp.parameter(p);
98  }
99  {
101  p.set(0.0);
102  p.lock();
103  grp.parameter(p);
104  }
105  {
106  ezc3d::ParametersNS::GroupNS::Parameter p("DATA_START", "");
107  p.set(0);
108  p.lock();
109  grp.parameter(p);
110  }
111  {
113  p.set(0);
114  p.lock();
115  grp.parameter(p);
116  }
117  {
119  p.set(std::vector<std::string>()={});
120  grp.parameter(p);
121  }
122  {
123  ezc3d::ParametersNS::GroupNS::Parameter p("DESCRIPTIONS", "");
124  p.set(std::vector<std::string>()={});
125  grp.parameter(p);
126  }
127  {
129  p.set(std::vector<std::string>()={});
130  grp.parameter(p);
131  }
132  group(grp);
133  }
134  {
135  ezc3d::ParametersNS::GroupNS::Group grp("ANALOG", "");
136  {
138  p.set(0);
139  p.lock();
140  grp.parameter(p);
141  }
142  {
144  p.set(std::vector<std::string>()={});
145  grp.parameter(p);
146  }
147  {
148  ezc3d::ParametersNS::GroupNS::Parameter p("DESCRIPTIONS", "");
149  p.set(std::vector<std::string>()={});
150  grp.parameter(p);
151  }
152  {
153  ezc3d::ParametersNS::GroupNS::Parameter p("GEN_SCALE", "");
154  p.set(1.0);
155  grp.parameter(p);
156  }
157  {
159  p.set(std::vector<float>()={});
160  grp.parameter(p);
161  }
162  {
164  p.set(std::vector<int>()={});
165  grp.parameter(p);
166  }
167  {
169  p.set(std::vector<std::string>()={});
170  grp.parameter(p);
171  }
172  {
174  p.set(0.0);
175  p.lock();
176  grp.parameter(p);
177  }
178  {
180  p.set(std::vector<std::string>()={});
181  grp.parameter(p);
182  }
183  {
185  p.set(std::vector<int>()={});
186  grp.parameter(p);
187  }
188  group(grp);
189  }
190  {
191  ezc3d::ParametersNS::GroupNS::Group grp("FORCE_PLATFORM", "");
192  {
194  p.set(0);
195  grp.parameter(p);
196  }
197  {
199  p.set(std::vector<int>()={});
200  grp.parameter(p);
201  }
202  {
204  p.set(std::vector<int>()={1,0});
205  grp.parameter(p);
206  }
207  {
209  p.set(std::vector<float>()={});
210  grp.parameter(p);
211  }
212  {
214  p.set(std::vector<float>()={});
215  grp.parameter(p);
216  }
217  {
219  p.set(std::vector<int>()={});
220  grp.parameter(p);
221  }
222  {
223  ezc3d::ParametersNS::GroupNS::Parameter p("CAL_MATRIX", "");
224  p.set(std::vector<float>()={});
225  grp.parameter(p);
226  }
227  group(grp);
228  }
229 }
230 
232 {
233  std::cout << "Parameters header" << std::endl;
234  std::cout << "parametersStart = " << parametersStart() << std::endl;
235  std::cout << "nbParamBlock = " << nbParamBlock() << std::endl;
236  std::cout << "processorType = " << processorType() << std::endl;
237 
238  for (size_t i = 0; i < nbGroups(); ++i){
239  std::cout << "Group " << i << std::endl;
240  group(i).print();
241  std::cout << std::endl;
242  }
243  std::cout << std::endl;
244 }
245 
246 void ezc3d::ParametersNS::Parameters::write(std::fstream &f, std::streampos &dataStartPosition) const
247 {
248  // Write the header of parameters
249  f.write(reinterpret_cast<const char*>(&_parametersStart), ezc3d::BYTE);
250  int checksum(0x50);
251  f.write(reinterpret_cast<const char*>(&checksum), ezc3d::BYTE);
252  // Leave a blank space which will be later fill
253  // (number of block can't be known before writing them)
254  std::streampos pos(f.tellg()); // remember where to input this value later
255  int blankValue(0);
256  f.write(reinterpret_cast<const char*>(&blankValue), ezc3d::BYTE);
257  int processorType = PROCESSOR_TYPE::INTEL;
258  f.write(reinterpret_cast<const char*>(&processorType), ezc3d::BYTE);
259 
260  // Write each groups
261  for (size_t i=0; i < nbGroups(); ++i)
262  group(i).write(f, -static_cast<int>(i+1), dataStartPosition);
263 
264  // Move the cursor to a beginning of a block
265  std::streampos currentPos(f.tellg());
266  for (int i=0; i<512 - static_cast<int>(currentPos) % 512; ++i){
267  f.write(reinterpret_cast<const char*>(&blankValue), ezc3d::BYTE);
268  }
269  // Go back at the left blank space and write the current position
270  currentPos = f.tellg();
271  f.seekg(pos);
272  int nBlocksToNext = int(currentPos - pos-2)/512;
273  if (int(currentPos - pos-2) % 512 > 0)
274  ++nBlocksToNext;
275  f.write(reinterpret_cast<const char*>(&nBlocksToNext), ezc3d::BYTE);
276  f.seekg(currentPos);
277 }
278 
280 {
281  return _parametersStart;
282 }
283 
285 {
286  return _checksum;
287 }
288 
290 {
291  return _nbParamBlock;
292 }
293 
295 {
296  return _processorType;
297 }
298 
300 {
301  return _groups.size();
302 }
303 
304 size_t ezc3d::ParametersNS::Parameters::groupIdx(const std::string &groupName) const
305 {
306  for (size_t i = 0; i < nbGroups(); ++i)
307  if (!group(i).name().compare(groupName))
308  return i;
309  throw std::invalid_argument("Parameters::groupIdx could not find " + groupName);
310 }
311 
313 {
314  try {
315  return _groups.at(idx);
316  } catch(std::out_of_range) {
317  throw std::out_of_range("Parameters::group method is trying to access the group "
318  + std::to_string(idx) +
319  " while the maximum number of groups is "
320  + std::to_string(nbGroups()) + ".");
321  }
322 }
323 
325 {
326  try {
327  return _groups.at(idx);
328  } catch(std::out_of_range) {
329  throw std::out_of_range("Parameters::group method is trying to access the group "
330  + std::to_string(idx) +
331  " while the maximum number of groups is "
332  + std::to_string(nbGroups()) + ".");
333  }
334 }
335 
337 {
338  return group(groupIdx(groupName));
339 }
340 
342 {
343  return group_nonConst(groupIdx(groupName));
344 }
345 
347 {
348  // If the group already exist, override and merge
349  size_t alreadyExtIdx(SIZE_MAX);
350  for (size_t i = 0; i < nbGroups(); ++i)
351  if (!group(i).name().compare(g.name()))
352  alreadyExtIdx = i;
353  if (alreadyExtIdx == SIZE_MAX)
354  _groups.push_back(g);
355  else {
356  for (size_t i=0; i < g.nbParameters(); ++i)
357  _groups[alreadyExtIdx].parameter(g.parameter(i));
358  }
359 }
360 
361 const std::vector<ezc3d::ParametersNS::GroupNS::Group> &ezc3d::ParametersNS::Parameters::groups() const
362 {
363  return _groups;
364 }
size_t parametersStart() const
Get the byte in the file where the data starts.
Definition: Parameters.cpp:279
size_t nbGroups() const
Get the number of groups.
Definition: Parameters.cpp:299
void set(int data)
Set the integer scalar value for the parameter.
Definition: Parameter.cpp:258
size_t readUint(PROCESSOR_TYPE processorType, std::fstream &file, unsigned int nByteToRead, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read a unsigned integer of nByteToRead bytes at the position current + nByteFromPrevious from a file...
Definition: ezc3d.cpp:203
size_t nbParamBlock() const
Get the number of 256-bytes the parameters need in the file.
Definition: Parameters.cpp:289
PROCESSOR_TYPE
The type of processor used to store the data.
Definition: ezc3d.h:85
Declaration of Header class.
size_t nbParameters() const
Get the number of parameters.
Definition: Group.cpp:129
Group of parameter of a C3D file.
Definition: Group.h:16
PROCESSOR_TYPE processorType() const
Get the processor type the file was writen on.
Definition: Parameters.cpp:294
const ezc3d::ParametersNS::GroupNS::Group & group(size_t idx) const
Get a particular group of index idx from the group holder.
Definition: Parameters.cpp:312
std::vector< ezc3d::ParametersNS::GroupNS::Group > _groups
Holder for the group of parameters.
Definition: Parameters.h:103
const ezc3d::ParametersNS::GroupNS::Parameter & parameter(size_t idx) const
Get a particular parameter of index idx from the group.
Definition: Group.cpp:143
const ezc3d::Header & header() const
The header of the C3D.
Definition: ezc3d.cpp:340
ezc3d::ParametersNS::GroupNS::Group & group_nonConst(size_t idx)
Get a particular group of index idx from the group holder in order to be modified by the caller...
Definition: Parameters.cpp:324
Main class for C3D holder.
Definition: ezc3d.h:154
size_t parametersAddress() const
Get the byte at which the parameters start in the file.
Definition: Header.cpp:214
const std::string & name() const
Get the name of the group.
Definition: Group.cpp:95
size_t nbOfZerosBeforeHeader() const
Get the number of zeros before the header starts in the file.
Definition: Header.cpp:209
int readInt(PROCESSOR_TYPE processorType, std::fstream &file, unsigned int nByteToRead, int nByteFromPrevious=0, const std::ios_base::seekdir &pos=std::ios::cur)
Read an integer of nByteToRead bytes at the position current + nByteFromPrevious from a file...
Definition: ezc3d.cpp:179
const std::vector< ezc3d::ParametersNS::GroupNS::Group > & groups() const
Get all groups the group holder with read-only access.
Definition: Parameters.cpp:361
void write(std::fstream &f, std::streampos &dataStartPosition) const
Write the groups to an opened file by calling the write method of all the groups. ...
Definition: Parameters.cpp:246
void setMandatoryParameters()
Add all required parameter for a c3d to be valid.
Definition: Parameters.cpp:82
Parameters()
Create a default group holder with minimal groups to have a valid c3d.
Definition: Parameters.cpp:13
size_t checksum() const
Get the checksum of the parameters.
Definition: Parameters.cpp:284
void print() const
Print the groups by calling the print method of all the groups.
Definition: Parameters.cpp:231
size_t groupIdx(const std::string &groupName) const
Get the index of a group in the group holder.
Definition: Parameters.cpp:304
Parameter of a C3D file.
Definition: Parameter.h:16
int read(ezc3d::c3d &c3d, const Parameters &params, std::fstream &file, int nbCharInName)
Read and store a group of parameter from an opened C3D file.
Definition: Group.cpp:65
void lock()
Set the locking status of the parameter to true.
Definition: Parameter.cpp:218
Declaration of Parameters class.