⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xen_common.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
{    int result = 0;    xmlNode *cur = n->children;    while (cur != NULL)    {        if (0 == strcmp((char *)cur->name, name))        {            result++;        }        cur = cur->next;    }    return result;}static void destring(xen_session *s, xmlChar *name, const abstract_type *type,                     void *value){    switch (type->typename)    {    case STRING:        *((char **)value) = xen_strdup_((const char *)name);        break;    case INT:        *((int64_t *)value) = atoll((const char *)name);        break;    case FLOAT:        *((double *)value) = atof((const char *)name);        break;    default:        server_error(s, "Invalid Map key type");    }}/** * result_type : STRING   => value : char **, the char * is yours. * result_type : ENUM     => value : int * * result_type : INT      => value : int64_t * * result_type : FLOAT    => value : double * * result_type : BOOL     => value : bool * * result_type : DATETIME => value : time_t * * result_type : SET      => value : arbitrary_set **, the set is yours. * result_type : MAP      => value : arbitrary_map **, the map is yours. * result_type : OPT      => value : arbitrary_record_opt **, *                                   the record is yours, the handle is *                                   filled. * result_type : STRUCT   => value : void **, the void * is yours. */static void parse_into(xen_session *s, xmlNode *value_node,                       const abstract_type *result_type, void *value,                       int slot){    if (result_type == NULL)    {        xmlChar *string = string_from_value(value_node, "string");        if (string == NULL || strcmp((char *)string, ""))        {            server_error(s,                         "Expected Void from the server, but didn't get it");        }        else        {            free(string);        }        return;    }    switch (result_type->typename)    {    case STRING:    {        xmlChar *string = string_from_value(value_node, "string");        if (string == NULL)        {            server_error(                s, "Expected a String from the server, but didn't get one");        }        else        {            ((char **)value)[slot] = xen_strdup_((const char *)string);            free(string);        }    }    break;    case ENUM:    {        xmlChar *string = string_from_value(value_node, "string");        if (string == NULL)        {#if PERMISSIVE            fprintf(stderr,                    "Expected an Enum from the server, but didn't get one\n");            ((int *)value)[slot] = 0;#else            server_error(                s, "Expected an Enum from the server, but didn't get one");#endif        }        else        {            ((int *)value)[slot] =                result_type->enum_demarshaller(s, (const char *)string);            free(string);        }    }    break;    case INT:    {        xmlChar *string = string_from_value(value_node, "string");        if (string == NULL)        {            server_error(                s, "Expected an Int from the server, but didn't get one");        }        else        {            ((int64_t *)value)[slot] = (int64_t)atoll((char *)string);            free(string);        }    }    break;    case FLOAT:    {        xmlChar *string = string_from_value(value_node, "double");        if (string == NULL)        {#if PERMISSIVE            fprintf(stderr,                    "Expected a Float from the server, but didn't get one\n");            ((double *)value)[slot] = 0.0;#else            server_error(                s, "Expected a Float from the server, but didn't get one");#endif        }        else        {            ((double *)value)[slot] = atof((char *)string);            free(string);        }    }    break;    case BOOL:    {        xmlChar *string = string_from_value(value_node, "boolean");        if (string == NULL)        {#if PERMISSIVE            fprintf(stderr,                    "Expected a Bool from the server, but didn't get one\n");            ((bool *)value)[slot] = false;#else            server_error(                s, "Expected a Bool from the server, but didn't get one");#endif        }        else        {            ((bool *)value)[slot] = (0 == strcmp((char *)string, "1"));            free(string);        }    }    break;    case DATETIME:    {        xmlChar *string = string_from_value(value_node, "dateTime.iso8601");        if (string == NULL)        {            server_error(                s, "Expected an DateTime from the server but didn't get one");        }        else        {            struct tm tm;            memset(&tm, 0, sizeof(tm));            strptime((char *)string, "%Y%m%dT%H:%M:%S", &tm);            ((time_t *)value)[slot] = (time_t)mktime(&tm);            free(string);        }    }    break;    case SET:    {        if (!is_container_node(value_node, "value") ||            !is_container_node(value_node->children, "array"))        {            server_error(s,                         "Expected Set from the server, but didn't get it");        }        else        {            arbitrary_set *set;            xmlNode *cur, *data_node = value_node->children->children;            int i, n = count_children(data_node, "value");            const abstract_type *member_type = result_type->child;            size_t member_size = size_of_member(member_type);            set = calloc(1, sizeof(arbitrary_set) + member_size * n);            set->size = n;            i = 0;            cur = data_node->children;            while (cur != NULL)            {                if (0 == strcmp((char *)cur->name, "value"))                {                    parse_into(s, cur, member_type, set->contents, i);                    i++;                }                cur = cur->next;            }            ((arbitrary_set **)value)[slot] = set;        }    }    break;    case MAP:    {        if (!is_container_node(value_node, "value") ||            value_node->children->type != XML_ELEMENT_NODE ||            0 != strcmp((char *)value_node->children->name, "struct"))        {            server_error(s,                         "Expected Map from the server, but didn't get it");        }        else        {            arbitrary_map *map;            xmlNode *cur, *struct_node = value_node->children;            int i, n = count_children(struct_node, "member");            size_t struct_size = result_type->struct_size;            const struct struct_member *key_member = result_type->members;            const struct struct_member *val_member = result_type->members + 1;            map = calloc(1, sizeof(arbitrary_map) + struct_size * n);            map->size = n;            i = 0;            cur = struct_node->children;            while (cur != NULL)            {                if (0 == strcmp((char *)cur->name, "member"))                {                    xmlChar *name;                    if (cur->children == NULL || cur->last == cur->children)                    {                        server_error(s, "Malformed Map");                        free(map);                        return;                    }                    name = string_from_name(cur);                    if (name == NULL)                    {                        server_error(s, "Malformed Map");                        free(map);                        return;                    }                    destring(s, name, key_member->type,                             ((void *)(map + 1)) +                             (i * struct_size) +                             key_member->offset);                    xmlFree(name);                    if (!s->ok)                    {                        free(map);                        return;                    }                    parse_structmap_value(s, cur, val_member->type,                                          ((void *)(map + 1)) +                                          (i * struct_size) +                                          val_member->offset);                    if (!s->ok)                    {                        free(map);                        return;                    }                    i++;                }                cur = cur->next;            }            ((arbitrary_map **)value)[slot] = map;        }    }    break;    case STRUCT:    {        if (!is_container_node(value_node, "value") ||            value_node->children->type != XML_ELEMENT_NODE ||            0 != strcmp((char *)value_node->children->name, "struct") ||            value_node->children->children == NULL)        {            server_error(s,                         "Expected Map from the server, but didn't get it");        }        else        {            xmlNode *struct_node = value_node->children;            void *result = calloc(1, result_type->struct_size);            xmlNode *cur = struct_node->children;            size_t member_count = result_type->member_count;            const struct_member **checklist =                malloc(sizeof(const struct_member *) * member_count);            int seen_count = 0;            while (cur != NULL)            {                if (0 == strcmp((char *)cur->name, "member"))                {                    xmlChar *name;                    if (cur->children == NULL || cur->last == cur->children)                    {                        server_error(s, "Malformed Struct");                        free(result);                        free(checklist);                        return;                    }                    name = string_from_name(cur);                    if (name == NULL)                    {                        server_error(s, "Malformed Struct");                        free(result);                        free(checklist);                        return;                    }                    for (size_t i = 0; i < member_count; i++)                    {                        const struct_member *mem = result_type->members + i;                        if (0 == strcmp((char *)name, mem->key))                        {                            parse_structmap_value(s, cur, mem->type,                                                  result + mem->offset);                            checklist[seen_count] = mem;                            seen_count++;                            break;                        }                    }                    /* Note that we're skipping unknown fields implicitly.                       This means that we'll be forward compatible with                       new servers. */                    xmlFree(name);                    if (!s->ok)                    {                        free(result);                        free(checklist);                        return;                    }                }                cur = cur->next;            }            /* Check that we've filled all fields. */            for (size_t i = 0; i < member_count; i++)            {                const struct_member *mem = result_type->members + i;                int j;                for (j = 0; j < seen_count; j++)                {                    if (checklist[j] == mem)                    {                        break;                    }                }                if (j == seen_count)                {#if PERMISSIVE                    fprintf(stderr,                            "Struct did not contain expected field %s.\n",                            mem->key);#else                    server_error_2(s,                                   "Struct did not contain expected field",                                   mem->key);                    free(result);                    free(checklist);                    return;#endif                }            }            free(checklist);            ((void **)value)[slot] = result;        }    }    break;    case REF:    {        arbitrary_record_opt *record_opt =            calloc(1, sizeof(arbitrary_record_opt));        record_opt->is_record = false;        parse_into(s, value_node, &abstract_type_string,                   &(record_opt->u.handle), 0);        ((arbitrary_record_opt **)value)[slot] = record_opt;    }    break;    default:        assert(false);    }}static size_t size_of_member(const abstract_type *type){    switch (type->typename)    {    case STRING:        return sizeof(char *);/*    case INT:        return sizeof(int64_t);    case FLOAT:        return sizeof(double);    case BOOL:        return sizeof(bool);*/    case ENUM:        return sizeof(int);    case REF:        return sizeof(arbitrary_record_opt *);    case STRUCT:        return type->struct_size;    default:        assert(false);    }}static void parse_structmap_value(xen_session *s, xmlNode *n,                                  const abstract_type *type, void *value){    xmlNode *cur = n->children;    while (cur != NULL)    {        if (0 == strcmp((char *)cur->name, "value"))        {            parse_into(s, cur, type, value, 0);            return;        }        cur = cur->next;    }    server_error(s, "Missing value in Map/Struct");}static void parse_fault(xen_session *session, xmlXPathContextPtr xpathCtx){    xmlNode *fault_node0, *fault_node1;    xmlChar *fault_code_str, *fault_string_str;    char **strings;    xmlXPathObjectPtr xpathObj = xmlXPathCompiledEval(faultPath, xpathCtx);    if (xpathObj == NULL)    {        server_error(session, "Method response is neither result nor fault");        return;    }    if (xpathObj->type != XPATH_NODESET ||        xpathObj->nodesetval->nodeNr != 2)    {        xmlXPathFreeObject(xpathObj);        server_error(session, "Method response is neither result nor fault");        return;    }    fault_node0 = xpathObj->nodesetval->nodeTab[0];    fault_node1 = xpathObj->nodesetval->nodeTab[1];    fault_code_str = string_from_value(fault_node0, "int");    if (fault_code_str == NULL)    {        fault_code_str = string_from_value(fault_node0, "i4");    }    if (fault_code_str == NULL)    {        xmlXPathFreeObject(xpathObj);        server_error(session, "Fault code is malformed");        return;    }    fault_string_str = string_from_value(fault_node1, "string");    if (fault_string_str == NULL)    {        xmlFree(fault_code_str);        xmlXPathFreeObject(xpathObj);        server_error(session, "Fault string is malformed");        return;    }    strings = malloc(3 * sizeof(char *));    strings[0] = xen_strdup_("FAULT");    strings[1] = xen_strdup_((char *)fault_code_str);    strings[2] = xen_strdup_((char *)fault_string_str);    session->ok = false;    session->error_description = strings;    session->error_description_count = 3;    xmlFree(fault_code_str);    xmlFree(fault_string_str);    xmlXPathFreeObject(xpathObj);}static void parse_failure(xen_session *session, xmlNode *node){    abstract_type error_description_type =        { .typename = SET,          .child = &abstract_type_string };    arbitrary_set *error_descriptions;    parse_into(session, node, &error_description_type, &error_descriptions,               0);    if (session->ok)    {        char **c, **strings;        int n;        session->ok = false;        c = (char **)error_descriptions->contents;        n = error_descriptions->size;        strings = malloc(n * sizeof(char *));        for (int i = 0; i < n; i++)        {            strings[i] = c[i];        }        session->error_description_count = n;        session->error_description = strings;    }    free(error_descriptions);}/** * Parameters as for xen_call_() above. */static void parse_result(xen_session *session, const char *result,                         const abstract_type *result_type, void *value){    xmlDocPtr doc =        xmlReadMemory(result, strlen(result), "", NULL, XML_PARSE_NONET);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -