File Coverage

third_party/modest/source/mycss/convert.c
Criterion Covered Total %
statement 13 120 10.8
branch 5 86 5.8
condition n/a
subroutine n/a
pod n/a
total 18 206 8.7


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2016-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "convert.h"
22             #include "mycore/utils/resources.h"
23              
24 0           const char * mycss_convert_split_dimension_string(mycore_string_t* str, double* value, bool* is_float)
25             {
26 0           size_t length = mycss_convert_data_to_double(str->data, str->length, value, is_float);
27 0           return &str->data[length];
28             }
29              
30             // TODO: float or double???
31 0           size_t mycss_convert_data_to_double(const char *data, size_t size, double *return_num, bool* is_float)
32             {
33             double p10;
34 0           bool is_negative = false;
35 0           size_t offset = 0;
36            
37 0           *return_num = 0.0f;
38            
39 0           switch (data[offset]) {
40 0           case '-': is_negative = true; /* fall through */
41 0           case '+': offset++;
42             }
43            
44 0           double number = 0.;
45 0           int num_digits = 0;
46 0           int num_decimals = 0;
47 0           int exponent = 0;
48            
49             // digits
50 0 0         while(offset < size && (data[offset] >= '0' && data[offset] <= '9'))
    0          
    0          
51             {
52 0           number = (data[offset] - '0') + number * 10;
53            
54 0           ++offset;
55 0           ++num_digits;
56             }
57            
58 0 0         if(offset == size) {
59 0 0         if(is_negative) number = -number;
60            
61 0           *return_num = number;
62            
63 0 0         if(is_float)
64 0           *is_float = false;
65            
66 0           return offset;
67             }
68            
69             // decimals
70 0 0         if(data[offset] == '.') {
71 0           ++offset;
72            
73 0 0         while (offset < size && (data[offset] >= '0' && data[offset] <= '9'))
    0          
    0          
74             {
75 0           number = (data[offset] - '0') + number * 10;
76            
77 0           ++offset;
78 0           ++num_digits;
79 0           ++num_decimals;
80             }
81            
82 0           exponent -= num_decimals;
83             }
84             else {
85 0 0         if(is_negative) number = -number;
86            
87 0           *return_num = number;
88            
89 0 0         if(is_float)
90 0           *is_float = false;
91            
92 0           return offset;
93             }
94            
95 0 0         if(num_digits == 0)
96 0           return 0;
97            
98 0 0         if(is_float)
99 0           *is_float = true;
100            
101             // Correct for sign
102 0 0         if(is_negative) number = -number;
103            
104 0           int n = 0;
105            
106             // Process an exponent string
107 0 0         if(offset < size && (data[offset] == 'e' || data[offset] == 'E'))
    0          
    0          
108             {
109 0           ++offset;
110            
111 0 0         if(offset >= size || (data[offset] != '-' && data[offset] != '+' &&
    0          
    0          
    0          
112 0 0         (data[offset] < '0' || data[offset] > '9')))
113             {
114 0           offset--;
115             }
116             else {
117             // Handle optional sign
118 0           is_negative = false;
119            
120 0           switch(data[offset]) {
121 0           case '-': is_negative = true; /* fall through */
122 0           case '+': offset++;
123             }
124            
125             // Process string of digits
126 0 0         while(offset < size && (data[offset] >= '0' && data[offset] <= '9'))
    0          
    0          
127             {
128 0           n = (data[offset] - '0') + n * 10;
129 0           ++offset;
130             }
131            
132 0 0         if(is_negative) {
133 0           exponent -= n;
134             } else {
135 0           exponent += n;
136             }
137             }
138             }
139            
140             // Scale the result
141 0           p10 = 10.;
142 0           n = exponent;
143            
144 0 0         if (n < 0) n = -n;
145            
146 0 0         while (n) {
147 0 0         if (n & 1) {
148 0 0         if (exponent < 0) {
149 0           number /= p10;
150             } else {
151 0           number *= p10;
152             }
153             }
154            
155 0           n >>= 1;
156 0           p10 *= p10;
157             }
158            
159 0           *return_num = number;
160            
161 0 0         if(is_float)
162 0           *is_float = true;
163            
164 0           return offset;
165             }
166              
167 2           size_t mycss_convert_data_to_integer(const char* data, size_t size, long* return_num)
168             {
169 2           long res_num = 0;
170 2           bool is_negative = false;
171 2           size_t offset = 0;
172            
173 2           switch (data[offset]) {
174 0           case '-': is_negative = true;
175 1           case '+': offset++;
176             }
177            
178 2           const unsigned char* u_data = (const unsigned char*)data;
179            
180 4 100         while(offset < size && mycore_string_chars_num_map[u_data[offset]] != 0xff)
    100          
181             {
182 2           res_num = mycore_string_chars_num_map[ u_data[offset] ] + res_num * 10;
183 2           ++offset;
184             }
185            
186 2 50         if(is_negative)
187 0           res_num = -res_num;
188            
189 2           *return_num = res_num;
190            
191 2           return offset;
192             }
193              
194 0           size_t mycss_convert_hex_to_codepoint(const char *data, size_t size, size_t *codepoint, unsigned int max_consumed)
195             {
196 0           const unsigned char *u_data = (const unsigned char*)data;
197            
198 0           size_t length = 0;
199 0           *codepoint = 0;
200            
201 0 0         while(length < size)
202             {
203 0 0         if(mycore_string_chars_hex_map[u_data[length]] != 0xff) {
204 0           *codepoint <<= 4;
205 0           *codepoint |= mycore_string_chars_hex_map[ u_data[length] ];
206            
207 0           --max_consumed;
208            
209 0 0         if(max_consumed == 0)
210 0           break;
211             }
212             else
213 0           break;
214            
215 0           ++length;
216             }
217            
218 0           return length;
219             }
220              
221 0           size_t mycss_convert_unicode_range_to_codepoint(const char *data, size_t size, size_t *start, size_t *end)
222             {
223 0           size_t length = mycss_convert_hex_to_codepoint(data, size, start, 6);
224            
225 0 0         if(length == size) {
226 0           *end = 0;
227 0           return length;
228             }
229            
230 0 0         if(data[length] == '?')
231             {
232 0           *end = *start;
233            
234             do {
235 0           *start <<= 4;
236 0           *start |= mycore_string_chars_hex_map[ 0x30 ]; // 0x30 == '0'
237            
238 0           *end <<= 4;
239 0           *end |= mycore_string_chars_hex_map[ 0x46 ]; // 0x46 == 'F'
240            
241 0           ++length;
242             }
243 0 0         while(length < size && data[length] == '?');
    0          
244            
245 0           return length;
246             }
247            
248 0 0         if(data[length] == '-') {
249 0           ++length;
250            
251 0           length += mycss_convert_hex_to_codepoint(&data[length], (size - length), end, 6);
252             }
253             else
254 0           *end = 0;
255            
256 0           return length;
257             }
258              
259