adding winetest from the vendor drop for usp10.dll
[reactos.git] / reactos / base / applications / downloader / xml.c
1 /* PROJECT: ReactOS Downloader
2 * LICENSE: GPL - See COPYING in the top level directory
3 * FILE: base\applications\downloader\xml.c
4 * PURPOSE: Parsing of application information xml files
5 * PROGRAMMERS: Maarten Bosma
6 */
7
8 #include <libs/expat/expat.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <windows.h>
12 #include "structures.h"
13 #include "resources.h"
14
15 BOOL TagOpen;
16 struct Category* Current;
17 struct Application* CurrentApplication;
18 char CurrentTag [0x100];
19 extern WCHAR Strings [STRING_COUNT][MAX_STRING_LENGHT];
20
21 void tag_opened (void* usrdata, const char* tag, const char** arg)
22 {
23 int i;
24
25 if(!strcmp(tag, "tree") && !CurrentApplication)
26 {
27 // check version
28 }
29
30 else if(!strcmp(tag, "category") && !CurrentApplication)
31 {
32 if (!Current)
33 {
34 Current = malloc(sizeof(struct Category));
35 memset(Current, 0, sizeof(struct Category));
36 }
37 else if (TagOpen)
38 {
39 Current->Children = malloc(sizeof(struct Category));
40 memset(Current->Children, 0, sizeof(struct Category));
41 Current->Children->Parent = Current;
42 Current = Current->Children;
43 }
44 else
45 {
46 Current->Next = malloc(sizeof(struct Category));
47 memset(Current->Next, 0, sizeof(struct Category));
48 Current->Next->Parent = Current->Parent;
49 Current = Current->Next;
50 }
51 TagOpen = TRUE;
52
53 for (i=0; arg[i]; i+=2)
54 {
55 if(!strcmp(arg[i], "name"))
56 {
57 MultiByteToWideChar(CP_ACP, 0, arg[i+1], -1, Current->Name, 0x100);
58 }
59 if(!strcmp(arg[i], "icon"))
60 {
61 Current->Icon = atoi(arg[i+1]);
62 }
63 }
64 }
65
66 else if(!strcmp(tag, "application") && !CurrentApplication)
67 {
68 if(Current->Apps)
69 {
70 CurrentApplication = Current->Apps;
71 while(CurrentApplication->Next)
72 CurrentApplication = CurrentApplication->Next;
73 CurrentApplication->Next = malloc(sizeof(struct Application));
74 memset(CurrentApplication->Next, 0, sizeof(struct Application));
75 CurrentApplication = CurrentApplication->Next;
76 }
77 else
78 {
79 Current->Apps = malloc(sizeof(struct Application));
80 memset(Current->Apps, 0, sizeof(struct Application));
81 CurrentApplication = Current->Apps;
82 }
83
84 for (i=0; arg[i]; i+=2)
85 {
86 if(!strcmp(arg[i], "name"))
87 {
88 MultiByteToWideChar(CP_ACP, 0, arg[i+1], -1, CurrentApplication->Name, 0x100);
89 }
90 }
91 }
92 else if (CurrentApplication)
93 {
94 strncpy(CurrentTag, tag, 0x100);
95 }
96 else
97 MessageBoxW(0,Strings[IDS_XMLERROR_2],0,0);
98 }
99
100
101 void text (void* usrdata, const char* data, int len)
102 {
103 if (!CurrentApplication)
104 return;
105
106 // FIXME: handle newlines e.g. in Description
107 if(!strcmp(CurrentTag, "maintainer"))
108 {
109 int currentlengt = lstrlenW(CurrentApplication->Location);
110 MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Maintainer[currentlengt], 0x100-currentlengt);
111 }
112 else if(!strcmp(CurrentTag, "description"))
113 {
114 int currentlengt = lstrlenW(CurrentApplication->Description);
115 MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Description[currentlengt], 0x400-currentlengt);
116 }
117 else if(!strcmp(CurrentTag, "location"))
118 {
119 int currentlengt = lstrlenW(CurrentApplication->Location);
120 MultiByteToWideChar(CP_ACP, 0, data, len, &CurrentApplication->Location[currentlengt], 0x100-currentlengt);
121 }
122 }
123
124 void tag_closed (void* tree, const char* tag)
125 {
126 CurrentTag[0] = 0;
127
128 if(!strcmp(tag, "category"))
129 {
130 if (TagOpen)
131 {
132 TagOpen = FALSE;
133 }
134 else
135 {
136 Current = Current->Parent;
137 }
138 }
139 else if(!strcmp(tag, "application"))
140 {
141 CurrentApplication = NULL;
142 }
143 }
144
145 BOOL ProcessXML (const char* filename, struct Category* Root)
146 {
147 int done = 0;
148 char buffer[255];
149 FILE* file;
150 XML_Parser parser;
151
152 if(Current)
153 return FALSE;
154
155 Current = Root;
156 TagOpen = TRUE;
157
158 file = fopen(filename, "r");
159 if(!file)
160 {
161 file = fopen("downloader.xml", "r");
162 if(!file)
163 {
164 MessageBoxW(0,Strings[IDS_XMLERROR_1],0,0);
165 return FALSE;
166 }
167 }
168
169 parser = XML_ParserCreate(NULL);
170 XML_SetElementHandler(parser, tag_opened, tag_closed);
171 XML_SetCharacterDataHandler(parser, text);
172
173 while (!done)
174 {
175 size_t len = fread (buffer, 1, sizeof(buffer), file);
176 done = len < sizeof(buffer);
177
178 buffer[len] = 0;
179 if(!XML_Parse(parser, buffer, len, done))
180 {
181 MessageBoxW(0,Strings[IDS_XMLERROR_2],0,0);
182 return FALSE;
183 }
184 }
185
186 XML_ParserFree(parser);
187 fclose(file);
188
189 return TRUE;
190 }
191
192 void FreeApps (struct Application* Apps)
193 {
194 if (Apps->Next)
195 FreeApps(Apps->Next);
196
197 free(Apps);
198 }
199
200 void FreeTree (struct Category* Node)
201 {
202 if (Node->Children)
203 FreeTree(Node->Children);
204
205 if (Node->Next)
206 FreeTree(Node->Next);
207
208 if (Node->Apps)
209 FreeApps(Node->Apps);
210
211 free(Node);
212 }