Logo ROOT  
Reference Guide
TGHtmlUri.cxx
Go to the documentation of this file.
1// $Id$
2// Author: Valeriy Onuchin 03/05/2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**************************************************************************
13
14 HTML widget for xclass. Based on tkhtml 1.28
15 Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
16 Copyright (C) 2002-2003 Hector Peraza.
17
18 This library is free software; you can redistribute it and/or
19 modify it under the terms of the GNU Library General Public
20 License as published by the Free Software Foundation; either
21 version 2 of the License, or (at your option) any later version.
22
23 This library is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
27
28 You should have received a copy of the GNU Library General Public
29 License along with this library; if not, write to the Free
30 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
32**************************************************************************/
33
34// Routines for processing URLs.
35
36#include <ctype.h>
37#include <string.h>
38#include <stdlib.h>
39
40#include "TGHtml.h"
41#include "TGHtmlUri.h"
42
43
44static char *StrNDup(const char *z, int n);
45static void ReplaceStr(char **pzDest, const char *zSrc);
46#if 0 // not used
47static char *Trim(char *z);
48#endif
49
50
51////////////////////////////////////////////////////////////////////////////////
52/// Parse a text URI into an HtmlUri structure.
53
54TGHtmlUri::TGHtmlUri(const char *zUri)
55{
56 int n;
57
58 fZScheme = fZAuthority = fZPath = fZQuery = fZFragment = (char *) 0;
59
60 if (zUri && *zUri) {
61 while (isspace(*zUri)) ++zUri;
62 n = ComponentLength(zUri, "", ":/?# ");
63 if (n > 0 && zUri[n] == ':') {
64 fZScheme = StrNDup(zUri, n);
65 zUri += n+1;
66 }
67 n = ComponentLength(zUri, "//", "/?# ");
68 if (n > 0) {
69 fZAuthority = StrNDup(&zUri[2], n-2);
70 zUri += n;
71 }
72 n = ComponentLength(zUri, "", "?# ");
73 if (n > 0) {
74 fZPath = StrNDup(zUri, n);
75 zUri += n;
76 }
77 n = ComponentLength(zUri, "?", "# ");
78 if (n > 0) {
79 fZQuery = StrNDup(&zUri[1], n-1);
80 zUri += n;
81 }
82 n = ComponentLength(zUri, "#", " ");
83 if (n > 0) {
84 fZFragment = StrNDup(&zUri[1], n-1);
85 }
86 }
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Html uri copy constructor.
91
93{
94 fZScheme = fZAuthority = fZPath = fZQuery = fZFragment = (char *) 0;
95
96 if (uri) {
97 if (uri->fZScheme) fZScheme = StrDup(uri->fZScheme);
98 if (uri->fZAuthority) fZAuthority = StrDup(uri->fZAuthority);
99 if (uri->fZPath) fZPath = StrDup(uri->fZPath);
100 if (uri->fZQuery) fZQuery = StrDup(uri->fZQuery);
101 if (uri->fZFragment) fZFragment = StrDup(uri->fZFragment);
102 }
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// Html uri destructor.
107
109{
110 if (fZScheme) delete[] fZScheme;
111 if (fZAuthority) delete[] fZAuthority;
112 if (fZPath) delete[] fZPath;
113 if (fZQuery) delete[] fZQuery;
114 if (fZFragment) delete[] fZFragment;
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Compare another uri with given field mask.
119
120int TGHtmlUri::EqualsUri(const TGHtmlUri *uri, int field_mask)
121{
122 if (!uri) return 0;
123
124 if (field_mask & URI_SCHEME_MASK) {
125 if (uri->fZScheme && fZScheme) {
126 if (strcmp(uri->fZScheme, fZScheme) != 0) return 0;
127 } else if (uri->fZScheme != fZScheme) { // one of them null?
128 return 0;
129 }
130 }
131
132 if (field_mask & URI_AUTH_MASK) {
133 if (uri->fZAuthority && fZAuthority) {
134 if (strcmp(uri->fZAuthority, fZAuthority) != 0) return 0;
135 } else if (uri->fZAuthority != fZAuthority) {
136 return 0;
137 }
138 }
139
140 if (field_mask & URI_PATH_MASK) {
141 if (uri->fZPath && fZPath) {
142 if (strcmp(uri->fZPath, fZPath) != 0) return 0;
143 } else if (uri->fZPath != fZPath) {
144 return 0;
145 }
146 }
147
148 if (field_mask & URI_QUERY_MASK) {
149 if (uri->fZQuery && fZQuery) {
150 if (strcmp(uri->fZQuery, fZQuery) != 0) return 0;
151 } else if (uri->fZQuery != fZQuery) {
152 return 0;
153 }
154 }
155
156 if (field_mask & URI_FRAGMENT_MASK) {
157 if (uri->fZFragment && fZFragment) {
158 if (strcmp(uri->fZFragment, fZFragment) != 0) return 0;
159 } else if (uri->fZFragment != fZFragment) {
160 return 0;
161 }
162 }
163
164 return 1;
165}
166
167////////////////////////////////////////////////////////////////////////////////
168/// Return the length of the next component of the URL in z[] given
169/// that the component starts at z[0]. The initial sequence of the
170/// component must be zInit[]. The component is terminated by any
171/// character in zTerm[]. The length returned is 0 if the component
172/// doesn't exist. The length includes the zInit[] string, but not
173/// the termination character.
174///
175/// Component zInit zTerm
176/// ---------- ------- -------
177/// scheme "" ":/?#"
178/// authority "//" "/?#"
179/// path "/" "?#"
180/// query "?" "#"
181/// fragment "#" ""
182
183int TGHtmlUri::ComponentLength(const char *z, const char *zInit, const char *zTerm)
184{
185 int i, n;
186
187 for (n = 0; zInit[n]; ++n) {
188 if (zInit[n] != z[n]) return 0;
189 }
190 while (z[n]) {
191 for (i = 0; zTerm[i]; ++i) {
192 if (z[n] == zTerm[i]) return n;
193 }
194 ++n;
195 }
196
197 return n;
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// Create a string to hold the given URI. Memory to hold the string is
202/// allocated with new[] and must be freed by the calling function.
203
205{
206 int n = 1;
207 char *z;
208
209 if (fZScheme) n += strlen(fZScheme) + 1;
210 if (fZAuthority) n += strlen(fZAuthority) + 3;
211 if (fZPath) n += strlen(fZPath) + 1;
212 if (fZQuery) n += strlen(fZQuery) + 1;
213 if (fZFragment) n += strlen(fZFragment) + 1;
214 z = new char[n];
215 if (z == 0) return 0;
216 n = 0;
217 if (fZScheme) {
218 // coverity[secure_coding]
219 sprintf(z, "%s:", fZScheme);
220 n = strlen(z);
221 }
222 if (fZAuthority) {
223 // coverity[secure_coding]
224 sprintf(&z[n], "//%s", fZAuthority);
225 n += strlen(&z[n]);
226 }
227 if (fZAuthority && fZAuthority[strlen(fZAuthority)-1] != '/' &&
228 !(fZPath && fZPath[0] == '/')) {
229 // coverity[secure_coding]
230 strcat(z, "/");
231 ++n;
232 }
233 if (fZPath) {
234 // coverity[secure_coding]
235 sprintf(&z[n], "%s", fZPath);
236 n += strlen(&z[n]);
237 }
238 if (fZQuery) {
239 // coverity[secure_coding]
240 sprintf(&z[n], "?%s", fZQuery);
241 n += strlen(&z[n]);
242 }
243 if (fZFragment) {
244 // coverity[secure_coding]
245 sprintf(&z[n], "#%s", fZFragment);
246 } else {
247 z[n] = 0;
248 }
249
250 return z;
251}
252
253
254////////////////////////////////////////////////////////////////////////////////
255/// Duplicate a string of length n.
256
257static char *StrNDup(const char *z, int n)
258{
259 char *zResult;
260
261 if (n <= 0) n = strlen(z);
262 zResult = new char[n + 1];
263 if (zResult) {
264 memcpy(zResult, z, n);
265 zResult[n] = 0;
266 }
267 return zResult;
268}
269
270////////////////////////////////////////////////////////////////////////////////
271/// Replace the string in *pzDest with the string in zSrc
272
273static void ReplaceStr(char **pzDest, const char *zSrc)
274{
275 if (*pzDest != 0) delete[] *pzDest;
276 if (zSrc == 0) {
277 *pzDest = 0;
278 } else {
279 *pzDest = StrNDup(zSrc, -1);
280 }
281}
282
283#if 0 // not used
284static char *Trim(char *z)
285{
286 // Remove leading and trailing spaces from the given string. Return
287 // a new string allocated with new[].
288 int i;
289 char *zNew;
290
291 while (isspace(*z)) z++;
292 i = strlen(z);
293 zNew = new char[i + 1];
294 if (zNew == 0) return 0;
295 strcpy(zNew, z);
296 while (i > 0 && isspace(zNew[i-1])) zNew[--i] = 0;
297
298 return zNew;
299}
300#endif
301
302////////////////////////////////////////////////////////////////////////////////
303/// This function resolves the specified URI and returns the result in
304/// a newly allocated string. The resolver algorithm specified in section
305/// 5.2 of RFC 2396 is used.
306
307char *TGHtml::ResolveUri(const char *zUri)
308{
309 char *result = 0;
310 TGHtmlUri *base, *term;
311
312 if (zUri == 0 || *zUri == 0) return 0;
313
314 if (fZBaseHref && *fZBaseHref) {
315 base = new TGHtmlUri(fZBaseHref);
316 } else {
317 base = new TGHtmlUri(fZBase);
318 }
319
320 term = new TGHtmlUri(zUri);
321
322 if (term->fZScheme == 0 &&
323 term->fZAuthority == 0 &&
324 term->fZPath == 0 &&
325 term->fZQuery == 0 &&
326 term->fZFragment) {
327 ReplaceStr(&base->fZFragment, term->fZFragment);
328 } else if (term->fZScheme) {
329 TGHtmlUri *temp;
330 temp = term;
331 term = base;
332 base = temp;
333 } else if (term->fZAuthority) {
334 ReplaceStr(&base->fZAuthority, term->fZAuthority);
335 ReplaceStr(&base->fZPath, term->fZPath);
336 ReplaceStr(&base->fZQuery, term->fZQuery);
337 ReplaceStr(&base->fZFragment, term->fZFragment);
338 } else if (term->fZPath && (term->fZPath[0] == '/' || base->fZPath == 0)) {
339 ReplaceStr(&base->fZPath, term->fZPath);
340 ReplaceStr(&base->fZQuery, term->fZQuery);
341 ReplaceStr(&base->fZFragment, term->fZFragment);
342 } else if (term->fZPath && base->fZPath) {
343 char *zBuf;
344 int i, j;
345 zBuf = new char[strlen(base->fZPath) + strlen(term->fZPath) + 2];
346 if (zBuf) {
347 // coverity[secure_coding]
348 sprintf(zBuf, "%s", base->fZPath);
349 for (i = strlen(zBuf) - 1; i >= 0 && zBuf[i] != '/'; --i) {
350 zBuf[i] = 0;
351 }
352 // coverity[secure_coding]
353 strcat(zBuf, term->fZPath);
354 for (i = 0; zBuf[i]; i++) {
355 if (zBuf[i] == '/' && zBuf[i+1] == '.' && zBuf[i+2] == '/') {
356 // coverity[secure_coding]
357 strcpy(&zBuf[i+1], &zBuf[i+3]);
358 --i;
359 continue;
360 }
361 if (zBuf[i] == '/' && zBuf[i+1] == '.' && zBuf[i+2] == 0) {
362 zBuf[i+1] = 0;
363 continue;
364 }
365 if (i > 0 && zBuf[i] == '/' && zBuf[i+1] == '.' &&
366 zBuf[i+2] == '.' && (zBuf[i+3] == '/' || zBuf[i+3] == 0)) {
367 for (j = i - 1; j >= 0 && zBuf[j] != '/'; --j) {}
368 if (zBuf[i+3]) {
369 // coverity[secure_coding]
370 strcpy(&zBuf[j+1], &zBuf[i+4]);
371 } else {
372 zBuf[j+1] = 0;
373 }
374 i = j - 1;
375 if (i < -1) i = -1;
376 continue;
377 }
378 }
379 delete[] base->fZPath;
380 base->fZPath = zBuf;
381 }
382 ReplaceStr(&base->fZQuery, term->fZQuery);
383 ReplaceStr(&base->fZFragment, term->fZFragment);
384 }
385 delete term;
386
387 result = base->BuildUri();
388 delete base;
389
390 return result;
391}
static char * StrNDup(const char *z, int n)
Duplicate a string of length n.
Definition: TGHtmlUri.cxx:257
static void ReplaceStr(char **pzDest, const char *zSrc)
Replace the string in *pzDest with the string in zSrc.
Definition: TGHtmlUri.cxx:273
#define URI_FRAGMENT_MASK
Definition: TGHtmlUri.h:43
#define URI_AUTH_MASK
Definition: TGHtmlUri.h:40
#define URI_SCHEME_MASK
Definition: TGHtmlUri.h:39
#define URI_PATH_MASK
Definition: TGHtmlUri.h:41
#define URI_QUERY_MASK
Definition: TGHtmlUri.h:42
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
char * fZAuthority
Definition: TGHtmlUri.h:72
int EqualsUri(const TGHtmlUri *uri, int field_mask=URI_FULL_MASK)
Compare another uri with given field mask.
Definition: TGHtmlUri.cxx:120
int ComponentLength(const char *z, const char *zInit, const char *zTerm)
Return the length of the next component of the URL in z[] given that the component starts at z[0].
Definition: TGHtmlUri.cxx:183
char * fZQuery
Definition: TGHtmlUri.h:74
TGHtmlUri(const TGHtmlUri &)
virtual ~TGHtmlUri()
Html uri destructor.
Definition: TGHtmlUri.cxx:108
char * BuildUri()
Create a string to hold the given URI.
Definition: TGHtmlUri.cxx:204
char * fZFragment
Definition: TGHtmlUri.h:75
char * fZPath
Definition: TGHtmlUri.h:73
char * fZScheme
Definition: TGHtmlUri.h:71
const char * fZBase
Definition: TGHtml.h:1259
virtual char * ResolveUri(const char *uri)
This function resolves the specified URI and returns the result in a newly allocated string.
Definition: TGHtmlUri.cxx:307
char * fZBaseHref
Definition: TGHtml.h:1260
const Int_t n
Definition: legend1.C:16