예제 #1
0
파일: xplist.c 프로젝트: EchoLiao/libplist
void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist)
{
    xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length);
    xmlNodePtr root_node = xmlDocGetRootElement(plist_doc);

    xml_to_node(root_node, plist);
    xmlFreeDoc(plist_doc);
}
예제 #2
0
파일: xplist.c 프로젝트: EchoLiao/libplist
static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
{
    xmlNodePtr node = NULL;
    plist_data_t data = NULL;
    plist_t subnode = NULL;

    //for string
    long len = 0;
    int type = 0;

    if (!xml_node)
        return;

    for (node = xml_node->children; node; node = node->next)
    {

        while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
            node = node->next;
        if (!node)
            break;

        if (!xmlStrcmp(node->name, BAD_CAST("comment"))) {
            continue;
        }

        data = plist_new_plist_data();
        subnode = plist_new_node(data);
        if (*plist_node)
            node_attach(*plist_node, subnode);
        else
            *plist_node = subnode;

        if (!xmlStrcmp(node->name, XPLIST_TRUE))
        {
            data->boolval = TRUE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_FALSE))
        {
            data->boolval = FALSE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_INT))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            int is_negative = 0;
            char *str = (char*)strval;
            if ((str[0] == '-') || (str[0] == '+')) {
                if (str[0] == '-') {
                    is_negative = 1;
                }
                str++;
            }
            char* endp = NULL;
            data->intval = strtoull((char*)str, &endp, 0);
            if ((endp != NULL) && (strlen(endp) > 0)) {
                fprintf(stderr, "%s: integer parse error: string contains invalid characters: '%s'\n", __func__, endp);
            }
            if (is_negative || (data->intval <= INT64_MAX)) {
                int64_t v = data->intval;
                if (is_negative) {
                    v = -v;
                }
                data->intval = (uint64_t)v;
                data->length = 8;
            } else {
                data->length = 16;
            }
            data->type = PLIST_UINT;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_REAL))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            data->realval = atof((char *) strval);
            data->type = PLIST_REAL;
            data->length = 8;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATE))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            time_t timev = 0;
            if (strlen((const char*)strval) >= 11) {
                struct tm btime;
                struct tm* tm_utc;
                parse_date((const char*)strval, &btime);
                timev = mktime(&btime);
                tm_utc = gmtime(&timev);
                timev -= (mktime(tm_utc) - timev);
            }
            data->timeval.tv_sec = (long)(timev - MAC_EPOCH);
            data->timeval.tv_usec = 0;
            data->type = PLIST_DATE;
            data->length = sizeof(struct timeval);
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_STRING))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            len = strlen((char *) strval);
            type = xmlDetectCharEncoding(strval, len);

            if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                data->strval = strdup((char *) strval);
                data->type = PLIST_STRING;
                data->length = strlen(data->strval);
            }
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_KEY))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            len = strlen((char *) strval);
            type = xmlDetectCharEncoding(strval, len);

            if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                data->strval = strdup((char *) strval);
                data->type = PLIST_KEY;
                data->length = strlen(data->strval);
            }
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATA))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            size_t size = 0;
            unsigned char *dec = base64decode((char*)strval, &size);
            data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
            memcpy(data->buff, dec, size * sizeof(uint8_t));
            free(dec);
            data->length = size;
            data->type = PLIST_DATA;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_ARRAY))
        {
            data->type = PLIST_ARRAY;
            xml_to_node(node, &subnode);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DICT))
        {
            data->type = PLIST_DICT;
            xml_to_node(node, &subnode);
            if (plist_get_node_type(subnode) == PLIST_DICT) {
                if (plist_dict_get_size(subnode) == 1) {
                    plist_t uid = plist_dict_get_item(subnode, "CF$UID");
                    if (uid) {
                        uint64_t val = 0;
                        plist_get_uint_val(uid, &val);
                        plist_dict_remove_item(subnode, "CF$UID");
                        plist_data_t nodedata = plist_get_data((node_t*)subnode);
                        free(nodedata->buff);
                        nodedata->type = PLIST_UID;
                        nodedata->length = sizeof(uint64_t);
                        nodedata->intval = val;
                    } 
                }
            }
            continue;
        }
    }
}
예제 #3
0
파일: xplist.c 프로젝트: Clstroud/libplist
static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
{
    xmlNodePtr node = NULL;
    plist_data_t data = NULL;
    plist_t subnode = NULL;

    //for string
    long len = 0;
    int type = 0;

    if (!xml_node)
        return;

    for (node = xml_node->children; node; node = node->next)
    {

        while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
            node = node->next;
        if (!node)
            break;

        if (!xmlStrcmp(node->name, BAD_CAST("comment"))) {
            continue;
        }

        data = plist_new_plist_data();
        subnode = plist_new_node(data);
        if (*plist_node)
            node_attach(*plist_node, subnode);
        else
            *plist_node = subnode;

        if (!xmlStrcmp(node->name, XPLIST_TRUE))
        {
            data->boolval = TRUE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_FALSE))
        {
            data->boolval = FALSE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_INT))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            data->intval = strtoull((char*)strval, NULL, 0);
            data->type = PLIST_UINT;
            data->length = 8;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_REAL))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            data->realval = atof((char *) strval);
            data->type = PLIST_REAL;
            data->length = 8;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATE))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            time_t time = 0;
            if (strlen((const char*)strval) >= 11) {
                struct tm btime;
                parse_date((const char*)strval, &btime);
                time = mktime(&btime);
            }
            data->timeval.tv_sec = (long)time;
            data->timeval.tv_usec = 0;
            data->type = PLIST_DATE;
            data->length = sizeof(struct timeval);
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_STRING))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            len = strlen((char *) strval);
            type = xmlDetectCharEncoding(strval, len);

            if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                data->strval = strdup((char *) strval);
                data->type = PLIST_STRING;
                data->length = strlen(data->strval);
            }
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_KEY))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            data->strval = strdup((char *) strval);
            data->type = PLIST_KEY;
            data->length = strlen(data->strval);
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATA))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            size_t size = 0;
            unsigned char *dec = base64decode((char*)strval, &size);
            data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
            memcpy(data->buff, dec, size * sizeof(uint8_t));
            free(dec);
            data->length = size;
            data->type = PLIST_DATA;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_ARRAY))
        {
            data->type = PLIST_ARRAY;
            xml_to_node(node, &subnode);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DICT))
        {
            data->type = PLIST_DICT;
            xml_to_node(node, &subnode);
            if (plist_get_node_type(subnode) == PLIST_DICT) {
                if (plist_dict_get_size(subnode) == 1) {
                    plist_t uid = plist_dict_get_item(subnode, "CF$UID");
                    if (uid) {
                        uint64_t val = 0;
                        plist_get_uint_val(uid, &val);
                        plist_dict_remove_item(subnode, "CF$UID");
                        plist_data_t nodedata = plist_get_data((node_t*)subnode);
                        free(nodedata->buff);
                        nodedata->type = PLIST_UID;
                        nodedata->length = sizeof(uint64_t);
                        nodedata->intval = val;
                    } 
                }
            }
            continue;
        }
    }
}