1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
/*
* 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
*/
#ifndef INKSCAPE_URI_H
#define INKSCAPE_URI_H
#include <exception>
#include <libxml/uri.h>
#include <string>
namespace Inkscape {
/**
* Represents an URI as per RFC 2396.
*
* Typical use-cases of this class:
* - converting between relative and absolute URIs
* - converting URIs to/from filenames (alternative: Glib functions, but those only handle absolute paths)
* - generic handling of data/file/http URIs (e.g. URI::getContents and URI::getMimeType)
*
* Wraps libxml2's URI functions. Direct usage of libxml2's C-API is discouraged if favor of
* Inkscape::URI. (At the time of writing this, no de-factor standard C++ URI library exists, so
* wrapping libxml2 seems like a good solution)
*
* Implementation detail: Immutable type, copies share a ref-counted data pointer.
*/
class URI {
public:
/* Blank constructor */
URI();
/**
* Copy constructor.
*/
URI(URI const &uri);
/**
* Constructor from a C-style ASCII string.
*
* @param preformed Properly quoted C-style string to be represented.
* @param baseuri If @a preformed is a relative URI, use @a baseuri to make it absolute
*
* @throw MalformedURIException
*/
explicit URI(char const *preformed, char const *baseuri = nullptr);
explicit URI(char const *preformed, URI const &baseuri);
/**
* Destructor.
*/
~URI();
/**
* Determines if the URI represented is an 'opaque' URI.
*
* @return \c true if the URI is opaque, \c false if hierarchial.
*/
bool isOpaque() const { return _impl->isOpaque(); }
/**
* Determines if the URI represented is 'relative' as per RFC 2396.
*
* Relative URI references are distinguished by not beginning with a
* scheme name.
*
* @return \c true if the URI is relative, \c false if it is absolute.
*/
bool isRelative() const { return _impl->isRelative(); }
/**
* Determines if the relative URI represented is a 'net-path' as per RFC 2396.
*
* A net-path is one that starts with "//".
*
* @return \c true if the URI is relative and a net-path, \c false otherwise.
*/
bool isNetPath() const { return _impl->isNetPath(); }
/**
* Determines if the relative URI represented is a 'relative-path' as per RFC 2396.
*
* A relative-path is one that starts with no slashes.
*
* @return \c true if the URI is relative and a relative-path, \c false otherwise.
*/
bool isRelativePath() const { return _impl->isRelativePath(); }
/**
* Determines if the relative URI represented is a 'absolute-path' as per RFC 2396.
*
* An absolute-path is one that starts with a single "/".
*
* @return \c true if the URI is relative and an absolute-path, \c false otherwise.
*/
bool isAbsolutePath() const { return _impl->isAbsolutePath(); }
const char *getScheme() const { return _impl->getScheme(); }
const char *getPath() const { return _impl->getPath(); }
const char *getQuery() const { return _impl->getQuery(); }
const char *getFragment() const { return _impl->getFragment(); }
const char *getOpaque() const { return _impl->getOpaque(); }
static URI fromUtf8( char const* path );
static URI from_native_filename(char const *path);
/**
* URI of a local directory. The URI path will end with a slash.
*/
static URI from_dirname(char const *path);
/**
* Convenience function for the common use case given a xlink:href attribute and a local
* directory as the document base. Returns an empty URI on failure.
*/
static URI from_href_and_basedir(char const *href, char const *basedir);
const std::string getFullPath(std::string const &base) const;
/**
* Convert this URI to a native filename.
*
* @throw Glib::ConvertError If this is not a "file" URI
*/
std::string toNativeFilename() const;
/**
* Return the string representation of this URI
*
* @param baseuri Return a relative path if this URI shares protocol and host with @a baseuri
*/
std::string str(char const *baseuri = nullptr) const;
/**
* Get the MIME type (e.g.\ "image/png")
*/
std::string getMimeType() const;
/**
* Return the contents of the file
*/
std::string getContents() const;
/**
* Return a CSS formatted url value
*
* @param baseuri Return a relative path if this URI shares protocol and host with @a baseuri
*/
std::string cssStr(char const *baseuri = nullptr) const {
return "url(" + str(baseuri) + ")";
}
/**
* True if the scheme equals the given string (not case sensitive)
*/
bool hasScheme(const char *scheme) const;
/**
* Assignment operator.
*/
URI &operator=(URI const &uri);
private:
class Impl {
public:
static Impl *create(xmlURIPtr uri);
void reference();
void unreference();
bool isOpaque() const;
bool isRelative() const;
bool isNetPath() const;
bool isRelativePath() const;
bool isAbsolutePath() const;
const char *getScheme() const;
const char *getPath() const;
const char *getQuery() const;
const char *getFragment() const;
const char *getOpaque() const;
char *toString() const;
private:
Impl(xmlURIPtr uri);
~Impl();
int _refcount;
xmlURIPtr _uri;
};
Impl *_impl;
};
} /* namespace Inkscape */
#endif
/*
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 :
|