Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
6c5bc9b4
Commit
6c5bc9b4
authored
Feb 06, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lib/expat: use C++ exceptions instead of class Error
parent
cd2f65aa
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
108 additions
and
174 deletions
+108
-174
ContentDirectoryService.cxx
src/db/plugins/upnp/ContentDirectoryService.cxx
+23
-27
Directory.cxx
src/db/plugins/upnp/Directory.cxx
+3
-3
Directory.hxx
src/db/plugins/upnp/Directory.hxx
+4
-1
UpnpDatabasePlugin.cxx
src/db/plugins/upnp/UpnpDatabasePlugin.cxx
+38
-86
ExpatParser.cxx
src/lib/expat/ExpatParser.cxx
+7
-12
ExpatParser.hxx
src/lib/expat/ExpatParser.hxx
+14
-5
ContentDirectoryService.hxx
src/lib/upnp/ContentDirectoryService.hxx
+9
-17
Device.cxx
src/lib/upnp/Device.cxx
+3
-9
Device.hxx
src/lib/upnp/Device.hxx
+1
-4
Discovery.cxx
src/lib/upnp/Discovery.cxx
+4
-7
Discovery.hxx
src/lib/upnp/Discovery.hxx
+2
-3
No files found.
src/db/plugins/upnp/ContentDirectoryService.cxx
View file @
6c5bc9b4
...
@@ -32,22 +32,22 @@
...
@@ -32,22 +32,22 @@
#include <stdio.h>
#include <stdio.h>
static
bool
static
void
ReadResultTag
(
UPnPDirContent
&
dirbuf
,
IXML_Document
*
response
,
Error
&
error
)
ReadResultTag
(
UPnPDirContent
&
dirbuf
,
IXML_Document
*
response
)
{
{
const
char
*
p
=
ixmlwrap
::
getFirstElementValue
(
response
,
"Result"
);
const
char
*
p
=
ixmlwrap
::
getFirstElementValue
(
response
,
"Result"
);
if
(
p
==
nullptr
)
if
(
p
==
nullptr
)
p
=
""
;
p
=
""
;
return
dirbuf
.
parse
(
p
,
error
);
dirbuf
.
Parse
(
p
);
}
}
inline
bool
inline
void
ContentDirectoryService
::
readDirSlice
(
UpnpClient_Handle
hdl
,
ContentDirectoryService
::
readDirSlice
(
UpnpClient_Handle
hdl
,
const
char
*
objectId
,
unsigned
offset
,
const
char
*
objectId
,
unsigned
offset
,
unsigned
count
,
UPnPDirContent
&
dirbuf
,
unsigned
count
,
UPnPDirContent
&
dirbuf
,
unsigned
&
didreadp
,
unsigned
&
totalp
,
unsigned
&
didreadp
,
Error
&
error
)
const
unsigned
&
totalp
)
const
{
{
// Create request
// Create request
char
ofbuf
[
100
],
cntbuf
[
100
];
char
ofbuf
[
100
],
cntbuf
[
100
];
...
@@ -85,35 +85,32 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
...
@@ -85,35 +85,32 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
if
(
value
!=
nullptr
)
if
(
value
!=
nullptr
)
totalp
=
ParseUnsigned
(
value
);
totalp
=
ParseUnsigned
(
value
);
return
ReadResultTag
(
dirbuf
,
response
,
error
);
ReadResultTag
(
dirbuf
,
response
);
}
}
bool
UPnPDirContent
ContentDirectoryService
::
readDir
(
UpnpClient_Handle
handle
,
ContentDirectoryService
::
readDir
(
UpnpClient_Handle
handle
,
const
char
*
objectId
,
const
char
*
objectId
)
const
UPnPDirContent
&
dirbuf
,
Error
&
error
)
const
{
{
UPnPDirContent
dirbuf
;
unsigned
offset
=
0
,
total
=
-
1
,
count
;
unsigned
offset
=
0
,
total
=
-
1
,
count
;
do
{
do
{
if
(
!
readDirSlice
(
handle
,
objectId
,
offset
,
m_rdreqcnt
,
dirbuf
,
readDirSlice
(
handle
,
objectId
,
offset
,
m_rdreqcnt
,
dirbuf
,
count
,
total
,
error
))
count
,
total
);
return
false
;
offset
+=
count
;
offset
+=
count
;
}
while
(
count
>
0
&&
offset
<
total
);
}
while
(
count
>
0
&&
offset
<
total
);
return
true
;
return
dirbuf
;
}
}
bool
UPnPDirContent
ContentDirectoryService
::
search
(
UpnpClient_Handle
hdl
,
ContentDirectoryService
::
search
(
UpnpClient_Handle
hdl
,
const
char
*
objectId
,
const
char
*
objectId
,
const
char
*
ss
,
const
char
*
ss
)
const
UPnPDirContent
&
dirbuf
,
Error
&
error
)
const
{
{
UPnPDirContent
dirbuf
;
unsigned
offset
=
0
,
total
=
-
1
,
count
;
unsigned
offset
=
0
,
total
=
-
1
,
count
;
do
{
do
{
...
@@ -155,18 +152,15 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
...
@@ -155,18 +152,15 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
if
(
value
!=
nullptr
)
if
(
value
!=
nullptr
)
total
=
ParseUnsigned
(
value
);
total
=
ParseUnsigned
(
value
);
if
(
!
ReadResultTag
(
dirbuf
,
response
.
get
(),
error
))
ReadResultTag
(
dirbuf
,
response
.
get
());
return
false
;
}
while
(
count
>
0
&&
offset
<
total
);
}
while
(
count
>
0
&&
offset
<
total
);
return
true
;
return
dirbuf
;
}
}
bool
UPnPDirContent
ContentDirectoryService
::
getMetadata
(
UpnpClient_Handle
hdl
,
ContentDirectoryService
::
getMetadata
(
UpnpClient_Handle
hdl
,
const
char
*
objectId
,
const
char
*
objectId
)
const
UPnPDirContent
&
dirbuf
,
Error
&
error
)
const
{
{
// Create request
// Create request
UniqueIxmlDocument
request
(
MakeActionHelper
(
"Browse"
,
m_serviceType
.
c_str
(),
UniqueIxmlDocument
request
(
MakeActionHelper
(
"Browse"
,
m_serviceType
.
c_str
(),
...
@@ -188,5 +182,7 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
...
@@ -188,5 +182,7 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
UpnpGetErrorMessage
(
code
));
UpnpGetErrorMessage
(
code
));
UniqueIxmlDocument
response
(
_response
);
UniqueIxmlDocument
response
(
_response
);
return
ReadResultTag
(
dirbuf
,
response
.
get
(),
error
);
UPnPDirContent
dirbuf
;
ReadResultTag
(
dirbuf
,
response
.
get
());
return
dirbuf
;
}
}
src/db/plugins/upnp/Directory.cxx
View file @
6c5bc9b4
...
@@ -236,9 +236,9 @@ protected:
...
@@ -236,9 +236,9 @@ protected:
}
}
};
};
bool
void
UPnPDirContent
::
parse
(
const
char
*
input
,
Error
&
error
)
UPnPDirContent
::
Parse
(
const
char
*
input
)
{
{
UPnPDirParser
parser
(
*
this
);
UPnPDirParser
parser
(
*
this
);
return
parser
.
Parse
(
input
,
strlen
(
input
),
true
,
error
);
parser
.
Parse
(
input
,
strlen
(
input
),
true
);
}
}
src/db/plugins/upnp/Directory.hxx
View file @
6c5bc9b4
...
@@ -36,6 +36,9 @@ class UPnPDirContent {
...
@@ -36,6 +36,9 @@ class UPnPDirContent {
public
:
public
:
std
::
vector
<
UPnPDirObject
>
objects
;
std
::
vector
<
UPnPDirObject
>
objects
;
UPnPDirContent
()
=
default
;
UPnPDirContent
(
UPnPDirContent
&&
)
=
default
;
~
UPnPDirContent
();
~
UPnPDirContent
();
gcc_pure
gcc_pure
...
@@ -60,7 +63,7 @@ public:
...
@@ -60,7 +63,7 @@ public:
* actually global, nothing really bad will happen if you mix
* actually global, nothing really bad will happen if you mix
* up...
* up...
*/
*/
bool
parse
(
const
char
*
didltext
,
Error
&
error
);
void
Parse
(
const
char
*
didltext
);
};
};
#endif
/* _UPNPDIRCONTENT_H_X_INCLUDED_ */
#endif
/* _UPNPDIRCONTENT_H_X_INCLUDED_ */
src/db/plugins/upnp/UpnpDatabasePlugin.cxx
View file @
6c5bc9b4
...
@@ -127,32 +127,26 @@ private:
...
@@ -127,32 +127,26 @@ private:
VisitSong
visit_song
,
VisitSong
visit_song
,
Error
&
error
)
const
;
Error
&
error
)
const
;
bool
SearchSongs
(
const
ContentDirectoryService
&
server
,
UPnPDirContent
SearchSongs
(
const
ContentDirectoryService
&
server
,
const
char
*
objid
,
const
char
*
objid
,
const
DatabaseSelection
&
selection
,
const
DatabaseSelection
&
selection
)
const
;
UPnPDirContent
&
dirbuf
,
Error
&
error
)
const
;
bool
Namei
(
const
ContentDirectoryService
&
server
,
UPnPDirObject
Namei
(
const
ContentDirectoryService
&
server
,
const
std
::
list
<
std
::
string
>
&
vpath
,
const
std
::
list
<
std
::
string
>
&
vpath
)
const
;
UPnPDirObject
&
dirent
,
Error
&
error
)
const
;
/**
/**
* Take server and objid, return metadata.
* Take server and objid, return metadata.
*/
*/
bool
ReadNode
(
const
ContentDirectoryService
&
server
,
UPnPDirObject
ReadNode
(
const
ContentDirectoryService
&
server
,
const
char
*
objid
,
UPnPDirObject
&
dirent
,
const
char
*
objid
)
const
;
Error
&
error
)
const
;
/**
/**
* Get the path for an object Id. This works much like pwd,
* Get the path for an object Id. This works much like pwd,
* except easier cause our inodes have a parent id. Not used
* except easier cause our inodes have a parent id. Not used
* any more actually (see comments in SearchSongs).
* any more actually (see comments in SearchSongs).
*/
*/
bool
BuildPath
(
const
ContentDirectoryService
&
server
,
std
::
string
BuildPath
(
const
ContentDirectoryService
&
server
,
const
UPnPDirObject
&
dirent
,
std
::
string
&
idpath
,
const
UPnPDirObject
&
dirent
)
const
;
Error
&
error
)
const
;
};
};
Database
*
Database
*
...
@@ -214,7 +208,7 @@ UpnpDatabase::ReturnSong(const LightSong *_song) const
...
@@ -214,7 +208,7 @@ UpnpDatabase::ReturnSong(const LightSong *_song) const
// Get song info by path. We can receive either the id path, or the titles
// Get song info by path. We can receive either the id path, or the titles
// one
// one
const
LightSong
*
const
LightSong
*
UpnpDatabase
::
GetSong
(
const
char
*
uri
,
Error
&
error
)
const
UpnpDatabase
::
GetSong
(
const
char
*
uri
,
gcc_unused
Error
&
error
)
const
{
{
auto
vpath
=
stringToTokens
(
uri
,
"/"
,
true
);
auto
vpath
=
stringToTokens
(
uri
,
"/"
,
true
);
if
(
vpath
.
size
()
<
2
)
if
(
vpath
.
size
()
<
2
)
...
@@ -227,12 +221,9 @@ UpnpDatabase::GetSong(const char *uri, Error &error) const
...
@@ -227,12 +221,9 @@ UpnpDatabase::GetSong(const char *uri, Error &error) const
UPnPDirObject
dirent
;
UPnPDirObject
dirent
;
if
(
vpath
.
front
()
!=
rootid
)
{
if
(
vpath
.
front
()
!=
rootid
)
{
if
(
!
Namei
(
server
,
vpath
,
dirent
,
error
))
dirent
=
Namei
(
server
,
vpath
);
return
nullptr
;
}
else
{
}
else
{
if
(
!
ReadNode
(
server
,
vpath
.
back
().
c_str
(),
dirent
,
dirent
=
ReadNode
(
server
,
vpath
.
back
().
c_str
());
error
))
return
nullptr
;
}
}
return
new
UpnpSong
(
std
::
move
(
dirent
),
uri
);
return
new
UpnpSong
(
std
::
move
(
dirent
),
uri
);
...
@@ -262,20 +253,18 @@ dquote(std::string &out, const char *in)
...
@@ -262,20 +253,18 @@ dquote(std::string &out, const char *in)
// Run an UPnP search, according to MPD parameters. Return results as
// Run an UPnP search, according to MPD parameters. Return results as
// UPnP items
// UPnP items
bool
UPnPDirContent
UpnpDatabase
::
SearchSongs
(
const
ContentDirectoryService
&
server
,
UpnpDatabase
::
SearchSongs
(
const
ContentDirectoryService
&
server
,
const
char
*
objid
,
const
char
*
objid
,
const
DatabaseSelection
&
selection
,
const
DatabaseSelection
&
selection
)
const
UPnPDirContent
&
dirbuf
,
Error
&
error
)
const
{
{
const
SongFilter
*
filter
=
selection
.
filter
;
const
SongFilter
*
filter
=
selection
.
filter
;
if
(
selection
.
filter
==
nullptr
)
if
(
selection
.
filter
==
nullptr
)
return
true
;
return
UPnPDirContent
()
;
const
auto
searchcaps
=
server
.
getSearchCapabilities
(
handle
);
const
auto
searchcaps
=
server
.
getSearchCapabilities
(
handle
);
if
(
searchcaps
.
empty
())
if
(
searchcaps
.
empty
())
return
true
;
return
UPnPDirContent
()
;
std
::
string
cond
;
std
::
string
cond
;
for
(
const
auto
&
item
:
filter
->
GetItems
())
{
for
(
const
auto
&
item
:
filter
->
GetItems
())
{
...
@@ -338,9 +327,7 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
...
@@ -338,9 +327,7 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
}
}
}
}
return
server
.
search
(
handle
,
return
server
.
search
(
handle
,
objid
,
cond
.
c_str
());
objid
,
cond
.
c_str
(),
dirbuf
,
error
);
}
}
static
bool
static
bool
...
@@ -381,13 +368,10 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
...
@@ -381,13 +368,10 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
VisitSong
visit_song
,
VisitSong
visit_song
,
Error
&
error
)
const
Error
&
error
)
const
{
{
UPnPDirContent
dirbuf
;
if
(
!
visit_song
)
if
(
!
visit_song
)
return
true
;
return
true
;
if
(
!
SearchSongs
(
server
,
objid
,
selection
,
dirbuf
,
error
))
return
false
;
for
(
auto
&
dirent
:
dirbuf
.
objects
)
{
for
(
auto
&
dirent
:
SearchSongs
(
server
,
objid
,
selection
)
.
objects
)
{
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
dirent
.
item_class
!=
UPnPDirObject
::
ItemClass
::
MUSIC
)
dirent
.
item_class
!=
UPnPDirObject
::
ItemClass
::
MUSIC
)
continue
;
continue
;
...
@@ -419,34 +403,25 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
...
@@ -419,34 +403,25 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
return
true
;
return
true
;
}
}
bool
UPnPDirObject
UpnpDatabase
::
ReadNode
(
const
ContentDirectoryService
&
server
,
UpnpDatabase
::
ReadNode
(
const
ContentDirectoryService
&
server
,
const
char
*
objid
,
UPnPDirObject
&
dirent
,
const
char
*
objid
)
const
Error
&
error
)
const
{
{
UPnPDirContent
dirbuf
;
auto
dirbuf
=
server
.
getMetadata
(
handle
,
objid
);
if
(
!
server
.
getMetadata
(
handle
,
objid
,
dirbuf
,
error
))
return
false
;
if
(
dirbuf
.
objects
.
size
()
!=
1
)
if
(
dirbuf
.
objects
.
size
()
!=
1
)
throw
std
::
runtime_error
(
"Bad resource"
);
throw
std
::
runtime_error
(
"Bad resource"
);
dirent
=
std
::
move
(
dirbuf
.
objects
.
front
());
return
std
::
move
(
dirbuf
.
objects
.
front
());
return
true
;
}
}
bool
std
::
string
UpnpDatabase
::
BuildPath
(
const
ContentDirectoryService
&
server
,
UpnpDatabase
::
BuildPath
(
const
ContentDirectoryService
&
server
,
const
UPnPDirObject
&
idirent
,
const
UPnPDirObject
&
idirent
)
const
std
::
string
&
path
,
Error
&
error
)
const
{
{
const
char
*
pid
=
idirent
.
id
.
c_str
();
const
char
*
pid
=
idirent
.
id
.
c_str
();
path
.
clear
();
std
::
string
path
;
UPnPDirObject
dirent
;
while
(
strcmp
(
pid
,
rootid
)
!=
0
)
{
while
(
strcmp
(
pid
,
rootid
)
!=
0
)
{
if
(
!
ReadNode
(
server
,
pid
,
dirent
,
error
))
auto
dirent
=
ReadNode
(
server
,
pid
);
return
false
;
pid
=
dirent
.
parent_id
.
c_str
();
pid
=
dirent
.
parent_id
.
c_str
();
if
(
path
.
empty
())
if
(
path
.
empty
())
...
@@ -456,33 +431,24 @@ UpnpDatabase::BuildPath(const ContentDirectoryService &server,
...
@@ -456,33 +431,24 @@ UpnpDatabase::BuildPath(const ContentDirectoryService &server,
path
.
c_str
());
path
.
c_str
());
}
}
path
=
PathTraitsUTF8
::
Build
(
server
.
getFriendlyName
(),
return
PathTraitsUTF8
::
Build
(
server
.
getFriendlyName
(),
path
.
c_str
());
path
.
c_str
());
return
true
;
}
}
// Take server and internal title pathname and return objid and metadata.
// Take server and internal title pathname and return objid and metadata.
bool
UPnPDirObject
UpnpDatabase
::
Namei
(
const
ContentDirectoryService
&
server
,
UpnpDatabase
::
Namei
(
const
ContentDirectoryService
&
server
,
const
std
::
list
<
std
::
string
>
&
vpath
,
const
std
::
list
<
std
::
string
>
&
vpath
)
const
UPnPDirObject
&
odirent
,
Error
&
error
)
const
{
{
if
(
vpath
.
empty
())
{
if
(
vpath
.
empty
())
// looking for root info
// looking for root info
if
(
!
ReadNode
(
server
,
rootid
,
odirent
,
error
))
return
ReadNode
(
server
,
rootid
);
return
false
;
return
true
;
}
std
::
string
objid
(
rootid
);
std
::
string
objid
(
rootid
);
// Walk the path elements, read each directory and try to find the next one
// Walk the path elements, read each directory and try to find the next one
for
(
auto
i
=
vpath
.
begin
(),
last
=
std
::
prev
(
vpath
.
end
());;
++
i
)
{
for
(
auto
i
=
vpath
.
begin
(),
last
=
std
::
prev
(
vpath
.
end
());;
++
i
)
{
UPnPDirContent
dirbuf
;
auto
dirbuf
=
server
.
readDir
(
handle
,
objid
.
c_str
());
if
(
!
server
.
readDir
(
handle
,
objid
.
c_str
(),
dirbuf
,
error
))
return
false
;
// Look for the name in the sub-container list
// Look for the name in the sub-container list
UPnPDirObject
*
child
=
dirbuf
.
FindObject
(
i
->
c_str
());
UPnPDirObject
*
child
=
dirbuf
.
FindObject
(
i
->
c_str
());
...
@@ -490,10 +456,8 @@ UpnpDatabase::Namei(const ContentDirectoryService &server,
...
@@ -490,10 +456,8 @@ UpnpDatabase::Namei(const ContentDirectoryService &server,
throw
DatabaseError
(
DatabaseErrorCode
::
NOT_FOUND
,
throw
DatabaseError
(
DatabaseErrorCode
::
NOT_FOUND
,
"No such object"
);
"No such object"
);
if
(
i
==
last
)
{
if
(
i
==
last
)
odirent
=
std
::
move
(
*
child
);
return
std
::
move
(
*
child
);
return
true
;
}
if
(
child
->
type
!=
UPnPDirObject
::
Type
::
CONTAINER
)
if
(
child
->
type
!=
UPnPDirObject
::
Type
::
CONTAINER
)
throw
DatabaseError
(
DatabaseErrorCode
::
NOT_FOUND
,
throw
DatabaseError
(
DatabaseErrorCode
::
NOT_FOUND
,
...
@@ -597,10 +561,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
...
@@ -597,10 +561,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
}
}
if
(
visit_song
)
{
if
(
visit_song
)
{
UPnPDirObject
dirent
;
auto
dirent
=
ReadNode
(
server
,
vpath
.
back
().
c_str
());
if
(
!
ReadNode
(
server
,
vpath
.
back
().
c_str
(),
dirent
,
error
))
return
false
;
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
dirent
.
item_class
!=
UPnPDirObject
::
ItemClass
::
MUSIC
)
dirent
.
item_class
!=
UPnPDirObject
::
ItemClass
::
MUSIC
)
...
@@ -618,9 +579,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
...
@@ -618,9 +579,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
}
}
// Translate the target path into an object id and the associated metadata.
// Translate the target path into an object id and the associated metadata.
UPnPDirObject
tdirent
;
const
auto
tdirent
=
Namei
(
server
,
vpath
);
if
(
!
Namei
(
server
,
vpath
,
tdirent
,
error
))
return
false
;
/* If recursive is set, this is a search... No use sending it
/* If recursive is set, this is a search... No use sending it
if the filter is empty. In this case, we implement limited
if the filter is empty. In this case, we implement limited
...
@@ -644,12 +603,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
...
@@ -644,12 +603,7 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
/* Target was a a container. Visit it. We could read slices
/* Target was a a container. Visit it. We could read slices
and loop here, but it's not useful as mpd will only return
and loop here, but it's not useful as mpd will only return
data to the client when we're done anyway. */
data to the client when we're done anyway. */
UPnPDirContent
dirbuf
;
for
(
const
auto
&
dirent
:
server
.
readDir
(
handle
,
tdirent
.
id
.
c_str
()).
objects
)
{
if
(
!
server
.
readDir
(
handle
,
tdirent
.
id
.
c_str
(),
dirbuf
,
error
))
return
false
;
for
(
auto
&
dirent
:
dirbuf
.
objects
)
{
const
std
::
string
uri
=
PathTraitsUTF8
::
Build
(
base_uri
,
const
std
::
string
uri
=
PathTraitsUTF8
::
Build
(
base_uri
,
dirent
.
name
.
c_str
());
dirent
.
name
.
c_str
());
if
(
!
VisitObject
(
dirent
,
uri
.
c_str
(),
if
(
!
VisitObject
(
dirent
,
uri
.
c_str
(),
...
@@ -712,9 +666,7 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
...
@@ -712,9 +666,7 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
std
::
set
<
std
::
string
>
values
;
std
::
set
<
std
::
string
>
values
;
for
(
auto
&
server
:
discovery
->
GetDirectories
())
{
for
(
auto
&
server
:
discovery
->
GetDirectories
())
{
UPnPDirContent
dirbuf
;
const
auto
dirbuf
=
SearchSongs
(
server
,
rootid
,
selection
);
if
(
!
SearchSongs
(
server
,
rootid
,
selection
,
dirbuf
,
error
))
return
false
;
for
(
const
auto
&
dirent
:
dirbuf
.
objects
)
{
for
(
const
auto
&
dirent
:
dirbuf
.
objects
)
{
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
if
(
dirent
.
type
!=
UPnPDirObject
::
Type
::
ITEM
||
...
...
src/lib/expat/ExpatParser.cxx
View file @
6c5bc9b4
...
@@ -36,16 +36,11 @@ ExpatParser::SetError(Error &error)
...
@@ -36,16 +36,11 @@ ExpatParser::SetError(Error &error)
XML_ErrorString
(
code
));
XML_ErrorString
(
code
));
}
}
bool
void
ExpatParser
::
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
,
ExpatParser
::
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
)
Error
&
error
)
{
{
bool
success
=
XML_Parse
(
parser
,
data
,
length
,
if
(
XML_Parse
(
parser
,
data
,
length
,
is_final
)
!=
XML_STATUS_OK
)
is_final
)
==
XML_STATUS_OK
;
throw
ExpatError
(
parser
);
if
(
!
success
)
SetError
(
error
);
return
success
;
}
}
bool
bool
...
@@ -59,14 +54,14 @@ ExpatParser::Parse(InputStream &is, Error &error)
...
@@ -59,14 +54,14 @@ ExpatParser::Parse(InputStream &is, Error &error)
if
(
nbytes
==
0
)
if
(
nbytes
==
0
)
break
;
break
;
if
(
!
Parse
(
buffer
,
nbytes
,
false
,
error
))
Parse
(
buffer
,
nbytes
,
false
);
return
false
;
}
}
if
(
error
.
IsDefined
())
if
(
error
.
IsDefined
())
return
false
;
return
false
;
return
Parse
(
""
,
0
,
true
,
error
);
Parse
(
""
,
0
,
true
);
return
true
;
}
}
const
char
*
const
char
*
...
...
src/lib/expat/ExpatParser.hxx
View file @
6c5bc9b4
...
@@ -25,9 +25,20 @@
...
@@ -25,9 +25,20 @@
#include <expat.h>
#include <expat.h>
#include <stdexcept>
class
InputStream
;
class
InputStream
;
class
Error
;
class
Error
;
class
ExpatError
final
:
public
std
::
runtime_error
{
public
:
ExpatError
(
XML_Error
code
)
:
std
::
runtime_error
(
XML_ErrorString
(
code
))
{}
ExpatError
(
XML_Parser
parser
)
:
ExpatError
(
XML_GetErrorCode
(
parser
))
{}
};
class
ExpatParser
final
{
class
ExpatParser
final
{
const
XML_Parser
parser
;
const
XML_Parser
parser
;
...
@@ -53,8 +64,7 @@ public:
...
@@ -53,8 +64,7 @@ public:
XML_SetCharacterDataHandler
(
parser
,
charhndl
);
XML_SetCharacterDataHandler
(
parser
,
charhndl
);
}
}
bool
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
,
void
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
);
Error
&
error
);
bool
Parse
(
InputStream
&
is
,
Error
&
error
);
bool
Parse
(
InputStream
&
is
,
Error
&
error
);
...
@@ -83,9 +93,8 @@ public:
...
@@ -83,9 +93,8 @@ public:
parser
.
SetCharacterDataHandler
(
CharacterData
);
parser
.
SetCharacterDataHandler
(
CharacterData
);
}
}
bool
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
,
void
Parse
(
const
char
*
data
,
size_t
length
,
bool
is_final
)
{
Error
&
error
)
{
parser
.
Parse
(
data
,
length
,
is_final
);
return
parser
.
Parse
(
data
,
length
,
is_final
,
error
);
}
}
bool
Parse
(
InputStream
&
is
,
Error
&
error
)
{
bool
Parse
(
InputStream
&
is
,
Error
&
error
)
{
...
...
src/lib/upnp/ContentDirectoryService.hxx
View file @
6c5bc9b4
...
@@ -76,17 +76,14 @@ public:
...
@@ -76,17 +76,14 @@ public:
/** Read a container's children list into dirbuf.
/** Read a container's children list into dirbuf.
*
*
* @param objectId the UPnP object Id for the container. Root has Id "0"
* @param objectId the UPnP object Id for the container. Root has Id "0"
* @param[out] dirbuf stores the entries we read.
*/
*/
bool
readDir
(
UpnpClient_Handle
handle
,
UPnPDirContent
readDir
(
UpnpClient_Handle
handle
,
const
char
*
objectId
,
UPnPDirContent
&
dirbuf
,
const
char
*
objectId
)
const
;
Error
&
error
)
const
;
bool
readDirSlice
(
UpnpClient_Handle
handle
,
void
readDirSlice
(
UpnpClient_Handle
handle
,
const
char
*
objectId
,
unsigned
offset
,
const
char
*
objectId
,
unsigned
offset
,
unsigned
count
,
UPnPDirContent
&
dirbuf
,
unsigned
count
,
UPnPDirContent
&
dirbuf
,
unsigned
&
didread
,
unsigned
&
total
,
unsigned
&
didread
,
unsigned
&
total
)
const
;
Error
&
error
)
const
;
/** Search the content directory service.
/** Search the content directory service.
*
*
...
@@ -96,22 +93,17 @@ public:
...
@@ -96,22 +93,17 @@ public:
* @param searchstring an UPnP searchcriteria string. Check the
* @param searchstring an UPnP searchcriteria string. Check the
* UPnP document: UPnP-av-ContentDirectory-v1-Service-20020625.pdf
* UPnP document: UPnP-av-ContentDirectory-v1-Service-20020625.pdf
* section 2.5.5. Maybe we'll provide an easier way some day...
* section 2.5.5. Maybe we'll provide an easier way some day...
* @param[out] dirbuf stores the entries we read.
*/
*/
bool
search
(
UpnpClient_Handle
handle
,
UPnPDirContent
search
(
UpnpClient_Handle
handle
,
const
char
*
objectId
,
const
char
*
searchstring
,
const
char
*
objectId
,
UPnPDirContent
&
dirbuf
,
const
char
*
searchstring
)
const
;
Error
&
error
)
const
;
/** Read metadata for a given node.
/** Read metadata for a given node.
*
*
* @param objectId the UPnP object Id. Root has Id "0"
* @param objectId the UPnP object Id. Root has Id "0"
* @param[out] dirbuf stores the entries we read. At most one entry will be
* returned.
*/
*/
bool
getMetadata
(
UpnpClient_Handle
handle
,
UPnPDirContent
getMetadata
(
UpnpClient_Handle
handle
,
const
char
*
objectId
,
UPnPDirContent
&
dirbuf
,
const
char
*
objectId
)
const
;
Error
&
error
)
const
;
/** Retrieve search capabilities
/** Retrieve search capabilities
*
*
...
...
src/lib/upnp/Device.cxx
View file @
6c5bc9b4
...
@@ -21,7 +21,6 @@
...
@@ -21,7 +21,6 @@
#include "Device.hxx"
#include "Device.hxx"
#include "Util.hxx"
#include "Util.hxx"
#include "lib/expat/ExpatParser.hxx"
#include "lib/expat/ExpatParser.hxx"
#include "util/Error.hxx"
#include <stdlib.h>
#include <stdlib.h>
...
@@ -100,15 +99,12 @@ protected:
...
@@ -100,15 +99,12 @@ protected:
}
}
};
};
bool
void
UPnPDevice
::
Parse
(
const
std
::
string
&
url
,
const
char
*
description
,
UPnPDevice
::
Parse
(
const
std
::
string
&
url
,
const
char
*
description
)
Error
&
error
)
{
{
{
{
UPnPDeviceParser
mparser
(
*
this
);
UPnPDeviceParser
mparser
(
*
this
);
if
(
!
mparser
.
Parse
(
description
,
strlen
(
description
),
mparser
.
Parse
(
description
,
strlen
(
description
),
true
);
true
,
error
))
return
false
;
}
}
if
(
URLBase
.
empty
())
{
if
(
URLBase
.
empty
())
{
...
@@ -129,6 +125,4 @@ UPnPDevice::Parse(const std::string &url, const char *description,
...
@@ -129,6 +125,4 @@ UPnPDevice::Parse(const std::string &url, const char *description,
}
}
}
}
}
}
return
true
;
}
}
src/lib/upnp/Device.hxx
View file @
6c5bc9b4
...
@@ -23,8 +23,6 @@
...
@@ -23,8 +23,6 @@
#include <vector>
#include <vector>
#include <string>
#include <string>
class
Error
;
/**
/**
* UPnP Description phase: interpreting the device description which we
* UPnP Description phase: interpreting the device description which we
* downloaded from the URL obtained by the discovery phase.
* downloaded from the URL obtained by the discovery phase.
...
@@ -81,8 +79,7 @@ public:
...
@@ -81,8 +79,7 @@ public:
* @param url where the description came from
* @param url where the description came from
* @param description the xml device description
* @param description the xml device description
*/
*/
bool
Parse
(
const
std
::
string
&
url
,
const
char
*
description
,
void
Parse
(
const
std
::
string
&
url
,
const
char
*
description
);
Error
&
error
);
};
};
#endif
/* _UPNPDEV_HXX_INCLUDED_ */
#endif
/* _UPNPDEV_HXX_INCLUDED_ */
src/lib/upnp/Discovery.cxx
View file @
6c5bc9b4
...
@@ -135,13 +135,10 @@ UPnPDeviceDirectory::Explore()
...
@@ -135,13 +135,10 @@ UPnPDeviceDirectory::Explore()
ContentDirectoryDescriptor
d
(
std
::
move
(
tsk
->
device_id
),
ContentDirectoryDescriptor
d
(
std
::
move
(
tsk
->
device_id
),
MonotonicClockS
(),
tsk
->
expires
);
MonotonicClockS
(),
tsk
->
expires
);
{
try
{
Error
error2
;
d
.
Parse
(
tsk
->
url
,
buf
);
bool
success
=
d
.
Parse
(
tsk
->
url
,
buf
,
error2
);
}
catch
(
const
std
::
exception
&
e
)
{
if
(
!
success
)
{
LogError
(
e
);
LogError
(
error2
);
continue
;
}
}
}
LockAdd
(
std
::
move
(
d
));
LockAdd
(
std
::
move
(
d
));
...
...
src/lib/upnp/Discovery.hxx
View file @
6c5bc9b4
...
@@ -87,9 +87,8 @@ class UPnPDeviceDirectory final : UpnpCallback {
...
@@ -87,9 +87,8 @@ class UPnPDeviceDirectory final : UpnpCallback {
unsigned
last
,
int
exp
)
unsigned
last
,
int
exp
)
:
id
(
std
::
move
(
_id
)),
expires
(
last
+
exp
+
20
)
{}
:
id
(
std
::
move
(
_id
)),
expires
(
last
+
exp
+
20
)
{}
bool
Parse
(
const
std
::
string
&
url
,
const
char
*
description
,
void
Parse
(
const
std
::
string
&
url
,
const
char
*
description
)
{
Error
&
_error
)
{
device
.
Parse
(
url
,
description
);
return
device
.
Parse
(
url
,
description
,
_error
);
}
}
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment