summaryrefslogtreecommitdiff
path: root/libs/libjson/src/NumberToString.h
blob: 4ecd8779c2b6645f521663c2b725084411d14ea1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#ifndef NUMBERTOSTRING_H
#define NUMBERTOSTRING_H

#include "JSONDebug.h"
#include "JSONMemory.h"
#include <cstdio>

static unsigned int getlen(unsigned int size){
	switch (size){
		case 1:
			return 5;   //3 digits for the number, plus null terminator and negation
		case 2:
			return 7;   //5 digits for the number, plus null terminator and negation
		case 4:
			return 12;  //10 digits for the number, plus null terminator and negation
		case 8:
			return 22;  //20 digits for the number, plus null terminator and negation
	}
	JSON_ASSERT(size == 16, JSON_TEXT("template is not recognized 2^x in size"));
	return 41;  //39 digits for the number, plus null terminator and negation
}

class NumberToString {
public:
	template<typename T>
	static json_string _itoa(T val, unsigned int size){
		int64_t value = (int64_t)val;
		const unsigned int digits = getlen(size);
		json_auto<json_char> result(digits);
		result.ptr[digits - 1] = JSON_TEXT('\0'); //null terminator
		json_char *runner = &result.ptr[digits - 2];
		bool negative;

		//first thing, check if it's negative, if so, make it positive
		if (value < 0){
			value = -value;
			negative = true;
		} else {
			negative = false;
		}

		//create the string
		do {
			*runner--=(json_char)(value % 10) + JSON_TEXT('0');
		} while(value /= 10);

		//if it's negative, add the negation
		json_string res;
		if (negative){
			*runner = JSON_TEXT('-');
			res = runner;
		} else {
			res = runner + 1;
		}
		return res;   
	}

	#ifndef JSON_LIBRARY
		template<typename T>
		static json_string _uitoa(T val, unsigned int size){
			uint64_t value = (uint64_t)val;
			const unsigned int digits = getlen(size) - 1;  //minus one because no '-' char
			json_auto<json_char> result(digits);
			result.ptr[digits - 1] = JSON_TEXT('\0'); //null terminator
			json_char * runner = &result.ptr[digits - 2];

			//create the string
			do {
				*runner--=(json_char)(value % 10) + JSON_TEXT('0');
			} while(value /= 10);

			json_string res = runner + 1;
			return res;   
		}
	#endif

	template<typename T>
	static json_string _ftoa(T value){
		json_char result[64];
		#ifdef JSON_UNICODE
			mir_snwprintf(result, 63, L"%f", value); 
		#else
			mir_snprintf(result, 63, "%f", value); 
		#endif
		//strip the trailing zeros
		for(json_char * pos = &result[0]; *pos; ++pos){
			if (*pos == '.') {  //only care about after the decimal
				for(json_char * runner = pos + 1; *runner; ++runner){
					if (*runner != JSON_TEXT('0')) pos = runner + 1;
				}
				*pos = JSON_TEXT('\0');
				break;
			}
		}
		return result;
	}

	static inline bool areEqual(const double & one, const double & two){
		const double temp = one - two;
		return (temp > 0.0) ? temp < 0.00001 : temp > -0.00001;
	}
};

#endif