diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-01-30 08:33:01 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-01-30 08:33:01 +0000 |
| commit | 267299811df952d08324a39008f52c19641de9e0 (patch) | |
| tree | 28fef736a52cb7a72119d119be8eb663ad20a77f /src/object/uri.cpp | |
| parent | Translations: update inkscape.pot (diff) | |
| download | inkscape-267299811df952d08324a39008f52c19641de9e0.tar.gz inkscape-267299811df952d08324a39008f52c19641de9e0.zip | |
Move classes derived from SPObject to own directory.
A lot of header clean-up.
Diffstat (limited to 'src/object/uri.cpp')
| -rw-r--r-- | src/object/uri.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/object/uri.cpp b/src/object/uri.cpp new file mode 100644 index 000000000..881b322b4 --- /dev/null +++ b/src/object/uri.cpp @@ -0,0 +1,249 @@ +/* + * Authors: + * MenTaLguY <mental@rydia.net> + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2003 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "uri.h" + +#include <glibmm/ustring.h> +#include <glibmm/miscutils.h> + +#include "bad-uri-exception.h" + +namespace Inkscape { + +URI::URI() { + const gchar *in = ""; + _impl = Impl::create(xmlParseURI(in)); +} + +URI::URI(const URI &uri) { + uri._impl->reference(); + _impl = uri._impl; +} + +URI::URI(gchar const *preformed) { + xmlURIPtr uri; + if (!preformed) { + throw MalformedURIException(); + } + uri = xmlParseURI(preformed); + if (!uri) { + throw MalformedURIException(); + } + _impl = Impl::create(uri); +} + +URI::~URI() { + _impl->unreference(); +} + +URI &URI::operator=(URI const &uri) { +// No check for self-assignment needed, as _impl refcounting increments first. + uri._impl->reference(); + _impl->unreference(); + _impl = uri._impl; + return *this; +} + +URI::Impl *URI::Impl::create(xmlURIPtr uri) { + return new Impl(uri); +} + +URI::Impl::Impl(xmlURIPtr uri) +: _refcount(1), _uri(uri) {} + +URI::Impl::~Impl() { + if (_uri) { + xmlFreeURI(_uri); + _uri = NULL; + } +} + +void URI::Impl::reference() { + _refcount++; +} + +void URI::Impl::unreference() { + if (!--_refcount) { + delete this; + } +} + +bool URI::Impl::isOpaque() const { + bool opq = !isRelative() && (getOpaque() != NULL); + return opq; +} + +bool URI::Impl::isRelative() const { + return !_uri->scheme; +} + +bool URI::Impl::isNetPath() const { + bool isNet = false; + if ( isRelative() ) + { + const gchar *path = getPath(); + isNet = path && path[0] == '\\' && path[1] == '\\'; + } + return isNet; +} + +bool URI::Impl::isRelativePath() const { + bool isRel = false; + if ( isRelative() ) + { + const gchar *path = getPath(); + isRel = !path || path[0] != '\\'; + } + return isRel; +} + +bool URI::Impl::isAbsolutePath() const { + bool isAbs = false; + if ( isRelative() ) + { + const gchar *path = getPath(); + isAbs = path && path[0] == '\\'&& path[1] != '\\'; + } + return isAbs; +} + +const gchar *URI::Impl::getScheme() const { + return (gchar *)_uri->scheme; +} + +const gchar *URI::Impl::getPath() const { + return (gchar *)_uri->path; +} + +const gchar *URI::Impl::getQuery() const { + return (gchar *)_uri->query; +} + +const gchar *URI::Impl::getFragment() const { + return (gchar *)_uri->fragment; +} + +const gchar *URI::Impl::getOpaque() const { + return (gchar *)_uri->opaque; +} + +gchar *URI::to_native_filename(gchar const* uri) +{ + gchar *filename = NULL; + URI tmp(uri); + filename = tmp.toNativeFilename(); + return filename; +} +/* + * Returns the absolute path to an existing file referenced in this URI, + * if the uri is data, the path is empty or the file doesn't exist, then + * an empty string is returned. + * + * Does not check if the returned path is the local document's path (local) + * and thus redundent. Caller is expected to check against the document's path. + */ +const std::string URI::getFullPath(std::string const &base) const { + if (!_impl->getPath()) { + return ""; + } + std::string path = std::string(_impl->getPath()); + // Calculate the absolute path from an available base + if(!base.empty() && !path.empty() && path[0] != '/') { + path = Glib::build_filename(base, path); + } + // Check the existence of the file + if(! g_file_test(path.c_str(), G_FILE_TEST_EXISTS) + || g_file_test(path.c_str(), G_FILE_TEST_IS_DIR) ) { + path.clear(); + } + return path; +} + + +/* TODO !!! proper error handling */ +gchar *URI::toNativeFilename() const { + gchar *uriString = toString(); + if (isRelativePath()) { + return uriString; + } else { + gchar *filename = g_filename_from_uri(uriString, NULL, NULL); + g_free(uriString); + if (filename) { + return filename; + } else { + throw MalformedURIException(); + } + } +} + +URI URI::fromUtf8( gchar const* path ) { + if ( !path ) { + throw MalformedURIException(); + } + Glib::ustring tmp; + for ( int i = 0; path[i]; i++ ) + { + gint one = 0x0ff & path[i]; + if ( ('a' <= one && one <= 'z') + || ('A' <= one && one <= 'Z') + || ('0' <= one && one <= '9') + || one == '_' + || one == '-' + || one == '!' + || one == '.' + || one == '~' + || one == '\'' + || one == '(' + || one == ')' + || one == '*' + ) { + tmp += (gunichar)one; + } else { + gchar scratch[4]; + g_snprintf( scratch, 4, "%%%02X", one ); + tmp.append( scratch ); + } + } + return URI( tmp.data() ); +} + +/* TODO !!! proper error handling */ +URI URI::from_native_filename(gchar const *path) { + gchar *uri = g_filename_to_uri(path, NULL, NULL); + URI result(uri); + g_free( uri ); + return result; +} + +gchar *URI::Impl::toString() const { + xmlChar *string = xmlSaveUri(_uri); + if (string) { + /* hand the string off to glib memory management */ + gchar *glib_string = g_strdup((gchar *)string); + xmlFree(string); + return glib_string; + } else { + return NULL; + } +} + +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |
