File Coverage

third_party/modest/source/myhtml/data_process.c
Criterion Covered Total %
statement 58 150 38.6
branch 22 120 18.3
condition n/a
subroutine n/a
pod n/a
total 80 270 29.6


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2015-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 "myhtml/data_process.h"
22             #include "mycore/utils/resources.h"
23              
24             #define MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING() \
25             tmp_offset += myhtml_string_before_append_any_preprocessing(str, &data[tmp_offset], (offset - tmp_offset), \
26             proc_entry->tmp_str_pos_proc); \
27             if(offset != tmp_offset) { \
28             if(proc_entry->encoding == MyENCODING_UTF_8) \
29             proc_entry->tmp_str_pos_proc = myhtml_string_append_with_preprocessing(str, &data[tmp_offset], (offset - tmp_offset), \
30             proc_entry->emit_null_char); \
31             else { \
32             proc_entry->tmp_str_pos_proc = \
33             myhtml_string_append_chunk_with_convert_encoding_with_preprocessing(str, &proc_entry->res, \
34             &data[tmp_offset], (offset - tmp_offset), \
35             proc_entry->encoding, proc_entry->emit_null_char); \
36             } \
37             }
38              
39 1131           void myhtml_data_process_entry_clean(myhtml_data_process_entry_t* proc_entry)
40             {
41 1131           memset(proc_entry, 0, sizeof(myhtml_data_process_entry_t));
42 1131           proc_entry->state = myhtml_data_process_state_data;
43 1131           }
44              
45 256           void myhtml_data_process_string_append_char(mycore_string_t* str, const char sm)
46             {
47 256 50         MyCORE_STRING_REALLOC_IF_NEED(str, 2, 0);
48            
49 256           str->data[str->length] = sm;
50 256           str->length++;
51            
52 256           str->data[str->length] = '\0';
53 256           }
54              
55 980           size_t myhtml_data_process_state_data(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
56             {
57 980           size_t tmp_offset = offset;
58            
59 6235 100         while(offset < size)
60             {
61 5383 100         if(data[offset] == '&')
62             {
63 128           tmp_offset += myhtml_string_before_append_any_preprocessing(str, &data[tmp_offset], (offset - tmp_offset),
64             proc_entry->tmp_str_pos_proc);
65 128 50         if(offset != tmp_offset) {
66 0 0         if(proc_entry->encoding == MyENCODING_UTF_8)
67 0           proc_entry->tmp_str_pos_proc = myhtml_string_append_with_preprocessing(str, &data[tmp_offset],
68             (offset - tmp_offset),
69 0           proc_entry->emit_null_char);
70             else {
71 0           proc_entry->tmp_str_pos_proc =
72 0           myhtml_string_append_chunk_with_convert_encoding_with_preprocessing(str, &proc_entry->res,
73             &data[tmp_offset], (offset - tmp_offset),
74 0           proc_entry->encoding, proc_entry->emit_null_char);
75 0           myencoding_result_clean(&proc_entry->res);
76             }
77             }
78            
79 128           proc_entry->tmp_str_pos = str->length;
80 128           proc_entry->state = myhtml_data_process_state_ampersand;
81            
82 128           myhtml_data_process_string_append_char(str, data[offset]);
83            
84 128           offset++;
85 128           return offset;
86             }
87            
88 5255           offset++;
89             }
90            
91 852 50         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    100          
92            
93 852           return offset;
94             }
95              
96 128           size_t myhtml_data_process_state_ampersand(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
97             {
98 128 50         if(data[offset] == '#')
99             {
100 0           myhtml_data_process_string_append_char(str, data[offset]);
101 0           offset++;
102            
103 0           proc_entry->tmp_num = 0;
104            
105 0 0         if(offset >= size) {
106 0           proc_entry->state = myhtml_data_process_state_ampersand_hash;
107 0           return offset;
108             }
109            
110 0 0         if(data[offset] == 'x' || data[offset] == 'X') {
    0          
111 0           myhtml_data_process_string_append_char(str, data[offset]);
112 0           offset++;
113            
114 0           proc_entry->state = myhtml_data_process_state_ampersand_hash_x_data;
115             }
116             else
117 0           proc_entry->state = myhtml_data_process_state_ampersand_hash_data;
118             }
119             else {
120 128           proc_entry->charef_res.last_entry = NULL;
121 128           proc_entry->charef_res.curr_entry = myhtml_charef_get_first_position(data[offset]);
122            
123 128 50         if(proc_entry->charef_res.curr_entry->ch == '\0')
124 0           proc_entry->state = myhtml_data_process_state_data;
125             else {
126 128           proc_entry->state = myhtml_data_process_state_ampersand_data;
127            
128 128           myhtml_data_process_string_append_char(str, data[offset]);
129 128           offset++;
130             }
131             }
132            
133 128           return offset;
134             }
135              
136 128           size_t myhtml_data_process_state_ampersand_data(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
137             {
138 128           size_t tmp_offset = offset;
139            
140 128           const charef_entry_t *current_entry = myhtml_charef_find_by_pos(proc_entry->charef_res.curr_entry->next, data, &offset, size, &proc_entry->charef_res);
141            
142 128 50         if(proc_entry->charef_res.is_done) {
143 128           proc_entry->state = myhtml_data_process_state_data;
144            
145 128 50         if(data[offset] == ';')
146 128           offset++;
147             else {
148             /* if current charef is atrribute */
149 0 0         if(proc_entry->is_attributes &&
    0          
150 0 0         (data[offset] == '=' || mycore_string_alphanumeric_character[ (unsigned char)data[offset] ] != 0xff))
151             {
152 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
153            
154 0           return offset;
155             }
156             }
157            
158 128 50         if(current_entry->codepoints_len) {
159 256 100         for (size_t i = 0; i < current_entry->codepoints_len; i++) {
160 128 50         MyCORE_STRING_REALLOC_IF_NEED(str, 5, 0);
161            
162 128           proc_entry->tmp_str_pos += myencoding_codepoint_to_ascii_utf_8(current_entry->codepoints[i], &str->data[proc_entry->tmp_str_pos]);
163             }
164            
165 128           str->length = proc_entry->tmp_str_pos;
166 128           str->data[str->length] = '\0';
167             }
168             else {
169 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
170             }
171            
172 128           proc_entry->charef_res.last_entry = NULL;
173             }
174             else {
175 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
176             }
177            
178 128           return offset;
179             }
180              
181 0           size_t myhtml_data_process_state_ampersand_hash(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
182             {
183 0 0         if(data[offset] == 'x' || data[offset] == 'X') {
    0          
184 0           myhtml_data_process_string_append_char(str, data[offset]);
185 0           offset++;
186            
187 0           proc_entry->state = myhtml_data_process_state_ampersand_hash_x_data;
188             }
189             else
190 0           proc_entry->state = myhtml_data_process_state_ampersand_hash_data;
191            
192 0           return offset;
193             }
194              
195 0           size_t myhtml_data_process_state_ampersand_hash_data(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
196             {
197 0           const unsigned char *u_data = (const unsigned char*)data;
198 0           size_t tmp_offset = offset;
199            
200 0 0         while(offset < size)
201             {
202 0 0         if(mycore_string_chars_num_map[ u_data[offset] ] == 0xff)
203             {
204 0           proc_entry->state = myhtml_data_process_state_data;
205            
206 0 0         if((offset - tmp_offset) == 0) {
207 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
208            
209 0           return offset;
210             }
211            
212 0 0         if(data[offset] == ';')
213 0           offset++;
214            
215 0           myhtml_data_process_state_end(proc_entry, str);
216 0           return offset;
217             }
218            
219 0 0         if(proc_entry->tmp_num <= 0x10FFFF) {
220 0           proc_entry->tmp_num = mycore_string_chars_num_map[ u_data[offset] ] + proc_entry->tmp_num * 10;
221             }
222            
223 0           offset++;
224             }
225            
226 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
227            
228 0           return offset;
229             }
230              
231 0           size_t myhtml_data_process_state_ampersand_hash_x_data(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t offset, size_t size)
232             {
233 0           unsigned const char *u_data = (unsigned const char*)data;
234 0           size_t tmp_offset = offset;
235            
236 0 0         while(offset < size)
237             {
238 0 0         if(mycore_string_chars_hex_map[ u_data[offset] ] == 0xff)
239             {
240 0           proc_entry->state = myhtml_data_process_state_data;
241            
242 0 0         if((offset - tmp_offset) == 0) {
243 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
244            
245 0           return offset;
246             }
247            
248 0 0         if(data[offset] == ';')
249 0           offset++;
250            
251 0           myhtml_data_process_state_end(proc_entry, str);
252 0           return offset;
253             }
254            
255 0 0         if(proc_entry->tmp_num <= 0x10FFFF) {
256 0           proc_entry->tmp_num <<= 4;
257 0           proc_entry->tmp_num |= mycore_string_chars_hex_map[ u_data[offset] ];
258             }
259            
260 0           offset++;
261             }
262            
263 0 0         MyHTML_DATA_PROCESS_APPEND_WITH_PREPROCESSING()
    0          
264            
265 0           return offset;
266             }
267              
268 0           void myhtml_data_process_state_end(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str)
269             {
270             /* 4 is max utf8 byte + \0 */
271 0 0         MyCORE_STRING_REALLOC_IF_NEED(str, 5, 0);
272            
273 0 0         if(proc_entry->tmp_num <= 0x9F)
274 0           proc_entry->tmp_num = replacement_character[proc_entry->tmp_num];
275 0 0         else if(proc_entry->tmp_num >= 0xD800 && proc_entry->tmp_num <= 0xDFFF)
    0          
276 0           proc_entry->tmp_num = replacement_character[0];
277 0 0         else if(proc_entry->tmp_num > 0x10FFFF)
278 0           proc_entry->tmp_num = replacement_character[0];
279            
280 0           str->length = proc_entry->tmp_str_pos +
281 0           myencoding_codepoint_to_ascii_utf_8(proc_entry->tmp_num, &str->data[proc_entry->tmp_str_pos]);
282            
283 0           str->data[str->length] = '\0';
284 0           }
285              
286 885           void myhtml_data_process(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str, const char* data, size_t size)
287             {
288 885           size_t offset = 0;
289            
290 2121 100         while (offset < size) {
291 1236           offset = proc_entry->state(proc_entry, str, data, offset, size);
292             }
293 885           }
294              
295 884           void myhtml_data_process_end(myhtml_data_process_entry_t* proc_entry, mycore_string_t* str)
296             {
297 884 50         if(proc_entry->state == myhtml_data_process_state_ampersand_data && proc_entry->charef_res.last_entry)
    0          
298 0           {
299 0           const charef_entry_t *entry = proc_entry->charef_res.last_entry;
300            
301 0 0         for (size_t i = 0; i < entry->codepoints_len; i++) {
302 0 0         MyCORE_STRING_REALLOC_IF_NEED(str, 5, 0);
303            
304 0           proc_entry->tmp_str_pos += myencoding_codepoint_to_ascii_utf_8(entry->codepoints[i], &str->data[proc_entry->tmp_str_pos]);
305             }
306            
307 0           str->length = proc_entry->tmp_str_pos;
308 0           str->data[str->length] = '\0';
309             }
310 884 50         else if(proc_entry->state == myhtml_data_process_state_ampersand_hash_data) {
311 0 0         if((str->length - (proc_entry->tmp_str_pos + 2)))
312 0           myhtml_data_process_state_end(proc_entry, str);
313             }
314 884 50         else if(proc_entry->state == myhtml_data_process_state_ampersand_hash_x_data) {
315 0 0         if((str->length - (proc_entry->tmp_str_pos + 3)))
316 0           myhtml_data_process_state_end(proc_entry, str);
317             }
318 884           }
319              
320