16#include <giomm/contenttype.h>
17#include <giomm/file.h>
18#include <glibmm/base64.h>
19#include <glibmm/convert.h>
20#include <glibmm/ustring.h>
21#include <glibmm/miscutils.h>
37 for (
auto *p = uri; *p; ++p) {
49URI::URI(gchar
const *preformed,
char const *baseuri)
57 xmlChar *escaped =
nullptr;
59 escaped = xmlURIEscapeStr(
60 (xmlChar
const *)preformed,
62 preformed = (
decltype(preformed))escaped;
66 xmlChar *full =
nullptr;
69 (xmlChar
const *)preformed,
70 (xmlChar
const *)baseuri);
71#if LIBXML_VERSION < 20905
73 auto f = (gchar
const *)full;
74 if (f && g_str_has_prefix(f,
"file:/") && f[6] !=
'/') {
75 auto fixed = std::string(f, 6) +
"//" + std::string(f + 6);
77 full = (xmlChar *)xmlMemStrdup(fixed.c_str());
80 preformed = (
decltype(preformed))full;
83 uri = xmlParseURI(preformed);
92 throw MalformedURIException();
98 :
URI::
URI(preformed, baseuri.str().c_str())
138 return path && path[0] !=
'/';
146 return path && path[0] ==
'/';
170 if (path && path[0] !=
'/') {
183 uristr.resize(uristr.find(
'#'));
186 return Glib::filename_from_uri(uristr);
191 gchar *uri = g_filename_to_uri(path,
nullptr,
nullptr);
199 std::string pathstr = path ? path :
".";
201 if (!Glib::path_is_absolute(pathstr)) {
202 pathstr = Glib::build_filename(Glib::get_current_dir(), pathstr);
205 auto uristr = Glib::filename_to_uri(pathstr);
207 if (uristr[uristr.size() - 1] !=
'/') {
208 uristr.push_back(
'/');
211 return URI(uristr.c_str());
240 for (; uri[i]; ++i) {
241 if (uri[i] != base[i]) {
256 if (n_slash == 3 && g_str_has_prefix(base,
"file:///") && base[8]) {
260 std::string relative;
262 for (
size_t j = i; base[j]; ++j) {
263 if (base[j] ==
'/') {
268 while (uri[i - 1] !=
'/') {
272 relative += (uri + i);
274 if (relative.empty() && base[i]) {
286 auto save = (
const char *)saveuri;
287 if (baseuri && baseuri[0]) {
303 for (
const char *p = path; *p; ++p) {
304 if (*p ==
';' || *p ==
',') {
305 return std::string(path, p);
310 auto type = Gio::content_type_guess(path,
nullptr, 0, uncertain);
311 return Gio::content_type_get_mime_type(type).raw();
315 return "unknown/unknown";
324 const char *tok =
nullptr;
327 for (; *p && *p !=
','; ++p) {
335 g_critical(
"data URI misses comma");
336 }
else if (tok && strncmp(
"base64", tok, p - tok) == 0) {
338 return Glib::Base64::decode(p + 1);
345 auto file = Gio::File::create_for_uri(
str());
348 char *buffer =
nullptr;
350 if (file->load_contents(buffer, length)) {
351 auto contents = std::string(buffer, buffer + length);
355 g_critical(
"failed to load contents from %.100s",
str().c_str());
365 return s && g_ascii_strcasecmp(s, scheme) == 0;
376 && (H1 = g_ascii_xdigit_value(s[1])) != -1
377 && (H2 = g_ascii_xdigit_value(s[2])) != -1) {
378 return (H1 << 4) | H2;
398 if ((value >> 5) == 0x6) {
401 }
else if ((value >> 4) == 0xE) {
404 }
else if ((value >> 3) == 0x1E) {
414 for (
int i = 1; i < n; ++i) {
417 if ((value >> 6) != 0x2) {
433 for (
const char *p = uri; *p;) {
TODO: insert short description here.
Represents an URI as per RFC 2396.
bool isOpaque() const
Determines if the URI represented is an 'opaque' URI.
const char * getQuery() const
Return the query, which is the part between "?" and the optional fragment hash ("#")
bool isRelative() const
Determines if the URI represented is 'relative' as per RFC 2396.
const char * getScheme() const
Return the scheme, e.g. "http", or NULL if this is not an absolute URI.
bool hasScheme(const char *scheme) const
True if the scheme equals the given string (not case sensitive)
xmlURI * _xmlURIPtr() const
static URI from_dirname(char const *path)
URI of a local directory.
std::string getMimeType() const
Get the MIME type (e.g. "image/png")
static URI from_href_and_basedir(char const *href, char const *basedir)
Convenience function for the common use case given a xlink:href attribute and a local directory as th...
std::string str(char const *baseuri=nullptr) const
Return the string representation of this URI.
const char * getPath() const
Return the path.
std::string toNativeFilename() const
Convert this URI to a native filename.
bool isNetPath() const
Determines if the relative URI represented is a 'net-path' as per RFC 2396.
const char * getOpaque() const
For an opaque URI, return everything between the scheme colon (":") and the optional fragment hash ("...
bool isAbsolutePath() const
Determines if the relative URI represented is a 'absolute-path' as per RFC 2396.
static URI from_native_filename(char const *path)
Construct a "file" URI from an absolute filename.
const char * getFragment() const
Return the fragment, which is everything after "#".
std::string getContents() const
Return the contents of the file.
bool isRelativePath() const
Determines if the relative URI represented is a 'relative-path' as per RFC 2396.
Helper class to stream background task notifications as a series of messages.
std::string uri_to_iri(const char *uri)
Unescape the UTF-8 parts of the given URI.
static int uri_unescape_utf8_codepoint(const char *s, char *out)
If s starts with a percent-escaped UTF-8 sequence, unescape one code point and store it in out variab...
auto const URI_ALLOWED_NON_ALNUM
static int uri_unescape_triplet(const char *s)
If s starts with a "%XX" triplet, return its byte value, 0 otherwise.
static std::string build_relative_uri(char const *uri, char const *base)
Replacement for buggy xmlBuildRelativeURI https://gitlab.gnome.org/GNOME/libxml2/merge_requests/12.
static bool uri_needs_escaping(char const *uri)
Return true if the given URI string contains characters that need escaping.