|
1 /** @file |
|
2 * Copyright (c) 2007 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: CUpnpContentHandlersController |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "upnpcontenthandlerscontroller.h" |
|
20 |
|
21 #include <xml/parser.h> |
|
22 #include <xml/xmlparsererrors.h> |
|
23 #include <xml/matchdata.h> |
|
24 |
|
25 #include "upnpstring.h" |
|
26 #include "upnpservice.h" |
|
27 #include "upnpdevice.h" |
|
28 #include "upnpdeviceimplementation.h" |
|
29 #include "upnpsilentdeviceimplementation.h" |
|
30 |
|
31 #include "upnpserviceliterals.h" |
|
32 #include "upnpdeviceliterals.h" |
|
33 |
|
34 #include "upnpcontenthandler.h" |
|
35 #include "upnpignorecontenthandler.h" |
|
36 #include "upnpsoapcontenthandler.h" |
|
37 #include "upnppropertysetcontenthandler.h" |
|
38 #include "upnpservicecontenthandler.h" |
|
39 #include "upnpdevicecontenthandler.h" |
|
40 |
|
41 using namespace Xml; |
|
42 |
|
43 // CONSTANTS |
|
44 const TUint KUtfLowMax = 0x1F; |
|
45 const TUint KUtfHighMin = 0x7F; |
|
46 const TUint KUtfHighMax = 0xA0; |
|
47 |
|
48 // ----------------------------------------------------------------------------- |
|
49 // CUpnpContentHandlersController::~CUpnpContentHandlersController |
|
50 // Destructor |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 CUpnpContentHandlersController::~CUpnpContentHandlersController() |
|
54 { |
|
55 delete iParser; |
|
56 ASSERT( NULL == iStack || iStack->IsEmpty() ); |
|
57 delete iStack; |
|
58 |
|
59 iContent.Close(); |
|
60 } |
|
61 |
|
62 // ----------------------------------------------------------------------------- |
|
63 // CUpnpContentHandlersController::NewL |
|
64 // Two-phased constructor |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 EXPORT_C CUpnpContentHandlersController* CUpnpContentHandlersController::NewL() |
|
68 { |
|
69 CUpnpContentHandlersController* controller = |
|
70 CUpnpContentHandlersController::NewLC(); |
|
71 CleanupStack::Pop( controller ); |
|
72 return controller; |
|
73 } |
|
74 |
|
75 // ----------------------------------------------------------------------------- |
|
76 // CUpnpContentHandlersController::NewLC |
|
77 // Two-phased constructor. Leaves the object on the CleanupStack |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 EXPORT_C CUpnpContentHandlersController* CUpnpContentHandlersController::NewLC() |
|
81 { |
|
82 CUpnpContentHandlersController* controller = |
|
83 new (ELeave) CUpnpContentHandlersController(); |
|
84 CleanupStack::PushL( controller ); |
|
85 controller->ConstructL(); |
|
86 return controller; |
|
87 } |
|
88 |
|
89 // ----------------------------------------------------------------------------- |
|
90 // CleanupResetAndDestroy |
|
91 // Releases array, and object keapt in it. |
|
92 // Used as method passed to TCleanupItem object. |
|
93 // ----------------------------------------------------------------------------- |
|
94 // |
|
95 LOCAL_C void CleanupResetAndDestroy(TAny* aRPointerArray) |
|
96 { |
|
97 reinterpret_cast<RPointerArray<CUpnpDescriptionProperty>* >(aRPointerArray) |
|
98 ->ResetAndDestroy(); |
|
99 } |
|
100 |
|
101 // ----------------------------------------------------------------------------- |
|
102 // CUpnpContentHandlersController::UpdateActionWithOKResponseL |
|
103 // For internal use. Update all necessary information from a SOAP-message |
|
104 // that should be OK answer (e.g. received by Http 200 OK message). |
|
105 // ----------------------------------------------------------------------------- |
|
106 // |
|
107 EXPORT_C void CUpnpContentHandlersController::UpdateActionWithOKResponseL( |
|
108 CUpnpSoapMessage* aMessage, CUpnpAction* aAction ) |
|
109 { |
|
110 iSoapParser.UpdateActionWithOKResponseL( aMessage, aAction ); |
|
111 } |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // CUpnpContentHandlersController::UpdateActionWithErrorResponseL |
|
115 // For internal use. Update all necessary information from a SOAP-message |
|
116 // that should contain SOAP error (fault) message (eg. received by http |
|
117 // 500 InternalServerError message. |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 EXPORT_C void CUpnpContentHandlersController::UpdateActionWithErrorResponseL( |
|
121 CUpnpSoapMessage* aMessage, CUpnpAction* aAction ) |
|
122 { |
|
123 iSoapParser.UpdateActionWithErrorResponseL( aMessage, aAction ); |
|
124 } |
|
125 |
|
126 // ----------------------------------------------------------------------------- |
|
127 // CUpnpContentHandlersController::UpdateActionWithRequestL |
|
128 // Update action with all necessary information from |
|
129 // a SOAP request message. |
|
130 // ----------------------------------------------------------------------------- |
|
131 // |
|
132 void CUpnpContentHandlersController::UpdateActionWithRequestL( |
|
133 CUpnpSoapMessage* aMessage, CUpnpAction* aAction ) |
|
134 { |
|
135 iSoapParser.UpdateActionWithRequestL( aMessage, aAction ); |
|
136 } |
|
137 |
|
138 // ----------------------------------------------------------------------------- |
|
139 // CUpnpContentHandlersController::AttachL |
|
140 // For internal use. Attaches the information contained in a GENA buffer |
|
141 // to this service. In practice, this means handling of received GENA messages. |
|
142 // ----------------------------------------------------------------------------- |
|
143 // |
|
144 EXPORT_C void CUpnpContentHandlersController::AttachL( const TDesC8& aGenaNotify, |
|
145 CUpnpService& aService ) |
|
146 { |
|
147 RPointerArray<CUpnpDescriptionProperty> parsedValues; |
|
148 CleanupStack::PushL( TCleanupItem( CleanupResetAndDestroy, &parsedValues ) ); |
|
149 |
|
150 TRAPD( parseError, ParseGenaL( aGenaNotify, parsedValues ) ); |
|
151 if ( KErrNone != parseError ) |
|
152 { |
|
153 User::Leave( KErrGeneral ); |
|
154 } |
|
155 for ( TInt i(0); i < parsedValues.Count(); ++i ) |
|
156 { |
|
157 CUpnpDescriptionProperty* property = parsedValues[i]; |
|
158 aService.SetStateVariableL( property->Name(), UpnpString::Trim( property->Value()) ); |
|
159 } |
|
160 CleanupStack::PopAndDestroy( &parsedValues ); |
|
161 } |
|
162 |
|
163 // ----------------------------------------------------------------------------- |
|
164 // CUpnpContentHandlersController::ParseSoapL |
|
165 // Parses a xml document and returns set objects of CUpnpDescriptionProperties |
|
166 // It is used to parse action messages (soap) |
|
167 // @pre description property array should be leave safe |
|
168 // (there will be PopAndDestroy called on it in case of leave) |
|
169 // ----------------------------------------------------------------------------- |
|
170 // |
|
171 void CUpnpContentHandlersController::ParseSoapL( |
|
172 const TDesC8& aDescription, |
|
173 RPointerArray<CUpnpDescriptionProperty>& aParsedValues ) |
|
174 { |
|
175 CUpnpSoapContentHandler* soapCH = |
|
176 CUpnpSoapContentHandler::NewL( *this, aParsedValues ); |
|
177 iCorrectUri.Set( KSoapNamespaceUri ); |
|
178 ParseXmlL( aDescription, soapCH ); |
|
179 delete soapCH; |
|
180 } |
|
181 |
|
182 // ----------------------------------------------------------------------------- |
|
183 // CUpnpContentHandlersController::ParseParseDescriptionPropertiesL |
|
184 // Parses a xml document and returns set objects of CUpnpDescriptionProperties |
|
185 // It is used to parse event notification |
|
186 // @pre description property array should be leave safe |
|
187 // (there will be PopAndDestroy called on it in case of leave) |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 void CUpnpContentHandlersController::ParseGenaL( |
|
191 const TDesC8& aDescription, |
|
192 RPointerArray<CUpnpDescriptionProperty>& aParsedValues ) |
|
193 { |
|
194 CUpnpPropertysetContentHandler* propsetCH = |
|
195 CUpnpPropertysetContentHandler::NewL( *this, aParsedValues ); |
|
196 iCorrectUri.Set( KEventNamespaceUri ); |
|
197 ParseXmlL( aDescription, propsetCH ); |
|
198 delete propsetCH; |
|
199 } |
|
200 |
|
201 // ----------------------------------------------------------------------------- |
|
202 // CUpnpContentHandlersController::ParseServiceL |
|
203 // Parses a xml document and returns object of CUpnpService class |
|
204 // It is used for the first time the xml document is parsed |
|
205 // ----------------------------------------------------------------------------- |
|
206 // |
|
207 EXPORT_C CUpnpService* CUpnpContentHandlersController::ParseServiceL( |
|
208 const TDesC8& aDescription, CUpnpDevice* aParentDevice ) |
|
209 { |
|
210 CUpnpServiceContentHandler* serviceCH = |
|
211 CUpnpServiceContentHandler::NewL( *this, aParentDevice ); |
|
212 iCorrectUri.Set( KServiceNamespaceUri ); |
|
213 ParseXmlL( aDescription, serviceCH ); |
|
214 CUpnpService* result = serviceCH->ResultService(); |
|
215 delete serviceCH; |
|
216 return result; |
|
217 } |
|
218 |
|
219 // ----------------------------------------------------------------------------- |
|
220 // CUpnpContentHandlersController::ParseServiceL |
|
221 // Parses an xml document |
|
222 // It is used in case when CUpnpService object already exists |
|
223 // ----------------------------------------------------------------------------- |
|
224 // |
|
225 EXPORT_C void CUpnpContentHandlersController::ParseServiceL( |
|
226 const TDesC8& aDescription, CUpnpService* aService ) |
|
227 { |
|
228 CUpnpServiceContentHandler* serviceCH = |
|
229 CUpnpServiceContentHandler::NewL( *this, *aService ); |
|
230 iCorrectUri.Set( KServiceNamespaceUri ); |
|
231 ParseXmlL(aDescription, serviceCH); |
|
232 delete serviceCH; |
|
233 } |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CUpnpContentHandlersController::ParseDeviceL |
|
237 // Parses an xml document and returns instance of CUpnpDevice class |
|
238 // It is used for the first time the device xml document is parsed |
|
239 // ----------------------------------------------------------------------------- |
|
240 // |
|
241 EXPORT_C CUpnpDevice* CUpnpContentHandlersController::ParseDeviceL( |
|
242 const TDesC8& aDescription ) |
|
243 { |
|
244 return DoParseDeviceL( aDescription, (CUpnpDevice*)NULL ); |
|
245 } |
|
246 |
|
247 // ----------------------------------------------------------------------------- |
|
248 // CUpnpContentHandlersController::ParseDeviceL |
|
249 // Parses an xml document and returns instance of CUpnpDevice class |
|
250 // It is used in case when CUpnpDevice object already exists and update of |
|
251 // device xml is required |
|
252 // ----------------------------------------------------------------------------- |
|
253 // |
|
254 EXPORT_C void CUpnpContentHandlersController::ParseDeviceL( |
|
255 const TDesC8& aDescription, CUpnpDevice* aDevice ) |
|
256 { |
|
257 ASSERT( NULL != aDevice ); |
|
258 DoParseDeviceL( aDescription, aDevice ); |
|
259 } |
|
260 |
|
261 template<class T> T* CUpnpContentHandlersController::DoParseDeviceL( |
|
262 const TDesC8& aDescription, T* aDevice ) |
|
263 { |
|
264 CUpnpDeviceContentHandler* deviceCH = CUpnpDeviceContentHandler::NewL( |
|
265 *this, aDevice ); |
|
266 iCorrectUri.Set( KDeviceNamespaceUri ); |
|
267 ParseXmlL( aDescription, deviceCH ); |
|
268 T* result(NULL); |
|
269 if ( !aDevice ) |
|
270 { |
|
271 deviceCH->GetResultDevice( result ); |
|
272 } |
|
273 delete deviceCH; |
|
274 return result; |
|
275 } |
|
276 |
|
277 // ----------------------------------------------------------------------------- |
|
278 // CUpnpContentHandlersController::ParseDeviceImplL |
|
279 // Parses an xml document and returns instance of CUpnpDevice class |
|
280 // It is used for the first time the device xml document is parsed |
|
281 // ----------------------------------------------------------------------------- |
|
282 // |
|
283 EXPORT_C CUpnpDeviceImplementation* CUpnpContentHandlersController::ParseDeviceImplL( |
|
284 const TDesC8& aDescription ) |
|
285 { |
|
286 return DoParseDeviceL( aDescription, (CUpnpDeviceImplementation*)NULL ); |
|
287 } |
|
288 |
|
289 // ----------------------------------------------------------------------------- |
|
290 // CUpnpContentHandlersController::ParseDeviceImplL |
|
291 // Parses an xml document and returns instance of CUpnpDevice class |
|
292 // It is used in case when CUpnpDeviceImplementation object already exists and |
|
293 // update of device xml is required |
|
294 // ----------------------------------------------------------------------------- |
|
295 // |
|
296 EXPORT_C void CUpnpContentHandlersController::ParseDeviceImplL( |
|
297 const TDesC8& aDescription, CUpnpDeviceImplementation* aDeviceImpl ) |
|
298 { |
|
299 ASSERT( NULL != aDeviceImpl ); |
|
300 DoParseDeviceL( aDescription, aDeviceImpl ); |
|
301 } |
|
302 |
|
303 // ----------------------------------------------------------------------------- |
|
304 // CUpnpContentHandlersController::ParseSilentDeviceImplL |
|
305 // Parses an xml document and returns instance of CUpnpDevice class |
|
306 // It is used for the first time the device xml document is parsed |
|
307 // ----------------------------------------------------------------------------- |
|
308 // |
|
309 EXPORT_C CUpnpSilentDeviceImplementation* CUpnpContentHandlersController::ParseSilentDeviceImplL( |
|
310 const TDesC8& aDescription ) |
|
311 { |
|
312 return DoParseDeviceL( aDescription, (CUpnpSilentDeviceImplementation*)NULL ); |
|
313 } |
|
314 |
|
315 // ----------------------------------------------------------------------------- |
|
316 // CUpnpContentHandlersController::ParseSilentDeviceImplL |
|
317 // Parses an xml document and returns instance of CUpnpDevice class |
|
318 // It is used in case when CUpnpSilentDeviceImplementation object already exists and |
|
319 // update of device xml is required |
|
320 // ----------------------------------------------------------------------------- |
|
321 // |
|
322 EXPORT_C void CUpnpContentHandlersController::ParseSilentDeviceImplL( |
|
323 const TDesC8& aDescription, CUpnpSilentDeviceImplementation* aDeviceImpl ) |
|
324 { |
|
325 ASSERT( NULL != aDeviceImpl ); |
|
326 DoParseDeviceL( aDescription, aDeviceImpl ); |
|
327 } |
|
328 |
|
329 // ----------------------------------------------------------------------------- |
|
330 // ReleaseHandlersOnStack |
|
331 // Releases all handlers that are on CStack<CUpnpContentHandler, ETrue> object |
|
332 // Used as method passed to TCleanupItem object. |
|
333 // ----------------------------------------------------------------------------- |
|
334 // |
|
335 LOCAL_C void ReleaseHandlersOnStack(TAny* aStack) |
|
336 { |
|
337 reinterpret_cast<CStack<CUpnpContentHandler, ETrue>*>(aStack)->Clear(); |
|
338 } |
|
339 |
|
340 // ----------------------------------------------------------------------------- |
|
341 // CUpnpContentHandlersController::ParseXmlL |
|
342 // Parses a xml document by passed content handler, |
|
343 // there is a guarantee that aHandlerToUse will be deleted in case of leave |
|
344 // precondition: iStack is empty |
|
345 // postcondition: iStack is empty |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 void CUpnpContentHandlersController::ParseXmlL( const TDesC8& aDescription, |
|
349 CUpnpContentHandler* aHandlerToUse ) |
|
350 { |
|
351 ASSERT( iStack->IsEmpty() ); |
|
352 iCurrentContentHandler = aHandlerToUse; |
|
353 iStack->PushL( aHandlerToUse ); |
|
354 CleanupStack::PushL( TCleanupItem( ReleaseHandlersOnStack, iStack ) ); |
|
355 iDocStarted = EFalse; |
|
356 TRAPD( parseError, Xml::ParseL( *iParser, aDescription ) ); |
|
357 if ( EXmlSyntax == parseError || EXmlInvalidToken == parseError ) |
|
358 { |
|
359 while ( iStack->Count() > 1 ) |
|
360 { |
|
361 delete iStack->Pop(); |
|
362 } |
|
363 aHandlerToUse->ResetState(); |
|
364 iCurrentContentHandler = aHandlerToUse; |
|
365 iDocStarted = EFalse; |
|
366 RBuf8 fixedDes; |
|
367 fixedDes.CreateL( aDescription ); |
|
368 CleanupClosePushL( fixedDes ); |
|
369 RemoveForbiddenCharacters( fixedDes ); |
|
370 TRAP( parseError, Xml::ParseL( *iParser, fixedDes ) ); |
|
371 CleanupStack::PopAndDestroy( &fixedDes ); |
|
372 } |
|
373 |
|
374 if ( EXmlJunkAfterDocElement != parseError ) |
|
375 { |
|
376 User::LeaveIfError( parseError ); |
|
377 } |
|
378 else |
|
379 { |
|
380 //EXmlJunkAfterDocElement must not be ignored when root isn't complete |
|
381 if ( !iDocStarted || iStack->Count() != 1 ) |
|
382 { |
|
383 User::Leave( KErrArgument ); //no valid root element were found |
|
384 } |
|
385 } |
|
386 ASSERT( iStack->Count() == 1 ); |
|
387 ASSERT( iStack->Head() == iCurrentContentHandler && iCurrentContentHandler == aHandlerToUse ); |
|
388 iStack->Pop(); |
|
389 CleanupStack::Pop( iStack ); |
|
390 ASSERT( iStack->IsEmpty() ); |
|
391 } |
|
392 |
|
393 // ----------------------------------------------------------------------------- |
|
394 // CUpnpContentHandlersController::RemoveForbiddenCharacters |
|
395 // Removes forbidden characters |
|
396 // ----------------------------------------------------------------------------- |
|
397 // |
|
398 void CUpnpContentHandlersController::RemoveForbiddenCharacters( TDes8& aDescription ) |
|
399 { |
|
400 for( TInt i=0; i<aDescription.Length(); i++ ) |
|
401 { |
|
402 if ( ( aDescription[i] <= KUtfLowMax ) || |
|
403 ( aDescription[i] >= KUtfHighMin && aDescription[i] <= KUtfHighMax ) ) |
|
404 { |
|
405 aDescription.Delete( i, 1 ); |
|
406 i--; |
|
407 } |
|
408 } |
|
409 } |
|
410 |
|
411 // ----------------------------------------------------------------------------- |
|
412 // CUpnpContentHandlersController::CUpnpContentHandlersController |
|
413 // Default C++ constructor |
|
414 // ----------------------------------------------------------------------------- |
|
415 // |
|
416 CUpnpContentHandlersController::CUpnpContentHandlersController() |
|
417 : iSoapParser( *this ) |
|
418 { |
|
419 } |
|
420 |
|
421 // ----------------------------------------------------------------------------- |
|
422 // CUpnpContentHandlersController::ConstructL |
|
423 // 2nd phase constructor, dedicated to be used by inherited classs |
|
424 // ----------------------------------------------------------------------------- |
|
425 // |
|
426 void CUpnpContentHandlersController::ConstructL() |
|
427 { |
|
428 _LIT8( KXmlMimeType, "text/xml" ); |
|
429 _LIT8( KLibxml2, "libxml2" ); |
|
430 CMatchData *matchData = CMatchData::NewL(); |
|
431 CleanupStack::PushL( matchData ); |
|
432 matchData->SetMimeTypeL( KXmlMimeType ); |
|
433 matchData->SetVariantL( KLibxml2 ); |
|
434 iParser = CParser::NewL( *matchData, *this ); |
|
435 CleanupStack::PopAndDestroy( matchData ); |
|
436 iStack = new (ELeave) CStack<CUpnpContentHandler,ETrue>(); |
|
437 } |
|
438 |
|
439 // ----------------------------------------------------------------------------- |
|
440 // CUpnpContentHandlersController::OnStartDocumentL |
|
441 // This method is a callback to indicate the start of the document. |
|
442 // ----------------------------------------------------------------------------- |
|
443 // |
|
444 void CUpnpContentHandlersController::OnStartDocumentL( |
|
445 const RDocumentParameters& /*aDocParam*/, TInt aErrorCode ) |
|
446 { |
|
447 User::LeaveIfError( aErrorCode ); |
|
448 iDocStarted = ETrue; |
|
449 } |
|
450 |
|
451 // ----------------------------------------------------------------------------- |
|
452 // CUpnpContentHandlersController::OnEndDocumentL |
|
453 // This method is a callback to indicate the end of the document. |
|
454 // ----------------------------------------------------------------------------- |
|
455 // |
|
456 void CUpnpContentHandlersController::OnEndDocumentL( TInt aErrorCode ) |
|
457 { |
|
458 User::LeaveIfError( aErrorCode ); |
|
459 } |
|
460 |
|
461 // ----------------------------------------------------------------------------- |
|
462 // CUpnpContentHandlersController::OnStartElementL |
|
463 // This method is a callback to indicate an element has been parsed. |
|
464 // ----------------------------------------------------------------------------- |
|
465 // |
|
466 void CUpnpContentHandlersController::OnStartElementL( |
|
467 const RTagInfo& aElement, const RAttributeArray& aAttributes, |
|
468 TInt aErrorCode ) |
|
469 { |
|
470 User::LeaveIfError( aErrorCode ); |
|
471 ChunksMergingEndL(); |
|
472 if ( iCurrentContentHandler->InterestedInAllNamespaces() |
|
473 || aElement.Uri().DesC().Compare( iCorrectUri ) == 0 ) |
|
474 { |
|
475 iCurrentContentHandler->OnStartElementL( aElement, aAttributes ); |
|
476 } |
|
477 else |
|
478 { |
|
479 SetCurrentContentHandlerL( CUpnpIgnoreContentHandler::NewL( *this ) ); |
|
480 } |
|
481 } |
|
482 |
|
483 // ----------------------------------------------------------------------------- |
|
484 // CUpnpContentHandlersController::OnEndElementL |
|
485 // This method is a callback to indicate the end of the element has been reached. |
|
486 // ----------------------------------------------------------------------------- |
|
487 // |
|
488 void CUpnpContentHandlersController::OnEndElementL( const RTagInfo& aElement, |
|
489 TInt aErrorCode ) |
|
490 { |
|
491 User::LeaveIfError( aErrorCode ); |
|
492 ChunksMergingEndL(); |
|
493 iCurrentContentHandler->OnEndElementL( aElement ); |
|
494 } |
|
495 |
|
496 // ----------------------------------------------------------------------------- |
|
497 // CUpnpContentHandlersController::OnContentL |
|
498 // This method is a callback that sends the content of the element. |
|
499 // Not all the content may be returned in one go. The data may be sent in chunks. |
|
500 // This method just append chunk to chunks previously received. When we get all |
|
501 // chunks ChunksMergingEndL method pass merged chunks to current content handler. |
|
502 // ----------------------------------------------------------------------------- |
|
503 // |
|
504 void CUpnpContentHandlersController::OnContentL( const TDesC8& aBytes, |
|
505 TInt aErrorCode ) |
|
506 { |
|
507 User::LeaveIfError( aErrorCode ); |
|
508 const TInt newLength = iContent.Length() + aBytes.Length(); |
|
509 if ( iContent.MaxLength() < newLength ) |
|
510 { |
|
511 iContent.ReAllocL( newLength ); |
|
512 } |
|
513 iContent.Append( aBytes ); |
|
514 } |
|
515 |
|
516 // ----------------------------------------------------------------------------- |
|
517 // CUpnpContentHandlersController::ChunksMergingEndL |
|
518 // Method that is called when all chunks that contain current content |
|
519 // were received, so we can pass merged content to current content handler |
|
520 // as an argument of OnContentL method |
|
521 // ----------------------------------------------------------------------------- |
|
522 // |
|
523 void CUpnpContentHandlersController::ChunksMergingEndL() |
|
524 { |
|
525 if ( iContent.Length() > 0 ) |
|
526 { |
|
527 TLex8 lex(iContent); |
|
528 lex.SkipSpace(); |
|
529 if ( !lex.Eos() ) |
|
530 { |
|
531 iCurrentContentHandler->OnContentL( iContent ); |
|
532 } |
|
533 iContent.Zero(); |
|
534 } |
|
535 } |
|
536 |
|
537 // ----------------------------------------------------------------------------- |
|
538 // CUpnpContentHandlersController::OnStartPrefixMappingL |
|
539 // This method is a notification of the beginning of the scope of a prefix-URI Namespace mapping. |
|
540 // This method is always called before the corresponding OnStartElementL method. |
|
541 // ----------------------------------------------------------------------------- |
|
542 // |
|
543 void CUpnpContentHandlersController::OnStartPrefixMappingL( |
|
544 const RString& /*aPrefix*/, const RString& /*aUri*/, TInt aErrorCode ) |
|
545 { |
|
546 User::LeaveIfError( aErrorCode ); |
|
547 } |
|
548 |
|
549 // ----------------------------------------------------------------------------- |
|
550 // CUpnpContentHandlersController::OnEndPrefixMappingL |
|
551 // This method is a notification of the end of the scope of a prefix-URI mapping. |
|
552 // This method is called after the corresponding DoEndElementL method. |
|
553 // ----------------------------------------------------------------------------- |
|
554 // |
|
555 void CUpnpContentHandlersController::OnEndPrefixMappingL( |
|
556 const RString& /*aPrefix*/, TInt aErrorCode ) |
|
557 { |
|
558 User::LeaveIfError( aErrorCode ); |
|
559 } |
|
560 |
|
561 // ----------------------------------------------------------------------------- |
|
562 // CUpnpContentHandlersController::OnIgnorableWhiteSpaceL |
|
563 // This method is a notification of ignorable whitespace in element content. |
|
564 // ----------------------------------------------------------------------------- |
|
565 // |
|
566 void CUpnpContentHandlersController::OnIgnorableWhiteSpaceL( |
|
567 const TDesC8& /*aBytes*/, TInt aErrorCode ) |
|
568 { |
|
569 User::LeaveIfError( aErrorCode ); |
|
570 } |
|
571 |
|
572 // ----------------------------------------------------------------------------- |
|
573 // CUpnpContentHandlersController::OnSkippedEntityL |
|
574 // This method is a notification of a skipped entity. If the parser encounters an |
|
575 // external entity it does not need to expand it - it can return the entity as aName |
|
576 // for the client to deal with. |
|
577 // ----------------------------------------------------------------------------- |
|
578 // |
|
579 void CUpnpContentHandlersController::OnSkippedEntityL( |
|
580 const RString& /*aName*/, TInt aErrorCode ) |
|
581 { |
|
582 User::LeaveIfError( aErrorCode ); |
|
583 } |
|
584 |
|
585 // ----------------------------------------------------------------------------- |
|
586 // CUpnpContentHandlersController::OnProcessingInstructionL |
|
587 // This method is a receive notification of a processing instruction. |
|
588 // ----------------------------------------------------------------------------- |
|
589 // |
|
590 void CUpnpContentHandlersController::OnProcessingInstructionL( |
|
591 const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt aErrorCode ) |
|
592 { |
|
593 User::LeaveIfError( aErrorCode ); |
|
594 ChunksMergingEndL(); |
|
595 } |
|
596 |
|
597 // ----------------------------------------------------------------------------- |
|
598 // CUpnpContentHandlersController::OnError |
|
599 // This method indicates an error has occurred. |
|
600 // ----------------------------------------------------------------------------- |
|
601 // |
|
602 void CUpnpContentHandlersController::OnError( TInt /*aErrorCode*/) |
|
603 { |
|
604 } |
|
605 |
|
606 // ----------------------------------------------------------------------------- |
|
607 // CUpnpContentHandlersController::GetExtendedInterface |
|
608 // This method obtains the interface matching the specified uid. |
|
609 // ----------------------------------------------------------------------------- |
|
610 // |
|
611 TAny* CUpnpContentHandlersController::GetExtendedInterface( const TInt32 /*aUid*/) |
|
612 { |
|
613 return 0; |
|
614 } |
|
615 |
|
616 // ----------------------------------------------------------------------------- |
|
617 // CUpnpContentHandlersController::SetCurrentContentHandlerL |
|
618 // Sets ContentHandler argument as a current content handler, so it will |
|
619 // receive parsing events. Previous content handler will be push on stack |
|
620 // that it could be againt current content handler after calling of |
|
621 // SetPreviousContentHandler. |
|
622 // ----------------------------------------------------------------------------- |
|
623 // |
|
624 void CUpnpContentHandlersController::SetCurrentContentHandlerL( |
|
625 CUpnpContentHandler* aNewContentHandler ) |
|
626 { |
|
627 ASSERT( NULL != aNewContentHandler ); |
|
628 iStack->PushL( aNewContentHandler ); |
|
629 iCurrentContentHandler = aNewContentHandler; |
|
630 } |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // CUpnpContentHandlersController::SetPreviousContentHandler |
|
634 // Deletes current content handler, and set previous content handler as current |
|
635 // contetnt handler. |
|
636 // ----------------------------------------------------------------------------- |
|
637 // |
|
638 void CUpnpContentHandlersController::SetPreviousContentHandler() |
|
639 { |
|
640 ASSERT( iStack->Count() > 1 ); |
|
641 delete iStack->Pop(); |
|
642 iCurrentContentHandler = iStack->Head(); |
|
643 } |
|
644 |
|
645 // End of File |