1 /*
2 * entry.cpp
3 *
4 * Created on: Dec 12, 2012
5 * Author: amarcketta
6 */
7
8 #include "entry.h"
9
10 /*
11 // This function implements an exact SNP test of Hardy-Weinberg
12 // Equilibrium as described in Wigginton, JE, Cutler, DJ, and
13 // Abecasis, GR (2005) A Note on Exact Tests of Hardy-Weinberg
14 // Equilibrium. American Journal of Human Genetics. 76: 000 - 000
15 //
16 // Written by Jan Wigginton
17 */
SNPHWE(int obs_hets,int obs_hom1,int obs_hom2,double & p_hwe,double & p_lo,double & p_hi)18 void entry::SNPHWE(int obs_hets, int obs_hom1, int obs_hom2, double &p_hwe, double &p_lo, double &p_hi)
19 {
20 p_hwe = 1.0; p_lo = 1.0; p_hi = 1.0; //p_hi_lo = 1.0;
21 if (obs_hom1 + obs_hom2 + obs_hets == 0 ) return;
22
23 if (obs_hom1 < 0 || obs_hom2 < 0 || obs_hets < 0)
24 LOG.error("Internal error: negative count in HWE test", 91);
25
26 int obs_homc = obs_hom1 < obs_hom2 ? obs_hom2 : obs_hom1;
27 int obs_homr = obs_hom1 < obs_hom2 ? obs_hom1 : obs_hom2;
28
29 int rare_copies = 2 * obs_homr + obs_hets;
30 int genotypes = obs_hets + obs_homc + obs_homr;
31
32 double * het_probs = (double *) malloc((size_t) (rare_copies + 1) * sizeof(double));
33 if (het_probs == NULL)
34 LOG.error("Internal error: SNP-HWE: Unable to allocate array", 90);
35
36 for (int i = 0; i <= rare_copies; i++)
37 het_probs[i] = 0.0;
38
39 /* start at midpoint */
40 int mid = rare_copies * (2 * genotypes - rare_copies) / (2 * genotypes);
41
42 /* check to ensure that midpoint and rare alleles have same parity */
43 if ((rare_copies & 1) ^ (mid & 1))
44 mid++;
45
46 int curr_hets = mid;
47 int curr_homr = (rare_copies - mid) / 2;
48 int curr_homc = genotypes - curr_hets - curr_homr;
49
50 het_probs[mid] = 1.0;
51 double sum = het_probs[mid];
52 for (curr_hets = mid; curr_hets > 1; curr_hets -= 2)
53 {
54 het_probs[curr_hets - 2] = het_probs[curr_hets] * curr_hets * (curr_hets - 1.0) / (4.0 * (curr_homr + 1.0) * (curr_homc + 1.0));
55 sum += het_probs[curr_hets - 2];
56
57 /* 2 fewer heterozygotes for next iteration -> add one rare, one common homozygote */
58 curr_homr++;
59 curr_homc++;
60 }
61
62 curr_hets = mid;
63 curr_homr = (rare_copies - mid) / 2;
64 curr_homc = genotypes - curr_hets - curr_homr;
65 for (curr_hets = mid; curr_hets <= rare_copies - 2; curr_hets += 2)
66 {
67 het_probs[curr_hets + 2] = het_probs[curr_hets] * 4.0 * curr_homr * curr_homc /((curr_hets + 2.0) * (curr_hets + 1.0));
68 sum += het_probs[curr_hets + 2];
69
70 /* add 2 heterozygotes for next iteration -> subtract one rare, one common homozygote */
71 curr_homr--;
72 curr_homc--;
73 }
74
75 for (int i = 0; i <= rare_copies; i++)
76 het_probs[i] /= sum;
77
78 // alternate p-value calculation for p_hi/p_lo
79 p_hi = het_probs[obs_hets];
80 for (int i = obs_hets + 1; i <= rare_copies; i++)
81 p_hi += het_probs[i];
82
83 p_lo = het_probs[obs_hets];
84 for (int i = obs_hets - 1; i >= 0; i--)
85 p_lo += het_probs[i];
86
87 //p_hi_lo = p_hi < p_lo ? 2.0 * p_hi : 2.0 * p_lo;
88
89 p_hwe = 0.0;
90 /* p-value calculation for p_hwe */
91 for (int i = 0; i <= rare_copies; i++)
92 {
93 if (het_probs[i] > het_probs[obs_hets])
94 continue;
95 p_hwe += het_probs[i];
96 }
97
98 p_hwe = p_hwe > 1.0 ? 1.0 : p_hwe;
99
100 free(het_probs);
101 }
102
make_typed_string(vector<char> & out,const string & in,bool typed)103 void entry::make_typed_string(vector<char> &out, const string &in, bool typed)
104 {
105 vector<char> tmp_vector;
106 out.resize(0);
107
108 if (in == "." or in == " " or in == "")
109 {
110 if (typed == false)
111 return;
112
113 int8_t tmp = (int8_t)0;
114 tmp = tmp << 4;
115 tmp = tmp | (int8_t)7;
116 out.push_back( tmp );
117
118 return;
119 }
120
121 if (typed == true)
122 {
123 if (in.length() >= 15)
124 {
125 int8_t tmp = (int8_t)15;
126 tmp = tmp << 4;
127 tmp = tmp | (int8_t)7;
128 out.push_back( tmp );
129
130 make_typed_int(tmp_vector, in.length(), typed);
131 out.insert( out.end(), tmp_vector.begin(), tmp_vector.end() );
132 }
133 else
134 {
135 int8_t tmp = (int8_t)in.length();
136 tmp = tmp << 4;
137 tmp = tmp | (int8_t)7;
138 out.push_back( tmp );
139 }
140 }
141 out.reserve(out.size()+in.size());
142 copy(in.begin(), in.end(), back_inserter(out));
143 }
144
make_typed_int(vector<char> & out,const int & in,bool typed)145 void entry::make_typed_int(vector<char> &out, const int &in, bool typed)
146 {
147 vector<char> tmp_char;
148 out.resize(0);
149
150 int type;
151 int8_t size_type = (int8_t)1;
152 if (in < 127 and in >-127)
153 type = 1;
154 else if (in < 32767 and in>-32767)
155 type = 2;
156 else
157 type = 3;
158
159 make_int(tmp_char, in, type);
160
161 if (typed == true)
162 {
163 size_type = size_type << 4;
164 size_type = size_type | type;
165 out.push_back(size_type);
166 }
167 out.insert(out.end(), tmp_char.begin(), tmp_char.end());
168 }
169
make_typed_string_vector(vector<char> & out,const vector<string> & in,int number)170 void entry::make_typed_string_vector( vector<char> &out, const vector<string> &in, int number )
171 {
172 vector<char> tmp_char;
173 int max_val = 0;
174 int8_t size_type;
175 out.resize(0);
176
177 if (number == -1)
178 {
179 for (unsigned int ui=0; ui<in.size(); ui++)
180 {
181 if ((int)in[ui].size() > max_val)
182 max_val = in[ui].size();
183 }
184 }
185 else
186 max_val = number;
187
188 if (max_val < 15)
189 {
190 size_type = (int8_t)max_val;
191 size_type = size_type << 4;
192 size_type = size_type | (int8_t)7;
193
194 out.push_back( size_type );
195 }
196 else
197 {
198 size_type = (int8_t)15;
199 size_type = size_type << 4;
200 size_type = size_type | (int8_t)7;
201
202 out.push_back( size_type );
203
204 make_typed_int(tmp_char, max_val, true);
205 out.insert( out.end(), tmp_char.begin(), tmp_char.end() );
206 }
207
208 for (unsigned int ui=0; ui<in.size(); ui++)
209 {
210 for (unsigned int uj=0; (int)uj<max_val; uj++)
211 {
212 if (in[ui] == ".")
213 out.push_back( '\0' );
214 else if (uj<in[ui].size())
215 out.push_back( in[ui][uj] );
216 else
217 out.push_back( '\0' );
218 }
219 }
220 }
221
make_typed_GT_vector(vector<char> & out,vector<string> & in)222 void entry::make_typed_GT_vector(vector<char> &out, vector<string> &in )
223 {
224 vector<char> tmp_vector;
225 int8_t size_type;
226 int max_ploidy = 0;
227 out.resize(0);
228
229 max_ploidy = *max_element(ploidy.begin(), ploidy.end());
230
231 if (max_ploidy < 15)
232 {
233 size_type = (int8_t)max_ploidy;
234 size_type = size_type << 4;
235 size_type = size_type | (int8_t)1;
236
237 out.push_back( size_type );
238 }
239 else
240 {
241 size_type = (int8_t)15;
242 size_type = size_type << 4;
243 size_type = size_type | (int8_t)1;
244
245 out.push_back( size_type );
246
247 make_typed_int(tmp_vector, max_ploidy, true);
248 out.insert( out.end(), tmp_vector.begin(), tmp_vector.end() );
249 tmp_vector.resize(0);
250 }
251
252 for (unsigned int ui=0; ui<in.size(); ui++)
253 {
254 encode_genotype(tmp_vector, in[ui], max_ploidy);
255 out.insert( out.end(), tmp_vector.begin(), tmp_vector.end() );
256 tmp_vector.resize(0);
257 }
258 out.insert( out.end(), tmp_vector.begin(), tmp_vector.end() );
259 }
260
encode_genotype(vector<char> & out,string & in,int exp_size)261 void entry::encode_genotype(vector<char> &out, string &in, int exp_size)
262 {
263 int8_t tmp_int;
264 int8_t phased = 0;
265 out.resize(exp_size);
266 int idx = 0;
267
268 for (unsigned int ui=0; ui<in.length(); ui++)
269 {
270 if (in[ui] =='|')
271 phased = 1;
272 else if (in[ui] == '/')
273 phased = 0;
274 else
275 {
276 if(in[ui] != '.')
277 {
278 tmp_int = header::str2int( in.substr(ui,1) );
279 tmp_int++;
280 tmp_int = tmp_int << 1;
281 tmp_int = tmp_int | phased;
282 }
283 else
284 tmp_int = 0x80;
285
286 out[idx] = (int8_t)tmp_int;
287 idx++;
288 }
289 }
290 while (idx<exp_size)
291 {
292 out[idx] = (int8_t)0x81;
293 idx++;
294 }
295 }
296
make_typed_int_vector(vector<char> & out,const string & in,int number)297 void entry::make_typed_int_vector(vector<char> &out, const string &in, int number )
298 {
299 vector<char> tmp_char;
300 vector<int> tmp_ints;
301 vector<string> split_string;
302 int converted, type;
303 int8_t size_type;
304 unsigned int max = 0;
305 unsigned int max_val = 0;
306 out.resize(0);
307
308 if (in == " " or in == "." or in == "")
309 {
310 size_type = (int8_t)0;
311 size_type = size_type << 4;
312 size_type = size_type | (int8_t)1;
313
314 out.push_back( size_type );
315 return;
316 }
317
318 header::tokenize(in, ',', split_string);
319 if (number == -1)
320 {
321 if (split_string.size() > max_val)
322 max_val = split_string.size();
323 }
324 else
325 max_val = number;
326
327 for (unsigned int ui=0; ui<max_val; ui++)
328 {
329 if ( ui<split_string.size() )
330 {
331 converted = header::str2int(split_string[ui], 0x80000000);
332
333 if ((abs(converted) > (int)max) and ( converted != (int)0x80000000))
334 max = abs(converted);
335 }
336 else
337 converted = 0x80000001;
338
339 tmp_ints.push_back( converted );
340 }
341
342 if (max < 127)
343 type = 1;
344 else if (max < 32767)
345 type = 2;
346 else
347 type = 3;
348
349 if (max_val < 15)
350 {
351 size_type = (int8_t)max_val;
352 size_type = size_type << 4;
353 size_type = size_type | (int8_t)type;
354
355 out.push_back( size_type );
356 }
357 else
358 {
359 size_type = (int8_t)15;
360 size_type = size_type << 4;
361 size_type = size_type | (int8_t)type;
362
363 out.push_back( size_type );
364
365 make_typed_int(tmp_char, max_val, true);
366 out.insert( out.end(), tmp_char.begin(), tmp_char.begin() );
367 }
368
369 for (unsigned int ui=0; ui<tmp_ints.size(); ui++)
370 {
371 make_int(tmp_char, tmp_ints[ui], type);
372 out.insert( out.end(), tmp_char.begin(), tmp_char.end() );
373 }
374 }
375
make_typed_int_vector(vector<char> & out,const vector<string> & in,int number)376 void entry::make_typed_int_vector(vector<char> &out, const vector<string> &in, int number )
377 {
378 vector<char> tmp_char;
379 vector<int> tmp_ints;
380 vector<string> split_string;
381 int converted, type;
382 int8_t size_type;
383 unsigned int max = 0;
384 unsigned int max_val = 0;
385 out.resize(0);
386
387 if (number == -1)
388 {
389 unsigned int tmp_int = 0;
390 for (unsigned int ui=0; ui<in.size(); ui++)
391 {
392 tmp_int = count(in[ui].begin(), in[ui].end(), ',');
393
394 if (tmp_int > max_val)
395 max_val = tmp_int;
396 }
397 max_val++;
398 }
399 else
400 max_val = number;
401
402 for (unsigned int ui=0; ui<in.size(); ui++)
403 {
404 header::tokenize(in[ui], ',', split_string);
405 for (unsigned int uj=0; uj<max_val; uj++)
406 {
407 if ( uj<split_string.size() )
408 {
409 converted = header::str2int(split_string[uj], 0x80000000);
410
411 if ((abs(converted) > (int)max) and (converted != (int)0x80000000))
412 max = abs(converted);
413 }
414 else
415 converted = 0x80000001;
416
417 tmp_ints.push_back( converted );
418 }
419 }
420
421 if (max < 127)
422 type = 1;
423 else if (max < 32767)
424 type = 2;
425 else
426 type = 3;
427 if (max_val < 15)
428 {
429 size_type = (int8_t)max_val;
430 size_type = size_type << 4;
431 size_type = size_type | (int8_t)type;
432
433 out.push_back( size_type );
434 }
435 else
436 {
437 size_type = (int8_t)15;
438 size_type = size_type << 4;
439 size_type = size_type | (int8_t)type;
440
441 out.push_back( size_type );
442
443 make_typed_int(tmp_char, max_val, true);
444 out.insert( out.end(), tmp_char.begin(), tmp_char.begin() );
445 }
446
447 for (unsigned int ui=0; ui<tmp_ints.size(); ui++)
448 {
449 make_int(tmp_char, tmp_ints[ui], type);
450 out.insert( out.end(), tmp_char.begin(), tmp_char.end() );
451 }
452 }
453
make_typed_int_vector(vector<char> & out,const vector<int> & in)454 void entry::make_typed_int_vector(vector<char> &out, const vector<int> &in )
455 {
456 vector<char> tmp_char;
457 int type;
458 int8_t size_type;
459 unsigned int max = 0;
460 out.resize(0);
461
462 for (unsigned int ui=0; ui<in.size(); ui++)
463 {
464 if ((abs(in[ui]) > (int)max) and ( (int8_t)in[ui] != (int8_t)0x80))
465 max = abs(in[ui]);
466 }
467
468 if (max < 127)
469 type = 1;
470 else if (max < 32767)
471 type = 2;
472 else
473 type = 3;
474
475 if (in.size() < 15)
476 {
477 size_type = (int8_t)in.size();
478 size_type = size_type << 4;
479 size_type = size_type | (int8_t)type;
480
481 out.push_back( size_type );
482 }
483 else
484 {
485 size_type = (int8_t)15;
486 size_type = size_type << 4;
487 size_type = size_type | (int8_t)type;
488
489 out.push_back( size_type );
490
491 make_typed_int(tmp_char, in.size(), true);
492 out.insert( out.end(), tmp_char.begin(), tmp_char.begin() );
493 }
494
495 for (unsigned int ui=0; ui<in.size(); ui++)
496 {
497 make_int(tmp_char, in[ui], type);
498 out.insert( out.end(), tmp_char.begin(), tmp_char.end() );
499 }
500 }
501
make_int(vector<char> & out,const int & in,int type)502 void entry::make_int(vector<char> &out, const int &in, int type)
503 {
504 out.resize(0);
505 if (type == 1)
506 {
507 int8_t tmp_int;
508 if (in == (int)0x80000000 || in >= 128)
509 tmp_int = (int8_t)0x80;
510 else if (in == (int)0x80000001)
511 tmp_int = (int8_t)0x81;
512 else
513 tmp_int = (int8_t)in;
514 out.push_back( (int8_t)tmp_int);
515 }
516 else if (type == 2)
517 {
518 int16_t tmp_int;
519
520 if (in == (int)0x80000000 || in >= 32768)
521 tmp_int = 0x8000;
522 else if (in == (int)0x80000001)
523 tmp_int = (int8_t)0x8001;
524 else
525 tmp_int = (int16_t)in;
526
527 int8_t split;
528 for(unsigned int ui=0; ui<2; ui++)
529 {
530 split = tmp_int & (int16_t)0x00FF;//0000000011111111
531 out.push_back(split);
532 tmp_int = tmp_int >> 8;
533 }
534 }
535 else
536 {
537 int32_t tmp_int;
538 tmp_int = (int32_t)in;
539
540 int8_t split;
541 for(unsigned int ui=0; ui<4; ui++)
542 {
543 split = tmp_int & (int32_t)0x0000FF;
544 out.push_back( (int8_t)split);
545 tmp_int = tmp_int >> 8;
546 }
547 }
548 }
549
make_typed_float_vector(vector<char> & out,const string & in,int number)550 void entry::make_typed_float_vector(vector<char> &out, const string &in, int number )
551 {
552 vector<string> split_string;
553 int8_t size_type;
554 int max_val = 0;
555 out.resize(0);
556
557 if (in == " " or in == "." or in == "")
558 {
559 size_type = (int8_t)0;
560 size_type = size_type << 4;
561 size_type = size_type | (int8_t)1;
562
563 out.push_back( size_type );
564 return;
565 }
566
567 header::tokenize(in, ',', split_string);
568 if (number == -1)
569 max_val = split_string.size();
570 else
571 max_val = number;
572
573 if ( max_val < 15 )
574 {
575 size_type = (int8_t)max_val;
576 size_type = size_type << 4;
577 size_type = size_type | (int8_t)5;
578 out.push_back( size_type );
579 }
580 else
581 {
582 size_type = (int8_t)15;
583 size_type = size_type << 4;
584 size_type = size_type | (int8_t)5;
585 out.push_back( size_type );
586
587 vector<char> size_vector;
588 make_typed_int(size_vector, max_val, true );
589 out.insert(out.end(), size_vector.begin(), size_vector.end());
590 }
591
592 float value;
593 char missing[4] = {static_cast<char>(0x01), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
594 char end[4] = {static_cast<char>(0x02), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
595
596 for(unsigned int ui=0; (int)ui<max_val; ui++)
597 {
598 if (ui < split_string.size() )
599 value = (float)header::str2double(split_string[ui], 0x7F800001);
600 else
601 value = 0x7F800002;
602
603 char *p = (char *)&value;
604
605 for(unsigned int uj=0; uj<sizeof(value); uj++)
606 if (value == (float)0x7F800001)
607 out.push_back( missing[uj] );
608 else if (value == (float)0x7F800002)
609 out.push_back( end[uj] );
610 else
611 out.push_back( p[uj] );
612 }
613 }
614
make_typed_float_vector(vector<char> & out,const vector<string> & in,int number)615 void entry::make_typed_float_vector(vector<char> &out, const vector<string> &in, int number )
616 {
617 vector<string> split_string;
618 int8_t size_type;
619 unsigned int max_val = 0;
620 out.resize(0);
621
622 if (number == -1)
623 {
624 unsigned int tmp_int = 0;
625 for (unsigned int ui=0; ui<in.size(); ui++)
626 {
627 tmp_int = count(in[ui].begin(), in[ui].end(), ',');
628 if (tmp_int > max_val)
629 max_val = tmp_int;
630 }
631 max_val++;
632 }
633 else
634 max_val = number;
635
636 if ( max_val < 15 )
637 {
638 size_type = (int8_t)max_val;
639 size_type = size_type << 4;
640 size_type = size_type | (int8_t)5;
641 out.push_back( size_type );
642 }
643 else
644 {
645 size_type = (int8_t)15;
646 size_type = size_type << 4;
647 size_type = size_type | (int8_t)5;
648 out.push_back( size_type );
649
650 vector<char> size_vector;
651 make_typed_int(size_vector, max_val, true );
652 out.insert(out.end(), size_vector.begin(), size_vector.end());
653 }
654
655 float value;
656 char missing[4] = {static_cast<char>(0x01), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
657 char end[4] = {static_cast<char>(0x02), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
658 for (unsigned int ui=0; ui<in.size(); ui++)
659 {
660 header::tokenize(in[ui], ',', split_string);
661 for(unsigned int uj=0; uj<max_val; uj++)
662 {
663 if (uj < split_string.size() )
664 value = (float)header::str2double(split_string[uj], 0x7F800001);
665 else
666 value = (float)0x7F800002;
667
668 char *p = (char *)&value;
669
670 for(unsigned int uk=0; uk<sizeof(value); uk++)
671 {
672 if (value == float(0x7F800001))
673 out.push_back( missing[uk] );
674 else if (value == float(0x7F800002))
675 out.push_back( end[uk] );
676 else
677 out.push_back( p[uk] );
678 }
679 }
680 }
681 }
682
make_type_size(vector<char> & out,const unsigned int & type,const unsigned int & size)683 void entry::make_type_size(vector<char> &out, const unsigned int &type, const unsigned int &size)
684 {
685 uint8_t byte;
686 vector<char> tmp_vector;
687 tmp_vector.resize(0);
688 out.resize(0);
689
690 if (size < 15)
691 {
692 byte = size;
693 byte = byte << 4;
694 }
695 else
696 {
697 byte = (uint8_t)15;
698 make_typed_int(tmp_vector, size, true);
699 }
700
701 byte = byte | (uint8_t)type;
702 out.push_back(byte);
703 out.insert(out.end(), tmp_vector.begin(), tmp_vector.end());
704 }
705
get_typed_string(unsigned int * line_position,const vector<char> & line)706 string entry::get_typed_string(unsigned int * line_position, const vector<char>& line)
707 {
708 unsigned int size, type;
709 string out;
710
711 get_type( line_position, line, type, size );
712 if (type != 7)
713 {
714 LOG.printLOG("Error: Expected type 7 for string. Found type " + header::int2str(type) + ".\n");
715 }
716
717 char * tmp = new char[size];
718 memcpy(tmp, &line[*line_position], size*sizeof(char));
719 *line_position += size;
720 out = string( tmp, size );
721
722 if (out == "" or out == " ")
723 out = ".";
724
725 delete [] tmp;
726 return out;
727 }
728
get_typed_int(unsigned int * line_position,const vector<char> & line,unsigned int & type,unsigned int & size)729 int entry::get_typed_int(unsigned int * line_position, const vector<char>& line, unsigned int &type, unsigned int &size)
730 {
731 int out;
732
733 get_type( line_position, line, type, size );
734
735 if (size > 1)
736 {
737 LOG.printLOG("Error: Int vector when expected only a single Integer value.\n" );
738 exit(0);
739 }
740
741 if (type == 1)
742 {
743 int8_t tmp;
744 tmp = *reinterpret_cast<const int8_t*>(&line[*line_position]);
745 *line_position += sizeof(tmp);
746 out = tmp;
747 }
748 else if (type == 2)
749 {
750 int16_t tmp;
751 tmp = *reinterpret_cast<const int16_t*>(&line[*line_position]);
752 *line_position += sizeof(tmp);
753 out = tmp;
754 }
755 else if (type == 3)
756 {
757 int32_t tmp;
758 tmp = *reinterpret_cast<const int32_t*>(&line[*line_position]);
759 *line_position += sizeof(tmp);
760 out = tmp;
761 }
762 else
763 {
764 LOG.printLOG("Error: Invalid type for integer size.\n");
765 exit(0);
766 }
767 return out;
768 }
769
get_int_vector(unsigned int * line_position,const vector<char> & line)770 vector<int> entry::get_int_vector(unsigned int * line_position, const vector<char>& line)
771 {
772 unsigned int size, type;
773 get_type( line_position, line, type, size );
774 vector<int> out(size);
775
776 if (type == 0)
777 {
778 return out;
779 }
780 else if (type == 1)
781 {
782 int8_t tmp;
783 for (unsigned int ui=0; ui<size; ui++)
784 {
785 tmp = *reinterpret_cast<const int8_t*>(&line[*line_position]);
786 *line_position += sizeof(tmp);
787 out[ui] = tmp;
788 }
789 }
790 else if (type == 2)
791 {
792 int16_t tmp;
793 for (unsigned int ui=0; ui<size; ui++)
794 {
795 tmp = *reinterpret_cast<const int16_t*>(&line[*line_position]);
796 *line_position += sizeof(tmp);
797 out[ui] = tmp;
798 }
799 }
800 else if (type == 3)
801 {
802 int32_t tmp;
803 for (unsigned int ui=0; ui<size; ui++)
804 {
805 tmp = *reinterpret_cast<const int32_t*>(&line[*line_position]);
806 *line_position += sizeof(tmp);
807 out[ui] = tmp;
808 }
809 }
810 else
811 {
812 LOG.printLOG("Error: Invalid type for integer size.\n");
813 exit(0);
814 }
815 return out;
816 }
817
get_type(unsigned int * line_position,const vector<char> & line,unsigned int & type,unsigned int & size)818 void entry::get_type(unsigned int * line_position, const vector<char>& line, unsigned int &type, unsigned int &size)
819 {
820 uint8_t byte = *reinterpret_cast<const uint8_t*>(&line[*line_position]);
821 *line_position += sizeof(byte);
822 size = byte >> 4;
823 type = (byte & (uint8_t)15);
824
825 if (size == 15)
826 {
827 int type2;
828 byte = *reinterpret_cast<const uint8_t*>(&line[*line_position]);
829 *line_position += sizeof(byte);
830
831 type2 = (byte & (uint8_t)15);
832 if (type2 == 1)
833 {
834 int8_t tmp;
835 tmp = *reinterpret_cast<const int8_t*>(&line[*line_position]);
836 *line_position += sizeof(tmp);
837 size = (unsigned int)tmp;
838 }
839 else if (type2 == 2)
840 {
841 int16_t tmp;
842 tmp = *reinterpret_cast<const int16_t*>(&line[*line_position]);
843 *line_position += sizeof(tmp);
844
845 size = (int)tmp;
846 }
847 else if (type2 == 3)
848 {
849 int32_t tmp;
850 tmp = *reinterpret_cast<const int32_t*>(&line[*line_position]);
851 *line_position += sizeof(tmp);
852 size = (unsigned int)tmp;
853 }
854 else
855 {
856 LOG.printLOG("Error: Invalid type for integer size.\n");
857 exit(0);
858 }
859 }
860 }
861
skip_section(unsigned int * line_position,const vector<char> & line)862 void entry::skip_section(unsigned int *line_position, const vector<char> &line)
863 {
864 unsigned int type, size;
865 get_type(line_position, line, type, size);
866
867 if ( (type == 1) || (type == 7) )
868 *line_position += sizeof(int8_t)*size;
869 else if (type == 2)
870 *line_position += sizeof(int16_t)*size;
871 else if ( (type == 3) || (type == 5) )
872 *line_position += sizeof(int32_t)*size;
873 }
874
check_missing(unsigned int line_position,const unsigned int type,const vector<char> & line)875 bool entry::check_missing(unsigned int line_position, const unsigned int type, const vector<char> &line)
876 {
877 static char missing_float[4] = {static_cast<char>(0x01), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
878 static char missing_int1 = static_cast<char>(0x80);
879 static char missing_int2[2] = {static_cast<char>(0x00), static_cast<char>(0x80)};
880 static char missing_int3[4] = {static_cast<char>(0x00), static_cast<char>(0x00), static_cast<char>(0x00), static_cast<char>(0x80)};
881
882 char test_char;
883 bool missing = true;
884 if (type==1)
885 {
886 test_char = *reinterpret_cast<const char*>(&line[line_position]);
887 missing = (test_char == missing_int1);
888 }
889 else if (type==2)
890 {
891 for (unsigned int ui=0; ui<sizeof(int16_t); ui++)
892 {
893 test_char = *reinterpret_cast<const char*>(&line[line_position]);
894 if (test_char != missing_int2[ui])
895 {
896 missing = false;
897 break;
898 }
899 line_position += sizeof(char);
900 }
901 }
902 else if (type==3)
903 {
904 for (unsigned int ui=0; ui<sizeof(int32_t); ui++)
905 {
906 test_char = *reinterpret_cast<const char*>(&line[line_position]);
907 if (test_char != missing_int3[ui])
908 {
909 missing = false;
910 break;
911 }
912 line_position += sizeof(char);
913 }
914 }
915 else if (type==5)
916 {
917 for (unsigned int ui=0; ui<sizeof(float); ui++)
918 {
919 test_char = *reinterpret_cast<const char*>(&line[line_position]);
920 if (test_char != missing_float[ui])
921 {
922 missing = false;
923 break;
924 }
925 line_position += sizeof(char);
926 }
927 }
928 else if (type==7)
929 missing = false;
930
931 return missing;
932 }
933
check_end(unsigned int line_position,const unsigned int type,const vector<char> & line)934 bool entry::check_end(unsigned int line_position, const unsigned int type, const vector<char> &line)
935 {
936 static char end_float[4] = {static_cast<char>(0x02), static_cast<char>(0x00), static_cast<char>(0x80), static_cast<char>(0x7F)};
937 static char end_int1 = static_cast<char>(0x81);
938 static char end_int2[2] = {static_cast<char>(0x01), static_cast<char>(0x80)};
939 static char end_int3[4] = {static_cast<char>(0x01), static_cast<char>(0x00), static_cast<char>(0x00), static_cast<char>(0x80)};
940
941 char test_char;
942 bool end = true;
943 if (type==1)
944 {
945 test_char = *reinterpret_cast<const char*>(&line[line_position]);
946 end = (test_char == end_int1);
947 }
948 else if (type==2)
949 {
950 for (unsigned int ui=0; ui<sizeof(int16_t); ui++)
951 {
952 test_char = *reinterpret_cast<const char*>(&line[line_position]);
953 if (test_char != end_int2[ui])
954 {
955 end = false;
956 break;
957 }
958 line_position += sizeof(char);
959 }
960 }
961 else if (type==3)
962 {
963 for (unsigned int ui=0; ui<sizeof(int32_t); ui++)
964 {
965 test_char = *reinterpret_cast<const char*>(&line[line_position]);
966 if (test_char != end_int3[ui])
967 {
968 end = false;
969 break;
970 }
971 line_position += sizeof(char);
972 }
973 }
974 else if (type==5)
975 {
976 for (unsigned int ui=0; ui<sizeof(float); ui++)
977 {
978 test_char = *reinterpret_cast<const char*>(&line[line_position]);
979 if (test_char != end_float[ui])
980 {
981 end = false;
982 break;
983 }
984 line_position += sizeof(char);
985 }
986 }
987 else if (type==7)
988 end = false;
989
990 return end;
991 }
992
get_number(uint32_t & out,unsigned int * line_position,const vector<char> & line)993 void entry::get_number(uint32_t &out, unsigned int *line_position, const vector<char>& line)
994 {
995 memcpy(&out, &line[*line_position], sizeof(out));
996 *line_position += sizeof(out);
997 }
998