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
e5039c47
Commit
e5039c47
authored
Jan 17, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Path: new class "Path" wraps filesystem path strings
parent
89015145
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
380 additions
and
238 deletions
+380
-238
DecoderThread.cxx
src/DecoderThread.cxx
+2
-1
ExcludeList.cxx
src/ExcludeList.cxx
+3
-5
ExcludeList.hxx
src/ExcludeList.hxx
+3
-1
Main.cxx
src/Main.cxx
+2
-1
Mapper.cxx
src/Mapper.cxx
+31
-51
Mapper.hxx
src/Mapper.hxx
+10
-9
Path.hxx
src/Path.hxx
+207
-0
PlaylistFile.cxx
src/PlaylistFile.cxx
+27
-42
PlaylistMapper.cxx
src/PlaylistMapper.cxx
+4
-9
PlaylistSave.cxx
src/PlaylistSave.cxx
+16
-31
PlaylistSong.cxx
src/PlaylistSong.cxx
+2
-2
SongUpdate.cxx
src/SongUpdate.cxx
+9
-9
StateFile.cxx
src/StateFile.cxx
+3
-3
StateFile.hxx
src/StateFile.hxx
+3
-2
TextFile.hxx
src/TextFile.hxx
+4
-2
UpdateArchive.cxx
src/UpdateArchive.cxx
+5
-5
UpdateContainer.cxx
src/UpdateContainer.cxx
+6
-7
UpdateIO.cxx
src/UpdateIO.cxx
+20
-27
UpdateWalk.cxx
src/UpdateWalk.cxx
+15
-27
SimpleDatabasePlugin.cxx
src/db/SimpleDatabasePlugin.cxx
+3
-2
SimpleDatabasePlugin.hxx
src/db/SimpleDatabasePlugin.hxx
+5
-2
No files found.
src/DecoderThread.cxx
View file @
e5039c47
...
...
@@ -26,6 +26,7 @@
#include "song.h"
#include "mpd_error.h"
#include "Mapper.hxx"
#include "Path.hxx"
#include "decoder_api.h"
#include "tag.h"
#include "input_stream.h"
...
...
@@ -431,7 +432,7 @@ decoder_run(struct decoder_control *dc)
assert
(
song
!=
NULL
);
if
(
song_is_file
(
song
))
uri
=
map_song_fs
(
song
);
uri
=
map_song_fs
(
song
)
.
Steal
()
;
else
uri
=
song_get_uri
(
song
);
...
...
src/ExcludeList.cxx
View file @
e5039c47
...
...
@@ -32,14 +32,12 @@
#include <errno.h>
bool
ExcludeList
::
LoadFile
(
const
char
*
path_fs
)
ExcludeList
::
LoadFile
(
const
Path
&
path_fs
)
{
assert
(
path_fs
!=
NULL
);
FILE
*
file
=
fopen
(
path_fs
,
"r"
);
FILE
*
file
=
fopen
(
path_fs
.
c_str
(),
"r"
);
if
(
file
==
NULL
)
{
if
(
errno
!=
ENOENT
)
{
char
*
path_utf8
=
fs_charset_to_utf8
(
path_fs
);
char
*
path_utf8
=
path_fs
.
ToUTF8
(
);
g_debug
(
"Failed to open %s: %s"
,
path_utf8
,
g_strerror
(
errno
));
g_free
(
path_utf8
);
...
...
src/ExcludeList.hxx
View file @
e5039c47
...
...
@@ -31,6 +31,8 @@
#include <glib.h>
class
Path
;
class
ExcludeList
{
class
Pattern
{
GPatternSpec
*
pattern
;
...
...
@@ -65,7 +67,7 @@ public:
/**
* Loads and parses a .mpdignore file.
*/
bool
LoadFile
(
const
char
*
path_fs
);
bool
LoadFile
(
const
Path
&
path_fs
);
/**
* Checks whether one of the patterns in the .mpdignore file matches
...
...
src/Main.cxx
View file @
e5039c47
...
...
@@ -238,7 +238,8 @@ glue_state_file_init(GError **error_r)
return
true
;
}
state_file
=
new
StateFile
(
path
,
*
global_partition
,
*
main_loop
);
state_file
=
new
StateFile
(
Path
::
FromUTF8
(
path
),
*
global_partition
,
*
main_loop
);
g_free
(
path
);
state_file
->
Read
();
return
true
;
...
...
src/Mapper.cxx
View file @
e5039c47
...
...
@@ -156,67 +156,54 @@ map_to_relative_path(const char *path_utf8)
:
path_utf8
;
}
char
*
Path
map_uri_fs
(
const
char
*
uri
)
{
char
*
uri_fs
,
*
path_fs
;
assert
(
uri
!=
NULL
);
assert
(
*
uri
!=
'/'
);
if
(
music_dir_fs
==
NULL
)
return
NULL
;
return
Path
::
Null
()
;
uri_fs
=
utf8_to_fs_charset
(
uri
);
if
(
uri_fs
==
NULL
)
return
NULL
;
path_fs
=
g_build_filename
(
music_dir_fs
,
uri_fs
,
NULL
);
g_free
(
uri_fs
);
const
Path
uri_fs
=
Path
::
FromUTF8
(
uri
);
if
(
uri_fs
.
IsNull
())
return
Path
::
Null
();
return
path_fs
;
return
Path
::
Build
(
music_dir_fs
,
uri_fs
)
;
}
char
*
Path
map_directory_fs
(
const
Directory
*
directory
)
{
assert
(
music_dir_utf8
!=
NULL
);
assert
(
music_dir_fs
!=
NULL
);
if
(
directory
->
IsRoot
())
return
g_strdup
(
music_dir_fs
);
return
Path
::
FromFS
(
music_dir_fs
);
return
map_uri_fs
(
directory
->
GetPath
());
}
char
*
Path
map_directory_child_fs
(
const
Directory
*
directory
,
const
char
*
name
)
{
assert
(
music_dir_utf8
!=
NULL
);
assert
(
music_dir_fs
!=
NULL
);
char
*
name_fs
,
*
parent_fs
,
*
path
;
/* check for invalid or unauthorized base names */
if
(
*
name
==
0
||
strchr
(
name
,
'/'
)
!=
NULL
||
strcmp
(
name
,
"."
)
==
0
||
strcmp
(
name
,
".."
)
==
0
)
return
NULL
;
return
Path
::
Null
()
;
parent_fs
=
map_directory_fs
(
directory
);
if
(
parent_fs
==
NULL
)
return
NULL
;
const
Path
parent_fs
=
map_directory_fs
(
directory
);
if
(
parent_fs
.
IsNull
()
)
return
Path
::
Null
()
;
name_fs
=
utf8_to_fs_charset
(
name
);
if
(
name_fs
==
NULL
)
{
g_free
(
parent_fs
);
return
NULL
;
}
path
=
g_build_filename
(
parent_fs
,
name_fs
,
NULL
);
g_free
(
parent_fs
);
g_free
(
name_fs
);
const
Path
name_fs
=
Path
::
FromUTF8
(
name
);
if
(
name_fs
.
IsNull
())
return
Path
::
Null
();
return
path
;
return
Path
::
Build
(
parent_fs
,
name_fs
)
;
}
/**
...
...
@@ -224,19 +211,17 @@ map_directory_child_fs(const Directory *directory, const char *name)
* not have a real parent directory, only the dummy object
* #detached_root.
*/
static
char
*
static
Path
map_detached_song_fs
(
const
char
*
uri_utf8
)
{
char
*
uri_fs
=
utf8_to_fs_charset
(
uri_utf8
);
if
(
uri_fs
==
NULL
)
return
NULL
;
Path
uri_fs
=
Path
::
FromUTF8
(
uri_utf8
);
if
(
uri_fs
.
IsNull
()
)
return
Path
::
Null
()
;
char
*
path
=
g_build_filename
(
music_dir_fs
,
uri_fs
,
NULL
);
g_free
(
uri_fs
);
return
path
;
return
Path
::
Build
(
music_dir_fs
,
uri_fs
);
}
char
*
Path
map_song_fs
(
const
struct
song
*
song
)
{
assert
(
song_is_file
(
song
));
...
...
@@ -246,7 +231,7 @@ map_song_fs(const struct song *song)
?
map_detached_song_fs
(
song
->
uri
)
:
map_directory_child_fs
(
song
->
parent
,
song
->
uri
);
else
return
utf8_to_fs_charset
(
song
->
uri
);
return
Path
::
FromUTF8
(
song
->
uri
);
}
char
*
...
...
@@ -273,22 +258,17 @@ map_spl_path(void)
return
playlist_dir_fs
;
}
char
*
Path
map_spl_utf8_to_fs
(
const
char
*
name
)
{
char
*
filename_utf8
,
*
filename_fs
,
*
path
;
if
(
playlist_dir_fs
==
NULL
)
return
NULL
;
return
Path
::
Null
()
;
filename_utf8
=
g_strconcat
(
name
,
PLAYLIST_FILE_SUFFIX
,
NULL
);
filename_fs
=
utf8_to_fs_charset
(
filename_utf8
);
char
*
filename_utf8
=
g_strconcat
(
name
,
PLAYLIST_FILE_SUFFIX
,
NULL
);
const
Path
filename_fs
=
Path
::
FromUTF8
(
filename_utf8
);
g_free
(
filename_utf8
);
if
(
filename_fs
==
NULL
)
return
NULL
;
path
=
g_build_filename
(
playlist_dir_fs
,
filename_fs
,
NULL
);
g_free
(
filename_fs
);
if
(
filename_fs
.
IsNull
())
return
Path
::
Null
();
return
path
;
return
Path
::
Build
(
playlist_dir_fs
,
filename_fs
)
;
}
src/Mapper.hxx
View file @
e5039c47
...
...
@@ -29,6 +29,7 @@
#define PLAYLIST_FILE_SUFFIX ".m3u"
class
Path
;
struct
Directory
;
struct
song
;
...
...
@@ -75,8 +76,8 @@ map_to_relative_path(const char *path_utf8);
* is basically done by converting the URI to the file system charset
* and prepending the music directory.
*/
gcc_
malloc
char
*
gcc_
pure
Path
map_uri_fs
(
const
char
*
uri
);
/**
...
...
@@ -85,8 +86,8 @@ map_uri_fs(const char *uri);
* @param directory the directory object
* @return the path in file system encoding, or nullptr if mapping failed
*/
gcc_
malloc
char
*
gcc_
pure
Path
map_directory_fs
(
const
Directory
*
directory
);
/**
...
...
@@ -97,8 +98,8 @@ map_directory_fs(const Directory *directory);
* @param name the child's name in UTF-8
* @return the path in file system encoding, or nullptr if mapping failed
*/
gcc_
malloc
char
*
gcc_
pure
Path
map_directory_child_fs
(
const
Directory
*
directory
,
const
char
*
name
);
/**
...
...
@@ -108,8 +109,8 @@ map_directory_child_fs(const Directory *directory, const char *name);
* @param song the song object
* @return the path in file system encoding, or nullptr if mapping failed
*/
gcc_
malloc
char
*
gcc_
pure
Path
map_song_fs
(
const
struct
song
*
song
);
/**
...
...
@@ -138,7 +139,7 @@ map_spl_path(void);
* @return the path in file system encoding, or nullptr if mapping failed
*/
gcc_pure
char
*
Path
map_spl_utf8_to_fs
(
const
char
*
name
);
#endif
src/Path.hxx
View file @
e5039c47
...
...
@@ -21,7 +21,14 @@
#define MPD_PATH_HXX
#include "check.h"
#include "gcc.h"
#include <glib.h>
#include <algorithm>
#include <assert.h>
#include <string.h>
#include <limits.h>
#if !defined(MPD_PATH_MAX)
...
...
@@ -54,4 +61,204 @@ utf8_to_fs_charset(const char *path_utf8);
const
char
*
path_get_fs_charset
();
/**
* A path name in the native file system character set.
*/
class
Path
{
public
:
typedef
char
value_type
;
typedef
value_type
*
pointer
;
typedef
const
value_type
*
const_pointer
;
private
:
pointer
value
;
struct
Donate
{};
/**
* Donate the allocated pointer to a new #Path object.
*/
constexpr
Path
(
Donate
,
pointer
_value
)
:
value
(
_value
)
{}
/**
* Release memory allocated by the value, but do not clear the
* value pointer.
*/
void
Free
()
{
/* free() can be optimized by gcc, while g_free() can
not: when the compiler knows that the value is
nullptr, it will not emit a free() call in the
inlined destructor; however on Windows, we need to
call g_free(), because the value has been allocated
by GLib, and on Windows, this matters */
#ifdef WIN32
g_free
(
value
);
#else
free
(
value
);
#endif
}
public
:
/**
* Copy a #Path object.
*/
Path
(
const
Path
&
other
)
:
value
(
g_strdup
(
other
.
value
))
{}
/**
* Move a #Path object.
*/
Path
(
Path
&&
other
)
:
value
(
other
.
value
)
{
other
.
value
=
nullptr
;
}
~
Path
()
{
Free
();
}
/**
* Return a "nulled" instance. Its IsNull() method will
* return true. Such an object must not be used.
*
* @see IsNull()
*/
gcc_const
static
Path
Null
()
{
return
Path
(
Donate
(),
nullptr
);
}
/**
* Join two path components with the path separator.
*/
gcc_pure
gcc_nonnull_all
static
Path
Build
(
const_pointer
a
,
const_pointer
b
)
{
return
Path
(
Donate
(),
g_build_filename
(
a
,
b
,
nullptr
));
}
gcc_pure
gcc_nonnull_all
static
Path
Build
(
const_pointer
a
,
const
Path
&
b
)
{
return
Build
(
a
,
b
.
c_str
());
}
gcc_pure
gcc_nonnull_all
static
Path
Build
(
const
Path
&
a
,
const_pointer
b
)
{
return
Build
(
a
.
c_str
(),
b
);
}
gcc_pure
static
Path
Build
(
const
Path
&
a
,
const
Path
&
b
)
{
return
Build
(
a
.
c_str
(),
b
.
c_str
());
}
/**
* Convert a C string that is already in the filesystem
* character set to a #Path instance.
*/
gcc_pure
static
Path
FromFS
(
const_pointer
fs
)
{
return
Path
(
Donate
(),
g_strdup
(
fs
));
}
/**
* Convert a UTF-8 C string to a #Path instance.
*
* TODO: return a "nulled" instance on error and add checks to
* all callers
*/
gcc_pure
static
Path
FromUTF8
(
const
char
*
utf8
)
{
return
Path
(
Donate
(),
utf8_to_fs_charset
(
utf8
));
}
/**
* Copy a #Path object.
*/
Path
&
operator
=
(
const
Path
&
other
)
{
if
(
this
!=
&
other
)
{
Free
();
value
=
g_strdup
(
other
.
value
);
}
return
*
this
;
}
/**
* Move a #Path object.
*/
Path
&
operator
=
(
Path
&&
other
)
{
std
::
swap
(
value
,
other
.
value
);
return
*
this
;
}
/**
* Steal the allocated value. This object has an undefined
* value, and the caller is response for freeing this method's
* return value.
*/
pointer
Steal
()
{
pointer
result
=
value
;
value
=
nullptr
;
return
result
;
}
/**
* Check if this is a "nulled" instance. A "nulled" instance
* must not be used.
*/
bool
IsNull
()
const
{
return
value
==
nullptr
;
}
/**
* Clear this object's value, make it "nulled".
*
* @see IsNull()
*/
void
SetNull
()
{
Free
();
value
=
nullptr
;
}
gcc_pure
bool
empty
()
const
{
assert
(
value
!=
nullptr
);
return
*
value
==
0
;
}
/**
* @return the length of this string in number of "value_type"
* elements (which may not be the number of characters).
*/
gcc_pure
size_t
length
()
const
{
assert
(
value
!=
nullptr
);
return
strlen
(
value
);
}
/**
* Returns the value as a const C string. The returned
* pointer is invalidated whenever the value of life of this
* instance ends.
*/
gcc_pure
const_pointer
c_str
()
const
{
assert
(
value
!=
nullptr
);
return
value
;
}
/**
* Convert the path to UTF-8. The caller is responsible for
* freeing the return value with g_free(). Returns nullptr on
* error.
*/
char
*
ToUTF8
()
const
{
return
value
!=
nullptr
?
fs_charset_to_utf8
(
value
)
:
nullptr
;
}
};
#endif
src/PlaylistFile.cxx
View file @
e5039c47
...
...
@@ -106,15 +106,15 @@ spl_check_name(const char *name_utf8, GError **error_r)
return
true
;
}
static
char
*
static
Path
spl_map_to_fs
(
const
char
*
name_utf8
,
GError
**
error_r
)
{
if
(
spl_map
(
error_r
)
==
NULL
||
!
spl_check_name
(
name_utf8
,
error_r
))
return
NULL
;
return
Path
::
Null
()
;
char
*
path_fs
=
map_spl_utf8_to_fs
(
name_utf8
);
if
(
path_fs
==
NULL
)
Path
path_fs
=
map_spl_utf8_to_fs
(
name_utf8
);
if
(
path_fs
.
IsNull
()
)
g_set_error_literal
(
error_r
,
playlist_quark
(),
PLAYLIST_RESULT_BAD_NAME
,
"Bad playlist name"
);
...
...
@@ -209,12 +209,11 @@ SavePlaylistFile(const PlaylistFileContents &contents, const char *utf8path,
if
(
spl_map
(
error_r
)
==
NULL
)
return
false
;
c
har
*
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
.
IsNull
()
)
return
false
;
FILE
*
file
=
fopen
(
path_fs
,
"w"
);
g_free
(
path_fs
);
FILE
*
file
=
fopen
(
path_fs
.
c_str
(),
"w"
);
if
(
file
==
NULL
)
{
playlist_errno
(
error_r
);
return
false
;
...
...
@@ -235,8 +234,8 @@ LoadPlaylistFile(const char *utf8path, GError **error_r)
if
(
spl_map
(
error_r
)
==
NULL
)
return
contents
;
c
har
*
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
.
IsNull
()
)
return
contents
;
TextFile
file
(
path_fs
);
...
...
@@ -308,17 +307,14 @@ spl_move_index(const char *utf8path, unsigned src, unsigned dest,
bool
spl_clear
(
const
char
*
utf8path
,
GError
**
error_r
)
{
FILE
*
file
;
if
(
spl_map
(
error_r
)
==
NULL
)
return
false
;
c
har
*
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
.
IsNull
()
)
return
false
;
file
=
fopen
(
path_fs
,
"w"
);
g_free
(
path_fs
);
FILE
*
file
=
fopen
(
path_fs
.
c_str
(),
"w"
);
if
(
file
==
NULL
)
{
playlist_errno
(
error_r
);
return
false
;
...
...
@@ -333,12 +329,11 @@ spl_clear(const char *utf8path, GError **error_r)
bool
spl_delete
(
const
char
*
name_utf8
,
GError
**
error_r
)
{
c
har
*
path_fs
=
spl_map_to_fs
(
name_utf8
,
error_r
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
spl_map_to_fs
(
name_utf8
,
error_r
);
if
(
path_fs
.
IsNull
()
)
return
false
;
int
ret
=
unlink
(
path_fs
);
g_free
(
path_fs
);
int
ret
=
unlink
(
path_fs
.
c_str
());
if
(
ret
<
0
)
{
playlist_errno
(
error_r
);
return
false
;
...
...
@@ -376,17 +371,14 @@ spl_remove_index(const char *utf8path, unsigned pos, GError **error_r)
bool
spl_append_song
(
const
char
*
utf8path
,
struct
song
*
song
,
GError
**
error_r
)
{
FILE
*
file
;
if
(
spl_map
(
error_r
)
==
NULL
)
return
false
;
c
har
*
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
spl_map_to_fs
(
utf8path
,
error_r
);
if
(
path_fs
.
IsNull
()
)
return
false
;
file
=
fopen
(
path_fs
,
"a"
);
g_free
(
path_fs
);
FILE
*
file
=
fopen
(
path_fs
.
c_str
(),
"a"
);
if
(
file
==
NULL
)
{
playlist_errno
(
error_r
);
return
false
;
...
...
@@ -439,24 +431,24 @@ spl_append_uri(const char *url, const char *utf8file, GError **error_r)
}
static
bool
spl_rename_internal
(
const
char
*
from_path_fs
,
const
char
*
to_path_fs
,
spl_rename_internal
(
const
Path
&
from_path_fs
,
const
Path
&
to_path_fs
,
GError
**
error_r
)
{
if
(
!
g_file_test
(
from_path_fs
,
G_FILE_TEST_IS_REGULAR
))
{
if
(
!
g_file_test
(
from_path_fs
.
c_str
()
,
G_FILE_TEST_IS_REGULAR
))
{
g_set_error_literal
(
error_r
,
playlist_quark
(),
PLAYLIST_RESULT_NO_SUCH_LIST
,
"No such playlist"
);
return
false
;
}
if
(
g_file_test
(
to_path_fs
,
G_FILE_TEST_EXISTS
))
{
if
(
g_file_test
(
to_path_fs
.
c_str
()
,
G_FILE_TEST_EXISTS
))
{
g_set_error_literal
(
error_r
,
playlist_quark
(),
PLAYLIST_RESULT_LIST_EXISTS
,
"Playlist exists already"
);
return
false
;
}
if
(
rename
(
from_path_fs
,
to_path_fs
)
<
0
)
{
if
(
rename
(
from_path_fs
.
c_str
(),
to_path_fs
.
c_str
()
)
<
0
)
{
playlist_errno
(
error_r
);
return
false
;
}
...
...
@@ -471,20 +463,13 @@ spl_rename(const char *utf8from, const char *utf8to, GError **error_r)
if
(
spl_map
(
error_r
)
==
NULL
)
return
false
;
char
*
from_path_fs
=
spl_map_to_fs
(
utf8from
,
error_r
);
if
(
from_path_fs
==
NULL
)
Path
from_path_fs
=
spl_map_to_fs
(
utf8from
,
error_r
);
if
(
from_path_fs
.
IsNull
()
)
return
false
;
char
*
to_path_fs
=
spl_map_to_fs
(
utf8to
,
error_r
);
if
(
to_path_fs
==
NULL
)
{
g_free
(
from_path_fs
);
Path
to_path_fs
=
spl_map_to_fs
(
utf8to
,
error_r
);
if
(
to_path_fs
.
IsNull
())
return
false
;
}
bool
success
=
spl_rename_internal
(
from_path_fs
,
to_path_fs
,
error_r
);
g_free
(
from_path_fs
);
g_free
(
to_path_fs
);
return
s
uccess
;
return
s
pl_rename_internal
(
from_path_fs
,
to_path_fs
,
error_r
)
;
}
src/PlaylistMapper.cxx
View file @
e5039c47
...
...
@@ -21,6 +21,7 @@
#include "PlaylistMapper.hxx"
#include "PlaylistFile.hxx"
#include "Mapper.hxx"
#include "Path.hxx"
extern
"C"
{
#include "playlist_list.h"
...
...
@@ -75,19 +76,13 @@ static struct playlist_provider *
playlist_open_in_music_dir
(
const
char
*
uri
,
GMutex
*
mutex
,
GCond
*
cond
,
struct
input_stream
**
is_r
)
{
char
*
path_fs
;
assert
(
uri_safe_local
(
uri
));
path_fs
=
map_uri_fs
(
uri
);
if
(
path
_fs
==
NULL
)
Path
path
=
map_uri_fs
(
uri
);
if
(
path
.
IsNull
()
)
return
NULL
;
struct
playlist_provider
*
playlist
=
playlist_open_path
(
path_fs
,
mutex
,
cond
,
is_r
);
g_free
(
path_fs
);
return
playlist
;
return
playlist_open_path
(
path
.
c_str
(),
mutex
,
cond
,
is_r
);
}
struct
playlist_provider
*
...
...
src/PlaylistSave.cxx
View file @
e5039c47
...
...
@@ -38,62 +38,47 @@ void
playlist_print_song
(
FILE
*
file
,
const
struct
song
*
song
)
{
if
(
playlist_saveAbsolutePaths
&&
song_in_database
(
song
))
{
char
*
path
=
map_song_fs
(
song
);
if
(
path
!=
NULL
)
{
fprintf
(
file
,
"%s
\n
"
,
path
);
g_free
(
path
);
}
const
Path
path
=
map_song_fs
(
song
);
if
(
!
path
.
IsNull
())
fprintf
(
file
,
"%s
\n
"
,
path
.
c_str
());
}
else
{
char
*
uri
=
song_get_uri
(
song
),
*
uri_fs
;
uri_fs
=
utf8_to_fs_charset
(
uri
);
char
*
uri
=
song_get_uri
(
song
);
const
Path
uri_fs
=
Path
::
FromUTF8
(
uri
);
g_free
(
uri
);
fprintf
(
file
,
"%s
\n
"
,
uri_fs
);
g_free
(
uri_fs
);
fprintf
(
file
,
"%s
\n
"
,
uri_fs
.
c_str
());
}
}
void
playlist_print_uri
(
FILE
*
file
,
const
char
*
uri
)
{
char
*
s
;
if
(
playlist_saveAbsolutePaths
&&
!
uri_has_scheme
(
uri
)
&&
!
g_path_is_absolute
(
uri
))
s
=
map_uri_fs
(
uri
);
else
s
=
utf8_to_fs_charset
(
uri
);
Path
path
=
playlist_saveAbsolutePaths
&&
!
uri_has_scheme
(
uri
)
&&
!
g_path_is_absolute
(
uri
)
?
map_uri_fs
(
uri
)
:
Path
::
FromUTF8
(
uri
);
if
(
s
!=
NULL
)
{
fprintf
(
file
,
"%s
\n
"
,
s
);
g_free
(
s
);
}
if
(
!
path
.
IsNull
())
fprintf
(
file
,
"%s
\n
"
,
path
.
c_str
());
}
enum
playlist_result
spl_save_queue
(
const
char
*
name_utf8
,
const
struct
queue
*
queue
)
{
char
*
path_fs
;
FILE
*
file
;
if
(
map_spl_path
()
==
NULL
)
return
PLAYLIST_RESULT_DISABLED
;
if
(
!
spl_valid_name
(
name_utf8
))
return
PLAYLIST_RESULT_BAD_NAME
;
path_fs
=
map_spl_utf8_to_fs
(
name_utf8
);
if
(
path_fs
==
NULL
)
const
Path
path_fs
=
map_spl_utf8_to_fs
(
name_utf8
);
if
(
path_fs
.
IsNull
()
)
return
PLAYLIST_RESULT_BAD_NAME
;
if
(
g_file_test
(
path_fs
,
G_FILE_TEST_EXISTS
))
{
g_free
(
path_fs
);
if
(
g_file_test
(
path_fs
.
c_str
(),
G_FILE_TEST_EXISTS
))
return
PLAYLIST_RESULT_LIST_EXISTS
;
}
file
=
fopen
(
path_fs
,
"w"
);
g_free
(
path_fs
);
FILE
*
file
=
fopen
(
path_fs
.
c_str
(),
"w"
);
if
(
file
==
NULL
)
return
PLAYLIST_RESULT_ERRNO
;
...
...
src/PlaylistSong.cxx
View file @
e5039c47
...
...
@@ -65,8 +65,8 @@ apply_song_metadata(struct song *dest, const struct song *src)
return
dest
;
if
(
song_in_database
(
dest
))
{
char
*
path_fs
=
map_song_fs
(
dest
);
if
(
path_fs
==
NULL
)
char
*
path_fs
=
map_song_fs
(
dest
)
.
Steal
()
;
if
(
path_fs
==
nullptr
)
return
dest
;
char
*
path_utf8
=
fs_charset_to_utf8
(
path_fs
);
...
...
src/SongUpdate.cxx
View file @
e5039c47
...
...
@@ -26,6 +26,7 @@ extern "C" {
#include "Directory.hxx"
#include "Mapper.hxx"
#include "Path.hxx"
#include "tag.h"
#include "input_stream.h"
...
...
@@ -85,7 +86,6 @@ bool
song_file_update
(
struct
song
*
song
)
{
const
char
*
suffix
;
char
*
path_fs
;
const
struct
decoder_plugin
*
plugin
;
struct
stat
st
;
struct
input_stream
*
is
=
NULL
;
...
...
@@ -102,8 +102,8 @@ song_file_update(struct song *song)
if
(
plugin
==
NULL
)
return
false
;
path_fs
=
map_song_fs
(
song
);
if
(
path_fs
==
NULL
)
const
Path
path_fs
=
map_song_fs
(
song
);
if
(
path_fs
.
IsNull
()
)
return
false
;
if
(
song
->
tag
!=
NULL
)
{
...
...
@@ -111,8 +111,7 @@ song_file_update(struct song *song)
song
->
tag
=
NULL
;
}
if
(
stat
(
path_fs
,
&
st
)
<
0
||
!
S_ISREG
(
st
.
st_mode
))
{
g_free
(
path_fs
);
if
(
stat
(
path_fs
.
c_str
(),
&
st
)
<
0
||
!
S_ISREG
(
st
.
st_mode
))
{
return
false
;
}
...
...
@@ -129,7 +128,7 @@ song_file_update(struct song *song)
do
{
/* load file tag */
song
->
tag
=
tag_new
();
if
(
decoder_plugin_scan_file
(
plugin
,
path_fs
,
if
(
decoder_plugin_scan_file
(
plugin
,
path_fs
.
c_str
()
,
&
full_tag_handler
,
song
->
tag
))
break
;
...
...
@@ -143,7 +142,8 @@ song_file_update(struct song *song)
if
(
is
==
NULL
)
{
mutex
=
g_mutex_new
();
cond
=
g_cond_new
();
is
=
input_stream_open
(
path_fs
,
mutex
,
cond
,
is
=
input_stream_open
(
path_fs
.
c_str
(),
mutex
,
cond
,
NULL
);
}
...
...
@@ -174,9 +174,9 @@ song_file_update(struct song *song)
}
if
(
song
->
tag
!=
NULL
&&
tag_is_empty
(
song
->
tag
))
tag_scan_fallback
(
path_fs
,
&
full_tag_handler
,
song
->
tag
);
tag_scan_fallback
(
path_fs
.
c_str
(),
&
full_tag_handler
,
song
->
tag
);
g_free
(
path_fs
);
return
song
->
tag
!=
NULL
;
}
...
...
src/StateFile.cxx
View file @
e5039c47
...
...
@@ -34,8 +34,8 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "state_file"
StateFile
::
StateFile
(
const
char
*
_path
,
Partition
&
_partition
,
EventLoop
&
_loop
)
:
TimeoutMonitor
(
_loop
),
path
(
_path
),
partition
(
_partition
),
StateFile
::
StateFile
(
Path
&&
_path
,
Partition
&
_partition
,
EventLoop
&
_loop
)
:
TimeoutMonitor
(
_loop
),
path
(
std
::
move
(
_path
)
),
partition
(
_partition
),
prev_volume_version
(
0
),
prev_output_version
(
0
),
prev_playlist_version
(
0
)
{
...
...
@@ -73,7 +73,7 @@ StateFile::Read()
g_debug
(
"Loading state file %s"
,
path
.
c_str
());
TextFile
file
(
path
.
c_str
()
);
TextFile
file
(
path
);
if
(
file
.
HasFailed
())
{
g_warning
(
"failed to open %s: %s"
,
path
.
c_str
(),
g_strerror
(
errno
));
...
...
src/StateFile.hxx
View file @
e5039c47
...
...
@@ -21,6 +21,7 @@
#define MPD_STATE_FILE_HXX
#include "event/TimeoutMonitor.hxx"
#include "Path.hxx"
#include "gcc.h"
#include <string>
...
...
@@ -28,7 +29,7 @@
struct
Partition
;
class
StateFile
final
:
private
TimeoutMonitor
{
std
::
string
path
;
Path
path
;
Partition
&
partition
;
...
...
@@ -40,7 +41,7 @@ class StateFile final : private TimeoutMonitor {
prev_playlist_version
;
public
:
StateFile
(
const
char
*
path
,
Partition
&
partition
,
EventLoop
&
loop
);
StateFile
(
Path
&&
path
,
Partition
&
partition
,
EventLoop
&
loop
);
void
Read
();
void
Write
();
...
...
src/TextFile.hxx
View file @
e5039c47
...
...
@@ -21,6 +21,7 @@
#define MPD_TEXT_FILE_HXX
#include "gcc.h"
#include "Path.hxx"
#include <glib.h>
...
...
@@ -35,8 +36,9 @@ class TextFile {
GString
*
const
buffer
;
public
:
TextFile
(
const
char
*
path_fs
)
:
file
(
fopen
(
path_fs
,
"r"
)),
buffer
(
g_string_sized_new
(
step
))
{}
TextFile
(
const
Path
&
path_fs
)
:
file
(
fopen
(
path_fs
.
c_str
(),
"r"
)),
buffer
(
g_string_sized_new
(
step
))
{}
TextFile
(
const
TextFile
&
other
)
=
delete
;
...
...
src/UpdateArchive.cxx
View file @
e5039c47
...
...
@@ -24,6 +24,7 @@
#include "Directory.hxx"
#include "song.h"
#include "Mapper.hxx"
#include "Path.hxx"
extern
"C"
{
#include "archive_list.h"
...
...
@@ -96,20 +97,19 @@ update_archive_file2(Directory *parent, const char *name,
changed since - don't consider updating it */
return
;
c
har
*
path_fs
=
map_directory_child_fs
(
parent
,
name
);
c
onst
Path
path_fs
=
map_directory_child_fs
(
parent
,
name
);
/* open archive */
GError
*
error
=
NULL
;
struct
archive_file
*
file
=
archive_file_open
(
plugin
,
path_fs
,
&
error
);
struct
archive_file
*
file
=
archive_file_open
(
plugin
,
path_fs
.
c_str
(),
&
error
);
if
(
file
==
NULL
)
{
g_free
(
path_fs
);
g_warning
(
"%s"
,
error
->
message
);
g_error_free
(
error
);
return
;
}
g_debug
(
"archive %s opened"
,
path_fs
);
g_free
(
path_fs
);
g_debug
(
"archive %s opened"
,
path_fs
.
c_str
());
if
(
directory
==
NULL
)
{
g_debug
(
"creating archive directory: %s"
,
name
);
...
...
src/UpdateContainer.cxx
View file @
e5039c47
...
...
@@ -26,6 +26,7 @@
#include "song.h"
#include "decoder_plugin.h"
#include "Mapper.hxx"
#include "Path.hxx"
extern
"C"
{
#include "tag_handler.h"
...
...
@@ -84,22 +85,22 @@ update_container_file(Directory *directory,
contdir
->
device
=
DEVICE_CONTAINER
;
db_unlock
();
c
har
*
const
pathname
=
map_directory_child_fs
(
directory
,
name
);
c
onst
Path
pathname
=
map_directory_child_fs
(
directory
,
name
);
char
*
vtrack
;
unsigned
int
tnum
=
0
;
while
((
vtrack
=
plugin
->
container_scan
(
pathname
,
++
tnum
))
!=
NULL
)
{
while
((
vtrack
=
plugin
->
container_scan
(
pathname
.
c_str
()
,
++
tnum
))
!=
NULL
)
{
struct
song
*
song
=
song_file_new
(
vtrack
,
contdir
);
// shouldn't be necessary but it's there..
song
->
mtime
=
st
->
st_mtime
;
char
*
child_path_fs
=
map_directory_child_fs
(
contdir
,
vtrack
);
const
Path
child_path_fs
=
map_directory_child_fs
(
contdir
,
vtrack
);
song
->
tag
=
tag_new
();
decoder_plugin_scan_file
(
plugin
,
child_path_fs
,
decoder_plugin_scan_file
(
plugin
,
child_path_fs
.
c_str
()
,
&
add_tag_handler
,
song
->
tag
);
g_free
(
child_path_fs
);
db_lock
();
contdir
->
AddSong
(
song
);
...
...
@@ -111,8 +112,6 @@ update_container_file(Directory *directory,
g_free
(
vtrack
);
}
g_free
(
pathname
);
if
(
tnum
==
1
)
{
db_lock
();
delete_directory
(
contdir
);
...
...
src/UpdateIO.cxx
View file @
e5039c47
...
...
@@ -21,6 +21,7 @@
#include "UpdateIO.hxx"
#include "Directory.hxx"
#include "Mapper.hxx"
#include "Path.hxx"
#include "glib_compat.h"
#include <glib.h>
...
...
@@ -31,15 +32,15 @@
int
stat_directory
(
const
Directory
*
directory
,
struct
stat
*
st
)
{
c
har
*
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
.
IsNull
()
)
return
-
1
;
int
ret
=
stat
(
path_fs
,
st
);
int
ret
=
stat
(
path_fs
.
c_str
()
,
st
);
if
(
ret
<
0
)
g_warning
(
"Failed to stat %s: %s"
,
path_fs
,
g_strerror
(
errno
));
g_warning
(
"Failed to stat %s: %s"
,
path_fs
.
c_str
(),
g_strerror
(
errno
));
g_free
(
path_fs
);
return
ret
;
}
...
...
@@ -47,23 +48,23 @@ int
stat_directory_child
(
const
Directory
*
parent
,
const
char
*
name
,
struct
stat
*
st
)
{
c
har
*
path_fs
=
map_directory_child_fs
(
parent
,
name
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_child_fs
(
parent
,
name
);
if
(
path_fs
.
IsNull
()
)
return
-
1
;
int
ret
=
stat
(
path_fs
,
st
);
int
ret
=
stat
(
path_fs
.
c_str
()
,
st
);
if
(
ret
<
0
)
g_warning
(
"Failed to stat %s: %s"
,
path_fs
,
g_strerror
(
errno
));
g_warning
(
"Failed to stat %s: %s"
,
path_fs
.
c_str
(),
g_strerror
(
errno
));
g_free
(
path_fs
);
return
ret
;
}
bool
directory_exists
(
const
Directory
*
directory
)
{
c
har
*
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
.
IsNull
()
)
/* invalid path: cannot exist */
return
false
;
...
...
@@ -72,25 +73,19 @@ directory_exists(const Directory *directory)
?
G_FILE_TEST_IS_REGULAR
:
G_FILE_TEST_IS_DIR
;
bool
exists
=
g_file_test
(
path_fs
,
test
);
g_free
(
path_fs
);
return
exists
;
return
g_file_test
(
path_fs
.
c_str
(),
test
);
}
bool
directory_child_is_regular
(
const
Directory
*
directory
,
const
char
*
name_utf8
)
{
c
har
*
path_fs
=
map_directory_child_fs
(
directory
,
name_utf8
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_child_fs
(
directory
,
name_utf8
);
if
(
path_fs
.
IsNull
()
)
return
false
;
struct
stat
st
;
bool
is_regular
=
stat
(
path_fs
,
&
st
)
==
0
&&
S_ISREG
(
st
.
st_mode
);
g_free
(
path_fs
);
return
is_regular
;
return
stat
(
path_fs
.
c_str
(),
&
st
)
==
0
&&
S_ISREG
(
st
.
st_mode
);
}
bool
...
...
@@ -104,14 +99,12 @@ directory_child_access(const Directory *directory,
(
void
)
mode
;
return
true
;
#else
c
har
*
path
=
map_directory_child_fs
(
directory
,
name
);
if
(
path
==
NULL
)
c
onst
Path
path
=
map_directory_child_fs
(
directory
,
name
);
if
(
path
.
IsNull
()
)
/* something went wrong, but that isn't a permission
problem */
return
true
;
bool
success
=
access
(
path
,
mode
)
==
0
||
errno
!=
EACCES
;
g_free
(
path
);
return
success
;
return
access
(
path
.
c_str
(),
mode
)
==
0
||
errno
!=
EACCES
;
#endif
}
src/UpdateWalk.cxx
View file @
e5039c47
...
...
@@ -102,27 +102,23 @@ remove_excluded_from_directory(Directory *directory,
Directory
*
child
,
*
n
;
directory_for_each_child_safe
(
child
,
n
,
directory
)
{
c
har
*
name_fs
=
utf8_to_fs_charset
(
child
->
GetName
());
c
onst
Path
name_fs
=
Path
::
FromUTF8
(
child
->
GetName
());
if
(
exclude_list
.
Check
(
name_fs
))
{
if
(
exclude_list
.
Check
(
name_fs
.
c_str
()
))
{
delete_directory
(
child
);
modified
=
true
;
}
g_free
(
name_fs
);
}
struct
song
*
song
,
*
ns
;
directory_for_each_song_safe
(
song
,
ns
,
directory
)
{
assert
(
song
->
parent
==
directory
);
c
har
*
name_fs
=
utf8_to_fs_charset
(
song
->
uri
);
if
(
exclude_list
.
Check
(
name_fs
))
{
c
onst
Path
name_fs
=
Path
::
FromUTF8
(
song
->
uri
);
if
(
exclude_list
.
Check
(
name_fs
.
c_str
()
))
{
delete_song
(
directory
,
song
);
modified
=
true
;
}
g_free
(
name_fs
);
}
db_unlock
();
...
...
@@ -145,18 +141,16 @@ purge_deleted_from_directory(Directory *directory)
struct
song
*
song
,
*
ns
;
directory_for_each_song_safe
(
song
,
ns
,
directory
)
{
char
*
path
;
struct
stat
st
;
if
((
path
=
map_song_fs
(
song
))
==
NULL
||
stat
(
path
,
&
st
)
<
0
||
!
S_ISREG
(
st
.
st_mode
))
{
const
Path
path
=
map_song_fs
(
song
);
if
(
path
.
IsNull
()
||
stat
(
path
.
c_str
(),
&
st
)
<
0
||
!
S_ISREG
(
st
.
st_mode
))
{
db_lock
();
delete_song
(
directory
,
song
);
db_unlock
();
modified
=
true
;
}
g_free
(
path
);
}
for
(
auto
i
=
directory
->
playlists
.
begin
(),
...
...
@@ -283,13 +277,12 @@ static bool
skip_symlink
(
const
Directory
*
directory
,
const
char
*
utf8_name
)
{
#ifndef WIN32
c
har
*
path_fs
=
map_directory_child_fs
(
directory
,
utf8_name
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_child_fs
(
directory
,
utf8_name
);
if
(
path_fs
.
IsNull
()
)
return
true
;
char
buffer
[
MPD_PATH_MAX
];
ssize_t
length
=
readlink
(
path_fs
,
buffer
,
sizeof
(
buffer
));
g_free
(
path_fs
);
ssize_t
length
=
readlink
(
path_fs
.
c_str
(),
buffer
,
sizeof
(
buffer
));
if
(
length
<
0
)
/* don't skip if this is not a symlink */
return
errno
!=
EINVAL
;
...
...
@@ -359,24 +352,19 @@ update_directory(Directory *directory, const struct stat *st)
directory_set_stat
(
directory
,
st
);
c
har
*
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
==
NULL
)
c
onst
Path
path_fs
=
map_directory_fs
(
directory
);
if
(
path_fs
.
IsNull
()
)
return
false
;
DIR
*
dir
=
opendir
(
path_fs
);
DIR
*
dir
=
opendir
(
path_fs
.
c_str
()
);
if
(
!
dir
)
{
g_warning
(
"Failed to open directory %s: %s"
,
path_fs
,
g_strerror
(
errno
));
g_free
(
path_fs
);
path_fs
.
c_str
(),
g_strerror
(
errno
));
return
false
;
}
char
*
exclude_path_fs
=
g_build_filename
(
path_fs
,
".mpdignore"
,
NULL
);
ExcludeList
exclude_list
;
exclude_list
.
LoadFile
(
exclude_path_fs
);
g_free
(
exclude_path_fs
);
g_free
(
path_fs
);
exclude_list
.
LoadFile
(
Path
::
Build
(
path_fs
,
".mpdignore"
));
if
(
!
exclude_list
.
IsEmpty
())
remove_excluded_from_directory
(
directory
,
exclude_list
);
...
...
src/db/SimpleDatabasePlugin.cxx
View file @
e5039c47
...
...
@@ -68,7 +68,7 @@ SimpleDatabase::Configure(const struct config_param *param, GError **error_r)
return
false
;
}
path
=
_path
;
path
=
Path
::
FromUTF8
(
_path
)
;
free
(
_path
);
return
true
;
...
...
@@ -77,6 +77,7 @@ SimpleDatabase::Configure(const struct config_param *param, GError **error_r)
bool
SimpleDatabase
::
Check
(
GError
**
error_r
)
const
{
assert
(
!
path
.
IsNull
());
assert
(
!
path
.
empty
());
/* Check if the file exists */
...
...
@@ -153,7 +154,7 @@ SimpleDatabase::Load(GError **error_r)
assert
(
!
path
.
empty
());
assert
(
root
!=
NULL
);
TextFile
file
(
path
.
c_str
()
);
TextFile
file
(
path
);
if
(
file
.
HasFailed
())
{
g_set_error
(
error_r
,
simple_db_quark
(),
errno
,
"Failed to open database file
\"
%s
\"
: %s"
,
...
...
src/db/SimpleDatabasePlugin.hxx
View file @
e5039c47
...
...
@@ -21,17 +21,17 @@
#define MPD_SIMPLE_DATABASE_PLUGIN_HXX
#include "DatabasePlugin.hxx"
#include "Path.hxx"
#include "gcc.h"
#include <cassert>
#include <string>
#include <time.h>
struct
Directory
;
class
SimpleDatabase
:
public
Database
{
std
::
string
path
;
Path
path
;
Directory
*
root
;
...
...
@@ -41,6 +41,9 @@ class SimpleDatabase : public Database {
unsigned
borrowed_song_count
;
#endif
SimpleDatabase
()
:
path
(
Path
::
Null
())
{}
public
:
gcc_pure
Directory
*
GetRoot
()
{
...
...
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