Ejemplo n.º 1
0
/*----------------------------------------------------------------------
|   PLT_MediaServer::ParseTagList
+---------------------------------------------------------------------*/
NPT_Result
PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags)
{
    // reset output params first
    tags.Clear();

    NPT_List<NPT_String> split = updates.Split(",");
    NPT_XmlNode*        node = NULL;
    NPT_XmlElementNode* didl_partial = NULL;
    NPT_XmlParser       parser;

    // as these are single name value pairs, separated by commas we wrap in a tag
    // to create a valid tree
    NPT_String xml("<TagValueList>");
    for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) {
        NPT_String& element = (*entry);
        if (element.IsEmpty())
           xml.Append("<empty>empty</empty>");
        else
           xml.Append(element);
    }
    xml.Append("</TagValueList>");

    NPT_LOG_FINE("Parsing TagList...");
    NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
    if (!node || !node->AsElementNode()) {
        NPT_LOG_SEVERE("Invalid node type");
        goto cleanup;
    }

    didl_partial = node->AsElementNode();
    if (didl_partial->GetTag().Compare("TagValueList", true)) {
        NPT_LOG_SEVERE("Invalid node tag");
        goto cleanup;
    }

    for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) {
        NPT_XmlElementNode* child = (*children)->AsElementNode();
        if (!child) continue;
        tags[child->GetTag()] = *child->GetText();
    }

    return NPT_SUCCESS;

cleanup:
    if (node) delete node;
    return NPT_FAILURE;
}
Ejemplo n.º 2
0
/*----------------------------------------------------------------------
|   CMediaCrawler::UpdateDidl
+---------------------------------------------------------------------*/
NPT_String
CMediaCrawler::UpdateDidl(const char* server_uuid, const NPT_String& didl, NPT_SocketInfo* info)
{
    NPT_String     new_didl;
    NPT_String     str;
    NPT_XmlNode*   node = NULL;
    NPT_XmlWriter  writer;
    NPT_OutputStreamReference stream(new NPT_StringOutputStream(&new_didl));

    NPT_LOG_FINE("Parsing Didl...");

    NPT_XmlElementNode* tree = NULL;
    NPT_XmlParser parser;
    if (NPT_FAILED(parser.Parse(didl, node)) || !node || !node->AsElementNode()) {
        goto cleanup;
    }

    tree = node->AsElementNode();

    NPT_LOG_FINE("Processing Didl xml...");
    if (tree->GetTag().Compare("DIDL-Lite", true)) {
        goto cleanup;
    }

    // iterate through children
    NPT_Result res;
    for (NPT_List<NPT_XmlNode*>::Iterator children = tree->GetChildren().GetFirstItem(); children; children++) {
        NPT_XmlElementNode* child = (*children)->AsElementNode();
        if (!child) continue;

        // object id remapping
        NPT_XmlAttribute* attribute_id;
        res = PLT_XmlHelper::GetAttribute(child, "id", attribute_id);
        if (NPT_SUCCEEDED(res) && attribute_id) {
            attribute_id->SetValue(FormatObjectId(server_uuid, attribute_id->GetValue()));
        }

        // parent ID remapping
        NPT_XmlAttribute* attribute_parent_id;
        res = PLT_XmlHelper::GetAttribute(child, "parentID", attribute_parent_id);
        if (NPT_SUCCEEDED(res)) {
            attribute_parent_id->SetValue(attribute_parent_id->GetValue().Compare("-1")?FormatObjectId(server_uuid, attribute_parent_id->GetValue()):"0");
        }

        // resources remapping
        NPT_Array<NPT_XmlElementNode*> res;
        PLT_XmlHelper::GetChildren(child, res, "res");
        if (res.GetItemCount() > 0) {
            for (unsigned int i=0; i<res.GetItemCount(); i++) {
                NPT_XmlElementNode* resource = res[i];
                NPT_XmlAttribute*   attribute_prot;
                const NPT_String*   url;
                if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(resource, "protocolInfo", attribute_prot)) && (url = resource->GetText())) {
                    // special case for Windows Media Connect
                    // When a browse is done on the same machine, WMC uses localhost 
                    // instead of the IP for all resources urls which means we cannot advertise that 
                    // since it would be useless for a remote device 
                    // so we try to replace it with the right IP address by looking at which interface we received the
                    // initial browse request on to make sure the remote device will be able to access the modified resource
                    // urls (in case the local PC has more than 1 NICs)

                    // replace the url
                    NPT_List<NPT_XmlNode*>& children = resource->GetChildren();
                    NPT_HttpUrl http_url(NPT_Uri::PercentDecode(*url));
                    if ((http_url.GetHost() == "localhost" || http_url.GetHost() == "127.0.0.1") && info) {
                        if (info->local_address.GetIpAddress().AsLong()) {
                            http_url.SetHost(info->local_address.GetIpAddress().ToString());

                            // replace text
                            children.Apply(NPT_ObjectDeleter<NPT_XmlNode>());
                            children.Clear();
                            resource->AddText(http_url.ToString());
                            url = resource->GetText();
                        }
                    }

                    CStreamHandler* handler = NULL;
                    NPT_Result res = NPT_ContainerFind(m_StreamHandlers, CStreamHandlerFinder(attribute_prot->GetValue(), *url), handler);
                    if (NPT_SUCCEEDED(res)) {
                        handler->ModifyResource(resource);
                    }
                }
            }
        }
    }

    // serialize modified node into new didl
    writer.Serialize(*node, *stream);
    delete node;
    return new_didl;

cleanup:
    delete node;
    return didl;
}