sl@0
|
1 |
// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
#include <escapeutils.h>
|
sl@0
|
17 |
#include <uri8.h>
|
sl@0
|
18 |
#include <uri16.h>
|
sl@0
|
19 |
#include <delimitedpath8.h>
|
sl@0
|
20 |
#include <delimitedpath16.h>
|
sl@0
|
21 |
#include <uriutilscommon.h>
|
sl@0
|
22 |
#include <uriutils.h>
|
sl@0
|
23 |
|
sl@0
|
24 |
#include "UriUtilsInternal.h"
|
sl@0
|
25 |
#include "TUriCInternal.h"
|
sl@0
|
26 |
#include "CUriInternal.h"
|
sl@0
|
27 |
|
sl@0
|
28 |
// Panic category
|
sl@0
|
29 |
//
|
sl@0
|
30 |
#ifdef _DEBUG
|
sl@0
|
31 |
_LIT(KUriPanicCategory,"URI-CURI");
|
sl@0
|
32 |
#endif
|
sl@0
|
33 |
|
sl@0
|
34 |
// Constants
|
sl@0
|
35 |
//
|
sl@0
|
36 |
_LIT(KFileUriPanicCategory,"FILEURI-CURI");
|
sl@0
|
37 |
|
sl@0
|
38 |
|
sl@0
|
39 |
|
sl@0
|
40 |
|
sl@0
|
41 |
//
|
sl@0
|
42 |
//
|
sl@0
|
43 |
// Implementation of CUri8
|
sl@0
|
44 |
//
|
sl@0
|
45 |
//
|
sl@0
|
46 |
|
sl@0
|
47 |
/**
|
sl@0
|
48 |
Static factory constructor. Uses two phase construction and leaves nothing on the
|
sl@0
|
49 |
CleanupStack. Creates a uri object which is a copy of the input parameter aUri.
|
sl@0
|
50 |
|
sl@0
|
51 |
@since 6.0
|
sl@0
|
52 |
@param aUri A reference to a parsed uri object.
|
sl@0
|
53 |
@return A pointer to the newly created CUri8 object.
|
sl@0
|
54 |
@post A fully constructed and initialized CUri8 object.
|
sl@0
|
55 |
*/
|
sl@0
|
56 |
EXPORT_C CUri8* CUri8::NewL(const TUriC8& aUri)
|
sl@0
|
57 |
{
|
sl@0
|
58 |
CUri8* self = CUri8::NewLC(aUri);
|
sl@0
|
59 |
CleanupStack::Pop(self);
|
sl@0
|
60 |
return self;
|
sl@0
|
61 |
}
|
sl@0
|
62 |
|
sl@0
|
63 |
/**
|
sl@0
|
64 |
Static factory constructor. Uses two phase construction and leaves a pointer to
|
sl@0
|
65 |
created object on the CleanupStack. Creates a uri object which is a copy of the
|
sl@0
|
66 |
input parameter aUri.
|
sl@0
|
67 |
|
sl@0
|
68 |
@since 6.0
|
sl@0
|
69 |
@param aUri A reference to a parsed uri object.
|
sl@0
|
70 |
@return A pointer to the newly created CUri8 object.
|
sl@0
|
71 |
@post A fully constructed and initialized CUri8 object.
|
sl@0
|
72 |
*/
|
sl@0
|
73 |
EXPORT_C CUri8* CUri8::NewLC(const TUriC8& aUri)
|
sl@0
|
74 |
{
|
sl@0
|
75 |
CUri8* self = new (ELeave) CUri8(aUri);
|
sl@0
|
76 |
CleanupStack::PushL(self);
|
sl@0
|
77 |
self->ConstructL();
|
sl@0
|
78 |
return self;
|
sl@0
|
79 |
}
|
sl@0
|
80 |
|
sl@0
|
81 |
/**
|
sl@0
|
82 |
Static factory constructor. Uses two phase construction and leaves nothing on the
|
sl@0
|
83 |
CleanupStack. Creates a uri object which is empty.
|
sl@0
|
84 |
|
sl@0
|
85 |
@since 6.0
|
sl@0
|
86 |
@return A pointer to the newly created CUri8 object.
|
sl@0
|
87 |
@post A fully constructed and initialized CUri8 object.
|
sl@0
|
88 |
*/
|
sl@0
|
89 |
EXPORT_C CUri8* CUri8::NewL()
|
sl@0
|
90 |
{
|
sl@0
|
91 |
CUri8* self = CUri8::NewLC();
|
sl@0
|
92 |
CleanupStack::Pop(self);
|
sl@0
|
93 |
return self;
|
sl@0
|
94 |
}
|
sl@0
|
95 |
|
sl@0
|
96 |
/**
|
sl@0
|
97 |
Static factory constructor. Uses two phase construction and leaves a pointer to created
|
sl@0
|
98 |
object on the CleanupStack. Creates a uri object which is empty.
|
sl@0
|
99 |
|
sl@0
|
100 |
@since 6.0
|
sl@0
|
101 |
@return A pointer to the newly created CUri8 object.
|
sl@0
|
102 |
@post A fully constructed and initialized CUri8 object.
|
sl@0
|
103 |
*/
|
sl@0
|
104 |
EXPORT_C CUri8* CUri8::NewLC()
|
sl@0
|
105 |
{
|
sl@0
|
106 |
CUri8* self = new (ELeave) CUri8(TUriC8());
|
sl@0
|
107 |
CleanupStack::PushL(self);
|
sl@0
|
108 |
self->ConstructL();
|
sl@0
|
109 |
return self;
|
sl@0
|
110 |
}
|
sl@0
|
111 |
|
sl@0
|
112 |
/**
|
sl@0
|
113 |
Static factory constructor. This creates a CUri8 object that is an absolute uri resulting
|
sl@0
|
114 |
from a reference uri being resolved against a base uri.
|
sl@0
|
115 |
|
sl@0
|
116 |
@warning Ownership of created CUri8 object is transferred to the caller.
|
sl@0
|
117 |
@leave KUriErrBadBasePath if the base path is not an absolute path and not empty.
|
sl@0
|
118 |
@since 6.0
|
sl@0
|
119 |
@param aBaseUri A referece to the parsed base uri.
|
sl@0
|
120 |
@param aRefUri A referece to the parsed reference uri.
|
sl@0
|
121 |
@return A pointer to the newly created CUri8 object.
|
sl@0
|
122 |
@pre The base uri must have an absolute or empty path, otherwise will leave
|
sl@0
|
123 |
with KUriErrBadBasePath.
|
sl@0
|
124 |
@post A fully constructed and initialized CUri8 object.
|
sl@0
|
125 |
*/
|
sl@0
|
126 |
EXPORT_C CUri8* CUri8::ResolveL(const TUriC8& aBaseUri, const TUriC8& aRefUri)
|
sl@0
|
127 |
{
|
sl@0
|
128 |
// Check for a base Uri
|
sl@0
|
129 |
if( aBaseUri.UriDes().Compare(KNullDesC8) == 0 )
|
sl@0
|
130 |
{
|
sl@0
|
131 |
// Empty base Uri - resolved Uri is the reference Uri
|
sl@0
|
132 |
return NewL(aRefUri);
|
sl@0
|
133 |
}
|
sl@0
|
134 |
// See if ref has scheme and it is the same as base Uri
|
sl@0
|
135 |
if( aRefUri.IsPresent(EUriScheme) && (aRefUri.Compare(aBaseUri, EUriScheme) != 0) )
|
sl@0
|
136 |
{
|
sl@0
|
137 |
// Ref has a scheme different to base Uri's - it is an absolute Uri
|
sl@0
|
138 |
return NewL(aRefUri);
|
sl@0
|
139 |
}
|
sl@0
|
140 |
// Check for presence of components
|
sl@0
|
141 |
TBool useBaseQuery = EFalse;
|
sl@0
|
142 |
HBufC8* resolvedPath = FormResolvedPathLC<HBufC8>(aBaseUri, aRefUri, useBaseQuery);
|
sl@0
|
143 |
|
sl@0
|
144 |
//Removes dot segemnts in Resolved uri as specified in RFC3986 section 5.2.
|
sl@0
|
145 |
RemoveExtraneousDotSegmentsL(resolvedPath);
|
sl@0
|
146 |
|
sl@0
|
147 |
// Put the Uri together
|
sl@0
|
148 |
TUriC8 uri;
|
sl@0
|
149 |
FormResolvedUri(uri.iComponent, aBaseUri, aRefUri, resolvedPath, useBaseQuery);
|
sl@0
|
150 |
|
sl@0
|
151 |
// Create the resolved Uri and cleanup
|
sl@0
|
152 |
CUri8* resolvedUri = NewL(uri);
|
sl@0
|
153 |
CleanupStack::PopAndDestroy(resolvedPath);
|
sl@0
|
154 |
|
sl@0
|
155 |
return resolvedUri;
|
sl@0
|
156 |
}
|
sl@0
|
157 |
|
sl@0
|
158 |
/**
|
sl@0
|
159 |
Destructor.
|
sl@0
|
160 |
|
sl@0
|
161 |
@since 6.0
|
sl@0
|
162 |
*/
|
sl@0
|
163 |
EXPORT_C CUri8::~CUri8()
|
sl@0
|
164 |
{
|
sl@0
|
165 |
delete iUriBuf;
|
sl@0
|
166 |
}
|
sl@0
|
167 |
|
sl@0
|
168 |
/**
|
sl@0
|
169 |
Provides a reference to the parsed uri. Allows access to the non-modifying API for TUriC8.
|
sl@0
|
170 |
|
sl@0
|
171 |
@since 6.0
|
sl@0
|
172 |
@return A const reference to the parsed uri object.
|
sl@0
|
173 |
*/
|
sl@0
|
174 |
EXPORT_C const TUriC8& CUri8::Uri() const
|
sl@0
|
175 |
{
|
sl@0
|
176 |
return iUri;
|
sl@0
|
177 |
}
|
sl@0
|
178 |
|
sl@0
|
179 |
/**
|
sl@0
|
180 |
Intended Usage : Sets the specified component in the uri. The component is set to the value
|
sl@0
|
181 |
given in the argument aData. If the specified component already exists then it is replaced
|
sl@0
|
182 |
with the new value.
|
sl@0
|
183 |
|
sl@0
|
184 |
@warning The userinfo and port components can only be set if the host component
|
sl@0
|
185 |
is present. Setting these components without a host component present will have no
|
sl@0
|
186 |
effect on the uri.
|
sl@0
|
187 |
@since 6.0
|
sl@0
|
188 |
@param aData A descriptor pointer to the new value for the uri component.
|
sl@0
|
189 |
@param aComponent An enum specifying the component to be set.
|
sl@0
|
190 |
@pre Object is fully constructed.
|
sl@0
|
191 |
@post The uri has the specified component set to the new value.
|
sl@0
|
192 |
@Leave KErrArgument If aComponent goes out of range.
|
sl@0
|
193 |
*/
|
sl@0
|
194 |
EXPORT_C void CUri8::SetComponentL(const TDesC8& aData, TUriComponent aComponent)
|
sl@0
|
195 |
{
|
sl@0
|
196 |
// Update the appropriate component table entry
|
sl@0
|
197 |
iUri.iComponent[aComponent].Set(aData);
|
sl@0
|
198 |
|
sl@0
|
199 |
// Copy to the buffer by forming the uri
|
sl@0
|
200 |
FormUriL();
|
sl@0
|
201 |
}
|
sl@0
|
202 |
|
sl@0
|
203 |
/**
|
sl@0
|
204 |
Removes the specified component from the uri. If the component does not exist then this function
|
sl@0
|
205 |
does nothing.
|
sl@0
|
206 |
|
sl@0
|
207 |
@warning If host is removed, then userinfo and port components will also
|
sl@0
|
208 |
be removed.
|
sl@0
|
209 |
@since 6.0
|
sl@0
|
210 |
@param aComponent An enum specifying the component to be removed.
|
sl@0
|
211 |
@pre Object is fully constructed.
|
sl@0
|
212 |
@post The uri is updated to exclude the specified component.
|
sl@0
|
213 |
*/
|
sl@0
|
214 |
EXPORT_C void CUri8::RemoveComponentL(TUriComponent aComponent)
|
sl@0
|
215 |
{
|
sl@0
|
216 |
if( iUri.IsPresent(aComponent) )
|
sl@0
|
217 |
{
|
sl@0
|
218 |
// Remove the component - set pointer to NULL and length to zero
|
sl@0
|
219 |
iUri.iComponent[aComponent].Set(NULL,0);
|
sl@0
|
220 |
|
sl@0
|
221 |
// Re-form buffer and component table
|
sl@0
|
222 |
FormUriL();
|
sl@0
|
223 |
}
|
sl@0
|
224 |
}
|
sl@0
|
225 |
|
sl@0
|
226 |
/**
|
sl@0
|
227 |
Constructor. First phase of two-phase construction method. Does non-allocating construction.
|
sl@0
|
228 |
|
sl@0
|
229 |
@since 6.0
|
sl@0
|
230 |
@param aUri The parsed uri component information from which to create
|
sl@0
|
231 |
the uri.
|
sl@0
|
232 |
*/
|
sl@0
|
233 |
CUri8::CUri8(const TUriC8& aUri)
|
sl@0
|
234 |
: CBase(), iUri(aUri)
|
sl@0
|
235 |
{
|
sl@0
|
236 |
}
|
sl@0
|
237 |
|
sl@0
|
238 |
/**
|
sl@0
|
239 |
Second phase of two-phase construction method. Does any allocations required to fully construct
|
sl@0
|
240 |
the object.
|
sl@0
|
241 |
|
sl@0
|
242 |
@since 6.0
|
sl@0
|
243 |
@pre First phase of construction is complete.
|
sl@0
|
244 |
@post The object is fully constructed and initialized.
|
sl@0
|
245 |
*/
|
sl@0
|
246 |
void CUri8::ConstructL()
|
sl@0
|
247 |
{
|
sl@0
|
248 |
// Create the HBufC
|
sl@0
|
249 |
FormUriL();
|
sl@0
|
250 |
}
|
sl@0
|
251 |
|
sl@0
|
252 |
/**
|
sl@0
|
253 |
Forms the uri from the parsed uri information. A copy of the parsed uri is created. The parsed uri
|
sl@0
|
254 |
is changed to refer to the copy.
|
sl@0
|
255 |
|
sl@0
|
256 |
@since 6.0
|
sl@0
|
257 |
@pre The parsed uri information is set.
|
sl@0
|
258 |
@post The uri buffer is updated with the parsed uri information.
|
sl@0
|
259 |
*/
|
sl@0
|
260 |
void CUri8::FormUriL()
|
sl@0
|
261 |
{
|
sl@0
|
262 |
TBool isIPv6Host;
|
sl@0
|
263 |
|
sl@0
|
264 |
// Calculate length of of the Uri
|
sl@0
|
265 |
TInt length = CalculateUriLength(iUri.iComponent, isIPv6Host);
|
sl@0
|
266 |
|
sl@0
|
267 |
// Create a temporary buffer and descriptor pointer to it
|
sl@0
|
268 |
HBufC8* buf = HBufC8::NewL(length);
|
sl@0
|
269 |
TPtr8 uri = buf->Des();
|
sl@0
|
270 |
|
sl@0
|
271 |
// Create the uri, updating the internal uri object
|
sl@0
|
272 |
DoFormUri(uri, iUri.iComponent, isIPv6Host);
|
sl@0
|
273 |
|
sl@0
|
274 |
// Update the internal buffer and descriptor pointer
|
sl@0
|
275 |
delete iUriBuf;
|
sl@0
|
276 |
iUriBuf = buf;
|
sl@0
|
277 |
iUri.iUriDes.Set(iUriBuf->Des());
|
sl@0
|
278 |
}
|
sl@0
|
279 |
|
sl@0
|
280 |
//
|
sl@0
|
281 |
//
|
sl@0
|
282 |
// Implementation of CUri16
|
sl@0
|
283 |
//
|
sl@0
|
284 |
//
|
sl@0
|
285 |
|
sl@0
|
286 |
/**
|
sl@0
|
287 |
Static factory constructor. Uses two phase construction and leaves nothing on the CleanupStack.
|
sl@0
|
288 |
Creates a uri object which is a copy of the input parameter aUri.
|
sl@0
|
289 |
|
sl@0
|
290 |
@deprecated Deprecated in 9.1
|
sl@0
|
291 |
@since 6.0
|
sl@0
|
292 |
@param aUri A reference to a parsed uri object.
|
sl@0
|
293 |
@return A pointer to the newly created CUri16 object.
|
sl@0
|
294 |
@post A fully constructed and initialized CUri16 object.
|
sl@0
|
295 |
*/
|
sl@0
|
296 |
EXPORT_C CUri16* CUri16::NewL(const TUriC16& aUri)
|
sl@0
|
297 |
{
|
sl@0
|
298 |
CUri16* self = CUri16::NewLC(aUri);
|
sl@0
|
299 |
CleanupStack::Pop(self);
|
sl@0
|
300 |
return self;
|
sl@0
|
301 |
}
|
sl@0
|
302 |
|
sl@0
|
303 |
/**
|
sl@0
|
304 |
Static factory constructor. Uses two phase construction and leaves a pointer to created object on
|
sl@0
|
305 |
the CleanupStack. Creates a uri object which is a copy of the input parameter aUri.
|
sl@0
|
306 |
|
sl@0
|
307 |
@since 6.0
|
sl@0
|
308 |
@deprecated Deprecated in 9.1
|
sl@0
|
309 |
@param aUri A reference to a parsed uri object.
|
sl@0
|
310 |
@return A pointer to the newly created CUri16 object.
|
sl@0
|
311 |
@post A fully constructed and initialized CUri16 object.
|
sl@0
|
312 |
*/
|
sl@0
|
313 |
EXPORT_C CUri16* CUri16::NewLC(const TUriC16& aUri)
|
sl@0
|
314 |
{
|
sl@0
|
315 |
CUri16* self = new (ELeave) CUri16(aUri);
|
sl@0
|
316 |
CleanupStack::PushL(self);
|
sl@0
|
317 |
self->ConstructL();
|
sl@0
|
318 |
return self;
|
sl@0
|
319 |
}
|
sl@0
|
320 |
|
sl@0
|
321 |
/**
|
sl@0
|
322 |
Static factory constructor. Uses two phase construction and leaves nothing on the CleanupStack.
|
sl@0
|
323 |
Creates a uri object which is empty.
|
sl@0
|
324 |
|
sl@0
|
325 |
@since 6.0
|
sl@0
|
326 |
@deprecated Deprecated in 9.1
|
sl@0
|
327 |
@return A pointer to the newly created CUri16 object.
|
sl@0
|
328 |
@post A fully constructed and initialized CUri16 object.
|
sl@0
|
329 |
*/
|
sl@0
|
330 |
EXPORT_C CUri16* CUri16::NewL()
|
sl@0
|
331 |
{
|
sl@0
|
332 |
CUri16* self = CUri16::NewLC();
|
sl@0
|
333 |
CleanupStack::Pop(self);
|
sl@0
|
334 |
return self;
|
sl@0
|
335 |
}
|
sl@0
|
336 |
|
sl@0
|
337 |
/**
|
sl@0
|
338 |
Static factory constructor. Uses two phase construction and leaves a pointer to created object on
|
sl@0
|
339 |
the CleanupStack. Creates a uri object which is empty.
|
sl@0
|
340 |
|
sl@0
|
341 |
@since 6.0
|
sl@0
|
342 |
@deprecated Deprecated in 9.1
|
sl@0
|
343 |
@return A pointer to the newly created CUri16 object.
|
sl@0
|
344 |
@post A fully constructed and initialized CUri16 object.
|
sl@0
|
345 |
*/
|
sl@0
|
346 |
EXPORT_C CUri16* CUri16::NewLC()
|
sl@0
|
347 |
{
|
sl@0
|
348 |
CUri16* self = new (ELeave) CUri16(TUriC16());
|
sl@0
|
349 |
CleanupStack::PushL(self);
|
sl@0
|
350 |
self->ConstructL();
|
sl@0
|
351 |
return self;
|
sl@0
|
352 |
}
|
sl@0
|
353 |
|
sl@0
|
354 |
/**
|
sl@0
|
355 |
Static factory constructor. This creates a CUri16 object that is an absolute uri resulting from a
|
sl@0
|
356 |
reference uri being resolved against a base uri.
|
sl@0
|
357 |
|
sl@0
|
358 |
@warning Ownership of created CUri16 object is transferred to caller.
|
sl@0
|
359 |
@leave KUriErrBadBasePath if the base path is not an absolute path and not empty.
|
sl@0
|
360 |
@since 6.0
|
sl@0
|
361 |
@deprecated Deprecated in 9.1
|
sl@0
|
362 |
@param aBaseUri A referece to the parsed base uri.
|
sl@0
|
363 |
@param aRefUri A referece to the parsed reference uri.
|
sl@0
|
364 |
@return A pointer to the newly created CUri16 object.
|
sl@0
|
365 |
@pre The base uri must have an absolute or empty path, otherwise will leave
|
sl@0
|
366 |
with KUriErrBadBasePath.
|
sl@0
|
367 |
@post A fully constructed and initialized CUri16 object.
|
sl@0
|
368 |
*/
|
sl@0
|
369 |
EXPORT_C CUri16* CUri16::ResolveL(const TUriC16& aBaseUri, const TUriC16& aRefUri)
|
sl@0
|
370 |
{
|
sl@0
|
371 |
// Check for a base Uri
|
sl@0
|
372 |
if( aBaseUri.UriDes().Compare(KNullDesC16) == 0 )
|
sl@0
|
373 |
{
|
sl@0
|
374 |
// Empty base Uri - resolved Uri is the reference Uri
|
sl@0
|
375 |
return NewL(aRefUri);
|
sl@0
|
376 |
}
|
sl@0
|
377 |
// See if ref has scheme and it is the same as base Uri
|
sl@0
|
378 |
if( aRefUri.IsPresent(EUriScheme) && aRefUri.Compare(aBaseUri, EUriScheme) != 0 )
|
sl@0
|
379 |
{
|
sl@0
|
380 |
// Ref has a scheme different to base Uri's - it is an absolute Uri
|
sl@0
|
381 |
return NewL(aRefUri);
|
sl@0
|
382 |
}
|
sl@0
|
383 |
// Check for presence of components
|
sl@0
|
384 |
TBool useBaseQuery = EFalse;
|
sl@0
|
385 |
HBufC16* resolvedPath = FormResolvedPathLC<HBufC16>(aBaseUri, aRefUri, useBaseQuery);
|
sl@0
|
386 |
|
sl@0
|
387 |
// Put the Uri together
|
sl@0
|
388 |
TUriC16 uri;
|
sl@0
|
389 |
FormResolvedUri(uri.iComponent, aBaseUri, aRefUri, resolvedPath, useBaseQuery);
|
sl@0
|
390 |
|
sl@0
|
391 |
// Create the resolved Uri and cleanup
|
sl@0
|
392 |
CUri16* resolvedUri = NewL(uri);
|
sl@0
|
393 |
CleanupStack::PopAndDestroy(resolvedPath);
|
sl@0
|
394 |
|
sl@0
|
395 |
return resolvedUri;
|
sl@0
|
396 |
}
|
sl@0
|
397 |
|
sl@0
|
398 |
/**
|
sl@0
|
399 |
Destructor.
|
sl@0
|
400 |
|
sl@0
|
401 |
@since 6.0
|
sl@0
|
402 |
@deprecated Deprecated in 9.1
|
sl@0
|
403 |
*/
|
sl@0
|
404 |
EXPORT_C CUri16::~CUri16()
|
sl@0
|
405 |
{
|
sl@0
|
406 |
delete iUriBuf;
|
sl@0
|
407 |
}
|
sl@0
|
408 |
|
sl@0
|
409 |
/**
|
sl@0
|
410 |
Provides a reference to the parsed uri. Allows access to the non-modifying API for TUriC16.
|
sl@0
|
411 |
|
sl@0
|
412 |
@since 6.0
|
sl@0
|
413 |
@deprecated Deprecated in 9.1
|
sl@0
|
414 |
@return A const reference to the parsed uri object.
|
sl@0
|
415 |
*/
|
sl@0
|
416 |
EXPORT_C const TUriC16& CUri16::Uri() const
|
sl@0
|
417 |
{
|
sl@0
|
418 |
return iUri;
|
sl@0
|
419 |
}
|
sl@0
|
420 |
|
sl@0
|
421 |
/**
|
sl@0
|
422 |
Sets the specified component in the uri. The component is set to the value given in the argument
|
sl@0
|
423 |
aData. If the specified component already exists then it is replaced with the new value.
|
sl@0
|
424 |
|
sl@0
|
425 |
@warning The userinfo and port components can only be set if the host component
|
sl@0
|
426 |
is present. Setting these components without a host component present will have no
|
sl@0
|
427 |
effect on the uri.
|
sl@0
|
428 |
@since 6.0
|
sl@0
|
429 |
@deprecated Deprecated in 9.1
|
sl@0
|
430 |
@param aData A descriptor pointer to the new value for the uri component.
|
sl@0
|
431 |
@param aComponent An enum specifying the component to be set.
|
sl@0
|
432 |
@pre Object is fully constructed.
|
sl@0
|
433 |
@post The uri has the specified component set to the new value.
|
sl@0
|
434 |
@Leave KErrArgument If aComponent goes out of range.
|
sl@0
|
435 |
*/
|
sl@0
|
436 |
EXPORT_C void CUri16::SetComponentL(const TDesC16& aData, TUriComponent aComponent)
|
sl@0
|
437 |
{
|
sl@0
|
438 |
// Update the appropriate component table entry
|
sl@0
|
439 |
iUri.iComponent[aComponent].Set(aData);
|
sl@0
|
440 |
|
sl@0
|
441 |
// Copy to the buffer by forming the uri
|
sl@0
|
442 |
FormUriL();
|
sl@0
|
443 |
}
|
sl@0
|
444 |
|
sl@0
|
445 |
/**
|
sl@0
|
446 |
Removes the specified component from the uri. If the component does not exist then this function
|
sl@0
|
447 |
does nothing.
|
sl@0
|
448 |
|
sl@0
|
449 |
@warning If host is removed, then userinfo and port components will also
|
sl@0
|
450 |
be removed.
|
sl@0
|
451 |
@since 6.0
|
sl@0
|
452 |
@deprecated Deprecated in 9.1
|
sl@0
|
453 |
@param aComponent An enum specifying the component to be removed.
|
sl@0
|
454 |
@pre Object is fully constructed.
|
sl@0
|
455 |
@post The uri is updated to exclude the specified component.
|
sl@0
|
456 |
*/
|
sl@0
|
457 |
EXPORT_C void CUri16::RemoveComponentL(TUriComponent aComponent)
|
sl@0
|
458 |
{
|
sl@0
|
459 |
if( iUri.IsPresent(aComponent) )
|
sl@0
|
460 |
{
|
sl@0
|
461 |
// Remove the component - set pointer to NULL and length to zero
|
sl@0
|
462 |
iUri.iComponent[aComponent].Set(NULL,0);
|
sl@0
|
463 |
|
sl@0
|
464 |
// Re-form buffer and component table
|
sl@0
|
465 |
FormUriL();
|
sl@0
|
466 |
}
|
sl@0
|
467 |
}
|
sl@0
|
468 |
|
sl@0
|
469 |
/**
|
sl@0
|
470 |
Constructor. First phase of two-phase construction method. Does non-allocating construction.
|
sl@0
|
471 |
|
sl@0
|
472 |
@since 6.0
|
sl@0
|
473 |
@param aUri The parsed uri component information from which to create
|
sl@0
|
474 |
the uri.
|
sl@0
|
475 |
*/
|
sl@0
|
476 |
|
sl@0
|
477 |
CUri16::CUri16(const TUriC16& aUri)
|
sl@0
|
478 |
: CBase(), iUri(aUri)
|
sl@0
|
479 |
{
|
sl@0
|
480 |
}
|
sl@0
|
481 |
|
sl@0
|
482 |
/**
|
sl@0
|
483 |
Second phase of two-phase construction method. Does any allocations required to fully construct
|
sl@0
|
484 |
the object.
|
sl@0
|
485 |
|
sl@0
|
486 |
@since 6.0
|
sl@0
|
487 |
@pre First phase of construction is complete.
|
sl@0
|
488 |
@post The object is fully constructed and initialized.
|
sl@0
|
489 |
*/
|
sl@0
|
490 |
void CUri16::ConstructL()
|
sl@0
|
491 |
{
|
sl@0
|
492 |
// Create the HBufC
|
sl@0
|
493 |
FormUriL();
|
sl@0
|
494 |
}
|
sl@0
|
495 |
|
sl@0
|
496 |
/**
|
sl@0
|
497 |
Forms the uri from the parsed uri information. A copy of the parsed uri is created. The parsed uri
|
sl@0
|
498 |
is changed to refer to the copy.
|
sl@0
|
499 |
|
sl@0
|
500 |
@since 6.0
|
sl@0
|
501 |
@pre The parsed uri information is set.
|
sl@0
|
502 |
@post The uri buffer is updated with the parsed uri information.
|
sl@0
|
503 |
*/
|
sl@0
|
504 |
void CUri16::FormUriL()
|
sl@0
|
505 |
{
|
sl@0
|
506 |
TBool isIPv6Host;
|
sl@0
|
507 |
|
sl@0
|
508 |
// Calculate length of of the Uri
|
sl@0
|
509 |
TInt length = CalculateUriLength(iUri.iComponent, isIPv6Host);
|
sl@0
|
510 |
|
sl@0
|
511 |
// Create a temporary buffer and descriptor pointer to it
|
sl@0
|
512 |
HBufC16* buf = HBufC16::NewL(length);
|
sl@0
|
513 |
TPtr16 uri = buf->Des();
|
sl@0
|
514 |
|
sl@0
|
515 |
// Create the uri, updating the internal uri object
|
sl@0
|
516 |
DoFormUri(uri, iUri.iComponent, isIPv6Host);
|
sl@0
|
517 |
|
sl@0
|
518 |
// Update the internal buffer and descriptor pointer
|
sl@0
|
519 |
delete iUriBuf;
|
sl@0
|
520 |
iUriBuf = buf;
|
sl@0
|
521 |
iUri.iUriDes.Set(iUriBuf->Des());
|
sl@0
|
522 |
}
|
sl@0
|
523 |
|
sl@0
|
524 |
//
|
sl@0
|
525 |
//
|
sl@0
|
526 |
// Implementation of templated LOCAL functions
|
sl@0
|
527 |
//
|
sl@0
|
528 |
//
|
sl@0
|
529 |
|
sl@0
|
530 |
/**
|
sl@0
|
531 |
Calculates the length of the uri from a list of the components.
|
sl@0
|
532 |
|
sl@0
|
533 |
@since 6.0
|
sl@0
|
534 |
@param aComponent The array of descriptor pointers to the uri
|
sl@0
|
535 |
components.
|
sl@0
|
536 |
@param aIsIPv6Host ETrue if an IPv6 format host is used
|
sl@0
|
537 |
@return The length of the uri including the required delimiters.
|
sl@0
|
538 |
*/
|
sl@0
|
539 |
template<class TPtrCType>
|
sl@0
|
540 |
TInt CalculateUriLength(const TPtrCType aComponent[], TBool& aIsIPv6Host)
|
sl@0
|
541 |
{
|
sl@0
|
542 |
TBool noAuthority = ETrue;
|
sl@0
|
543 |
TInt length=0;
|
sl@0
|
544 |
aIsIPv6Host=EFalse;
|
sl@0
|
545 |
for( TInt i=0; i<EUriMaxComponents; ++i )
|
sl@0
|
546 |
{
|
sl@0
|
547 |
if( aComponent[i].Ptr() )
|
sl@0
|
548 |
{
|
sl@0
|
549 |
length += aComponent[i].Length();
|
sl@0
|
550 |
if( noAuthority && (i==EUriUserinfo || i==EUriHost || i==EUriPort) )
|
sl@0
|
551 |
{
|
sl@0
|
552 |
// There's an authority part...
|
sl@0
|
553 |
noAuthority = EFalse;
|
sl@0
|
554 |
}
|
sl@0
|
555 |
// Need to make space for a delimiter if not path or host
|
sl@0
|
556 |
if( i!=EUriHost && i!=EUriPath )
|
sl@0
|
557 |
++length;
|
sl@0
|
558 |
|
sl@0
|
559 |
// If it's an IPv6 hostname, need extra space for []
|
sl@0
|
560 |
if(i==EUriHost && (UriUtils::HostType(aComponent[i])==UriUtils::EIPv6Host))
|
sl@0
|
561 |
{
|
sl@0
|
562 |
length+=2;
|
sl@0
|
563 |
aIsIPv6Host=ETrue;
|
sl@0
|
564 |
}
|
sl@0
|
565 |
}
|
sl@0
|
566 |
}
|
sl@0
|
567 |
if( !noAuthority && IsNetworkScheme(aComponent[EUriScheme]))
|
sl@0
|
568 |
{
|
sl@0
|
569 |
// Make space for authority delimiter
|
sl@0
|
570 |
length += KUriNetworkAuthorityDelimiterLength;
|
sl@0
|
571 |
}
|
sl@0
|
572 |
return length;
|
sl@0
|
573 |
}
|
sl@0
|
574 |
|
sl@0
|
575 |
/**
|
sl@0
|
576 |
Templated function to form a uri. The output argument aUri points to a descriptor
|
sl@0
|
577 |
buffer large enough to hold the uri. The new uri component information is given by
|
sl@0
|
578 |
the input/output argument aComponent. For each uri component that exists in aComponent,
|
sl@0
|
579 |
that component and its appropriate delimiters are appended to aUri. Then the components
|
sl@0
|
580 |
in aComponent are updated to refer to the copies versions in aUri.
|
sl@0
|
581 |
|
sl@0
|
582 |
@since 6.0
|
sl@0
|
583 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
584 |
@param aComponent The array of descriptor pointers to be copied and
|
sl@0
|
585 |
then updated.
|
sl@0
|
586 |
@param aIsIPv6Host ETrue if an IPv6 format host is used
|
sl@0
|
587 |
@pre The buffer pointed to by aUri should be large enough to have the uri
|
sl@0
|
588 |
components given in aNewComponent copied into it, as well as the required delimiters.
|
sl@0
|
589 |
This can be obtained using CalculateUriLength().
|
sl@0
|
590 |
@post The uri buffer pointed to by aUri will have a copy of the uri defined
|
sl@0
|
591 |
in aComponent, and then aComponent will refer to the copies of these components in aUri.
|
sl@0
|
592 |
*/
|
sl@0
|
593 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
594 |
void DoFormUri(TPtrType& aUri, TPtrCType aComponent[], TBool& aIsIPv6Host)
|
sl@0
|
595 |
{
|
sl@0
|
596 |
TBool isNetworkScheme = ETrue;
|
sl@0
|
597 |
if( aComponent[EUriScheme].Ptr() )
|
sl@0
|
598 |
{
|
sl@0
|
599 |
// Update the scheme
|
sl@0
|
600 |
SetScheme(aUri, aComponent[EUriScheme]);
|
sl@0
|
601 |
isNetworkScheme = IsNetworkScheme(aComponent[EUriScheme]);
|
sl@0
|
602 |
}
|
sl@0
|
603 |
if( aComponent[EUriHost].Ptr() )
|
sl@0
|
604 |
{
|
sl@0
|
605 |
// Update the authority - only needed if there is a host; update userinfo, host and port
|
sl@0
|
606 |
SetAuthority(aUri, aComponent[EUriUserinfo], aComponent[EUriHost], aComponent[EUriPort], aIsIPv6Host, isNetworkScheme);
|
sl@0
|
607 |
}
|
sl@0
|
608 |
else
|
sl@0
|
609 |
{
|
sl@0
|
610 |
// Ensure that there is no userinfo or port components if there is no host
|
sl@0
|
611 |
// - set pointer to NULL and length to zero
|
sl@0
|
612 |
aComponent[EUriUserinfo].Set(NULL,0);
|
sl@0
|
613 |
aComponent[EUriPort].Set(NULL,0);
|
sl@0
|
614 |
}
|
sl@0
|
615 |
if( aComponent[EUriPath].Ptr() )
|
sl@0
|
616 |
{
|
sl@0
|
617 |
// Update the path
|
sl@0
|
618 |
SetPath(aUri, aComponent[EUriPath]);
|
sl@0
|
619 |
}
|
sl@0
|
620 |
if( aComponent[EUriQuery].Ptr() )
|
sl@0
|
621 |
{
|
sl@0
|
622 |
// Update the query
|
sl@0
|
623 |
SetQuery(aUri, aComponent[EUriQuery]);
|
sl@0
|
624 |
}
|
sl@0
|
625 |
if( aComponent[EUriFragment].Ptr() )
|
sl@0
|
626 |
{
|
sl@0
|
627 |
// Update the fragment
|
sl@0
|
628 |
SetFragment(aUri, aComponent[EUriFragment]);
|
sl@0
|
629 |
}
|
sl@0
|
630 |
}
|
sl@0
|
631 |
|
sl@0
|
632 |
/**
|
sl@0
|
633 |
Templated function to set the scheme in a uri. The output argument aUri points to the descriptor
|
sl@0
|
634 |
buffer into which aScheme will be copied.The argument aScheme is then updated to point to the
|
sl@0
|
635 |
copied version in aUri.
|
sl@0
|
636 |
|
sl@0
|
637 |
@warning This function will panic with KUriErrBufferOverflow if there is not
|
sl@0
|
638 |
enough space in the descriptor to append the scheme and the required delimiter.
|
sl@0
|
639 |
@since 6.0
|
sl@0
|
640 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
641 |
@param aScheme The descriptor pointer to the scheme component to be copied
|
sl@0
|
642 |
and then updated.
|
sl@0
|
643 |
@pre The buffer pointed to by aUri should be large enough to have aNewScheme
|
sl@0
|
644 |
appended to it with the required delimiter. This can be obtained using CalculateUriLength().
|
sl@0
|
645 |
@post The uri buffer now includes a copy of aScheme and aScheme points to the
|
sl@0
|
646 |
copy of the scheme component in aUri.
|
sl@0
|
647 |
*/
|
sl@0
|
648 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
649 |
void SetScheme(TPtrType& aUri, TPtrCType& aScheme)
|
sl@0
|
650 |
{
|
sl@0
|
651 |
__ASSERT_DEBUG(aUri.Length() + aScheme.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
652 |
|
sl@0
|
653 |
// Append the scheme and delimiter
|
sl@0
|
654 |
aUri.Append(aScheme);
|
sl@0
|
655 |
aUri.Append(KSchemeDelimiter);
|
sl@0
|
656 |
|
sl@0
|
657 |
// Update the component table to use the copy
|
sl@0
|
658 |
aScheme.Set(aUri.Left(aScheme.Length()));
|
sl@0
|
659 |
}
|
sl@0
|
660 |
|
sl@0
|
661 |
/**
|
sl@0
|
662 |
Templated function to set the authority in a uri. The output argument aUri points to the descriptor
|
sl@0
|
663 |
buffer into which aUserinfo, aHost and aPort will be copied. The arguments aUserinfo, aHost and aPort
|
sl@0
|
664 |
are updated to point to the copied versions in aUri.
|
sl@0
|
665 |
|
sl@0
|
666 |
@warning This function will panic with KUriErrBufferOverflow if there
|
sl@0
|
667 |
is not enough space in the descriptor to append the components and any required
|
sl@0
|
668 |
delimiters.
|
sl@0
|
669 |
@since 6.0
|
sl@0
|
670 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
671 |
@param aUserinfo The descriptor pointer to the userinfo component to
|
sl@0
|
672 |
be copied and then updated.
|
sl@0
|
673 |
@param aHost The descriptor pointer to the host component to
|
sl@0
|
674 |
be copied and then updated.
|
sl@0
|
675 |
@param aPort The descriptor pointer to the port component to
|
sl@0
|
676 |
be copied and then updated.
|
sl@0
|
677 |
@param aIsIPv6Host ETrue if an IPv6 format host is used
|
sl@0
|
678 |
@param aUseNetworkDelimiter EFalse if this is a SIP scheme otherwise ETrue
|
sl@0
|
679 |
@pre The buffer pointed to by aUri should be large enough to have
|
sl@0
|
680 |
aUserinfo, aHost and aPort appended to it with the required delimiters.
|
sl@0
|
681 |
This can be obtained using CalculateUriLength().
|
sl@0
|
682 |
@post The uri buffer now includes a copy of aUserinfo, aHost and
|
sl@0
|
683 |
aPort, and aUserinfo, aHost and aPort will refer to the copies versions in aUri.
|
sl@0
|
684 |
*/
|
sl@0
|
685 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
686 |
void SetAuthority(TPtrType& aUri, TPtrCType& aUserinfo, TPtrCType& aHost, TPtrCType& aPort, TBool& aIsIPv6Host, TBool aUseNetworkDelimiter)
|
sl@0
|
687 |
{
|
sl@0
|
688 |
__ASSERT_DEBUG(aUri.Length() + aHost.Length() + (aUseNetworkDelimiter ? KUriNetworkAuthorityDelimiterLength:0) <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
689 |
|
sl@0
|
690 |
if (aUseNetworkDelimiter)
|
sl@0
|
691 |
{
|
sl@0
|
692 |
// If a network scheme append authority delimiter (TWO slash delimiters!)
|
sl@0
|
693 |
aUri.Append(KSlashDelimiter);
|
sl@0
|
694 |
aUri.Append(KSlashDelimiter);
|
sl@0
|
695 |
}
|
sl@0
|
696 |
|
sl@0
|
697 |
// Check for userinfo
|
sl@0
|
698 |
if( aUserinfo.Ptr() )
|
sl@0
|
699 |
{
|
sl@0
|
700 |
__ASSERT_DEBUG(aUri.Length() + aUserinfo.Length() + aHost.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
701 |
|
sl@0
|
702 |
// Append userinfo and update the component table to use copy
|
sl@0
|
703 |
aUri.Append(aUserinfo);
|
sl@0
|
704 |
aUserinfo.Set(aUri.Right(aUserinfo.Length()));
|
sl@0
|
705 |
|
sl@0
|
706 |
// Append delimiter
|
sl@0
|
707 |
aUri.Append(KUserinfoDelimiter);
|
sl@0
|
708 |
}
|
sl@0
|
709 |
// There's always a host - append and update the component table to use the copy
|
sl@0
|
710 |
|
sl@0
|
711 |
// Check if it's an IPv6 address
|
sl@0
|
712 |
if ( aIsIPv6Host )
|
sl@0
|
713 |
{
|
sl@0
|
714 |
aUri.Append(KIPv6UriOpenBrace);
|
sl@0
|
715 |
aUri.Append(aHost);
|
sl@0
|
716 |
aUri.Append(KIPv6UriCloseBrace);
|
sl@0
|
717 |
// Dont include the braces in the host
|
sl@0
|
718 |
// Position = (length of uri - length of host) - length of end brace
|
sl@0
|
719 |
aHost.Set( aUri.Mid((aUri.Length()-aHost.Length())-1, aHost.Length()) );
|
sl@0
|
720 |
}
|
sl@0
|
721 |
else
|
sl@0
|
722 |
{
|
sl@0
|
723 |
aUri.Append(aHost);
|
sl@0
|
724 |
aHost.Set(aUri.Right(aHost.Length()));
|
sl@0
|
725 |
}
|
sl@0
|
726 |
|
sl@0
|
727 |
// Check for a port
|
sl@0
|
728 |
if( aPort.Ptr() )
|
sl@0
|
729 |
{
|
sl@0
|
730 |
__ASSERT_DEBUG(aUri.Length() + aPort.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
731 |
|
sl@0
|
732 |
// Append delimiter
|
sl@0
|
733 |
aUri.Append(KPortDelimiter);
|
sl@0
|
734 |
|
sl@0
|
735 |
// Append port and update the component table to use copy
|
sl@0
|
736 |
aUri.Append(aPort);
|
sl@0
|
737 |
aPort.Set(aUri.Right(aPort.Length()));
|
sl@0
|
738 |
}
|
sl@0
|
739 |
}
|
sl@0
|
740 |
/**
|
sl@0
|
741 |
Templated function to set the path in a uri. The output argument aUri points to the descriptor
|
sl@0
|
742 |
buffer into which aPath will be copied.The argument aPath is then updated to point to the copied
|
sl@0
|
743 |
version in aUri.
|
sl@0
|
744 |
|
sl@0
|
745 |
@warning This function will panic with KUriErrBufferOverflow if there
|
sl@0
|
746 |
is not enough space in the descriptor to append the path.
|
sl@0
|
747 |
@since 6.0
|
sl@0
|
748 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
749 |
@param aPath The descriptor pointer to the path component to be copied
|
sl@0
|
750 |
and then updated.
|
sl@0
|
751 |
@pre The buffer pointed to by aUri should be large enough to have
|
sl@0
|
752 |
aPath appended to it. This can be obtained using CalculateUriLength().
|
sl@0
|
753 |
@post The uri buffer now includes a copy of aPath and aPath points to the
|
sl@0
|
754 |
copy of the path component in aUri.
|
sl@0
|
755 |
*/
|
sl@0
|
756 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
757 |
void SetPath(TPtrType& aUri, TPtrCType& aPath)
|
sl@0
|
758 |
{
|
sl@0
|
759 |
__ASSERT_DEBUG(aUri.Length() + aPath.Length() <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
760 |
|
sl@0
|
761 |
// Append the path
|
sl@0
|
762 |
aUri.Append(aPath);
|
sl@0
|
763 |
|
sl@0
|
764 |
// Update the component table
|
sl@0
|
765 |
aPath.Set(aUri.Right(aPath.Length()));
|
sl@0
|
766 |
}
|
sl@0
|
767 |
|
sl@0
|
768 |
/**
|
sl@0
|
769 |
Templated function to set the query in a uri. The output argument aUri points to the descriptor
|
sl@0
|
770 |
buffer into which aQuery will be copied. The argument aQuery is then updated to point to the copied
|
sl@0
|
771 |
version in aUri.
|
sl@0
|
772 |
|
sl@0
|
773 |
@warning This function will panic with KUriErrBufferOverflow if there
|
sl@0
|
774 |
is not enough space in the descriptor to append the query and the delimiter.
|
sl@0
|
775 |
@since 6.0
|
sl@0
|
776 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
777 |
@param aQuery The descriptor pointer to the query component to be copied
|
sl@0
|
778 |
and then updated.
|
sl@0
|
779 |
@pre The buffer pointed to by aUri should be large enough to have
|
sl@0
|
780 |
aQuery appended to it. This can be obtained using CalculateUriLength().
|
sl@0
|
781 |
@post The uri buffer now includes a copy of aQuery and aQuery points to the
|
sl@0
|
782 |
copy of the query component in aUri.
|
sl@0
|
783 |
*/
|
sl@0
|
784 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
785 |
void SetQuery(TPtrType& aUri, TPtrCType& aQuery)
|
sl@0
|
786 |
{
|
sl@0
|
787 |
__ASSERT_DEBUG(aUri.Length() + aQuery.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
788 |
|
sl@0
|
789 |
// Append delimiter and the query
|
sl@0
|
790 |
aUri.Append(KQueryDelimiter);
|
sl@0
|
791 |
aUri.Append(aQuery);
|
sl@0
|
792 |
|
sl@0
|
793 |
// Update the component table
|
sl@0
|
794 |
aQuery.Set(aUri.Right(aQuery.Length()));
|
sl@0
|
795 |
}
|
sl@0
|
796 |
|
sl@0
|
797 |
/**
|
sl@0
|
798 |
Templated function to set the fragment in a uri. The output argument aUri points to the descriptor
|
sl@0
|
799 |
buffer into which aFragment will be copied. The argument aFragment is then updated to point to the
|
sl@0
|
800 |
copied version in aUri.
|
sl@0
|
801 |
|
sl@0
|
802 |
@warning This function will panic with KUriErrBufferOverflow if there
|
sl@0
|
803 |
is not enough space in the descriptor to append the fragment and the delimiter.
|
sl@0
|
804 |
@since 6.0
|
sl@0
|
805 |
@param aUri The descriptor pointer to buffer to be appended.
|
sl@0
|
806 |
@param aFragment The descriptor pointer to the fragment component
|
sl@0
|
807 |
to be copied and then updated.
|
sl@0
|
808 |
@pre The buffer pointed to by aUri should be large enough to have
|
sl@0
|
809 |
aFragment appended to it. This can be obtained using CalculateUriLength().
|
sl@0
|
810 |
@post The uri buffer now includes a copy of aFragment and aFragment points
|
sl@0
|
811 |
to the copy of the fragment component in aUri.
|
sl@0
|
812 |
*/
|
sl@0
|
813 |
template<class TPtrType, class TPtrCType>
|
sl@0
|
814 |
void SetFragment(TPtrType& aUri, TPtrCType& aFragment)
|
sl@0
|
815 |
{
|
sl@0
|
816 |
__ASSERT_DEBUG(aUri.Length() + aFragment.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
|
sl@0
|
817 |
|
sl@0
|
818 |
// Append delimiter and the fragment
|
sl@0
|
819 |
aUri.Append(KFragmentDelimiter);
|
sl@0
|
820 |
aUri.Append(aFragment);
|
sl@0
|
821 |
|
sl@0
|
822 |
// Update the component table
|
sl@0
|
823 |
aFragment.Set(aUri.Right(aFragment.Length()));
|
sl@0
|
824 |
}
|
sl@0
|
825 |
|
sl@0
|
826 |
/**
|
sl@0
|
827 |
Forms the resolved path. Checks to see if the base query needs to be used in the resolved uri.
|
sl@0
|
828 |
The pointer to the resolved path is left on the cleanup stack.
|
sl@0
|
829 |
|
sl@0
|
830 |
@since 6.0
|
sl@0
|
831 |
@param aBaseUri The base uri.
|
sl@0
|
832 |
@param aRefUri The reference uri.
|
sl@0
|
833 |
@param aUseBaseQuery An output argument specifying whether the base
|
sl@0
|
834 |
query should be used in the resolved uri.
|
sl@0
|
835 |
@return A pointer to a buffer that contains the resolved path.
|
sl@0
|
836 |
*/
|
sl@0
|
837 |
template<class HBufCType, class TUriCType>
|
sl@0
|
838 |
HBufCType* FormResolvedPathLC(const TUriCType& aBaseUri, const TUriCType& aRefUri, TBool& aUseBaseQuery)
|
sl@0
|
839 |
{
|
sl@0
|
840 |
HBufCType* resolvedPath = NULL;
|
sl@0
|
841 |
if( !aRefUri.IsPresent(EUriScheme) && !aRefUri.IsPresent(EUriHost) && !aRefUri.Extract(EUriPath).Length() && !aRefUri.IsPresent(EUriQuery) )
|
sl@0
|
842 |
{
|
sl@0
|
843 |
// Ref is just a fragment
|
sl@0
|
844 |
aUseBaseQuery = ETrue;
|
sl@0
|
845 |
resolvedPath = aBaseUri.Extract(EUriPath).AllocLC();
|
sl@0
|
846 |
}
|
sl@0
|
847 |
else if( aRefUri.IsPresent(EUriHost) )
|
sl@0
|
848 |
{
|
sl@0
|
849 |
// Ref is a network path
|
sl@0
|
850 |
resolvedPath = aRefUri.Extract(EUriPath).AllocLC();
|
sl@0
|
851 |
}
|
sl@0
|
852 |
else
|
sl@0
|
853 |
{
|
sl@0
|
854 |
// Need to some path resolving...
|
sl@0
|
855 |
resolvedPath = ResolvePathsL(aBaseUri.Extract(EUriPath), aRefUri.Extract(EUriPath));
|
sl@0
|
856 |
CleanupStack::PushL(resolvedPath);
|
sl@0
|
857 |
}
|
sl@0
|
858 |
return resolvedPath;
|
sl@0
|
859 |
}
|
sl@0
|
860 |
|
sl@0
|
861 |
/**
|
sl@0
|
862 |
Cleans up a resolved path. This deals with occurences of '.' and '..' where these are complete
|
sl@0
|
863 |
path segments.
|
sl@0
|
864 |
|
sl@0
|
865 |
@since 6.0
|
sl@0
|
866 |
@param aResolvedPath The delimited data object that contains the
|
sl@0
|
867 |
resolved path.
|
sl@0
|
868 |
@pre The input/output argument contains the path to be cleaned.
|
sl@0
|
869 |
@post The resolved path has had all the occurences of '.' and '..'
|
sl@0
|
870 |
processed and has been updated to contain the cleaned path.
|
sl@0
|
871 |
*/
|
sl@0
|
872 |
template<class TPtrCType, class CDelimitedDataBaseType>
|
sl@0
|
873 |
void CleanResolvedPathL(CDelimitedDataBaseType* aResolvedPath)
|
sl@0
|
874 |
{
|
sl@0
|
875 |
// Create a modifiable path object for resolved path
|
sl@0
|
876 |
aResolvedPath->Parse();
|
sl@0
|
877 |
|
sl@0
|
878 |
TBool done = EFalse;
|
sl@0
|
879 |
while( !done )
|
sl@0
|
880 |
{
|
sl@0
|
881 |
// Get the next segment
|
sl@0
|
882 |
TPtrCType segment;
|
sl@0
|
883 |
TInt more = aResolvedPath->Parser().Peek(segment);
|
sl@0
|
884 |
|
sl@0
|
885 |
if( more == KErrNotFound )
|
sl@0
|
886 |
{
|
sl@0
|
887 |
// No more segments - done
|
sl@0
|
888 |
done = ETrue;
|
sl@0
|
889 |
}
|
sl@0
|
890 |
else if( IsParentDir(segment) )
|
sl@0
|
891 |
{
|
sl@0
|
892 |
// Found a '..' - remove '..' from path, and remove previous segment
|
sl@0
|
893 |
aResolvedPath->RemoveCurrentL();
|
sl@0
|
894 |
if( aResolvedPath->Parser().Dec() == KErrNotFound )
|
sl@0
|
895 |
{
|
sl@0
|
896 |
// No previous directory - put back '..' and stop
|
sl@0
|
897 |
InsertParentDirL(aResolvedPath);
|
sl@0
|
898 |
done = ETrue;
|
sl@0
|
899 |
}
|
sl@0
|
900 |
else
|
sl@0
|
901 |
{
|
sl@0
|
902 |
// Remove the parent directory
|
sl@0
|
903 |
aResolvedPath->RemoveCurrentL();
|
sl@0
|
904 |
if( aResolvedPath->Parser().Eos() )
|
sl@0
|
905 |
{
|
sl@0
|
906 |
// '..' is the last segment - add a '/' to the path (add empty segment)
|
sl@0
|
907 |
aResolvedPath->AddBackDelimiterL();
|
sl@0
|
908 |
done = ETrue;
|
sl@0
|
909 |
}
|
sl@0
|
910 |
}
|
sl@0
|
911 |
}
|
sl@0
|
912 |
else if( IsSameDir(segment) )
|
sl@0
|
913 |
{
|
sl@0
|
914 |
// Found a '.' - remove -.- from the path
|
sl@0
|
915 |
aResolvedPath->RemoveCurrentL();
|
sl@0
|
916 |
if( aResolvedPath->Parser().Eos() )
|
sl@0
|
917 |
{
|
sl@0
|
918 |
// '..' is the last segment - add a '/' to the path (add empty segment)
|
sl@0
|
919 |
aResolvedPath->AddBackDelimiterL();
|
sl@0
|
920 |
done = ETrue;
|
sl@0
|
921 |
}
|
sl@0
|
922 |
}
|
sl@0
|
923 |
else
|
sl@0
|
924 |
{
|
sl@0
|
925 |
// Segment wasn't '.' or '..' - parse to next segment
|
sl@0
|
926 |
aResolvedPath->Parser().Inc();
|
sl@0
|
927 |
}
|
sl@0
|
928 |
}
|
sl@0
|
929 |
}
|
sl@0
|
930 |
|
sl@0
|
931 |
/**
|
sl@0
|
932 |
Forms the resolved uri. Sets the components for the resolved uri from those in the base uri and
|
sl@0
|
933 |
the reference uri. The resolved path is given by the input argument aResolvedPath
|
sl@0
|
934 |
|
sl@0
|
935 |
@since 6.0
|
sl@0
|
936 |
@param aComponent The array of components to be set for the resolved uri.
|
sl@0
|
937 |
@param aBaseUri The base uri.
|
sl@0
|
938 |
@param aRefUri The reference uri.
|
sl@0
|
939 |
@param aResolvedPath The resolved path.
|
sl@0
|
940 |
@param aUseBaseQuery A boolean indicating whether the base query
|
sl@0
|
941 |
should be used.
|
sl@0
|
942 |
*/
|
sl@0
|
943 |
template<class TPtrCType, class TUriCType, class HBufCType>
|
sl@0
|
944 |
void FormResolvedUri(TPtrCType aComponent[], const TUriCType& aBaseUri, const TUriCType& aRefUri, const HBufCType* aResolvedPath, TBool aUseBaseQuery)
|
sl@0
|
945 |
{
|
sl@0
|
946 |
// Scheme...
|
sl@0
|
947 |
if( aBaseUri.IsPresent(EUriScheme) )
|
sl@0
|
948 |
{
|
sl@0
|
949 |
// Use the base scheme
|
sl@0
|
950 |
aComponent[EUriScheme].Set(aBaseUri.Extract(EUriScheme));
|
sl@0
|
951 |
}
|
sl@0
|
952 |
// Authority
|
sl@0
|
953 |
if( aRefUri.IsPresent(EUriHost) )
|
sl@0
|
954 |
{
|
sl@0
|
955 |
// Use the ref host, userinfo and port - must set host first
|
sl@0
|
956 |
aComponent[EUriHost].Set(aRefUri.Extract(EUriHost));
|
sl@0
|
957 |
aComponent[EUriUserinfo].Set(aRefUri.Extract(EUriUserinfo));
|
sl@0
|
958 |
aComponent[EUriPort].Set(aRefUri.Extract(EUriPort));
|
sl@0
|
959 |
}
|
sl@0
|
960 |
else if( aBaseUri.IsPresent(EUriHost) )
|
sl@0
|
961 |
{
|
sl@0
|
962 |
// Use the base host, userinfo and port - must set host first
|
sl@0
|
963 |
aComponent[EUriHost].Set(aBaseUri.Extract(EUriHost));
|
sl@0
|
964 |
aComponent[EUriUserinfo].Set(aBaseUri.Extract(EUriUserinfo));
|
sl@0
|
965 |
aComponent[EUriPort].Set(aBaseUri.Extract(EUriPort));
|
sl@0
|
966 |
}
|
sl@0
|
967 |
// Path...
|
sl@0
|
968 |
aComponent[EUriPath].Set(*aResolvedPath);
|
sl@0
|
969 |
|
sl@0
|
970 |
// Query...
|
sl@0
|
971 |
if( aUseBaseQuery && aBaseUri.IsPresent(EUriQuery) )
|
sl@0
|
972 |
{
|
sl@0
|
973 |
// Use the query from the base
|
sl@0
|
974 |
aComponent[EUriQuery].Set(aBaseUri.Extract(EUriQuery));
|
sl@0
|
975 |
}
|
sl@0
|
976 |
else if( aRefUri.IsPresent(EUriQuery) )
|
sl@0
|
977 |
{
|
sl@0
|
978 |
// Use the query from the ref
|
sl@0
|
979 |
aComponent[EUriQuery].Set(aRefUri.Extract(EUriQuery));
|
sl@0
|
980 |
}
|
sl@0
|
981 |
// Fragment
|
sl@0
|
982 |
if( aRefUri.IsPresent(EUriFragment) )
|
sl@0
|
983 |
{
|
sl@0
|
984 |
// Use the fragment from the ref
|
sl@0
|
985 |
aComponent[EUriFragment].Set(aRefUri.Extract(EUriFragment));
|
sl@0
|
986 |
}
|
sl@0
|
987 |
}
|
sl@0
|
988 |
|
sl@0
|
989 |
//
|
sl@0
|
990 |
//
|
sl@0
|
991 |
// Implemetation of LOCAL functions
|
sl@0
|
992 |
//
|
sl@0
|
993 |
//
|
sl@0
|
994 |
|
sl@0
|
995 |
/**
|
sl@0
|
996 |
Function used to resolve a base path (aBasePath) against a reference path (aRefPath),
|
sl@0
|
997 |
as described by RFC2396.
|
sl@0
|
998 |
|
sl@0
|
999 |
@since 6.0
|
sl@0
|
1000 |
@param aBasePath A descriptor reference to the base path.
|
sl@0
|
1001 |
@param aRefPath A descriptor reference to the reference path.
|
sl@0
|
1002 |
@return A pointer to a buffer containing the resolve path.
|
sl@0
|
1003 |
@leave KUriErrBadBasePath if the base path is not an absolute path and not empty.
|
sl@0
|
1004 |
*/
|
sl@0
|
1005 |
HBufC8* ResolvePathsL(const TDesC8& aBasePath, const TDesC8& aRefPath)
|
sl@0
|
1006 |
{
|
sl@0
|
1007 |
TInt refLength = aRefPath.Length();
|
sl@0
|
1008 |
if( refLength && aRefPath[0] == KSlashDelimiter )
|
sl@0
|
1009 |
{
|
sl@0
|
1010 |
// Relative path is absolute - that is the resolved path
|
sl@0
|
1011 |
return aRefPath.AllocL();
|
sl@0
|
1012 |
}
|
sl@0
|
1013 |
// Ok got work to do - base path must be absolute (check 1st char) or empty
|
sl@0
|
1014 |
if( aBasePath.Length() && aBasePath[0] != KSlashDelimiter )
|
sl@0
|
1015 |
{
|
sl@0
|
1016 |
// Base path not empty and not abosolute - bad base path
|
sl@0
|
1017 |
User::Leave(KUriUtilsErrBadBasePath);
|
sl@0
|
1018 |
}
|
sl@0
|
1019 |
// Create a modifiable path object for resolved path
|
sl@0
|
1020 |
CDelimitedPath8* resolvedPath = CDelimitedPath8::NewLC(aBasePath);
|
sl@0
|
1021 |
|
sl@0
|
1022 |
// Check for empty ref path - use all of base path if empty
|
sl@0
|
1023 |
if( refLength )
|
sl@0
|
1024 |
{
|
sl@0
|
1025 |
// Not empty - ensure that base path's last segment is removed and add reference
|
sl@0
|
1026 |
resolvedPath->PopBackL();
|
sl@0
|
1027 |
resolvedPath->PushBackL(aRefPath);
|
sl@0
|
1028 |
}
|
sl@0
|
1029 |
// Clean up the path to resolve occurences of '..' and '.' - parser path first
|
sl@0
|
1030 |
CleanResolvedPathL<TPtrC8>(resolvedPath);
|
sl@0
|
1031 |
|
sl@0
|
1032 |
// Return pointer to HBufC with path
|
sl@0
|
1033 |
HBufC8* path = resolvedPath->Parser().Des().AllocL();
|
sl@0
|
1034 |
CleanupStack::PopAndDestroy(resolvedPath);
|
sl@0
|
1035 |
return path;
|
sl@0
|
1036 |
}
|
sl@0
|
1037 |
|
sl@0
|
1038 |
/**
|
sl@0
|
1039 |
Function used to resolve a base path (aBasePath) against a reference path (aRefPath),
|
sl@0
|
1040 |
as described by RFC2396.
|
sl@0
|
1041 |
|
sl@0
|
1042 |
@since 6.0
|
sl@0
|
1043 |
@param aBasePath A descriptor reference to the base path.
|
sl@0
|
1044 |
@param aRefPath A descriptor reference to the reference path.
|
sl@0
|
1045 |
@return A pointer to a buffer containing the resolve path.
|
sl@0
|
1046 |
@leave KUriErrBadBasePath if the base path is not an absolute path and not empty.
|
sl@0
|
1047 |
*/
|
sl@0
|
1048 |
HBufC16* ResolvePathsL(const TDesC16& aBasePath, const TDesC16& aRefPath)
|
sl@0
|
1049 |
{
|
sl@0
|
1050 |
TInt refLength = aRefPath.Length();
|
sl@0
|
1051 |
if( refLength && aRefPath[0] == KSlashDelimiter )
|
sl@0
|
1052 |
{
|
sl@0
|
1053 |
// Relative path is absolute - that is the resolved path
|
sl@0
|
1054 |
return aRefPath.AllocL();
|
sl@0
|
1055 |
}
|
sl@0
|
1056 |
// Ok got work to do - base path must be absolute (check 1st char) or empty
|
sl@0
|
1057 |
if( aBasePath.Length() && aBasePath[0] != KSlashDelimiter )
|
sl@0
|
1058 |
{
|
sl@0
|
1059 |
// Base path not empty and not abosolute - bad base path
|
sl@0
|
1060 |
User::Leave(KUriUtilsErrBadBasePath);
|
sl@0
|
1061 |
}
|
sl@0
|
1062 |
// Create a modifiable path object for resolved path
|
sl@0
|
1063 |
CDelimitedPath16* resolvedPath = CDelimitedPath16::NewLC(aBasePath);
|
sl@0
|
1064 |
|
sl@0
|
1065 |
// Check for empty ref path - use all of base path if empty
|
sl@0
|
1066 |
if( refLength )
|
sl@0
|
1067 |
{
|
sl@0
|
1068 |
// Not empty - ensure that base path's last segment is removed and add reference
|
sl@0
|
1069 |
resolvedPath->PopBackL();
|
sl@0
|
1070 |
resolvedPath->PushBackL(aRefPath);
|
sl@0
|
1071 |
}
|
sl@0
|
1072 |
// Clean up the path to resolve occurences of '..' and '.' - parser path first
|
sl@0
|
1073 |
CleanResolvedPathL<TPtrC16>(resolvedPath);
|
sl@0
|
1074 |
|
sl@0
|
1075 |
// Return pointer to HBufC with path
|
sl@0
|
1076 |
HBufC16* path = resolvedPath->Parser().Des().AllocL();
|
sl@0
|
1077 |
CleanupStack::PopAndDestroy(resolvedPath);
|
sl@0
|
1078 |
return path;
|
sl@0
|
1079 |
}
|
sl@0
|
1080 |
|
sl@0
|
1081 |
/**
|
sl@0
|
1082 |
Checks if the segment is '.' (8-bit version).
|
sl@0
|
1083 |
|
sl@0
|
1084 |
@since 6.0
|
sl@0
|
1085 |
@param aSegment A descriptor with the segment to check.
|
sl@0
|
1086 |
@return A boolean value of ETrue if the segment is '.', EFalse if not.
|
sl@0
|
1087 |
*/
|
sl@0
|
1088 |
TBool IsSameDir(const TDesC8& aSegment)
|
sl@0
|
1089 |
{
|
sl@0
|
1090 |
_LIT8(KSameDir, ".");
|
sl@0
|
1091 |
return (aSegment.Compare(KSameDir) == 0);
|
sl@0
|
1092 |
}
|
sl@0
|
1093 |
|
sl@0
|
1094 |
/**
|
sl@0
|
1095 |
Checks if the segment is '.' (16-bit version).
|
sl@0
|
1096 |
|
sl@0
|
1097 |
@since 6.0
|
sl@0
|
1098 |
@param aSegment A descriptor with the segment to check.
|
sl@0
|
1099 |
@return A boolean value of ETrue if the segment is '.', EFalse if not.
|
sl@0
|
1100 |
*/
|
sl@0
|
1101 |
TBool IsSameDir(const TDesC16& aSegment)
|
sl@0
|
1102 |
{
|
sl@0
|
1103 |
_LIT16(KSameDir, ".");
|
sl@0
|
1104 |
return (aSegment.Compare(KSameDir) == 0);
|
sl@0
|
1105 |
}
|
sl@0
|
1106 |
|
sl@0
|
1107 |
/**
|
sl@0
|
1108 |
Checks if the segment is '..' (8-bit version).
|
sl@0
|
1109 |
|
sl@0
|
1110 |
@since 6.0
|
sl@0
|
1111 |
@param aSegment A descriptor with the segment to check.
|
sl@0
|
1112 |
@return A boolean value of ETrue if the segment is '..', EFalse if not.
|
sl@0
|
1113 |
*/
|
sl@0
|
1114 |
TBool IsParentDir(const TDesC8& aSegment)
|
sl@0
|
1115 |
{
|
sl@0
|
1116 |
_LIT8(KParentDir, "..");
|
sl@0
|
1117 |
return (aSegment.Compare(KParentDir) == 0);
|
sl@0
|
1118 |
}
|
sl@0
|
1119 |
|
sl@0
|
1120 |
/**
|
sl@0
|
1121 |
Checks if the segment is '..' (16-bit version).
|
sl@0
|
1122 |
|
sl@0
|
1123 |
@since 6.0
|
sl@0
|
1124 |
@param aSegment A descriptor with the segment to check.
|
sl@0
|
1125 |
@return A boolean value of ETrue if the segment is '..', EFalse if not.
|
sl@0
|
1126 |
*/
|
sl@0
|
1127 |
TBool IsParentDir(const TDesC16& aSegment)
|
sl@0
|
1128 |
{
|
sl@0
|
1129 |
_LIT16(KParentDir, "..");
|
sl@0
|
1130 |
return (aSegment.Compare(KParentDir) == 0);
|
sl@0
|
1131 |
}
|
sl@0
|
1132 |
|
sl@0
|
1133 |
/**
|
sl@0
|
1134 |
Inserts the segment '..' at the current parsed position (8-bit version).
|
sl@0
|
1135 |
|
sl@0
|
1136 |
@since 6.0
|
sl@0
|
1137 |
@param aResolvedPath The delimited data object to have the segment
|
sl@0
|
1138 |
inserted.
|
sl@0
|
1139 |
@pre The delimited data object must be parsed to the position where
|
sl@0
|
1140 |
the segment is to be inserted.
|
sl@0
|
1141 |
@post The segment '..' has been inserted at the current position.
|
sl@0
|
1142 |
*/
|
sl@0
|
1143 |
void InsertParentDirL(CDelimitedDataBase8* aResolvedPath)
|
sl@0
|
1144 |
{
|
sl@0
|
1145 |
_LIT8(KParentDir, "..");
|
sl@0
|
1146 |
aResolvedPath->InsertCurrentL(KParentDir);
|
sl@0
|
1147 |
}
|
sl@0
|
1148 |
|
sl@0
|
1149 |
/**
|
sl@0
|
1150 |
Inserts the segment '..' at the current parsed position (16-bit version).
|
sl@0
|
1151 |
|
sl@0
|
1152 |
@since 6.0
|
sl@0
|
1153 |
@param aResolvedPath The delimited data object to have the segment
|
sl@0
|
1154 |
inserted.
|
sl@0
|
1155 |
@pre The delimited data object must be parsed to the position where
|
sl@0
|
1156 |
the segment is to be inserted.
|
sl@0
|
1157 |
@post The segment '..' has been inserted at the current position.
|
sl@0
|
1158 |
*/
|
sl@0
|
1159 |
void InsertParentDirL(CDelimitedDataBase16* aResolvedPath)
|
sl@0
|
1160 |
{
|
sl@0
|
1161 |
_LIT16(KParentDir, "..");
|
sl@0
|
1162 |
aResolvedPath->InsertCurrentL(KParentDir);
|
sl@0
|
1163 |
}
|
sl@0
|
1164 |
|
sl@0
|
1165 |
|
sl@0
|
1166 |
//
|
sl@0
|
1167 |
//
|
sl@0
|
1168 |
// File URI Implementation - CUri8
|
sl@0
|
1169 |
//
|
sl@0
|
1170 |
//
|
sl@0
|
1171 |
|
sl@0
|
1172 |
/**
|
sl@0
|
1173 |
Initializes the file URI components (scheme, empty hostname and path).
|
sl@0
|
1174 |
|
sl@0
|
1175 |
It uses GenerateFileUriPathL() to generate a file Uri path using the filename and drive.
|
sl@0
|
1176 |
|
sl@0
|
1177 |
@since 9.1
|
sl@0
|
1178 |
@param aFileName A reference to a filename
|
sl@0
|
1179 |
@param aDrive A drive number. This is a TFileUriFlags value.
|
sl@0
|
1180 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1181 |
This is a TFileUriFlags value.
|
sl@0
|
1182 |
@pre Object fully constructed
|
sl@0
|
1183 |
@post The object is initialized with file URI components.
|
sl@0
|
1184 |
*/
|
sl@0
|
1185 |
void CUri8::InitializeFileUriComponentsL(const TDesC& aFileName, TDriveNumber aDrive, TUint aFlags)
|
sl@0
|
1186 |
{
|
sl@0
|
1187 |
HBufC* uriPath16 = GenerateFileUriPathL(aFileName, aDrive, aFlags);
|
sl@0
|
1188 |
CleanupStack::PushL(uriPath16);
|
sl@0
|
1189 |
HBufC8* uriPath = EscapeUtils::ConvertFromUnicodeToUtf8L(*uriPath16);
|
sl@0
|
1190 |
CleanupStack::PopAndDestroy(uriPath16);
|
sl@0
|
1191 |
CleanupStack::PushL(uriPath);
|
sl@0
|
1192 |
HBufC8* escpedUriPath = EscapeUtils::EscapeEncodeL(*uriPath, EscapeUtils::EEscapeNormal);
|
sl@0
|
1193 |
CleanupStack::PopAndDestroy(uriPath);
|
sl@0
|
1194 |
CleanupStack::PushL(escpedUriPath);
|
sl@0
|
1195 |
|
sl@0
|
1196 |
//SetComponent is not used in order to increase efficiency, by avoiding overhead of length calculation,
|
sl@0
|
1197 |
//tmp buffer allocation and updation of internal uri object, internal buffer & descriptor pointer
|
sl@0
|
1198 |
//for each SetComponent call
|
sl@0
|
1199 |
iUri.iComponent[EUriPath].Set(*escpedUriPath);
|
sl@0
|
1200 |
iUri.iComponent[EUriHost].Set(KNullDesC8);
|
sl@0
|
1201 |
iUri.iComponent[EUriScheme].Set(KFileUriScheme8);
|
sl@0
|
1202 |
FormUriL();
|
sl@0
|
1203 |
|
sl@0
|
1204 |
CleanupStack::PopAndDestroy(escpedUriPath);
|
sl@0
|
1205 |
}
|
sl@0
|
1206 |
|
sl@0
|
1207 |
/**
|
sl@0
|
1208 |
Allocates and constructs a file URI object for a specified file.
|
sl@0
|
1209 |
|
sl@0
|
1210 |
- If the file exists on a fixed drive, then the file URI takes the form: 'file://\<drive-letter\>/\<filepath including filename\>'.
|
sl@0
|
1211 |
- If the file exists on a removable media drive, then the file URI takes the form: 'file://ext-media/\<filepath including filename\>'.
|
sl@0
|
1212 |
|
sl@0
|
1213 |
@since 9.1
|
sl@0
|
1214 |
@param aFullFileName A reference to a fully qualified filename
|
sl@0
|
1215 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1216 |
This is a TFileUriFlags value.
|
sl@0
|
1217 |
@return A pointer to the newly created file URI (CUri8) object.
|
sl@0
|
1218 |
@post A fully constructed and initialized file URI (CUri8) object.
|
sl@0
|
1219 |
*/
|
sl@0
|
1220 |
EXPORT_C CUri8* CUri8::CreateFileUriL(const TDesC& aFullFileName, TUint aFlags)
|
sl@0
|
1221 |
{
|
sl@0
|
1222 |
//It should be called to construct a file URI for a public file stored on a fix drive
|
sl@0
|
1223 |
// or on a removable media drive only
|
sl@0
|
1224 |
__ASSERT_ALWAYS( ((aFlags == 0) || (aFlags & EExtMedia)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
|
sl@0
|
1225 |
|
sl@0
|
1226 |
CUri8* self = CUri8::NewLC();
|
sl@0
|
1227 |
self->InitializeFileUriComponentsL(aFullFileName, EDriveA, aFlags);
|
sl@0
|
1228 |
CleanupStack::Pop(self);
|
sl@0
|
1229 |
return self;
|
sl@0
|
1230 |
}
|
sl@0
|
1231 |
|
sl@0
|
1232 |
/**
|
sl@0
|
1233 |
Allocates and constructs a file URI object for a file that is private to the application.
|
sl@0
|
1234 |
|
sl@0
|
1235 |
- If the file exists on a fixed drive, then the file URI takes the form 'file://private/\<drive-letter\>/<filepath including filename\>'.
|
sl@0
|
1236 |
- If the file exists on a removable media drive, then the file URI takes the form 'file://private/ext-media/\<filepath including filename\>'.
|
sl@0
|
1237 |
|
sl@0
|
1238 |
@since 9.1
|
sl@0
|
1239 |
@param aRelativeFileName A reference to the filename relative to the application's private directory.
|
sl@0
|
1240 |
@param aDrive Drive number, if the private file stored on fixed drive, otherwise not used
|
sl@0
|
1241 |
This is a TDriveNumber value
|
sl@0
|
1242 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1243 |
This is a TFileUriFlags value.
|
sl@0
|
1244 |
@return A pointer to the newly created file URI (CUri8) object.
|
sl@0
|
1245 |
@post A fully constructed and initialized file URI (CUri8) object.
|
sl@0
|
1246 |
*/
|
sl@0
|
1247 |
|
sl@0
|
1248 |
|
sl@0
|
1249 |
EXPORT_C CUri8* CUri8::CreatePrivateFileUriL(const TDesC& aRelativeFileName, TDriveNumber aDrive, TInt aFlags)
|
sl@0
|
1250 |
{
|
sl@0
|
1251 |
//It should be called to construct a file URI for the application's private file stored on a fix drive
|
sl@0
|
1252 |
// or on a removable media drive only
|
sl@0
|
1253 |
__ASSERT_ALWAYS( (((aFlags == 0) || (aFlags & EExtMedia)) && (aDrive >= EDriveA && aDrive <= EDriveZ)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
|
sl@0
|
1254 |
|
sl@0
|
1255 |
CUri8* self = CUri8::NewLC();
|
sl@0
|
1256 |
self->InitializeFileUriComponentsL(aRelativeFileName, aDrive, aFlags|EPrivate);
|
sl@0
|
1257 |
CleanupStack::Pop(self);
|
sl@0
|
1258 |
return self;
|
sl@0
|
1259 |
}
|
sl@0
|
1260 |
|
sl@0
|
1261 |
|
sl@0
|
1262 |
//
|
sl@0
|
1263 |
//
|
sl@0
|
1264 |
// File URI Implementation - CUri16
|
sl@0
|
1265 |
//
|
sl@0
|
1266 |
//
|
sl@0
|
1267 |
|
sl@0
|
1268 |
/**
|
sl@0
|
1269 |
Initializes the file URI components (scheme, empty hostname and path).
|
sl@0
|
1270 |
|
sl@0
|
1271 |
It uses GenerateFileUriPathL() to generate a file Uri path using the filename and drive.
|
sl@0
|
1272 |
|
sl@0
|
1273 |
@since 9.1
|
sl@0
|
1274 |
@param aFileName A reference to a filename
|
sl@0
|
1275 |
@param aDrive A drive number. This is a TFileUriFlags value.
|
sl@0
|
1276 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1277 |
This is a TFileUriFlags value.
|
sl@0
|
1278 |
@pre Object fully constructed
|
sl@0
|
1279 |
@post The object is initialized with file URI components.
|
sl@0
|
1280 |
*/
|
sl@0
|
1281 |
void CUri16::InitializeFileUriComponentsL(const TDesC& aFileName, TDriveNumber aDrive, TUint aFlags)
|
sl@0
|
1282 |
{
|
sl@0
|
1283 |
HBufC* uriPath = GenerateFileUriPathL(aFileName, aDrive, aFlags);
|
sl@0
|
1284 |
CleanupStack::PushL(uriPath);
|
sl@0
|
1285 |
|
sl@0
|
1286 |
HBufC8* uriPath8 = EscapeUtils::ConvertFromUnicodeToUtf8L(*uriPath);
|
sl@0
|
1287 |
CleanupStack::PopAndDestroy(uriPath);
|
sl@0
|
1288 |
CleanupStack::PushL(uriPath8);
|
sl@0
|
1289 |
|
sl@0
|
1290 |
HBufC8* escapedUriPath8 = EscapeUtils::EscapeEncodeL(*uriPath8, EscapeUtils::EEscapeNormal);
|
sl@0
|
1291 |
CleanupStack::PopAndDestroy(uriPath8);
|
sl@0
|
1292 |
CleanupStack::PushL(escapedUriPath8);
|
sl@0
|
1293 |
|
sl@0
|
1294 |
HBufC* escapedUriPath = HBufC::NewLC(escapedUriPath8->Length());
|
sl@0
|
1295 |
escapedUriPath->Des().Copy(*escapedUriPath8);
|
sl@0
|
1296 |
|
sl@0
|
1297 |
//SetComponent is not used in order to increase efficiency, by avoiding overhead of length calculation,
|
sl@0
|
1298 |
//tmp buffer allocation and updation of internal uri object, internal buffer & descriptor pointer
|
sl@0
|
1299 |
//for each SetComponent call
|
sl@0
|
1300 |
iUri.iComponent[EUriPath].Set(*escapedUriPath);
|
sl@0
|
1301 |
iUri.iComponent[EUriHost].Set(KNullDesC16);
|
sl@0
|
1302 |
iUri.iComponent[EUriScheme].Set(KFileUriScheme16);
|
sl@0
|
1303 |
FormUriL();
|
sl@0
|
1304 |
|
sl@0
|
1305 |
CleanupStack::PopAndDestroy(escapedUriPath);
|
sl@0
|
1306 |
CleanupStack::PopAndDestroy(escapedUriPath8);
|
sl@0
|
1307 |
}
|
sl@0
|
1308 |
|
sl@0
|
1309 |
/**
|
sl@0
|
1310 |
Allocates and constructs a file URI object for a specified file.
|
sl@0
|
1311 |
|
sl@0
|
1312 |
- If the file exists on a fixed drive, then the file URI takes the form: 'file://\<drive-letter\>/\<filepath including filename\>'.
|
sl@0
|
1313 |
- If the file exists on a removable media drive, then the file URI takes the form: 'file://ext-media/\<filepath including filename\>'.
|
sl@0
|
1314 |
|
sl@0
|
1315 |
@since 9.1
|
sl@0
|
1316 |
@param aFullFileName A reference to a fully qualified filename
|
sl@0
|
1317 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1318 |
This is a TFileUriFlags value.
|
sl@0
|
1319 |
@return A pointer to the newly created file URI (CUri16) object.
|
sl@0
|
1320 |
@post A fully constructed and initialized file URI (CUri16) object.
|
sl@0
|
1321 |
*/
|
sl@0
|
1322 |
EXPORT_C CUri16* CUri16::CreateFileUriL(const TDesC& aFullFileName, TUint aFlags)
|
sl@0
|
1323 |
{
|
sl@0
|
1324 |
//It should be called to construct a file URI for a public file stored on a fix drive
|
sl@0
|
1325 |
// or on a removable media drive only
|
sl@0
|
1326 |
__ASSERT_ALWAYS( ((aFlags == 0) || (aFlags & EExtMedia)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
|
sl@0
|
1327 |
|
sl@0
|
1328 |
CUri16* self = CUri16::NewLC();
|
sl@0
|
1329 |
self->InitializeFileUriComponentsL(aFullFileName, EDriveA, aFlags);
|
sl@0
|
1330 |
CleanupStack::Pop(self);
|
sl@0
|
1331 |
return self;
|
sl@0
|
1332 |
}
|
sl@0
|
1333 |
|
sl@0
|
1334 |
/**
|
sl@0
|
1335 |
Allocates and constructs a file URI object for a file that is private to the application.
|
sl@0
|
1336 |
|
sl@0
|
1337 |
- If the file exists on a fixed drive, then the file URI takes the form 'file://private/\<drive-letter\>/<filepath including filename\>'.
|
sl@0
|
1338 |
- If the file exists on a removable media drive, then the file URI takes the form 'file://private/ext-media/\<filepath including filename\>'.
|
sl@0
|
1339 |
|
sl@0
|
1340 |
@since 9.1
|
sl@0
|
1341 |
@param aRelativeFileName A reference to the filename relative to the application's private directory.
|
sl@0
|
1342 |
@param aDrive Drive number, if the private file stored on fixed drive, otherwise not used
|
sl@0
|
1343 |
This is a TDriveNumber value
|
sl@0
|
1344 |
@param aFlags A flag to indicate if the file exists on a fixed drive or removable media drive.
|
sl@0
|
1345 |
This is a TFileUriFlags value.
|
sl@0
|
1346 |
@return A pointer to the newly created file URI (CUri16) object.
|
sl@0
|
1347 |
@post A fully constructed and initialized file URI (CUri16) object.
|
sl@0
|
1348 |
*/
|
sl@0
|
1349 |
|
sl@0
|
1350 |
|
sl@0
|
1351 |
EXPORT_C CUri16* CUri16::CreatePrivateFileUriL(const TDesC& aRelativeFileName, TDriveNumber aDrive, TInt aFlags)
|
sl@0
|
1352 |
{
|
sl@0
|
1353 |
//It should be called to construct a file URI for the application's private file stored on a fix drive
|
sl@0
|
1354 |
// or on a removable media drive only
|
sl@0
|
1355 |
__ASSERT_ALWAYS( (((aFlags == 0) || (aFlags & EExtMedia)) && (aDrive >= EDriveA && aDrive <= EDriveZ)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
|
sl@0
|
1356 |
|
sl@0
|
1357 |
CUri16* self = CUri16::NewLC();
|
sl@0
|
1358 |
self->InitializeFileUriComponentsL(aRelativeFileName, aDrive, aFlags|EPrivate);
|
sl@0
|
1359 |
CleanupStack::Pop(self);
|
sl@0
|
1360 |
return self;
|
sl@0
|
1361 |
}
|
sl@0
|
1362 |
|
sl@0
|
1363 |
|
sl@0
|
1364 |
//
|
sl@0
|
1365 |
//
|
sl@0
|
1366 |
// Implemetation of LOCAL functions for the File URI
|
sl@0
|
1367 |
//
|
sl@0
|
1368 |
//
|
sl@0
|
1369 |
|
sl@0
|
1370 |
/**
|
sl@0
|
1371 |
Function used to generate 16bit file uri using 1st parameter aFileName and
|
sl@0
|
1372 |
2nd parameter aDrive for the application's private or a public file.
|
sl@0
|
1373 |
|
sl@0
|
1374 |
This is called by API CreateFileUri() and CreatePrivateFileUri()to
|
sl@0
|
1375 |
generate a filename.
|
sl@0
|
1376 |
|
sl@0
|
1377 |
Note: The space allocated for the returned descriptor will likely be larger
|
sl@0
|
1378 |
than the length of the descriptor
|
sl@0
|
1379 |
|
sl@0
|
1380 |
@leave KErrBadName A provided Drivename or filename is not valid
|
sl@0
|
1381 |
@since 9.1
|
sl@0
|
1382 |
@param aFileName A descriptor reference to the filename.
|
sl@0
|
1383 |
@param aDrive A descriptor reference to drive letter.
|
sl@0
|
1384 |
@param aFlags A flag to indicate the private or a public file exists on removable media or a fixed drive.
|
sl@0
|
1385 |
@return A pointer to a buffer containing the resolved fully qualified filename.
|
sl@0
|
1386 |
*/
|
sl@0
|
1387 |
HBufC* GenerateFileUriPathL(const TDesC& aFileName, TDriveNumber aDrive, TUint aFlags)
|
sl@0
|
1388 |
{
|
sl@0
|
1389 |
TInt origLength = aFileName.Length();
|
sl@0
|
1390 |
|
sl@0
|
1391 |
//Leaves with KErrBadName if filename length is out of range
|
sl@0
|
1392 |
if (origLength == 0 || origLength > KMaxFileName)
|
sl@0
|
1393 |
{
|
sl@0
|
1394 |
User::Leave(KErrBadName);
|
sl@0
|
1395 |
}
|
sl@0
|
1396 |
|
sl@0
|
1397 |
TPtrC filename(aFileName);
|
sl@0
|
1398 |
|
sl@0
|
1399 |
//extract drive letter and remove drive "x:" from filename
|
sl@0
|
1400 |
TUint drive = filename[0];
|
sl@0
|
1401 |
|
sl@0
|
1402 |
// hasDrive means it begins with a drive, e.g. "c:"
|
sl@0
|
1403 |
const TBool hasDrive = ((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z')) && (filename[1] == KDriveSeparator);
|
sl@0
|
1404 |
// hasTopPath means it begins with a \ (possibly after the drive)
|
sl@0
|
1405 |
const TBool hasTopPath = (hasDrive && (filename[2] == KFilePathSeparator)) || (!hasDrive && (drive == TUint(KFilePathSeparator) ));
|
sl@0
|
1406 |
|
sl@0
|
1407 |
TInt skip = KDefaultPath().Length(); // skip leading "<drive>:\" by default
|
sl@0
|
1408 |
if(aFlags & TUint(EPrivate))
|
sl@0
|
1409 |
{
|
sl@0
|
1410 |
skip = (hasDrive ? (KDefaultPath().Length() - 1) : 0) + (hasTopPath ? 1 : 0) ;
|
sl@0
|
1411 |
}
|
sl@0
|
1412 |
else
|
sl@0
|
1413 |
{
|
sl@0
|
1414 |
// if not private then it should have valid drive i.e. "<drive>:\"
|
sl@0
|
1415 |
if (!(hasDrive && hasTopPath))
|
sl@0
|
1416 |
{
|
sl@0
|
1417 |
User::Leave(KErrBadName);
|
sl@0
|
1418 |
}
|
sl@0
|
1419 |
}
|
sl@0
|
1420 |
|
sl@0
|
1421 |
if(skip)
|
sl@0
|
1422 |
{
|
sl@0
|
1423 |
filename.Set(aFileName.Right(origLength - skip));
|
sl@0
|
1424 |
}
|
sl@0
|
1425 |
|
sl@0
|
1426 |
TInt uriLen = aFileName.Length() + KExtMedia().Length() + KPrivate().Length() + 1 /* for drive letter */;
|
sl@0
|
1427 |
|
sl@0
|
1428 |
HBufC* fileUri = HBufC::NewLC(uriLen);
|
sl@0
|
1429 |
TPtr fileUriPtr = fileUri->Des();
|
sl@0
|
1430 |
fileUriPtr.Append(KUriPathSeparator);
|
sl@0
|
1431 |
|
sl@0
|
1432 |
if (aFlags & TUint(EPrivate))
|
sl@0
|
1433 |
{
|
sl@0
|
1434 |
fileUriPtr.Append(KPrivate);
|
sl@0
|
1435 |
drive = TInt16('A' + aDrive);
|
sl@0
|
1436 |
}
|
sl@0
|
1437 |
|
sl@0
|
1438 |
if (aFlags & EExtMedia)
|
sl@0
|
1439 |
{
|
sl@0
|
1440 |
fileUriPtr.Append(KExtMedia);
|
sl@0
|
1441 |
}
|
sl@0
|
1442 |
else
|
sl@0
|
1443 |
{
|
sl@0
|
1444 |
fileUriPtr.Append(drive);
|
sl@0
|
1445 |
fileUriPtr.Append(KUriPathSeparator);
|
sl@0
|
1446 |
}
|
sl@0
|
1447 |
|
sl@0
|
1448 |
fileUriPtr.Append(filename);
|
sl@0
|
1449 |
|
sl@0
|
1450 |
//Convert "\" to "/"
|
sl@0
|
1451 |
ChangePathSeparator(fileUriPtr, KFilePathSeparator, KUriPathSeparator);
|
sl@0
|
1452 |
|
sl@0
|
1453 |
//Handling "./" and "../" in the file URI path or resolving the URI path
|
sl@0
|
1454 |
CDelimitedPath16* resolvedPath = CDelimitedPath16::NewLC(fileUriPtr);
|
sl@0
|
1455 |
// Clean up the path to resolve occurences of '..' and '.'
|
sl@0
|
1456 |
CleanResolvedPathL<TPtrC>(resolvedPath);
|
sl@0
|
1457 |
fileUriPtr.Copy(resolvedPath->Parser().Des()); // new path will always be shorter than old one
|
sl@0
|
1458 |
CleanupStack::PopAndDestroy(resolvedPath);
|
sl@0
|
1459 |
|
sl@0
|
1460 |
CleanupStack::Pop(fileUri);
|
sl@0
|
1461 |
return fileUri;
|
sl@0
|
1462 |
}
|