static double xpath_get_double(xmlXPathContextPtr ctx, const char *xpath) { char *str; char *endptr; double ret; str = xpath_get_str(ctx, xpath); if (str == NULL) { return 0; } ret = g_ascii_strtod(str, &endptr); g_assert(*str != 0 && *endptr == 0); g_free(str); return ret; }
/* Returns 0 if the node is not found. */ static uint64_t xpath_get_uint(xmlXPathContextPtr ctx, const char *xpath) { char *str; char *endptr; uint64_t ret; str = xpath_get_str(ctx, xpath); if (str == NULL) { return 0; } ret = g_ascii_strtoull(str, &endptr, 10); /* Assert if invalid number, since schema validation should have caught this */ g_assert(*str != 0 && *endptr == 0); g_free(str); return ret; }
static bool image_add(GHashTable *images, xmlDocPtr args, xmlNodePtr image_args, GError **err) { struct vmnetfs_image *img; xmlXPathContextPtr ctx; xmlXPathObjectPtr obj; xmlChar *content; int i; ctx = make_xpath_context(args); ctx->node = image_args; img = g_slice_new0(struct vmnetfs_image); img->url = xpath_get_str(ctx, "v:origin/v:url/text()"); img->username = xpath_get_str(ctx, "v:origin/v:credentials/v:username/text()"); img->password = xpath_get_str(ctx, "v:origin/v:credentials/v:password/text()"); img->read_base = xpath_get_str(ctx, "v:cache/v:path/text()"); img->fetch_offset = xpath_get_uint(ctx, "v:origin/v:offset/text()"); img->initial_size = xpath_get_uint(ctx, "v:size/text()"); img->chunk_size = xpath_get_uint(ctx, "v:cache/v:chunk-size/text()"); img->etag = xpath_get_str(ctx, "v:origin/v:validators/v:etag/text()"); img->last_modified = xpath_get_uint(ctx, "v:origin/v:validators/v:last-modified/text()"); obj = xmlXPathEval(BAD_CAST "v:origin/v:cookies/v:cookie/text()", ctx); for (i = 0; obj && obj->nodesetval && i < obj->nodesetval->nodeNr; i++) { content = xmlNodeGetContent(obj->nodesetval->nodeTab[i]); img->cookies = g_list_prepend(img->cookies, g_strdup((const char *) content)); xmlFree(content); } xmlXPathFreeObject(obj); img->io_stream = _vmnetfs_stream_group_new(NULL, NULL); img->bytes_read = _vmnetfs_stat_new(); img->bytes_written = _vmnetfs_stat_new(); img->chunk_fetches = _vmnetfs_stat_new(); img->chunk_dirties = _vmnetfs_stat_new(); img->io_errors = _vmnetfs_stat_new(); if (!_vmnetfs_io_init(img, err)) { _image_free(img); xmlXPathFreeContext(ctx); return false; } g_hash_table_insert(images, xpath_get_str(ctx, "v:name/text()"), img); xmlXPathFreeContext(ctx); return true; }