/*****************************************************************************
* device.cpp: Media library network device
*****************************************************************************
* Copyright (C) 2018 VLC authors, VideoLAN and VideoLabs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "device.h"
#include <algorithm>
#include <cassert>
#include <cstring>
namespace vlc {
namespace medialibrary {
SDDevice::SDDevice(const std::string& uuid, std::string scheme, bool removable, bool isNetwork)
: m_uuid(uuid)
, m_scheme( std::move( scheme ) )
, m_removable(removable)
, m_isNetwork(isNetwork)
{
}
const std::string &
SDDevice::uuid() const
{
return m_uuid;
}
bool
SDDevice::isRemovable() const
{
return m_removable;
}
bool
SDDevice::isPresent() const
{
return m_mountpoints.empty() == false;
}
bool SDDevice::isNetwork() const
{
return m_isNetwork;
}
std::vector<std::string> SDDevice::mountpoints() const
{
std::vector<std::string> res;
res.reserve( m_mountpoints.size() );
for ( const auto& m : m_mountpoints )
res.push_back( m.mrl );
return res;
}
void SDDevice::addMountpoint( std::string mrl )
{
// Ensure the mountpoint always ends with a '/' to avoid mismatch between
// smb://foo and smb://foo/
if ( *mrl.crbegin() != '/' )
mrl += '/';
auto it = std::find_if( cbegin( m_mountpoints ), cend( m_mountpoints ),
[&mrl]( const Mountpoint& mp ) { return mp.mrl == mrl; } );
if ( it != cend( m_mountpoints ) )
return;
try
{
auto mp = Mountpoint{ std::move( mrl ) };
m_mountpoints.push_back( std::move( mp ) );
}
catch ( const vlc::url::invalid& )
{
}
}
void SDDevice::removeMountpoint( const std::string& cmrl )
{
std::string mrl;
if ( *cmrl.crbegin() != '/' )
mrl = cmrl + '/';
else
mrl = cmrl;
auto it = std::find_if( begin( m_mountpoints ), end( m_mountpoints ),
[&mrl]( const Mountpoint& mp ) { return mp.mrl == mrl; } );
if ( it != end( m_mountpoints ) )
m_mountpoints.erase( it );
}
std::tuple<bool, std::string>
SDDevice::matchesMountpoint( const std::string& mrl ) const
{
vlc::url probedUrl;
try
{
probedUrl = vlc::url{ mrl };
}
catch ( const vlc::url::invalid& )
{
return std::make_tuple( false, "" );
}
for ( const auto& m : m_mountpoints )
{
if ( strcasecmp( probedUrl.psz_protocol, m.url.psz_protocol ) )
continue;
if ( strcasecmp( probedUrl.psz_host, m.url.psz_host ) )
continue;
/* Ignore path for plain network hosts, ie. without any path specified */
if ( m.url.psz_path != nullptr && *m.url.psz_path != 0 &&
probedUrl.psz_path != nullptr &&
strncasecmp( m.url.psz_path, probedUrl.psz_path,
strlen( m.url.psz_path ) ) != 0 )
{
continue;
}
if ( probedUrl.i_port != m.url.i_port )
{
unsigned int defaultPort = 0;
if ( !strcasecmp( probedUrl.psz_protocol, "smb" ) )
defaultPort = 445;
if ( defaultPort != 0 )
{
if ( probedUrl.i_port != 0 && probedUrl.i_port != defaultPort &&
m.url.i_port != 0 && m.url.i_port != defaultPort )
{
continue;
}
vlc_url_t url = m.url;
url.i_port = probedUrl.i_port;
char* tmpUrl_psz = vlc_uri_compose(&url);
if (!tmpUrl_psz)
continue;
std::string tmpUrl(tmpUrl_psz);
free(tmpUrl_psz);
return std::make_tuple( true, tmpUrl );
}
continue;
}
return std::make_tuple( true, m.mrl );
}
return std::make_tuple( false, "" );
}
std::string SDDevice::relativeMrl( const std::string& absoluteMrl ) const
{
auto match = matchesMountpoint( absoluteMrl );
if ( std::get<0>( match ) == false )
return absoluteMrl;
const auto& mountpoint = std::get<1>( match );
return absoluteMrl.substr( mountpoint.length() );
}
std::string SDDevice::absoluteMrl( const std::string& relativeMrl ) const
{
assert( m_mountpoints.empty() == false );
return m_mountpoints[0].mrl + relativeMrl;
}
const std::string& SDDevice::scheme() const
{
return m_scheme;
}
} /* namespace medialibrary */
} /* namespace vlc */
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland