|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 #include <SenXmlUtils.h> |
|
26 #include <SenXmlConstants.h> // KErrSenZeroLengthDescriptor, KSenColon, ++ |
|
27 |
|
28 #include "senpropertieselement.h" |
|
29 |
|
30 namespace |
|
31 { |
|
32 _LIT8(KSenPropertyType, "Type"); |
|
33 _LIT8(KSenPropertyTrue, "true"); |
|
34 _LIT8(KSenPropertyFalse, "false"); |
|
35 } |
|
36 |
|
37 EXPORT_C CSenPropertiesElement* CSenPropertiesElement::NewL(const TDesC8& aLocalName, |
|
38 RStringPool* aStringPool) |
|
39 { |
|
40 CSenPropertiesElement* pNew = new (ELeave) CSenPropertiesElement; |
|
41 CleanupStack::PushL(pNew); |
|
42 pNew->BaseConstructL(aLocalName, aStringPool); |
|
43 CleanupStack::Pop(); // pNew; |
|
44 return pNew; |
|
45 } |
|
46 |
|
47 EXPORT_C CSenPropertiesElement* CSenPropertiesElement::NewL(const TDesC8& aNsUri, |
|
48 const TDesC8& aLocalName, |
|
49 RStringPool* aStringPool) |
|
50 { |
|
51 CSenPropertiesElement* pNew = new (ELeave) CSenPropertiesElement; |
|
52 CleanupStack::PushL(pNew); |
|
53 pNew->BaseConstructL(aNsUri, aLocalName, aStringPool); |
|
54 CleanupStack::Pop(); // pNew; |
|
55 return pNew; |
|
56 } |
|
57 |
|
58 EXPORT_C CSenPropertiesElement* CSenPropertiesElement::NewL(const TDesC8& aNsUri, |
|
59 const TDesC8& aLocalName, |
|
60 const TDesC8& aQName, |
|
61 RStringPool* aStringPool) |
|
62 { |
|
63 CSenPropertiesElement* pNew = new (ELeave) CSenPropertiesElement; |
|
64 CleanupStack::PushL(pNew); |
|
65 pNew->BaseConstructL(aNsUri, aLocalName, aQName, aStringPool); |
|
66 CleanupStack::Pop(); // pNew; |
|
67 return pNew; |
|
68 } |
|
69 |
|
70 EXPORT_C CSenPropertiesElement* CSenPropertiesElement::NewL(const TDesC8& aNsUri, |
|
71 const TDesC8& aLocalName, |
|
72 const TDesC8& aQName, |
|
73 const RAttributeArray& apAttrs, |
|
74 RStringPool* aStringPool) |
|
75 { |
|
76 CSenPropertiesElement* pNew = new (ELeave) CSenPropertiesElement; |
|
77 CleanupStack::PushL(pNew); |
|
78 pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aStringPool); |
|
79 CleanupStack::Pop(); // pNew; |
|
80 return pNew; |
|
81 } |
|
82 |
|
83 |
|
84 EXPORT_C CSenPropertiesElement* CSenPropertiesElement::NewL(const TDesC8& aNsUri, |
|
85 const TDesC8& aLocalName, |
|
86 const TDesC8& aQName, |
|
87 const RAttributeArray& apAttrs, |
|
88 CSenElement& aParent, |
|
89 RStringPool* aStringPool) |
|
90 { |
|
91 CSenPropertiesElement* pNew = new (ELeave) CSenPropertiesElement; |
|
92 CleanupStack::PushL(pNew); |
|
93 pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aParent, aStringPool); |
|
94 CleanupStack::Pop(); // pNew; |
|
95 return pNew; |
|
96 } |
|
97 |
|
98 CSenPropertiesElement::CSenPropertiesElement() |
|
99 { |
|
100 } |
|
101 |
|
102 CSenPropertiesElement::~CSenPropertiesElement() |
|
103 { |
|
104 iLocalName.Close(); |
|
105 iContent.Close(); |
|
106 } |
|
107 |
|
108 void CSenPropertiesElement::BaseConstructL(const TDesC8& aLocalName, |
|
109 RStringPool* aStringPool) |
|
110 { |
|
111 ipStringPool = aStringPool; |
|
112 if (aLocalName == KNullDesC8) |
|
113 { |
|
114 User::Leave(KErrSenZeroLengthDescriptor); |
|
115 } |
|
116 SenXmlUtils::LeaveOnXmlEscapesL(aLocalName); |
|
117 |
|
118 if ( ipStringPool ) |
|
119 { |
|
120 iLocalName = ipStringPool->OpenStringL(aLocalName); |
|
121 } |
|
122 else |
|
123 { |
|
124 Set(KNullDesC8, aLocalName, aLocalName); |
|
125 } |
|
126 } |
|
127 |
|
128 void CSenPropertiesElement::BaseConstructL(const TDesC8& aNsUri, |
|
129 const TDesC8& aLocalName, |
|
130 RStringPool* aStringPool) |
|
131 { |
|
132 ipStringPool = aStringPool; |
|
133 if (aLocalName == KNullDesC8) |
|
134 { |
|
135 User::Leave(KErrSenZeroLengthDescriptor); |
|
136 } |
|
137 SenXmlUtils::LeaveOnXmlEscapesL(aLocalName); |
|
138 |
|
139 if(aNsUri.Length()>0) |
|
140 { |
|
141 SetNamespaceL(aNsUri); |
|
142 } |
|
143 if ( ipStringPool ) |
|
144 { |
|
145 iLocalName = ipStringPool->OpenStringL(aLocalName); |
|
146 } |
|
147 else |
|
148 { |
|
149 Set(KNullDesC8, aLocalName, aLocalName); |
|
150 } |
|
151 } |
|
152 |
|
153 void CSenPropertiesElement::BaseConstructL(const TDesC8& aNsUri, |
|
154 const TDesC8& aLocalName, |
|
155 const TDesC8& aQName, |
|
156 RStringPool* aStringPool) |
|
157 { |
|
158 ipStringPool = aStringPool; |
|
159 |
|
160 if (aLocalName == KNullDesC8) |
|
161 { |
|
162 User::Leave(KErrSenZeroLengthDescriptor); |
|
163 } |
|
164 SenXmlUtils::LeaveOnXmlEscapesL(aLocalName); |
|
165 |
|
166 if (aQName == KNullDesC8) |
|
167 { |
|
168 User::Leave(KErrSenZeroLengthDescriptor); |
|
169 } |
|
170 SenXmlUtils::LeaveOnXmlEscapesL(aQName); |
|
171 |
|
172 if ( ipStringPool ) |
|
173 { |
|
174 iLocalName = ipStringPool->OpenStringL(aLocalName); |
|
175 } |
|
176 else |
|
177 { |
|
178 Set(KNullDesC8, aLocalName, aLocalName); |
|
179 } |
|
180 TPtrC8 ptrPrefix(KNullDesC8); |
|
181 |
|
182 if (aQName.Length() > 0 ) |
|
183 { |
|
184 TInt colon = aQName.Locate(':'); |
|
185 if (colon > 0) // Note: 0 also treated as no prefix |
|
186 { |
|
187 ptrPrefix.Set(aQName.Ptr(),colon); |
|
188 } |
|
189 } |
|
190 |
|
191 SetNamespaceL(ptrPrefix, aNsUri); |
|
192 } |
|
193 |
|
194 void CSenPropertiesElement::BaseConstructL(const TDesC8& aNsUri, |
|
195 const TDesC8& aLocalName, |
|
196 const TDesC8& aQName, |
|
197 const RAttributeArray& apAttrs, |
|
198 RStringPool* aStringPool) |
|
199 { |
|
200 BaseConstructL(aNsUri, aLocalName, aQName, aStringPool); |
|
201 SetAttributesL(apAttrs); |
|
202 } |
|
203 |
|
204 void CSenPropertiesElement::BaseConstructL(const TDesC8& aNsUri, |
|
205 const TDesC8& aLocalName, |
|
206 const TDesC8& aQName, |
|
207 const RAttributeArray& apAttrs, |
|
208 CSenElement& aParent, |
|
209 RStringPool* aStringPool) |
|
210 { |
|
211 // parent must be set here at first line, because |
|
212 // namespace setting dependends of it(!) |
|
213 SetParent(&aParent); |
|
214 |
|
215 BaseConstructL(aNsUri, aLocalName, aQName, aStringPool); |
|
216 SetAttributesL(apAttrs); |
|
217 } |
|
218 |
|
219 void CSenPropertiesElement::WriteContentToL(RWriteStream& aWriteStream) |
|
220 { |
|
221 HBufC8* pEncoded = SenXmlUtils::EncodeHttpCharactersLC(Content()); |
|
222 aWriteStream.WriteL(*pEncoded); |
|
223 CleanupStack::PopAndDestroy(pEncoded); |
|
224 } |
|
225 |
|
226 CSenElement* CSenPropertiesElement::CreateElementL(const TDesC8& aNsPrefix, |
|
227 const TDesC8& aLocalName) |
|
228 { |
|
229 CSenElement* pNewElement = NULL; |
|
230 |
|
231 if (aNsPrefix.Length() > 0) |
|
232 { |
|
233 CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aNsPrefix); |
|
234 if (pNamespace) |
|
235 { |
|
236 HBufC8 *pQName = |
|
237 HBufC8::NewLC(aNsPrefix.Length() + aLocalName.Length() +5); |
|
238 TPtr8 ptr = pQName->Des(); |
|
239 ptr.Append(aNsPrefix); |
|
240 ptr.Append(':'); |
|
241 ptr.Append(aLocalName); |
|
242 pNewElement = CSenPropertiesElement::NewL(pNamespace->URI(), |
|
243 aLocalName, |
|
244 *pQName, |
|
245 ipStringPool); |
|
246 |
|
247 CleanupStack::PopAndDestroy(); // pQName |
|
248 } |
|
249 } |
|
250 else |
|
251 { |
|
252 pNewElement = CSenPropertiesElement::NewL(aLocalName, ipStringPool); |
|
253 } |
|
254 |
|
255 return pNewElement; // Returns NULL if required namespace can not be found! |
|
256 } |
|
257 |
|
258 CSenElement& CSenPropertiesElement::AddElementL(const TDesC8& aNsUri, |
|
259 const TDesC8& aLocalName) |
|
260 { |
|
261 return CSenXmlElement::AddElementL(*CSenPropertiesElement::NewL(aNsUri, |
|
262 aLocalName, |
|
263 ipStringPool)); |
|
264 } |
|
265 |
|
266 CSenElement& CSenPropertiesElement::AddElementL(const TDesC8& aNsUri, |
|
267 const TDesC8& aLocalName, |
|
268 const TDesC8& aQName) |
|
269 { |
|
270 return CSenXmlElement::AddElementL(*CSenPropertiesElement::NewL(aNsUri, |
|
271 aLocalName, |
|
272 aQName, |
|
273 ipStringPool)); |
|
274 } |
|
275 |
|
276 CSenElement& CSenPropertiesElement::AddElementL(const TDesC8& aLocalName) |
|
277 { |
|
278 return CSenXmlElement::AddElementL(*CSenPropertiesElement::NewL(aLocalName, |
|
279 ipStringPool)); |
|
280 } |
|
281 |
|
282 void CSenPropertiesElement::CopyFromL(CSenElement& aSource) |
|
283 { |
|
284 TPtrC8 sourceContent = aSource.Content(); |
|
285 if (sourceContent.Length() > 0) |
|
286 { |
|
287 SetContentL(sourceContent); |
|
288 } |
|
289 |
|
290 RPointerArray<CSenElement> sourceElements = aSource.ElementsL(); |
|
291 if (sourceElements.Count() > 0) |
|
292 { |
|
293 for (TInt i=0;i<sourceElements.Count(); i++) |
|
294 { |
|
295 CSenElement* pElement = sourceElements[i]; |
|
296 CSenElement* pNewElement = |
|
297 CSenPropertiesElement::NewL(pElement->LocalName(), |
|
298 ipStringPool); |
|
299 pNewElement->CopyFromL(*pElement); |
|
300 |
|
301 CSenXmlElement::AddElementL(*pNewElement); |
|
302 } |
|
303 } |
|
304 RPointerArray<CSenBaseAttribute> sourceAttributes = aSource.AttributesL(); |
|
305 if (sourceAttributes.Count() > 0) |
|
306 { |
|
307 for (TInt i=0;i<sourceAttributes.Count(); i++) |
|
308 { |
|
309 CSenBaseAttribute* pBaseAttribute = sourceAttributes[i]; |
|
310 |
|
311 // 2005-04-28: check for duplicate and override existing value if |
|
312 // attribute already exists. |
|
313 CSenBaseAttribute* pOriginal = FindAttr(pBaseAttribute->Name()); |
|
314 if (pOriginal) |
|
315 { |
|
316 pOriginal->SetValueL(pBaseAttribute->Value()); |
|
317 continue; |
|
318 } |
|
319 |
|
320 CSenBaseAttribute* pNewBaseAttribute = |
|
321 CSenBaseAttribute::NewL(pBaseAttribute->Name(), |
|
322 pBaseAttribute->Value()); |
|
323 |
|
324 CSenXmlElement::AddAttributeL(pNewBaseAttribute); |
|
325 } |
|
326 } |
|
327 |
|
328 RPointerArray<CSenNamespace> sourceNamespaces = aSource.NamespacesL(); |
|
329 if (sourceNamespaces.Count() > 0) |
|
330 { |
|
331 for (TInt i=0;i<sourceNamespaces.Count(); i++) |
|
332 { |
|
333 CSenNamespace* pNamespace = sourceNamespaces[i]; |
|
334 CSenNamespace* pNewNamespace = |
|
335 CSenNamespace::NewL(pNamespace->Prefix(),pNamespace->URI()); |
|
336 |
|
337 CSenXmlElement::AddNamespaceL(*pNewNamespace, EFalse); |
|
338 } |
|
339 } |
|
340 |
|
341 SetNamespaceL(aSource.NamespaceURI()); |
|
342 } |
|
343 |
|
344 TPtrC8 CSenPropertiesElement::Name() |
|
345 { |
|
346 return this->LocalName(); |
|
347 } |
|
348 |
|
349 TPtrC8 CSenPropertiesElement::Type() |
|
350 { |
|
351 TPtrC8 retVal(*this->AttrValue(KSenPropertyType)); |
|
352 return retVal; |
|
353 } |
|
354 |
|
355 TPtrC8 CSenPropertiesElement::Value() |
|
356 { |
|
357 return this->Content(); |
|
358 } |
|
359 |
|
360 TInt CSenPropertiesElement::IntValue(TInt& aValue) |
|
361 { |
|
362 TInt retVal(KErrNone); |
|
363 |
|
364 TPtrC8 value = this->Content(); |
|
365 TLex8 lex(value); |
|
366 retVal = lex.Val(aValue); |
|
367 |
|
368 return retVal; |
|
369 } |
|
370 |
|
371 TInt CSenPropertiesElement::BoolValue(TBool& aValue) |
|
372 { |
|
373 TInt retVal(KErrNone); |
|
374 |
|
375 TPtrC8 value = this->Content(); |
|
376 if (value == KSenPropertyTrue) |
|
377 { |
|
378 aValue = ETrue; |
|
379 } |
|
380 else if (value == KSenPropertyFalse) |
|
381 { |
|
382 aValue = EFalse; |
|
383 } |
|
384 else |
|
385 { |
|
386 retVal = KErrGeneral; |
|
387 } |
|
388 |
|
389 return retVal; |
|
390 } |
|
391 |
|
392 TInt CSenPropertiesElement::ValueTokensL(const TDesC8& aDelimiter, |
|
393 RPointerArray<TPtrC8>& aTokens) |
|
394 { |
|
395 TPtrC8 content = this->Content(); |
|
396 TInt delim = content.Find(aDelimiter); |
|
397 while ( delim != KErrNotFound ) |
|
398 { |
|
399 TPtrC8* piece = new (ELeave) TPtrC8(); |
|
400 piece->Set(content.Mid(0,delim)); |
|
401 aTokens.Append(piece); |
|
402 |
|
403 content.Set(content.Mid(delim+aDelimiter.Length(), |
|
404 content.Length()-(delim+aDelimiter.Length()))); |
|
405 |
|
406 delim = content.Find(aDelimiter); |
|
407 } |
|
408 |
|
409 if(!(this->Content()!=KNullDesC8 && content==KNullDesC8)) |
|
410 { |
|
411 // If this property does NOT zero-length content |
|
412 // and the "last" (or first) token is KNullDesC8 |
|
413 // it means that the string ends with delimiter; |
|
414 // Therefore, KNullDesC8 must NOT be added as a |
|
415 // result of "tailing delimiter". |
|
416 |
|
417 // Add all other tokens here; even KNullDesC8 |
|
418 // gets added, if it is eiher first or |
|
419 TPtrC8* token = new (ELeave) TPtrC8(); |
|
420 token->Set(content); |
|
421 aTokens.Append(token); |
|
422 } |
|
423 if (aTokens.Count() == 0) |
|
424 { |
|
425 return KErrNotFound; |
|
426 } |
|
427 return KErrNone; |
|
428 } |
|
429 |
|
430 const TDesC8& CSenPropertiesElement::LocalName() const |
|
431 { |
|
432 if ( !ipStringPool ) |
|
433 { |
|
434 return CSenXmlElement::LocalName(); |
|
435 } |
|
436 else |
|
437 { |
|
438 return iLocalName.DesC(); |
|
439 } |
|
440 } |
|
441 |
|
442 void CSenPropertiesElement::Set( const TDesC8& aNamespaceURI, |
|
443 const TDesC8& aLocalName, |
|
444 const TDesC8& aQName ) |
|
445 { |
|
446 if ( !ipStringPool ) |
|
447 { |
|
448 CSenXmlElement::Set(aNamespaceURI, aLocalName, aQName); |
|
449 } |
|
450 else |
|
451 { |
|
452 RString localName; |
|
453 TInt leaveCode(KErrNone); |
|
454 TRAP( leaveCode, localName = ipStringPool->OpenStringL(aLocalName); ) |
|
455 if( !leaveCode ) |
|
456 { |
|
457 iLocalName.Close(); |
|
458 iLocalName = localName; |
|
459 |
|
460 TPtrC8 prefix(KNullDesC8); |
|
461 |
|
462 if(aQName != KNullDesC8) |
|
463 { |
|
464 TInt colon(KErrNotFound); |
|
465 colon = aQName.Locate(':'); |
|
466 if(colon!=KErrNotFound) |
|
467 { |
|
468 prefix.Set(aQName.Left(colon)); |
|
469 } |
|
470 } |
|
471 TRAP( leaveCode, SetNamespaceL(prefix, aNamespaceURI); ) |
|
472 leaveCode=0; // ignored |
|
473 } // else { // ipStringPool->OpenStringL leaved(!) } |
|
474 } |
|
475 } |
|
476 |
|
477 TBool CSenPropertiesElement::HasContent() const |
|
478 { |
|
479 if ( !ipStringPool ) |
|
480 { |
|
481 return CSenXmlElement::HasContent(); |
|
482 } |
|
483 else |
|
484 { |
|
485 return (iContent.DesC().Length() > 0); |
|
486 } |
|
487 } |
|
488 |
|
489 TPtrC8 CSenPropertiesElement::Content() const |
|
490 { |
|
491 if ( !ipStringPool ) |
|
492 { |
|
493 return CSenXmlElement::Content(); |
|
494 } |
|
495 else |
|
496 { |
|
497 return TPtrC8(iContent.DesC()); |
|
498 } |
|
499 } |
|
500 |
|
501 TPtrC8 CSenPropertiesElement::SetContentL(const TDesC8& aContent) |
|
502 { |
|
503 if ( !ipStringPool ) |
|
504 { |
|
505 return CSenXmlElement::SetContentL(aContent); |
|
506 } |
|
507 else |
|
508 { |
|
509 iContent.Close(); |
|
510 iContent = ipStringPool->OpenStringL(aContent); |
|
511 return TPtrC8(iContent.DesC()); |
|
512 } |
|
513 } |
|
514 |
|
515 void CSenPropertiesElement::AllocContentBufL() |
|
516 { |
|
517 if ( !ipStringPool ) |
|
518 { |
|
519 CSenXmlElement::AllocContentBufL(); |
|
520 } |
|
521 } |
|
522 |
|
523 RWriteStream& CSenPropertiesElement::ContentWriteStreamL() |
|
524 { |
|
525 if ( !ipStringPool ) |
|
526 { |
|
527 return CSenXmlElement::ContentWriteStreamL(); |
|
528 } |
|
529 else |
|
530 { |
|
531 return CSenXmlElement::ContentWriteStreamL(); |
|
532 } |
|
533 } |
|
534 |
|
535 void CSenPropertiesElement::WriteAsXMLToL(RWriteStream& aWriteStream) |
|
536 { |
|
537 if ( !ipStringPool ) |
|
538 { |
|
539 CSenXmlElement::WriteAsXMLToL(aWriteStream); |
|
540 } |
|
541 else |
|
542 { |
|
543 // Find out whether we should declare the namespace |
|
544 TPtrC8 nsPrefix = NsPrefix(); |
|
545 |
|
546 // Element name |
|
547 aWriteStream.WriteL(KSenLessThan); |
|
548 if (nsPrefix.Length() > 0) |
|
549 { |
|
550 aWriteStream.WriteL(nsPrefix); |
|
551 aWriteStream.WriteL(KSenColon); |
|
552 } |
|
553 aWriteStream.WriteL(iLocalName.DesC()); |
|
554 |
|
555 |
|
556 WriteNamespacesToL(aWriteStream); |
|
557 WriteAttrsToL(aWriteStream); |
|
558 |
|
559 // Elements and content |
|
560 RPointerArray<CSenElement> elements = ElementsL(); |
|
561 if ((elements.Count() > 0) || HasContent()) |
|
562 { |
|
563 aWriteStream.WriteL(KSenGreaterThan); |
|
564 |
|
565 // Body |
|
566 WriteElementsToL(aWriteStream); |
|
567 WriteContentToL(aWriteStream); |
|
568 |
|
569 // Closing element |
|
570 aWriteStream.WriteL(KSenLessThanSlash); |
|
571 if (nsPrefix.Length() > 0) |
|
572 { |
|
573 aWriteStream.WriteL(nsPrefix); |
|
574 aWriteStream.WriteL(KSenColon); |
|
575 } |
|
576 aWriteStream.WriteL(iLocalName.DesC()); |
|
577 aWriteStream.WriteL(KSenGreaterThan); |
|
578 } |
|
579 else |
|
580 { |
|
581 aWriteStream.WriteL(KSenSlashGreaterThan); |
|
582 } |
|
583 } |
|
584 } |
|
585 |
|
586 |
|
587 RStringPool& CSenPropertiesElement::StringPool() |
|
588 { |
|
589 // __ASSERT_ALWAYS(ipStringPool, User::Panic(KPanic, EStringPoolNotInitialized)); |
|
590 return *ipStringPool; |
|
591 } |
|
592 |
|
593 void CSenPropertiesElement::SetStringPool(RStringPool& aStringPool) |
|
594 { |
|
595 ipStringPool = &aStringPool; |
|
596 } |
|
597 |
|
598 |
|
599 // END OF FILE |
|
600 |
|
601 |
|
602 |