1 /* EINA - EFL data type library
2  * Copyright (C) 2008 Cedric Bail
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;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include <Eina.h>
28 
29 #include "eina_suite.h"
30 
get_file_full_path(const char * filename)31 static const char *get_file_full_path(const char *filename)
32 {
33    static char full_path[PATH_MAX] = "";
34    struct stat st;
35 
36    eina_str_join(full_path, sizeof(full_path), '/', TESTS_SRC_DIR, filename);
37 
38    if (stat(full_path, &st) == 0)
39      return full_path;
40 
41    if (full_path[0] != '/')
42      {
43         snprintf(full_path, sizeof(full_path), "%s/%s/%s", TESTS_WD, TESTS_SRC_DIR, filename);
44 
45         if (stat(full_path, &st) == 0)
46           return full_path;
47      }
48 
49    return NULL;
50 }
51 
EFL_START_TEST(eina_simple_xml_parser_node_dump)52 EFL_START_TEST(eina_simple_xml_parser_node_dump)
53 {
54    FILE *f;
55 
56    f = fopen(get_file_full_path("sample.gpx"), "rb");
57    if (f)
58      {
59         long sz;
60 
61         fseek(f, 0, SEEK_END);
62         sz = ftell(f);
63         if (sz > 0)
64           {
65              char *buf;
66 
67              fseek(f, 0, SEEK_SET);
68              buf = malloc(sz + 1);
69              if (buf)
70                {
71                   if (fread(buf, 1, sz, f))
72                     {
73                        Eina_Simple_XML_Node_Root *root = eina_simple_xml_node_load
74                          (buf, sz, EINA_TRUE);
75                        buf[sz] = '\0';
76                        char *out = eina_simple_xml_node_dump(&root->base, "  ");
77                        //puts(out);
78                        ck_assert_str_eq(out, buf);
79                        free(out);
80                        eina_simple_xml_node_root_free(root);
81                     }
82                   free(buf);
83                }
84           }
85         fclose(f);
86      }
87 
88 }
89 EFL_END_TEST
90 
EFL_START_TEST(eina_simple_xml_parser_null_node_dump)91 EFL_START_TEST(eina_simple_xml_parser_null_node_dump)
92 {
93 
94    char *out = eina_simple_xml_node_dump(NULL, "  ");
95    fail_if(out != NULL);
96 
97 }
98 EFL_END_TEST
99 
EFL_START_TEST(eina_simple_xml_parser_childs_count)100 EFL_START_TEST(eina_simple_xml_parser_childs_count)
101 {
102 
103     const char *buf = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
104 	    "<test version=\"0.1\"><child>I'm a child.</child><child><![CDATA[I'm a 2-nd child.]]></child><!-- Some comment --></test>";
105     const int sz = strlen(buf);
106     Eina_Simple_XML_Node_Root *root = eina_simple_xml_node_load(buf, sz, EINA_TRUE);
107     fail_if(root == NULL);
108     fail_if(root->children == NULL);
109     fail_if(eina_inlist_count(root->children) != 2);
110     eina_simple_xml_node_root_free(root);
111 
112 }
113 EFL_END_TEST
114 
115 enum simple_xml_parser_current_state
116 {
117     simple_xml_parser_current_state_begin,
118     simple_xml_parser_current_state_gpx,
119     simple_xml_parser_current_state_metadata,
120     simple_xml_parser_current_state_link,
121     simple_xml_parser_current_state_text,
122     simple_xml_parser_current_state_time,
123     simple_xml_parser_current_state_trk,
124     simple_xml_parser_current_state_name,
125     simple_xml_parser_current_state_trkseg,
126     simple_xml_parser_current_state_trkpt,
127     simple_xml_parser_current_state_comment,
128     simple_xml_parser_current_state_cdata,
129     simple_xml_parser_current_state_end
130 };
131 
132 static Eina_Bool
eina_simple_xml_parser_parse_with_custom_callback_tag_cb(void * data,Eina_Simple_XML_Type type,const char * content,unsigned offset EINA_UNUSED,unsigned length EINA_UNUSED)133 eina_simple_xml_parser_parse_with_custom_callback_tag_cb(void *data,
134                                                          Eina_Simple_XML_Type type,
135                                                          const char *content,
136                                                          unsigned offset EINA_UNUSED,
137                                                          unsigned length EINA_UNUSED)
138 {
139     int* parse_current_state = (int*) data;
140 
141     if (type == EINA_SIMPLE_XML_OPEN)
142       {
143         if (!strncmp("gpx ", content, strlen("gpx ")))
144           {
145             fail_if(*parse_current_state != simple_xml_parser_current_state_begin);
146             *parse_current_state = simple_xml_parser_current_state_gpx;
147           }
148         else if (!strncmp("metadata>", content, strlen("metadata>")))
149           {
150             fail_if(*parse_current_state != simple_xml_parser_current_state_gpx);
151             *parse_current_state = simple_xml_parser_current_state_metadata;
152           }
153         else if (!strncmp("link ", content, strlen("link ")))
154           {
155             fail_if(*parse_current_state != simple_xml_parser_current_state_metadata);
156             *parse_current_state = simple_xml_parser_current_state_link;
157           }
158         else if (!strncmp("text>", content, strlen("text>")))
159           {
160             fail_if(*parse_current_state != simple_xml_parser_current_state_link);
161             *parse_current_state = simple_xml_parser_current_state_text;
162           }
163         else if (!strncmp("time>", content, strlen("time>")))
164           {
165             fail_if(*parse_current_state != simple_xml_parser_current_state_text);
166             *parse_current_state = simple_xml_parser_current_state_time;
167           }
168         else if (!strncmp("trk>", content, strlen("trk>")))
169           {
170             fail_if(*parse_current_state != simple_xml_parser_current_state_time);
171             *parse_current_state = simple_xml_parser_current_state_trk;
172           }
173         else if (!strncmp("name>", content, strlen("name>")))
174           {
175             fail_if(*parse_current_state != simple_xml_parser_current_state_trk);
176             *parse_current_state = simple_xml_parser_current_state_name;
177           }
178         else if (!strncmp("trkseg>", content, strlen("trkseg>")))
179           {
180             fail_if(*parse_current_state != simple_xml_parser_current_state_name);
181             *parse_current_state = simple_xml_parser_current_state_trkseg;
182           }
183         else
184           {
185             fail_if(*parse_current_state != simple_xml_parser_current_state_trkpt);
186           }
187       }
188     else if (type == EINA_SIMPLE_XML_OPEN_EMPTY)
189       {
190         if (!strncmp("trkpt ", content, strlen("trkpt ")))
191           {
192             fail_if(*parse_current_state != simple_xml_parser_current_state_trkseg &&
193                     *parse_current_state != simple_xml_parser_current_state_trkpt);
194             *parse_current_state = simple_xml_parser_current_state_trkpt;
195           }
196       }
197     else if (type == EINA_SIMPLE_XML_COMMENT)
198       {
199         fail_if(*parse_current_state != simple_xml_parser_current_state_trkpt);
200         *parse_current_state = simple_xml_parser_current_state_comment;
201       }
202     else if (type == EINA_SIMPLE_XML_CDATA)
203       {
204         fail_if(*parse_current_state != simple_xml_parser_current_state_comment);
205         *parse_current_state = simple_xml_parser_current_state_cdata;
206       }
207     else if (type == EINA_SIMPLE_XML_CLOSE)
208       {
209         if (!strncmp("gpx", content, strlen("gpx")))
210           {
211             fail_if(*parse_current_state != simple_xml_parser_current_state_cdata);
212             *parse_current_state = simple_xml_parser_current_state_end;
213           }
214       }
215     return EINA_TRUE;
216 }
217 
EFL_START_TEST(eina_simple_xml_parser_parse_with_custom_callback)218 EFL_START_TEST(eina_simple_xml_parser_parse_with_custom_callback)
219 {
220     FILE *f;
221 
222     f = fopen(get_file_full_path("sample.gpx"), "rb");
223 
224     if (f)
225       {
226         long sz;
227 
228         fseek(f, 0, SEEK_END);
229         sz = ftell(f);
230 
231         if (sz > 0)
232           {
233             char *buf;
234 
235             fseek(f, 0, SEEK_SET);
236             buf = malloc(sz + 1);
237 
238             if (buf)
239               {
240                 if (fread(buf, 1, sz, f))
241                   {
242                     int parse_current_state = simple_xml_parser_current_state_begin;
243                     eina_simple_xml_parse(buf,
244                                           sz,
245                                           EINA_TRUE,
246                                           eina_simple_xml_parser_parse_with_custom_callback_tag_cb,
247                                           &parse_current_state);
248                     fail_if(parse_current_state != simple_xml_parser_current_state_end);
249                   }
250                 free(buf);
251               }
252           }
253 
254         fclose(f);
255       }
256 
257 }
258 EFL_END_TEST
259 
260 void
eina_test_simple_xml_parser(TCase * tc)261 eina_test_simple_xml_parser(TCase *tc)
262 {
263    tcase_add_test(tc, eina_simple_xml_parser_node_dump);
264    tcase_add_test(tc, eina_simple_xml_parser_null_node_dump);
265    tcase_add_test(tc, eina_simple_xml_parser_childs_count);
266    tcase_add_test(tc, eina_simple_xml_parser_parse_with_custom_callback);
267 }
268