virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
                          xmlNodePtr node,
                          xmlXPathContextPtr ctxt,
                          unsigned int flags)
{
    virDomainSoundDefPtr def;
    VIR_XPATH_NODE_AUTORESTORE(ctxt);
    g_autofree char *model = NULL;

    if (VIR_ALLOC(def) < 0)
        return NULL;

    ctxt->node = node;

    model = virXMLPropString(node, "model");
    if ((def->model = virDomainSoundModelTypeFromString(model)) < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown sound model '%s'"), model);
        goto error;
    }

    if (def->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
        def->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
        int ncodecs;
        g_autofree xmlNodePtr *codecNodes = NULL;

        /* parse the <codec> subelements for sound models that support it */
        ncodecs = virXPathNodeSet("./codec", ctxt, &codecNodes);
        if (ncodecs < 0)
            goto error;

        if (ncodecs > 0) {
            size_t i;

            if (VIR_ALLOC_N(def->codecs, ncodecs) < 0)
                goto error;

            for (i = 0; i < ncodecs; i++) {
                virDomainSoundCodecDefPtr codec = virDomainSoundCodecDefParseXML(codecNodes[i]);
                if (codec == NULL)
                    goto error;

                codec->cad = def->ncodecs; /* that will do for now */
                def->codecs[def->ncodecs++] = codec;
            }
        }
    }

    if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0)
        goto error;

    return def;

 error:
    virDomainSoundDefFree(def);
    return NULL;
}
virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
                          xmlNodePtr node,
                          xmlXPathContextPtr ctxt,
                          unsigned int flags)
{
    virDomainSoundDefPtr def;
    VIR_XPATH_NODE_AUTORESTORE(ctxt);
    g_autofree char *model = NULL;

    if (VIR_ALLOC(def) < 0)
        return NULL;

    ctxt->node = node;

    model = virXMLPropString(node, "model");
    if ((def->model = virDomainSoundModelTypeFromString(model)) < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown sound model '%s'"), model);
        goto error;
    }

    if (def->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
        def->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
        int ncodecs;
        g_autofree xmlNodePtr *codecNodes = NULL;

         
        ncodecs = virXPathNodeSet("./codec", ctxt, &codecNodes);
        if (ncodecs < 0)
            goto error;

        if (ncodecs > 0) {
            size_t i;

            if (VIR_ALLOC_N(def->codecs, ncodecs) < 0)
                goto error;

            for (i = 0; i < ncodecs; i++) {
                virDomainSoundCodecDefPtr codec = virDomainSoundCodecDefParseXML(codecNodes[i]);
                if (codec == NULL)
                    goto error;

                codec->cad = def->ncodecs;  
                def->codecs[def->ncodecs++] = codec;
            }
        }
    }

    if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0)
        goto error;

    return def;

 error:
    virDomainSoundDefFree(def);
    return NULL;
}