taskwarrior/src/Uri.cpp
Paul Beckingham dab06f8672 Code Cleanup
- All objects now use the same convention for naming members.  The
  consistency is a good thing.
2011-08-25 21:54:28 -04:00

281 lines
6.6 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2010 - 2011, Johannes Schlatow.
// All rights reserved.
//
// 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.
//
// 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; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#define L10N // Localization complete.
#include <Context.h>
#include <text.h>
#include <i18n.h>
#include <Uri.h>
extern Context context;
////////////////////////////////////////////////////////////////////////////////
Uri::Uri ()
{
_parsed = false;
}
////////////////////////////////////////////////////////////////////////////////
Uri::Uri (const Uri& other)
{
if (this != &other)
{
_data = other._data;
_host = other._host;
_path = other._path;
_user = other._user;
_port = other._port;
_protocol = other._protocol;
_parsed = other._parsed;
}
}
////////////////////////////////////////////////////////////////////////////////
Uri::Uri (const std::string& in, const std::string& configPrefix)
{
_data = in;
_parsed = false;
if (configPrefix != "")
expand(configPrefix);
}
////////////////////////////////////////////////////////////////////////////////
Uri::~Uri ()
{
}
////////////////////////////////////////////////////////////////////////////////
Uri& Uri::operator= (const Uri& other)
{
if (this != &other)
{
this->_data = other._data;
this->_host = other._host;
this->_path = other._path;
this->_user = other._user;
this->_port = other._port;
this->_protocol = other._protocol;
this->_parsed = other._parsed;
}
return *this;
}
////////////////////////////////////////////////////////////////////////////////
Uri::operator std::string () const
{
return _data;
}
////////////////////////////////////////////////////////////////////////////////
std::string Uri::name () const
{
if (_path.length ())
{
std::string::size_type slash = _path.rfind ('/');
if (slash != std::string::npos)
return _path.substr (slash + 1, std::string::npos);
}
return _path;
}
////////////////////////////////////////////////////////////////////////////////
std::string Uri::parent () const
{
if (_path.length ())
{
std::string::size_type slash = _path.rfind ('/');
if (slash != std::string::npos)
return _path.substr (0, slash+1);
}
return "";
}
////////////////////////////////////////////////////////////////////////////////
std::string Uri::extension () const
{
if (_path.length ())
{
std::string::size_type dot = _path.rfind ('.');
if (dot != std::string::npos)
return _path.substr (dot + 1, std::string::npos);
}
return "";
}
////////////////////////////////////////////////////////////////////////////////
bool Uri::is_directory () const
{
if (is_local ()) {
return Path (this->_data).is_directory ();
} else
return (_path == ".")
|| (_path == "")
|| (_path[_path.length()-1] == '/');
}
////////////////////////////////////////////////////////////////////////////////
bool Uri::is_local () const
{
if (_parsed)
return (_protocol == "");
else
return ( (_data.find("://") == std::string::npos)
&& (_data.find(":") == std::string::npos) );
}
////////////////////////////////////////////////////////////////////////////////
bool Uri::append (const std::string& path)
{
if (is_directory ())
{
this->_path += path;
return true;
}
else
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Uri::expand (const std::string& configPrefix )
{
std::string tmp;
if (_data.length ())
{
// try to replace argument with uri from config
tmp = context.config.get (configPrefix + "." + _data + ".uri");
}
else
{
// get default target from config
tmp = context.config.get (configPrefix + ".default.uri");
}
if (tmp != "")
{
_data = tmp;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
void Uri::parse ()
{
if (_parsed)
return;
if (is_local ())
{
_path = _data;
_parsed = true;
return;
}
std::string::size_type pos;
std::string _data = this->_data;
std::string pathDelimiter = "/";
_user = "";
_port = "";
// skip ^.*://
if ((pos = _data.find ("://")) != std::string::npos)
{
_protocol = _data.substr(0, pos);
_data = _data.substr (pos+3);
// standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data
pathDelimiter = "/";
}
else
{
_protocol = "ssh";
// scp-like syntax: [user@]host.xz:path/to/undo.data
pathDelimiter = ":";
}
// user delimited by single quotes?
if ( _data[0] == '\''
&& (pos = _data.find("'", 1)) != std::string::npos )
{
if (_data[pos+1] == '@')
{
// end of user name
_user = _data.substr (1, pos-1);
_data = _data.substr (pos+2);
}
else
{
throw std::string (format (STRING_URI_QUOTES, _data));
}
}
else
{
// find user name
if ((pos = _data.find ("@")) != std::string::npos)
{
_user = _data.substr (0, pos);
_data = _data.substr (pos+1);
}
}
// get host, port and path
if ((pos = _data.find (pathDelimiter)) != std::string::npos)
{
_host = _data.substr (0, pos);
_path = _data.substr (pos+1);
}
else
{
throw std::string (format (STRING_URI_BAD_FORMAT, _data));
}
// path is absolute for ssh:// syntax
if ( (_protocol == "ssh") && (pathDelimiter == "/") )
{
_path = "/" + _path;
}
// port specified?
// remark: this find() will never be != npos for scp-like syntax
// because we found pathDelimiter, which is ":", before
if ((pos = _host.find (":")) != std::string::npos)
{
_port = _host.substr (pos+1);
_host = _host.substr (0,pos);
}
_parsed = true;
}
////////////////////////////////////////////////////////////////////////////////
// vim: et ts=2 sw=2