1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** USBX Component                                                        */
17 /**                                                                       */
18 /**   Pictbridge Application                                              */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /* Include necessary system files.  */
25 
26 #define UX_SOURCE_CODE
27 
28 #include "ux_api.h"
29 #include "ux_pictbridge.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_pictbridge_object_parse                         PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function parses a XML based pictbridge object.                 */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    pictbridge                             Pictbridge instance          */
49 /*    xml_object_buffer                      Pointer to object buffer     */
50 /*    xml_object_length                      Length of the object         */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    Completion Status                                                   */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    _ux_pictbridge_object_get                                           */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
68 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
69 /*                                            resulting in version 6.1    */
70 /*                                                                        */
71 /**************************************************************************/
_ux_pictbridge_object_parse(UX_PICTBRIDGE * pictbridge,UCHAR * xml_object_buffer,ULONG xml_object_length)72 UINT  _ux_pictbridge_object_parse(UX_PICTBRIDGE *pictbridge, UCHAR *xml_object_buffer,
73                                     ULONG xml_object_length)
74 {
75 UX_PICTBRIDGE_XML_ITEM                  *tag_item;
76 UX_PICTBRIDGE_XML_ITEM                  *tag_entry =  UX_NULL;
77 UCHAR                                   tag_name[UX_PICTBRIDGE_MAX_TAG_SIZE];
78 UCHAR                                   variable_name[UX_PICTBRIDGE_MAX_VARIABLE_SIZE];
79 UCHAR                                   variable_string[UX_PICTBRIDGE_MAX_STRING_SIZE];
80 UCHAR                                   xml_parameter[UX_PICTBRIDGE_MAX_STRING_SIZE];
81 UX_PICTBRIDGE_XML_ITEM                  *tag_history[UX_PICTBRIDGE_MAX_TAG_DEPTH];
82 ULONG                                   tag_history_index;
83 ULONG                                   tag_flag;
84 ULONG                                   closing_tag_count;
85 UINT                                    tag_name_length;
86 UINT                                    tag_history_length;
87 UINT                                    status;
88 
89     /* Set the tag position at root.  */
90     tag_item = _ux_pictbridge_xml_item_root;
91 
92     /* Clear the input tags.  */
93     pictbridge -> ux_pictbridge_input_tags =  0;
94 
95     /* Clear the input request.  */
96     pictbridge -> ux_pictbridge_input_request =  0;
97 
98     /* Tag history index is at root.  */
99     tag_history_index =  0;
100 
101     /* Closing tag count is reset.  */
102     closing_tag_count = 0;
103 
104     /* This variable remains untouched if the XML object's length is 0.  */
105     status =  UX_SUCCESS;
106 
107     /* We parse the object until all items are parsed or there is a syntax error
108        or a short object.  */
109     while(xml_object_length)
110     {
111 
112         /* Scan the object buffer for a tag.  */
113         status = _ux_pictbridge_tag_name_get(xml_object_buffer, xml_object_length, tag_name,
114                                         variable_name, variable_string, xml_parameter,
115                                         &xml_object_buffer, &xml_object_length, &tag_flag);
116 
117         /* We may have an error.  Check if this is an empty line in which case we are done. */
118         if (status != UX_SUCCESS)
119         {
120 
121             /* Check for empty line.  */
122             if (status == UX_PICTBRIDGE_ERROR_EMPTY_LINE)
123 
124                 /* Yes, we have an empty line. Do not proceed but we have a successful completion. */
125                 status = UX_SUCCESS;
126 
127             /* Do not proceed.  */
128             break;
129         }
130 
131         /* Check if this is a closing tag ? */
132         if (tag_flag & UX_PICTBRIDGE_TAG_FLAG_CLOSING)
133         {
134 
135             /* Assume the worst.  */
136             status = UX_PICTBRIDGE_ERROR_SCRIPT_SYNTAX_ERROR;
137 
138             /* Ensure we do not have a closing tag without a prior normal tag entry.  */
139             if (tag_history_index == 0)
140 
141                 /* Syntax error.  */
142                 break;
143 
144             /* One step back in the tag history.  */
145             tag_history_index--;
146 
147             /* Calculate the length of the tag item.  */
148             status = _ux_utility_string_length_check(tag_name, &tag_name_length, UX_PICTBRIDGE_MAX_TAG_SIZE);
149             if (status != UX_SUCCESS)
150 
151                 /* Bad name, we should never here if _tag_name_get is OK.  */
152                 break;
153 
154             /* Calculate the length of the current tag name in the tag history.  */
155             status = _ux_utility_string_length_check(tag_history[tag_history_index] -> ux_pictbridge_xml_item_tag_name, &tag_history_length, UX_PICTBRIDGE_MAX_TAG_SIZE);
156             if (status != UX_SUCCESS)
157 
158                 /* Bad name, we should never here if _tag_name_get is OK.  */
159                 return(status);
160 
161             /* If both length do not match, no need to check for a match.  */
162             if (tag_history_length == tag_name_length)
163             {
164 
165                 /* Both length match, we may have a tag match. Check the names */
166                 if (_ux_utility_memory_compare(tag_name, tag_history[tag_history_index] -> ux_pictbridge_xml_item_tag_name,
167                                         tag_name_length) != UX_SUCCESS)
168 
169                     /* Syntax error.  */
170                     break;
171             }
172             else
173 
174                 /* Syntax error.  */
175                 break;
176 
177             /* Increment the closing tag count. */
178             closing_tag_count++;
179 
180             /* If we have more than one closing tag consecutively, look for the parent.  */
181             if (closing_tag_count > 1)
182             {
183 
184                 /* Get the parent for this item and set it as the current tag_item.  We may already be at the root.  */
185                 if (tag_entry -> ux_pictbridge_xml_item_parent != UX_NULL)
186 
187                     /* We have a parent, set it.  */
188                     tag_item =  tag_entry -> ux_pictbridge_xml_item_parent;
189             }
190 
191             /* We set status to success.  */
192             status = UX_SUCCESS;
193 
194         }
195         else
196         {
197 
198             /* The tag name is in the tag_name variable but has not been verified yet.  */
199             status = _ux_pictbridge_tag_name_scan(tag_item, tag_name, &tag_entry);
200 
201             /* We may have an error.  */
202             if (status != UX_SUCCESS)
203 
204                 /* Do not proceed.  */
205                 break;
206 
207             /* Check if this is a comment tag ? */
208             if ((tag_flag & UX_PICTBRIDGE_TAG_FLAG_COMMENT) == 0)
209             {
210 
211                 /* Reset the closing tag count.  */
212                 closing_tag_count =  0;
213 
214                 /* Save the current tag in the tag history.  */
215                 tag_history[tag_history_index] = tag_entry;
216 
217                 /* Increase the current tag index.  */
218                 tag_history_index++;
219 
220                 /* Check if there is a main tag specified in the tag entry. */
221                 if (tag_entry -> ux_pictbridge_xml_item_tag_code != 0)
222                 {
223 
224                     /* If this is a leaf, the tag is not a main request but a variable to be returned.  */
225                     if (tag_entry -> ux_pictbridge_xml_item_child == UX_PICTBRIDGE_XML_LEAF)
226 
227                         /* This is a variable. Add it to the other ones.  */
228                         pictbridge -> ux_pictbridge_input_tags |=  tag_entry -> ux_pictbridge_xml_item_tag_code;
229 
230                     else
231 
232                         /* Yes we have a tag code, memorize it.  This is a main input request. */
233                         pictbridge -> ux_pictbridge_input_request =  tag_entry -> ux_pictbridge_xml_item_tag_code;
234                 }
235                 /* We may have a function associated with this tag. Do a sanity check.  */
236                 if (tag_entry -> ux_pictbridge_xml_item_function != UX_NULL)
237                 {
238                     /* There is a function associated, so call it.  */
239                     status = tag_entry -> ux_pictbridge_xml_item_function(pictbridge, variable_name, variable_string, xml_parameter);
240 
241                     /* We may have an error.  */
242                     if (status != UX_SUCCESS)
243 
244                        /* Do not proceed.  */
245                         break;
246                 }
247 
248                 /* Check if the tag has a child attached to it.
249                    If there is neither a child or a function, it means we do not treat this tag name. */
250                 if (tag_entry -> ux_pictbridge_xml_item_child != UX_NULL && tag_entry -> ux_pictbridge_xml_item_child != UX_PICTBRIDGE_XML_LEAF)
251                 {
252 
253                     /* We have a child, set it.  */
254                     tag_item =  tag_entry -> ux_pictbridge_xml_item_child;
255 
256                     /* Reset the tag codes.  */
257                     pictbridge -> ux_pictbridge_input_tags =  0;
258                 }
259 
260                 /* Check if this is a self closing tag ? */
261                 if (tag_flag & UX_PICTBRIDGE_TAG_FLAG_SELF_CLOSING)
262                 {
263 
264                     /* Assume the worst.  */
265                     status = UX_PICTBRIDGE_ERROR_SCRIPT_SYNTAX_ERROR;
266 
267                     /* Ensure we do not have a closing tag without a prior normal tag entry.  */
268                     if (tag_history_index == 0)
269 
270                         /* Syntax error.  */
271                         break;
272 
273                     /* One step back in the tag history.  */
274                     tag_history_index--;
275 
276                     /* Calculate the length of the tag item.   */
277                     status = _ux_utility_string_length_check(tag_name, &tag_name_length, UX_PICTBRIDGE_MAX_TAG_SIZE);
278                     if (status != UX_SUCCESS)
279 
280                         /* Bad name, we should never here if _tag_name_scan is OK!  */
281                         break;
282 
283                     /* Calculate the length of the current tag name in the tag history.  */
284                     status = _ux_utility_string_length_check(tag_history[tag_history_index] -> ux_pictbridge_xml_item_tag_name, &tag_history_length, UX_PICTBRIDGE_MAX_TAG_SIZE);
285                     if (status != UX_SUCCESS)
286 
287                         /* Bad name, we should never here if _tag_name_scan is OK!  */
288                         break;
289 
290                     /* If both length do not match, no need to check for a match.  */
291                     if (tag_history_length == tag_name_length)
292                     {
293 
294                         /* Both length match, we may have a tag match. Check the names */
295                         if (_ux_utility_memory_compare(tag_name, tag_history[tag_history_index] -> ux_pictbridge_xml_item_tag_name,
296                                             tag_name_length) != UX_SUCCESS)
297 
298                             /* Syntax error.  */
299                             break;
300                     }
301                     else
302 
303                         /* Syntax error.  */
304                         break;
305 
306                     /* Increment the closing tag count. */
307                     closing_tag_count++;
308 
309                     /* We set status to success.  */
310                     status = UX_SUCCESS;
311 
312                 }
313             }
314         }
315     }
316 
317     /* Return completion status.  */
318     return(status);
319 }
320 
321