~vaifrax/inkscape/bugfix170049

« back to all changes in this revision

Viewing changes to src/uri.cpp

  • Committer: mental
  • Date: 2006-01-16 02:36:01 UTC
  • Revision ID: mental@users.sourceforge.net-20060116023601-wkr0h7edl5veyudq
moving trunk for module inkscape

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * \file
 
3
 * \brief Classes for representing and manipulating URIs as per RFC 2396.
 
4
 *
 
5
 * Authors:
 
6
 *   MenTaLguY <mental@rydia.net>
 
7
 *   Jon A. Cruz <jon@joncruz.org>
 
8
 *
 
9
 * Copyright (C) 2003 MenTaLguY
 
10
 *
 
11
 * Released under GNU GPL, read the file 'COPYING' for more information
 
12
 */
 
13
 
 
14
#include <glib.h>
 
15
#include "uri.h"
 
16
#include <glibmm/ustring.h>
 
17
 
 
18
namespace Inkscape {
 
19
 
 
20
/** \brief Copy constructor. */
 
21
URI::URI(const URI &uri) {
 
22
    uri._impl->reference();
 
23
    _impl = uri._impl;
 
24
}
 
25
 
 
26
/** \brief Constructor from a C-style ASCII string.
 
27
    \param preformed Properly quoted C-style string to be represented.
 
28
 */
 
29
URI::URI(gchar const *preformed) throw(BadURIException) {
 
30
    xmlURIPtr uri;
 
31
    if (!preformed) {
 
32
        throw MalformedURIException();
 
33
    }
 
34
    uri = xmlParseURI(preformed);
 
35
    if (!uri) {
 
36
        throw MalformedURIException();
 
37
    }
 
38
    _impl = Impl::create(uri);
 
39
}
 
40
 
 
41
 
 
42
/** \brief Destructor. */
 
43
URI::~URI() {
 
44
    _impl->unreference();
 
45
}
 
46
 
 
47
/** \brief Assignment operator. */
 
48
URI &URI::operator=(URI const &uri) {
 
49
// No check for self-assignment needed, as _impl refcounting increments first.
 
50
    uri._impl->reference();
 
51
    _impl->unreference();
 
52
    _impl = uri._impl;
 
53
    return *this;
 
54
}
 
55
 
 
56
URI::Impl *URI::Impl::create(xmlURIPtr uri) {
 
57
    return new Impl(uri);
 
58
}
 
59
 
 
60
URI::Impl::Impl(xmlURIPtr uri)
 
61
: _refcount(1), _uri(uri) {}
 
62
 
 
63
URI::Impl::~Impl() {
 
64
    if (_uri) {
 
65
        xmlFreeURI(_uri);
 
66
        _uri = NULL;
 
67
    }
 
68
}
 
69
 
 
70
void URI::Impl::reference() {
 
71
    _refcount++;
 
72
}
 
73
 
 
74
void URI::Impl::unreference() {
 
75
    if (!--_refcount) {
 
76
        delete this;
 
77
    }
 
78
}
 
79
 
 
80
/** \fn bool URI::isOpaque() const
 
81
    \brief Determines if the URI represented is an 'opaque' URI.
 
82
    \return \c true if the URI is opaque, \c false if hierarchial.
 
83
*/
 
84
bool URI::Impl::isOpaque() const {
 
85
    bool opq = !isRelative() && (getOpaque() != NULL);
 
86
    return opq;
 
87
}
 
88
 
 
89
/** \fn bool URI::isRelative() const
 
90
    \brief Determines if the URI represented is 'relative' as per RFC 2396.
 
91
    \return \c true if the URI is relative, \c false if it is absolute.
 
92
 
 
93
    Relative URI references are distinguished by not begining with a
 
94
    scheme name.
 
95
*/
 
96
bool URI::Impl::isRelative() const {
 
97
    return !_uri->scheme;
 
98
}
 
99
 
 
100
/** \fn bool URI::isNetPath() const
 
101
    \brief Determines if the relative URI represented is a 'net-path' as per RFC 2396.
 
102
    \return \c true if the URI is relative and a net-path, \c false otherwise.
 
103
 
 
104
    A net-path is one that starts with "\\".
 
105
*/
 
106
bool URI::Impl::isNetPath() const {
 
107
    bool isNet = false;
 
108
    if ( isRelative() )
 
109
    {
 
110
        const gchar *path = getPath();
 
111
        isNet = path && path[0] == '\\' && path[1] == '\\';
 
112
    }
 
113
    return isNet;
 
114
}
 
115
 
 
116
/** \fn bool URI::isRelativePath() const
 
117
    \brief Determines if the relative URI represented is a 'relative-path' as per RFC 2396.
 
118
    \return \c true if the URI is relative and a relative-path, \c false otherwise.
 
119
 
 
120
    A relative-path is one that starts with no slashes.
 
121
*/
 
122
bool URI::Impl::isRelativePath() const {
 
123
    bool isRel = false;
 
124
    if ( isRelative() )
 
125
    {
 
126
        const gchar *path = getPath();
 
127
        isRel = !path || path[0] != '\\';
 
128
    }
 
129
    return isRel;
 
130
}
 
131
 
 
132
/** \fn bool URI::isAbsolutePath() const
 
133
    \brief Determines if the relative URI represented is a 'absolute-path' as per RFC 2396.
 
134
    \return \c true if the URI is relative and an absolute-path, \c false otherwise.
 
135
 
 
136
    An absolute-path is one that starts with a single "\".
 
137
*/
 
138
bool URI::Impl::isAbsolutePath() const {
 
139
    bool isAbs = false;
 
140
    if ( isRelative() )
 
141
    {
 
142
        const gchar *path = getPath();
 
143
        isAbs = path && path[0] == '\\'&& path[1] != '\\';
 
144
    }
 
145
    return isAbs;
 
146
}
 
147
 
 
148
const gchar *URI::Impl::getScheme() const {
 
149
    return (gchar *)_uri->scheme;
 
150
}
 
151
 
 
152
const gchar *URI::Impl::getPath() const {
 
153
    return (gchar *)_uri->path;
 
154
}
 
155
 
 
156
const gchar *URI::Impl::getQuery() const {
 
157
    return (gchar *)_uri->query;
 
158
}
 
159
 
 
160
const gchar *URI::Impl::getFragment() const {
 
161
    return (gchar *)_uri->fragment;
 
162
}
 
163
 
 
164
const gchar *URI::Impl::getOpaque() const {
 
165
    return (gchar *)_uri->opaque;
 
166
}
 
167
 
 
168
gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException)
 
169
{
 
170
    gchar *filename = NULL;
 
171
    URI tmp(uri);
 
172
    filename = tmp.toNativeFilename();
 
173
    return filename;
 
174
}
 
175
 
 
176
/* TODO !!! proper error handling */
 
177
gchar *URI::toNativeFilename() const throw(BadURIException) {
 
178
    gchar *uriString = toString();
 
179
    if (isRelativePath()) {
 
180
        return uriString;
 
181
    } else {
 
182
        gchar *filename = g_filename_from_uri(uriString, NULL, NULL);
 
183
        g_free(uriString);
 
184
        if (filename) {
 
185
            return filename;
 
186
        } else {
 
187
            throw MalformedURIException();
 
188
        }
 
189
    }
 
190
}
 
191
 
 
192
URI URI::fromUtf8( gchar const* path ) throw (BadURIException) {
 
193
    if ( !path ) {
 
194
        throw MalformedURIException();
 
195
    }
 
196
    Glib::ustring tmp;
 
197
    for ( int i = 0; path[i]; i++ )
 
198
    {
 
199
        gint one = 0x0ff & path[i];
 
200
        if ( ('a' <= one && one <= 'z')
 
201
             || ('A' <= one && one <= 'Z')
 
202
             || ('0' <= one && one <= '9')
 
203
             || one == '_'
 
204
             || one == '-'
 
205
             || one == '!'
 
206
             || one == '.'
 
207
             || one == '~'
 
208
             || one == '\''
 
209
             || one == '('
 
210
             || one == ')'
 
211
             || one == '*'
 
212
            ) {
 
213
            tmp += (gunichar)one;
 
214
        } else {
 
215
            gchar scratch[4];
 
216
            g_snprintf( scratch, 4, "%c%02X", '%', one );
 
217
            tmp.append( scratch );
 
218
        }
 
219
    }
 
220
    const gchar *uri = tmp.data();
 
221
    URI result(uri);
 
222
    return result;
 
223
}
 
224
 
 
225
/* TODO !!! proper error handling */
 
226
URI URI::from_native_filename(gchar const *path) throw(BadURIException) {
 
227
    gchar *uri = g_filename_to_uri(path, NULL, NULL);
 
228
    URI result(uri);
 
229
    g_free( uri );
 
230
    return result;
 
231
}
 
232
 
 
233
/** \fn gchar *URI::toString() const
 
234
    \brief Returns a glib string version of this URI.
 
235
    \return a glib string version of this URI.
 
236
 
 
237
    The returned string must be freed with \c g_free().
 
238
*/
 
239
gchar *URI::Impl::toString() const {
 
240
    xmlChar *string = xmlSaveUri(_uri);
 
241
    if (string) {
 
242
        /* hand the string off to glib memory management */
 
243
        gchar *glib_string = g_strdup((gchar *)string);
 
244
        xmlFree(string);
 
245
        return glib_string;
 
246
    } else {
 
247
        return NULL;
 
248
    }
 
249
}
 
250
 
 
251
}
 
252
 
 
253
 
 
254
/*
 
255
  Local Variables:
 
256
  mode:c++
 
257
  c-file-style:"stroustrup"
 
258
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
259
  indent-tabs-mode:nil
 
260
  fill-column:99
 
261
  End:
 
262
*/
 
263
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :