diff deps/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deps/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp	Mon Jul 06 08:06:28 2009 -0700
@@ -0,0 +1,316 @@
+/*****************************************************************
+|
+|   Platinum - Synchronous Media Browser
+|
+| Copyright (c) 2004-2008, Plutinosoft, LLC.
+| All rights reserved.
+| http://www.plutinosoft.com
+|
+| This program is free software; you can redistribute it and/or
+| modify it under the terms of the GNU General Public License
+| as published by the Free Software Foundation; either version 2
+| of the License, or (at your option) any later version.
+|
+| OEMs, ISVs, VARs and other distributors that combine and 
+| distribute commercially licensed software with Platinum software
+| and do not wish to distribute the source code for the commercially
+| licensed software under version 2, or (at your option) any later
+| version, of the GNU General Public License (the "GPL") must enter
+| into a commercial license agreement with Plutinosoft, LLC.
+| 
+| This program is distributed in the hope that it will be useful,
+| but WITHOUT ANY WARRANTY; without even the implied warranty of
+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+| GNU General Public License for more details.
+|
+| You should have received a copy of the GNU General Public License
+| along with this program; see the file LICENSE.txt. If not, write to
+| the Free Software Foundation, Inc., 
+| 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+| http://www.gnu.org/licenses/gpl-2.0.html
+|
+****************************************************************/
+
+/*----------------------------------------------------------------------
+|   includes
++---------------------------------------------------------------------*/
+#include "PltSyncMediaBrowser.h"
+
+NPT_SET_LOCAL_LOGGER("platinum.media.server.syncbrowser")
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::PLT_SyncMediaBrowser
++---------------------------------------------------------------------*/
+PLT_SyncMediaBrowser::PLT_SyncMediaBrowser(PLT_CtrlPointReference&            ctrlPoint,
+                                           bool                               use_cache /* = false */, 
+                                           PLT_MediaContainerChangesListener* listener /* = NULL */) :
+    PLT_MediaBrowser(ctrlPoint),
+    m_ContainerListener(listener),
+    m_UseCache(use_cache)
+{
+    SetDelegate(this);
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::~PLT_SyncMediaBrowser
++---------------------------------------------------------------------*/
+PLT_SyncMediaBrowser::~PLT_SyncMediaBrowser()
+{
+}
+
+/*  Blocks forever waiting for a response from a request
+ *  It is expected the request to succeed or to timeout and return an error eventually
+ */
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::WaitForResponse
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::WaitForResponse(NPT_SharedVariable& shared_var)
+{
+    return shared_var.WaitUntilEquals(1, 30000);
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::OnDeviceAdded
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::OnDeviceAdded(PLT_DeviceDataReference& device)
+{
+    NPT_String uuid = device->GetUUID();
+
+    // test if it's a media server
+    PLT_Service* service;
+    if (NPT_SUCCEEDED(device->FindServiceByType("urn:schemas-upnp-org:service:ContentDirectory:1", service))) {
+        NPT_AutoLock lock(m_MediaServers);
+        m_MediaServers.Put(uuid, device);
+    }
+    
+    return PLT_MediaBrowser::OnDeviceAdded(device);
+}
+    
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::OnDeviceRemoved
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::OnDeviceRemoved(PLT_DeviceDataReference& device)
+{
+    NPT_String uuid = device->GetUUID();
+
+    // Remove from our list of servers first if found
+    {
+        NPT_AutoLock lock(m_MediaServers);
+        m_MediaServers.Erase(uuid);
+    }
+
+    // clear cache for that device
+    if (m_UseCache) m_Cache.Clear(device.AsPointer()->GetUUID());
+    
+    return PLT_MediaBrowser::OnDeviceRemoved(device);
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::Find
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::Find(const char* ip, PLT_DeviceDataReference& device)
+{
+    NPT_AutoLock lock(m_MediaServers);
+    const NPT_List<PLT_DeviceMapEntry*>::Iterator it = 
+        m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByIp(ip));
+    if (it) {
+        device = (*it)->GetValue();
+        return NPT_SUCCESS;
+    }
+    return NPT_FAILURE;
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::OnBrowseResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnBrowseResult(NPT_Result               res, 
+                                     PLT_DeviceDataReference& device, 
+                                     PLT_BrowseInfo*          info, 
+                                     void*                    userdata)
+{
+    NPT_COMPILER_UNUSED(device);
+
+    if (!userdata) return;
+
+    PLT_BrowseDataReference* data = (PLT_BrowseDataReference*) userdata;
+    (*data)->res = res;
+    if (NPT_SUCCEEDED(res) && info) {
+        (*data)->info = *info;
+    }
+    (*data)->shared_var.SetValue(1);
+    delete data;
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::OnMSStateVariablesChanged
++---------------------------------------------------------------------*/
+void 
+PLT_SyncMediaBrowser::OnMSStateVariablesChanged(PLT_Service*                  service, 
+                                                NPT_List<PLT_StateVariable*>* vars)
+{
+    NPT_AutoLock lock(m_MediaServers);
+    
+    PLT_DeviceDataReference device;
+    const NPT_List<PLT_DeviceMapEntry*>::Iterator it = 
+        m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByUUID(service->GetDevice()->GetUUID()));
+    if (!it) return; // device with this service has gone away
+
+    device = (*it)->GetValue();
+    PLT_StateVariable* var = PLT_StateVariable::Find(*vars, "ContainerUpdateIDs");
+    if (var) {
+        // variable found, parse value
+        NPT_String value = var->GetValue();
+        NPT_String item_id, update_id;
+        int index;
+
+        while (value.GetLength()) {
+            // look for container id
+            index = value.Find(',');
+            if (index < 0) break;
+            item_id = value.Left(index);
+            value = value.SubString(index+1);
+
+            // look for update id
+            if (value.GetLength()) {
+                index = value.Find(',');
+                update_id = (index<0)?value:value.Left(index);
+                value = (index<0)?"":value.SubString(index+1);
+
+                // clear cache for that device
+                if (m_UseCache) m_Cache.Clear(device->GetUUID(), item_id);
+
+                // notify listener
+                if (m_ContainerListener) m_ContainerListener->OnContainerChanged(device, item_id, update_id);
+            }       
+        }
+    }        
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::BrowseSync
++---------------------------------------------------------------------*/
+NPT_Result 
+PLT_SyncMediaBrowser::BrowseSync(PLT_BrowseDataReference& browse_data,
+                                 PLT_DeviceDataReference& device, 
+                                 const char*              object_id, 
+                                 NPT_Int32                index, 
+                                 NPT_Int32                count,
+                                 bool                     browse_metadata,
+                                 const char*              filter, 
+                                 const char*              sort)
+{
+    NPT_Result res;
+
+    browse_data->shared_var.SetValue(0);
+
+    // send off the browse packet.  Note that this will
+    // not block.  There is a call to WaitForResponse in order
+    // to block until the response comes back.
+    res = PLT_MediaBrowser::Browse(device,
+        (const char*)object_id,
+        index,
+        count,
+        browse_metadata,
+        filter,
+        sort,
+        new PLT_BrowseDataReference(browse_data));		
+    NPT_CHECK_SEVERE(res);
+
+    return WaitForResponse(browse_data->shared_var);
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::BrowseSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::BrowseSync(PLT_DeviceDataReference&      device, 
+                                 const char*                   object_id, 
+                                 PLT_MediaObjectListReference& list)
+{
+    NPT_Result res = NPT_FAILURE;
+    NPT_Int32  index = 0;
+
+    // reset output params
+    list = NULL;
+
+    // look into cache first
+    if (m_UseCache && NPT_SUCCEEDED(m_Cache.Get(device->GetUUID(), object_id, list))) return NPT_SUCCESS;
+
+    do {	
+        PLT_BrowseDataReference browse_data(new PLT_BrowseData());
+
+        // send off the browse packet.  Note that this will
+        // not block.  There is a call to WaitForResponse in order
+        // to block until the response comes back.
+        res = BrowseSync(
+            browse_data,
+            device,
+            (const char*)object_id,
+            index,
+            1024,
+            false,
+            "*",
+            "");		
+        NPT_CHECK_LABEL_WARNING(res, done);
+        
+        if (NPT_FAILED(browse_data->res)) {
+            res = browse_data->res;
+            NPT_CHECK_LABEL_WARNING(res, done);
+        }
+
+        if (browse_data->info.items->GetItemCount() == 0)
+            break;
+
+        if (list.IsNull()) {
+            list = browse_data->info.items;
+        } else {
+            list->Add(*browse_data->info.items);
+            // clear the list items so that the data inside is not
+            // cleaned up by PLT_MediaItemList dtor since we copied
+            // each pointer into the new list.
+            browse_data->info.items->Clear();
+        }
+
+        // stop now if our list contains exactly what the server said it had
+        if (browse_data->info.tm && browse_data->info.tm == list->GetItemCount())
+            break;
+
+        // ask for the next chunk of entries
+        index = list->GetItemCount();
+    } while(1);
+
+done:
+    // cache the result
+    if (m_UseCache && NPT_SUCCEEDED(res) && !list.IsNull() && list->GetItemCount()) {
+        m_Cache.Put(device->GetUUID(), object_id, list);
+    }
+
+    // clear entire cache data for device if failed, the device could be gone
+    if (NPT_FAILED(res) && m_UseCache) m_Cache.Clear(device->GetUUID());
+    
+    return res;
+}
+
+/*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::IsCached
++---------------------------------------------------------------------*/
+bool
+PLT_SyncMediaBrowser::IsCached(const char* uuid, const char* object_id)
+{
+    NPT_AutoLock lock(m_MediaServers);
+    const NPT_List<PLT_DeviceMapEntry*>::Iterator it = 
+        m_MediaServers.GetEntries().Find(PLT_DeviceMapFinderByUUID(uuid));
+    if (!it) {
+        m_Cache.Clear(uuid);
+        return false; // device with this service has gone away
+    }
+    
+    PLT_MediaObjectListReference list;
+    return NPT_SUCCEEDED(m_Cache.Get(uuid, object_id, list))?true:false;
+}
+