summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/patches/0028-platinum-add-SearchSync-method-to-SyncMediaBrowser.patch
blob: e5932710f66a2b23d9be43146f69ebd5a0d6b91e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
From 4d9d36139eed70da5ee922501bcf68443a349b44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Piechowiak?= <misiek.piechowiak@gmail.com>
Date: Fri, 2 Aug 2013 18:55:34 +0200
Subject: [PATCH 05/11] platinum: add SearchSync method to SyncMediaBrowser

---
 .../Devices/MediaServer/PltSyncMediaBrowser.cpp    | 150 +++++++++++++++++++--
 .../Devices/MediaServer/PltSyncMediaBrowser.h      |  25 +++-
 2 files changed, 164 insertions(+), 11 deletions(-)

diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
index 24219ff..96e4121 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
@@ -126,6 +126,24 @@ PLT_SyncMediaBrowser::Find(const char* ip, PLT_DeviceDataReference& device)
     return NPT_FAILURE;
 }
 
+static void OnResult(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::OnBrowseResult
 +---------------------------------------------------------------------*/
@@ -135,17 +153,19 @@ PLT_SyncMediaBrowser::OnBrowseResult(NPT_Result               res,
                                      PLT_BrowseInfo*          info, 
                                      void*                    userdata)
 {
-    NPT_COMPILER_UNUSED(device);
-
-    if (!userdata) return;
+  OnResult(res, device, info, userdata);
+}
 
-    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::OnSearchResult
++---------------------------------------------------------------------*/
+void
+PLT_SyncMediaBrowser::OnSearchResult(NPT_Result               res, 
+                                     PLT_DeviceDataReference& device, 
+                                     PLT_BrowseInfo*          info, 
+                                     void*                    userdata)
+{
+  OnResult(res, device, info, userdata);
 }
 
 /*----------------------------------------------------------------------
@@ -228,6 +248,38 @@ PLT_SyncMediaBrowser::BrowseSync(PLT_BrowseDataReference& browse_data,
 }
 
 /*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::SearchSync
++---------------------------------------------------------------------*/
+NPT_Result 
+PLT_SyncMediaBrowser::SearchSync(PLT_BrowseDataReference& browse_data,
+                                 PLT_DeviceDataReference& device, 
+                                 const char*              container_id,
+                                 const char*              search_criteria,
+                                 NPT_Int32                index, 
+                                 NPT_Int32                count,
+                                 const char*              filter)
+{
+    NPT_Result res;
+
+    browse_data->shared_var.SetValue(0);
+    browse_data->info.si = index;
+
+    // send off the search 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::Search(device,
+        container_id,
+        search_criteria,
+        index,
+        count,
+        filter,
+        new PLT_BrowseDataReference(browse_data));
+    NPT_CHECK_SEVERE(res);
+
+    return WaitForResponse(browse_data->shared_var);
+}
+
+/*----------------------------------------------------------------------
 |   PLT_SyncMediaBrowser::BrowseSync
 +---------------------------------------------------------------------*/
 NPT_Result
@@ -319,6 +371,84 @@ done:
 }
 
 /*----------------------------------------------------------------------
+|   PLT_SyncMediaBrowser::SearchSync
++---------------------------------------------------------------------*/
+NPT_Result
+PLT_SyncMediaBrowser::SearchSync(PLT_DeviceDataReference&      device,
+                                 const char*                   container_id,
+                                 const char*                   search_criteria,
+                                 PLT_MediaObjectListReference& list,
+                                 NPT_Int32                     start, /* = 0 */
+                                 NPT_Cardinal                  max_results /* = 0 */)
+{
+    NPT_Result res = NPT_FAILURE;
+    NPT_Int32  index = start;
+    NPT_UInt32 count = 0;
+
+    // reset output params
+    list = NULL;
+
+    do {	
+        PLT_BrowseDataReference browse_data(new PLT_BrowseData(), true);
+
+        // send off the search packet.  Note that this will
+        // not block.  There is a call to WaitForResponse in order
+        // to block until the response comes back.
+        res = SearchSync(
+            browse_data,
+            device,
+            container_id,
+            search_criteria,
+            index,
+            200); // DLNA recommendations for browsing children is no more than 30 at a time
+
+        NPT_CHECK_LABEL_WARNING(res, done);
+        
+        if (NPT_FAILED(browse_data->res)) {
+            res = browse_data->res;
+            NPT_CHECK_LABEL_WARNING(res, done);
+        }
+
+        // server returned no more, bail now
+        if (browse_data->info.nr == 0)
+            break;
+
+        if (browse_data->info.nr != browse_data->info.items->GetItemCount()) {
+            NPT_LOG_WARNING_2("Server returned unexpected number of items (%d vs %d)",
+                              browse_data->info.nr, browse_data->info.items->GetItemCount());
+        }
+        count += std::max<NPT_UInt32>(browse_data->info.nr, browse_data->info.items->GetItemCount());
+
+        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.
+        // Note that the server could return 0 if it didn't know how many items were
+        // available. In this case we have to continue browsing until
+        // nothing is returned back by the server.
+        // Unless we were told to stop after reaching a certain amount to avoid
+        // length delays
+        // (some servers may return a total matches out of whack at some point too)
+        if ((browse_data->info.tm && browse_data->info.tm <= count) ||
+            (max_results && count >= max_results))
+            break;
+
+        // ask for the next chunk of entries
+        index = count;
+    } while(1);
+
+done:
+    return res;
+}
+
+/*----------------------------------------------------------------------
 |   PLT_SyncMediaBrowser::IsCached
 +---------------------------------------------------------------------*/
 bool
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
index ffdddda..5ef9f37 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.h
@@ -61,6 +61,9 @@ typedef struct PLT_BrowseData {
 
 typedef NPT_Reference<PLT_BrowseData> PLT_BrowseDataReference;
 
+// explicitely specify res otherwise WMP won't return a URL!
+#define PLT_DEFAULT_FILTER  "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,dc:publisher,searchable,childCount,dc:title,dc:creator,upnp:actor,res@resolution,upnp:episodeCount,upnp:episodeSeason,xbmc:dateadded,xbmc:rating,xbmc:votes,xbmc:artwork"
+
 /*----------------------------------------------------------------------
 |   PLT_MediaContainerListener
 +---------------------------------------------------------------------*/
@@ -96,6 +99,10 @@ public:
                                 PLT_DeviceDataReference& device, 
                                 PLT_BrowseInfo*          info, 
                                 void*                    userdata);
+    virtual void OnSearchResult(NPT_Result               res, 
+                                PLT_DeviceDataReference& device, 
+                                PLT_BrowseInfo*          info, 
+                                void*                    userdata);
 
     // methods
     void       SetContainerListener(PLT_MediaContainerChangesListener* listener) {
@@ -108,6 +115,13 @@ public:
                           NPT_Int32                     start = 0,
                           NPT_Cardinal                  max_results = 0); // 0 means all
 
+    NPT_Result SearchSync(PLT_DeviceDataReference&      device,
+                          const char*                   container_id,
+                          const char*                   search_criteria,
+                          PLT_MediaObjectListReference& list,
+                          NPT_Int32                     start = 0,
+                          NPT_Cardinal                  max_results = 0); // 0 means all
+
     const NPT_Lock<PLT_DeviceMap>& GetMediaServersMap() const { return m_MediaServers; }
     bool IsCached(const char* uuid, const char* object_id);
 
@@ -118,8 +132,17 @@ protected:
                           NPT_Int32                index, 
                           NPT_Int32                count,
                           bool                     browse_metadata = false,
-                          const char*              filter = "dc:date,dc:description,upnp:longDescription,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:rating,upnp:lastPlaybackPosition,upnp:lastPlaybackTime,upnp:playbackCount,upnp:originalTrackNumber,upnp:episodeNumber,upnp:programTitle,upnp:seriesTitle,upnp:album,upnp:artist,upnp:author,upnp:director,dc:publisher,searchable,childCount,dc:title,dc:creator,upnp:actor,res@resolution,upnp:episodeCount,upnp:episodeSeason,xbmc:dateadded,xbmc:rating,xbmc:votes,xbmc:artwork", // explicitely specify res otherwise WMP won't return a URL!
+                          const char*              filter = PLT_DEFAULT_FILTER,
                           const char*              sort = "");
+
+    NPT_Result SearchSync(PLT_BrowseDataReference& browse_data,
+                          PLT_DeviceDataReference& device, 
+                          const char*              container_id,
+                          const char*              search_criteria,
+                          NPT_Int32                index, 
+                          NPT_Int32                count,
+                          const char*              filter = PLT_DEFAULT_FILTER); // explicitely specify res otherwise WMP won't return a URL!
+
 private:
     NPT_Result Find(const char* ip, PLT_DeviceDataReference& device);
     NPT_Result WaitForResponse(NPT_SharedVariable& shared_var);
-- 
1.7.11.msysgit.0