/* * Fetches and parses the UPNP response */ bool MediaServer::_fetchContents( Container* p_parent ) { if (!p_parent) { msg_Err( _p_sd, "No parent" ); return false; } IXML_Document* p_response = _browseAction( p_parent->getObjectID(), "BrowseDirectChildren", "*", "0", "0", "" ); if ( !p_response ) { msg_Err( _p_sd, "No response from browse() action" ); return false; } IXML_Document* p_result = parseBrowseResult( p_response ); ixmlDocument_free( p_response ); if ( !p_result ) { msg_Err( _p_sd, "browse() response parsing failed" ); return false; } #ifndef NDEBUG else { msg_Dbg( _p_sd, "Got DIDL document: %s", ixmlPrintDocument( p_result ) ); } #endif IXML_NodeList* containerNodeList = ixmlDocument_getElementsByTagName( p_result, "container" ); if ( containerNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( containerNodeList ); i++ ) { IXML_Element* containerElement = ( IXML_Element* )ixmlNodeList_item( containerNodeList, i ); const char* objectID = ixmlElement_getAttribute( containerElement, "id" ); if ( !objectID ) continue; const char* title = xml_getChildElementValue( containerElement, "dc:title" ); if ( !title ) continue; Container* container = new Container( p_parent, objectID, title ); p_parent->addContainer( container ); _fetchContents( container ); } ixmlNodeList_free( containerNodeList ); } IXML_NodeList* itemNodeList = ixmlDocument_getElementsByTagName( p_result, "item" ); if ( itemNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( itemNodeList ); i++ ) { IXML_Element* itemElement = ( IXML_Element* )ixmlNodeList_item( itemNodeList, i ); const char* objectID = ixmlElement_getAttribute( itemElement, "id" ); if ( !objectID ) continue; const char* title = xml_getChildElementValue( itemElement, "dc:title" ); if ( !title ) continue; const char* resource = xml_getChildElementValue( itemElement, "res" ); if ( !resource ) continue; const char* psz_duration = xml_getChildElementAttributeValue( itemElement, "res", "duration" ); mtime_t i_duration = -1; int i_hours, i_minutes, i_seconds, i_decis; if ( psz_duration ) { if( sscanf( psz_duration, "%02d:%02d:%02d.%d", &i_hours, &i_minutes, &i_seconds, &i_decis )) i_duration = INT64_C(1000000) * ( i_hours*3600 + i_minutes*60 + i_seconds ) + INT64_C(100000) * i_decis; } Item* item = new Item( p_parent, objectID, title, resource, i_duration ); p_parent->addItem( item ); } ixmlNodeList_free( itemNodeList ); } ixmlDocument_free( p_result ); return true; }
/* * Fetches and parses the UPNP response */ bool MediaServer::_fetchContents( Container* p_parent, int i_offset ) { if (!p_parent) { msg_Err( _p_sd, "No parent" ); return false; } char* psz_starting_index; if( asprintf( &psz_starting_index, "%d", i_offset ) < 0 ) { msg_Err( _p_sd, "asprintf error:%d", i_offset ); return false; } IXML_Document* p_response = _browseAction( p_parent->getObjectID(), "BrowseDirectChildren", "*", /* Filter */ psz_starting_index, /* StartingIndex */ "0", /* RequestedCount */ "" /* SortCriteria */ ); free( psz_starting_index ); if ( !p_response ) { msg_Err( _p_sd, "No response from browse() action" ); return false; } IXML_Document* p_result = parseBrowseResult( p_response ); int i_number_returned = xml_getNumber( p_response, "NumberReturned" ); int i_total_matches = xml_getNumber( p_response , "TotalMatches" ); #ifndef NDEBUG msg_Dbg( _p_sd, "i_offset[%d]i_number_returned[%d]_total_matches[%d]\n", i_offset, i_number_returned, i_total_matches ); #endif ixmlDocument_free( p_response ); if ( !p_result ) { msg_Err( _p_sd, "browse() response parsing failed" ); return false; } #ifndef NDEBUG msg_Dbg( _p_sd, "Got DIDL document: %s", ixmlPrintDocument( p_result ) ); #endif IXML_NodeList* containerNodeList = ixmlDocument_getElementsByTagName( p_result, "container" ); if ( containerNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( containerNodeList ); i++ ) { IXML_Element* containerElement = ( IXML_Element* )ixmlNodeList_item( containerNodeList, i ); const char* objectID = ixmlElement_getAttribute( containerElement, "id" ); if ( !objectID ) continue; const char* title = xml_getChildElementValue( containerElement, "dc:title" ); if ( !title ) continue; Container* container = new Container( p_parent, objectID, title ); p_parent->addContainer( container ); _fetchContents( container, 0 ); } ixmlNodeList_free( containerNodeList ); } IXML_NodeList* itemNodeList = ixmlDocument_getElementsByTagName( p_result, "item" ); if ( itemNodeList ) { for ( unsigned int i = 0; i < ixmlNodeList_length( itemNodeList ); i++ ) { IXML_Element* itemElement = ( IXML_Element* )ixmlNodeList_item( itemNodeList, i ); const char* objectID = ixmlElement_getAttribute( itemElement, "id" ); if ( !objectID ) continue; const char* title = xml_getChildElementValue( itemElement, "dc:title" ); if ( !title ) continue; const char* resource = xml_getChildElementValue( itemElement, "res" ); if ( !resource ) continue; const char* psz_duration = xml_getChildElementAttributeValue( itemElement, "res", "duration" ); mtime_t i_duration = -1; int i_hours, i_minutes, i_seconds, i_decis; if ( psz_duration ) { if( sscanf( psz_duration, "%02d:%02d:%02d.%d", &i_hours, &i_minutes, &i_seconds, &i_decis )) i_duration = INT64_C(1000000) * ( i_hours*3600 + i_minutes*60 + i_seconds ) + INT64_C(100000) * i_decis; } Item* item = new Item( p_parent, objectID, title, resource, i_duration ); p_parent->addItem( item ); } ixmlNodeList_free( itemNodeList ); } ixmlDocument_free( p_result ); if( i_offset + i_number_returned < i_total_matches ) return _fetchContents( p_parent, i_offset + i_number_returned ); return true; }