00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include <sys/types.h>
00039
00040 #include <assert.h>
00041 #include <limits.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044
00045 #include <expat.h>
00046
00047 #include <discover.h>
00048 #include <discover-xml.h>
00049
00050 #include "load-url.h"
00051 #include "utils.h"
00052
00054 struct discover_xml_busclass {
00055 char *id;
00056 char *name;
00057 discover_xml_busclass_t *next;
00058 };
00059
00060 static discover_xml_busclass_t *busclasses[BUS_COUNT];
00061
00062 struct context {
00063 discover_xml_busclass_t **blist;
00064
00065 int unknown_level;
00066 };
00067
00068 static char *known_bus_elements[] = {
00069 "busclass",
00070 "busclass_list",
00071 NULL
00072 };
00073
00074 static bool
00075 unknown_bus_element(const XML_Char * const tag)
00076 {
00077 int i;
00078 for (i = 0; known_bus_elements[i] != NULL; i++) {
00079 if (strcmp(tag, known_bus_elements[i]) == 0)
00080 return false;
00081 }
00082 return true;
00083 }
00084
00085 static void
00086 start_element(void *ctx, const XML_Char *name, const XML_Char *attrs[])
00087 {
00088 struct context *context = ctx;
00089 int i;
00090 char *vid, *vname;
00091 discover_xml_busclass_t *next, **blist;
00092
00093 assert(context != NULL);
00094 assert(name != NULL);
00095 assert(attrs != NULL);
00096
00097 if (unknown_bus_element(name)) {
00098 context->unknown_level++;
00099 return;
00100 }
00101
00102 if (context->unknown_level > 0) {
00103 return;
00104 }
00105
00106 if (strcmp(name, "busclass") == 0) {
00107 vid = vname = NULL;
00108 for (i = 0; attrs[i]; i += 2) {
00109 if (strcmp(attrs[i], "id") == 0) {
00110 vid = (char *) attrs[i + 1];
00111 } else if (strcmp(attrs[i], "name") == 0) {
00112 vname = (char *) attrs[i + 1];
00113 }
00114 }
00115
00116 assert(vid != NULL);
00117 assert(vname != NULL);
00118
00119 blist = context->blist;
00120 next = *blist;
00121 *blist = discover_xml_busclass_new();
00122 (*blist)->id = _discover_xstrdup(vid);
00123 (*blist)->name = _discover_xstrdup(vname);
00124 (*blist)->next = next;
00125 }
00126 }
00127
00128 static void
00129 end_element(void *ctx, const XML_Char *name)
00130 {
00131 struct context *context = ctx;
00132
00133 assert(context != NULL);
00134 assert(name != NULL);
00135
00136 if (unknown_bus_element(name)) {
00137 context->unknown_level--;
00138 return;
00139 }
00140
00141 if (context->unknown_level > 0) {
00142 return;
00143 }
00144
00145
00146
00147
00148
00149 }
00150
00151
00164
00165
00166
00167
00168
00169
00170 void
00171 discover_xml_merge_busclass_url(discover_xml_busclass_t **blist,
00172 char *url, discover_error_t *status)
00173 {
00174 XML_Parser parser;
00175 struct context context;
00176
00177 assert(url != NULL);
00178 assert(status != NULL);
00179
00180 status->code = 0;
00181
00182 context.blist = blist;
00183 context.unknown_level = 0;
00184
00185 parser = XML_ParserCreate(NULL);
00186 XML_SetElementHandler(parser, start_element, end_element);
00187 XML_SetUserData(parser, &context);
00188
00189 if (!_discover_load_url(url, parser)) {
00190 XML_ParserFree(parser);
00191 status->code = DISCOVER_EIO;
00192 return;
00193 }
00194
00195 if (!XML_Parse(parser, "", 0, 1)) {
00196 XML_ParserFree(parser);
00197 status->code = DISCOVER_EXML;
00198 return;
00199 }
00200
00201 XML_ParserFree(parser);
00202
00203 return;
00204 }
00205
00212 discover_xml_busclass_t *
00213 discover_xml_get_busclasses(discover_bus_t bus, discover_error_t *status)
00214 {
00215 discover_xml_url_t *urls, *i;
00216 char *url;
00217
00218 assert(status != NULL);
00219
00220 status->code = 0;
00221
00222 if (!busclasses[bus]) {
00223 urls = discover_xml_get_data_urls(bus, BUSCLASS_TYPE, status);
00224 if (status->code != 0) {
00225 return NULL;
00226 }
00227
00228 for (i = urls;
00229 i;
00230 i = discover_xml_url_get_next(i)) {
00231 url = discover_xml_url_get_url(i);
00232 discover_xml_merge_busclass_url(&(busclasses[bus]), url, status);
00233 if (status->code != 0) {
00234 return NULL;
00235 }
00236 }
00237 }
00238
00239 return busclasses[bus];
00240 }
00241
00242
00246 void
00247 discover_xml_free_busclasses(void)
00248 {
00249 int i;
00250 for (i = 0; i < BUS_COUNT; i++) {
00251 discover_xml_busclass_free(busclasses[i]);
00252 busclasses[i] = NULL;
00253 }
00254 }
00255
00262 char *
00263 discover_xml_busclass_to_class(char *busclass,
00264 discover_xml_busclass_t *busclasses)
00265 {
00266 char *result;
00267
00268 assert(busclass != NULL);
00269 assert(busclasses != NULL);
00270
00271 result = NULL;
00272
00273 for (;
00274 busclasses;
00275 busclasses = busclasses->next) {
00276 if (strcmp(busclass, busclasses->id) == 0) {
00277 result = busclasses->name;
00278 break;
00279 }
00280 }
00281
00282 return result;
00283 }
00284
00294 int
00295 discover_xml_busclass_cmp(char *busclass, char *discover_class,
00296 discover_xml_busclass_t *busclasses)
00297 {
00298 assert(busclass != NULL);
00299 assert(discover_class != NULL);
00300 assert(busclasses != NULL);
00301
00302 if (strcmp(discover_class, "all") == 0) {
00303 return 0;
00304 }
00305
00306 return strcmp(discover_xml_busclass_to_class(busclass, busclasses),
00307 discover_class);
00308 }
00309
00315 char *
00316 discover_xml_busclass_get_id(discover_xml_busclass_t *busclass)
00317 {
00318 assert(busclass != NULL);
00319
00320 return busclass->id;
00321 }
00322
00328 char *
00329 discover_xml_busclass_get_name(discover_xml_busclass_t *busclass)
00330 {
00331 assert(busclass != NULL);
00332
00333 return busclass->name;
00334 }
00335
00340 discover_xml_busclass_t *
00341 discover_xml_busclass_get_next(discover_xml_busclass_t *busclass)
00342 {
00343 assert(busclass != NULL);
00344
00345 return busclass->next;
00346 }
00347
00351 discover_xml_busclass_t *
00352 discover_xml_busclass_new(void)
00353 {
00354 discover_xml_busclass_t *new;
00355
00356 new = _discover_xmalloc(sizeof(discover_xml_busclass_t));
00357
00358 new->id = NULL;
00359 new->name = NULL;
00360 new->next = NULL;
00361
00362 return new;
00363 }
00364
00370 void
00371 discover_xml_busclass_free(discover_xml_busclass_t *busclasses)
00372 {
00373 discover_xml_busclass_t *busclass, *last;
00374
00375 last = NULL;
00376
00377 for (busclass = busclasses;
00378 busclass;
00379 busclass = busclass->next) {
00380 if (busclass->id) {
00381 free(busclass->id);
00382 }
00383
00384 if (busclass->name) {
00385 free(busclass->name);
00386 }
00387
00388 if (last) {
00389 free(last);
00390 }
00391 last = busclass;
00392 }
00393
00394 if (last) {
00395 free(last);
00396 }
00397 }
00398
00401
00402
00403
00404
00405
00406
00407