Revert r46466 this time for real
[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, Lester Kortenhoeven
6 */
7
8 #include <libs/expat/expat.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <windows.h>
12 #include <shlwapi.h>
13 #include "structures.h"
14 #include "resources.h"
15
16 BOOL TagOpen;
17 struct Category* Current;
18 struct Application* CurrentApplication;
19 char CurrentTag [0x100];
20 extern WCHAR Strings [STRING_COUNT][MAX_STRING_LENGHT];
21
22 void tag_opened (void* usrdata, const char* tag, const char** arg)
23 {
24 int i;
25
26 if(!strcmp(tag, "tree") && !CurrentApplication)
27 {
28 // check version
29 }
30
31 else if(!strcmp(tag, "category") && !CurrentApplication)
32 {
33 if (!Current)
34 {
35 Current = malloc(sizeof(struct Category));
36 memset(Current, 0, sizeof(struct Category));
37 }
38 else if (TagOpen)
39 {
40 Current->Children = malloc(sizeof(struct Category));
41 memset(Current->Children, 0, sizeof(struct Category));
42 Current->Children->Parent = Current;
43 Current = Current->Children;
44 }
45 else
46 {
47 Current->Next = malloc(sizeof(struct Category));
48 memset(Current->Next, 0, sizeof(struct Category));
49 Current->Next->Parent = Current->Parent;
50 Current = Current->Next;
51 }
52 TagOpen = TRUE;
53
54 for (i=0; arg[i]; i+=2)
55 {
56 if(!strcmp(arg[i], "name"))
57 {
58 MultiByteToWideChar(CP_UTF8, 0, arg[i+1], -1, Current->Name, 0x100);
59 }
60 if(!strcmp(arg[i], "icon"))
61 {
62 Current->Icon = atoi(arg[i+1]);
63 }
64 }
65 }
66
67 else if(!strcmp(tag, "application") && !CurrentApplication)
68 {
69 if(Current->Apps)
70 {
71 CurrentApplication = Current->Apps;
72 while(CurrentApplication->Next)
73 CurrentApplication = CurrentApplication->Next;
74 CurrentApplication->Next = malloc(sizeof(struct Application));
75 memset(CurrentApplication->Next, 0, sizeof(struct Application));
76 CurrentApplication = CurrentApplication->Next;
77 }
78 else
79 {
80 Current->Apps = malloc(sizeof(struct Application));
81 memset(Current->Apps, 0, sizeof(struct Application));
82 CurrentApplication = Current->Apps;
83 }
84
85 for (i=0; arg[i]; i+=2)
86 {
87 if(!strcmp(arg[i], "name"))
88 {
89 MultiByteToWideChar(CP_UTF8, 0, arg[i+1], -1, CurrentApplication->Name, 0x100);
90 }
91 }
92 }
93 else if (CurrentApplication)
94 {
95 strncpy(CurrentTag, tag, 0x100);
96 }
97 else
98 MessageBoxW(0,Strings[IDS_XMLERROR_2],0,0);
99 }
100
101
102 void text (void* usrdata, const char* data, int len)
103 {
104 if (!CurrentApplication)
105 return;
106
107 if(!strcmp(CurrentTag, "maintainer"))
108 {
109 int currentlengt = lstrlenW(CurrentApplication->Maintainer);
110 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Maintainer[currentlengt], 0x100-currentlengt);
111 }
112 else if(!strcmp(CurrentTag, "regname"))
113 {
114 int currentlengt = lstrlenW(CurrentApplication->RegName);
115 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->RegName[currentlengt], 0x100-currentlengt);
116 }
117 else if(!strcmp(CurrentTag, "description"))
118 {
119 int currentlengt = lstrlenW(CurrentApplication->Description);
120 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Description[currentlengt], 0x400-currentlengt);
121 }
122 else if(!strcmp(CurrentTag, "location"))
123 {
124 int currentlengt = lstrlenW(CurrentApplication->Location);
125 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Location[currentlengt], 0x100-currentlengt);
126 }
127 else if(!strcmp(CurrentTag, "version"))
128 {
129 int currentlengt = lstrlenW(CurrentApplication->Version);
130 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Version[currentlengt], 0x400-currentlengt);
131 }
132 else if(!strcmp(CurrentTag, "licence"))
133 {
134 int currentlengt = lstrlenW(CurrentApplication->Licence);
135 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Licence[currentlengt], 0x100-currentlengt);
136 }
137 else if(!strcmp(CurrentTag, "depends"))
138 {
139 int currentlengt = lstrlenW(CurrentApplication->Depends);
140 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->Depends[currentlengt], 0x100-currentlengt);
141 }
142 else if(!strcmp(CurrentTag, "postinstallaction"))
143 {
144 int currentlengt = lstrlenW(CurrentApplication->PostInstallAction);
145 MultiByteToWideChar(CP_UTF8, 0, data, len, &CurrentApplication->PostInstallAction[currentlengt], 0x100-currentlengt);
146 }
147 }
148
149 void tag_closed (void* tree, const char* tag)
150 {
151 CurrentTag[0] = 0;
152
153 if(!strcmp(tag, "category"))
154 {
155 if (TagOpen)
156 {
157 TagOpen = FALSE;
158 }
159 else
160 {
161 Current = Current->Parent;
162 }
163 }
164 else if(!strcmp(tag, "application"))
165 {
166 CurrentApplication = NULL;
167 }
168 }
169
170 BOOL ProcessXML (const char* filename, struct Category* Root)
171 {
172 int done = 0;
173 char buffer[255];
174 FILE* file;
175 XML_Parser parser;
176
177 if(Current)
178 return FALSE;
179
180 Current = Root;
181 TagOpen = TRUE;
182
183 file = fopen("downloader.xml", "r");
184 if(!file)
185 {
186 file = fopen(filename, "r");
187 if(!file)
188 {
189 MessageBoxW(0,Strings[IDS_XMLERROR_1],0,0);
190 return FALSE;
191 }
192 }
193
194 parser = XML_ParserCreate(NULL);
195 XML_SetElementHandler(parser, tag_opened, tag_closed);
196 XML_SetCharacterDataHandler(parser, text);
197
198 while (!done)
199 {
200 size_t len = fread (buffer, 1, sizeof(buffer), file);
201 done = len < sizeof(buffer);
202
203 if(!XML_Parse(parser, buffer, len, done))
204 {
205 MessageBoxW(0,Strings[IDS_XMLERROR_2],0,0);
206 fclose(file);
207 return FALSE;
208 }
209 }
210
211 XML_ParserFree(parser);
212 fclose(file);
213
214 return TRUE;
215 }
216
217 void FreeApps (struct Application* Apps)
218 {
219 if (Apps->Next)
220 FreeApps(Apps->Next);
221
222 free(Apps);
223 }
224
225 void FreeTree (struct Category* Node)
226 {
227 if (Node->Children)
228 FreeTree(Node->Children);
229
230 if (Node->Next)
231 FreeTree(Node->Next);
232
233 if (Node->Apps)
234 FreeApps(Node->Apps);
235
236 free(Node);
237 }