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