|
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <btsdp.h> |
|
17 #include "responsesizevisitor.h" |
|
18 #include "SDPDatabase.h" |
|
19 #include "mignorer.h" |
|
20 #include "DataEncoder.h" |
|
21 |
|
22 |
|
23 // Class CHandleItem |
|
24 EXPORT_C CHandleItem* CHandleItem::NewLC() |
|
25 { |
|
26 CHandleItem* self = new(ELeave)CHandleItem(); |
|
27 CleanupStack::PushL(self); |
|
28 self->ConstructL(); |
|
29 return self; |
|
30 } |
|
31 |
|
32 EXPORT_C CHandleItem* CHandleItem::NewL() |
|
33 { |
|
34 CHandleItem* self = CHandleItem::NewLC(); |
|
35 CleanupStack::Pop(); |
|
36 return self; |
|
37 } |
|
38 |
|
39 void CHandleItem::ConstructL() |
|
40 { |
|
41 iAttrSizeList = new (ELeave) CArrayPtrFlat<CAttrSizeItem>(KSDPAttListGran); |
|
42 } |
|
43 |
|
44 CHandleItem::~CHandleItem() |
|
45 { |
|
46 if (iAttrSizeList) |
|
47 { |
|
48 iAttrSizeList->ResetAndDestroy(); |
|
49 delete iAttrSizeList; |
|
50 } |
|
51 } |
|
52 |
|
53 EXPORT_C CHandleItem* CHandleItem::CHandleItemL(TSdpServRecordHandle aHandleID, CSdpServRecord* aRecord) |
|
54 { |
|
55 CHandleItem* self = NewL(); |
|
56 self->iHandleID = aHandleID; |
|
57 self->iRecord = aRecord; |
|
58 self->iRecordSize = 0; |
|
59 return self; |
|
60 } |
|
61 |
|
62 void CHandleItem::AddAttrItemL(CAttrSizeItem* aItem) |
|
63 { |
|
64 iAttrSizeList->AppendL(aItem); |
|
65 iRecordSize += aItem->Size() + 3; // add the attrID header size; |
|
66 } |
|
67 |
|
68 void CHandleItem::AddAttrItemL(const TSdpAttributeID aAttributeID, TUint aSize, CSdpAttr* aAttribute) |
|
69 { |
|
70 CAttrSizeItem* sizeItem = new (ELeave) CAttrSizeItem(aAttributeID, aSize, aAttribute); |
|
71 AddAttrItemL(sizeItem); |
|
72 } |
|
73 |
|
74 |
|
75 // Class CSizeAccumulator |
|
76 |
|
77 EXPORT_C CSizeAccumulator* CSizeAccumulator::NewLC() |
|
78 { |
|
79 CSizeAccumulator* self = new(ELeave)CSizeAccumulator(); |
|
80 CleanupStack::PushL(self); |
|
81 self->ConstructL(); |
|
82 return self; |
|
83 } |
|
84 |
|
85 EXPORT_C CSizeAccumulator* CSizeAccumulator::NewL() |
|
86 { |
|
87 CSizeAccumulator* self = CSizeAccumulator::NewLC(); |
|
88 CleanupStack::Pop(); |
|
89 return self; |
|
90 } |
|
91 |
|
92 void CSizeAccumulator::ConstructL() |
|
93 { |
|
94 iHandleList = new (ELeave) CArrayPtrFlat<CHandleItem>(KSDPHandListGran); |
|
95 } |
|
96 |
|
97 CSizeAccumulator::~CSizeAccumulator() |
|
98 { |
|
99 if ( iHandleList ) |
|
100 { |
|
101 iHandleList->ResetAndDestroy(); |
|
102 delete iHandleList; |
|
103 } |
|
104 } |
|
105 |
|
106 void CSizeAccumulator::AddHandleL(CHandleItem* aHandleItem) |
|
107 { |
|
108 iHandleList->AppendL(aHandleItem); |
|
109 } |
|
110 |
|
111 // do a crc across all the attributes |
|
112 EXPORT_C TUint16 CSizeAccumulator::CrcAttribs() |
|
113 { |
|
114 TUint16 totalCrc=0; |
|
115 for (TInt i = 0; i<HandleCount(); i++) |
|
116 { |
|
117 for (TInt j = 0; j<AttrCount(i); j++) |
|
118 { |
|
119 CAttrSizeItem* attr = AttributeOf(i,j); |
|
120 CSdpAttrValue& theVal = attr->Attr()->Value(); |
|
121 Mem::Crc(totalCrc, reinterpret_cast<const TAny*>(theVal.Des()[0]), attr->Size()); |
|
122 } |
|
123 } |
|
124 return totalCrc; |
|
125 |
|
126 } |
|
127 |
|
128 /** |
|
129 CSizeAccumulator::SizeLeft |
|
130 calculate the size of the attribute list. |
|
131 |
|
132 Foundation of the continuation handling. |
|
133 It is used together with StartAt. |
|
134 It walks through the list of records, each should contain |
|
135 a list of attributes. There are internal start offsets for |
|
136 both the record and attribute lists. These are set with StartAt. |
|
137 |
|
138 The method returns the size (in bytes) of the attributes, together with |
|
139 3 bytes for each attribute ID (1 byte header, 2 byte UInt) and the correct |
|
140 number of bytes for each DES header for the attributes of each record. |
|
141 |
|
142 It does NOT calculate the DES header for a list of records. So an extra |
|
143 DES must be created for Searvice Search Attribute. |
|
144 |
|
145 This allows the total length to be written before the rest of the response |
|
146 packet. It also allows the request handler to decide if it can fit the whole |
|
147 response in to the response packet with or without continuation. |
|
148 Return format is |
|
149 @verbatim |
|
150 Size left TUint |
|
151 @endverbatim |
|
152 **/ |
|
153 EXPORT_C TUint CSizeAccumulator::SizeLeft() |
|
154 { |
|
155 TUint totalSize=0; |
|
156 TInt handleCount = HandleCount(); // for testing |
|
157 for (TInt i = iFirstRec; i < handleCount; i++) |
|
158 { |
|
159 TUint recordSize = 0; |
|
160 TInt attrCount = AttrCount(i); // for testing |
|
161 for (TInt j = iFirstAtt; j < attrCount; j++) |
|
162 { |
|
163 CAttrSizeItem* attr = AttributeOf(i,j); |
|
164 recordSize += attr->Size(); |
|
165 recordSize +=3; // the size of a attribute ID in the list |
|
166 } |
|
167 if (iFirstAtt == 0) |
|
168 { // are we sizing the whole record ? |
|
169 TUint recRecSize = iHandleList->At(i)->CHandleItem::iRecordSize; // for testing |
|
170 if (recordSize != recRecSize) DbPanic(ESdpDbBadSearchPattern); |
|
171 } |
|
172 if (recordSize) |
|
173 { // only add the header if there is any data |
|
174 TUint desSize; |
|
175 desSize = (recordSize > 0xff) ? 3 : 2; |
|
176 desSize = (recordSize > 0xffff) ? 5 : desSize; |
|
177 totalSize += recordSize + desSize; // size of the DES header for this record |
|
178 } |
|
179 } |
|
180 return totalSize; |
|
181 |
|
182 } |
|
183 |
|
184 |
|
185 /** |
|
186 CSizeAccumulator::StartAt |
|
187 Supplied with the data sent so far. |
|
188 This walks through the list of service search record handles |
|
189 and the the list of attributes associated with each record. |
|
190 |
|
191 Once it has found the location where the size is less than or |
|
192 equal to the parameter supplied, it sets CSizeAccumulators |
|
193 internal record and attribute offsets to the point it has |
|
194 reached. It will not update the offsets if the data is greater |
|
195 than the input offset. |
|
196 |
|
197 The method returns the two offsets and the data already sent |
|
198 from the current attribute. |
|
199 |
|
200 The method counts the DES header at the start of any record. It |
|
201 does NOT count the overall DES header if there is more than one |
|
202 record. To do this would require a count of all bytes to evaluate |
|
203 the DES header size. This action is the same as that of SizeLeft. |
|
204 |
|
205 ******************************************************** |
|
206 IMPORTANT NOTE: If aOffset traverses the database and |
|
207 STOPS IN THE MIDDLE OF A NEW RECORD DES HEADER, it will return |
|
208 THE DES HEADER OFFSET in the ATTRIBUTE OFFSET PARAMETER. |
|
209 This is ambiguous... |
|
210 ****A calling function should ensure aOffset cannot do this*** |
|
211 |
|
212 The method returns a bool to indicate the setting was OK. It will |
|
213 be false if the two index parameters were used and they would |
|
214 have set the lists beyond their end. Also it returns false if the |
|
215 offset was beyond the end of the data. If the method returns EFalse, |
|
216 the two index parameters are set to 0. |
|
217 |
|
218 This method can reset the parameters by being called with offset 0. |
|
219 However it will then return false. |
|
220 Parameter format is |
|
221 @verbatim |
|
222 Offset in bytes from start of attribute data TUint |
|
223 Record index (0...) TInt |
|
224 Attribute index (0...) TInt |
|
225 @endverbatim |
|
226 Return format is |
|
227 @verbatim |
|
228 Were the offsets set OK TBool |
|
229 Record index is set TInt |
|
230 Attribute index is set TInt |
|
231 @endverbatim |
|
232 |
|
233 **/ |
|
234 EXPORT_C TBool CSizeAccumulator::StartAt(TUint aOffset, TUint& aPartSent, TInt& aRec, TInt& aAtt) |
|
235 { |
|
236 // calculates and sets the next record and attribute |
|
237 if (aOffset == 0) |
|
238 { |
|
239 aRec = 0; iFirstRec = 0; |
|
240 aAtt = 0; iFirstAtt = 0; |
|
241 aPartSent = 0; |
|
242 return EFalse; |
|
243 } |
|
244 TUint totalSize=0; |
|
245 TBool more = ETrue; |
|
246 TInt topRec = HandleCount(); |
|
247 if (aRec > topRec) |
|
248 { |
|
249 aRec = 0; iFirstRec = 0; |
|
250 aAtt = 0; iFirstAtt = 0; |
|
251 aPartSent = 0; |
|
252 return EFalse; |
|
253 } |
|
254 else if (aRec == topRec) |
|
255 { |
|
256 TInt partAtt = AttrCount(topRec); |
|
257 if (aAtt > partAtt) |
|
258 { |
|
259 aRec = 0; iFirstRec = 0; |
|
260 aAtt = 0; iFirstAtt = 0; |
|
261 aPartSent = 0; |
|
262 return EFalse; |
|
263 } |
|
264 } |
|
265 iFirstRec = aRec; |
|
266 TInt firstAttForNextRecord = aAtt; |
|
267 while (more && (iFirstRec < topRec)) |
|
268 { |
|
269 TUint recordSize = iHandleList->At(iFirstRec)->CHandleItem::iRecordSize; |
|
270 TInt topAtt = AttrCount(iFirstRec); |
|
271 iFirstAtt = firstAttForNextRecord < topAtt ? firstAttForNextRecord : topAtt; |
|
272 // except for first record we always start with a record's first attribute |
|
273 firstAttForNextRecord = 0; |
|
274 // add in the DES header size for this record |
|
275 TUint desSize; |
|
276 desSize = (recordSize > 0xff) ? 3 : 2; |
|
277 desSize = (recordSize > 0xffff) ? 5 : desSize; |
|
278 if (totalSize + desSize > aOffset) |
|
279 //see "IMPORTANT NOTE" above this method |
|
280 { |
|
281 more = EFalse; |
|
282 break; |
|
283 } |
|
284 totalSize += desSize; |
|
285 while (more && (iFirstAtt < topAtt)) |
|
286 { |
|
287 CAttrSizeItem* attr = AttributeOf(iFirstRec, iFirstAtt); |
|
288 TUint nextSize = attr->Size(); |
|
289 nextSize += 3; // Attribute ID and its header |
|
290 if (totalSize + nextSize > aOffset) |
|
291 { |
|
292 more = EFalse; |
|
293 break; |
|
294 } |
|
295 totalSize += nextSize; |
|
296 iFirstAtt++; |
|
297 } |
|
298 if (more) iFirstRec++; |
|
299 } |
|
300 if (totalSize == aOffset) more = EFalse; |
|
301 if (more) |
|
302 { |
|
303 aRec = 0; iFirstRec = 0; |
|
304 aAtt = 0; iFirstAtt = 0; |
|
305 aPartSent = 0; |
|
306 return EFalse; |
|
307 } |
|
308 aRec = iFirstRec; |
|
309 aAtt = iFirstAtt; |
|
310 aPartSent = aOffset - totalSize; |
|
311 return ETrue; |
|
312 // __ASSERT_DEBUG(totalSize != aOffset, DbPanic(ESdpDbBadSearchPattern)); |
|
313 } |
|
314 |
|
315 EXPORT_C TInt CSizeAccumulator::HandleCount() |
|
316 { |
|
317 return iHandleList->Count(); |
|
318 } |
|
319 |
|
320 EXPORT_C TSdpServRecordHandle CSizeAccumulator::HandleAt(TInt aOffset) |
|
321 { |
|
322 __ASSERT_DEBUG(aOffset <= iHandleList->Count(), DbPanic(ESdpDbBadSearchPattern)); // FIXME different panic code please |
|
323 return iHandleList->At(aOffset)->CHandleItem::iHandleID; |
|
324 } |
|
325 |
|
326 EXPORT_C TUint CSizeAccumulator::HandleSize(TInt aOffset) |
|
327 { |
|
328 return iHandleList->At(aOffset)->CHandleItem::iRecordSize; |
|
329 } |
|
330 |
|
331 EXPORT_C TInt CSizeAccumulator::AttrCount(TInt aOffset) |
|
332 { |
|
333 if (iHandleList->Count() == 0) return 0; |
|
334 __ASSERT_DEBUG(aOffset <= iHandleList->Count(), DbPanic(ESdpDbBadSearchPattern)); |
|
335 if (iHandleList->At(aOffset) == NULL) return 0; |
|
336 return iHandleList->At(aOffset)->CHandleItem::iAttrSizeList->Count(); |
|
337 } |
|
338 |
|
339 EXPORT_C CAttrSizeItem* CSizeAccumulator::AttributeOf(TInt aHandleOffset, TInt aAttOffset) |
|
340 { |
|
341 if (iHandleList->Count() == 0) return (CAttrSizeItem*)0; |
|
342 __ASSERT_DEBUG(aHandleOffset < iHandleList->Count(), DbPanic(ESdpDbBadSearchPattern)); |
|
343 CHandleItem* hnd = iHandleList->At(aHandleOffset); |
|
344 if (hnd->iAttrSizeList->Count() == 0) return (CAttrSizeItem*)0; |
|
345 __ASSERT_DEBUG(aAttOffset < hnd->iAttrSizeList->Count(), DbPanic(ESdpDbBadSearchPattern)); |
|
346 // return iHandleList->At(aHandleOffset)->CHandleItem::iAttrSizeList->At(aAttOffset); |
|
347 return hnd->iAttrSizeList->At(aAttOffset); |
|
348 } |
|
349 |
|
350 |
|
351 |
|
352 // need this because CResponseSizeVisitor already has start list method... |
|
353 class CSizeEncVisitorAdaptor : public MIgnorer |
|
354 { |
|
355 public: |
|
356 CSizeEncVisitorAdaptor(CResponseSizeVisitor& aVisitor) |
|
357 :iVisitor(aVisitor) |
|
358 {} |
|
359 MSdpElementBuilder* BuildUUIDL(const TUUID& aUUID) |
|
360 { |
|
361 iVisitor.FoundUUIDL(aUUID); |
|
362 return this; |
|
363 } |
|
364 private: |
|
365 CResponseSizeVisitor& iVisitor; |
|
366 }; |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 // Class CResponseSizeVisitor |
|
372 |
|
373 CResponseSizeVisitor::CResponseSizeVisitor() |
|
374 { |
|
375 } |
|
376 |
|
377 CResponseSizeVisitor::~CResponseSizeVisitor() |
|
378 { |
|
379 delete iFoundIndex; |
|
380 delete iCurrentRec; |
|
381 delete iAdapter; |
|
382 delete iParser; |
|
383 } |
|
384 |
|
385 CResponseSizeVisitor* CResponseSizeVisitor::NewLC() |
|
386 { |
|
387 CResponseSizeVisitor* self = new(ELeave)CResponseSizeVisitor(); |
|
388 CleanupStack::PushL(self); |
|
389 self->ConstructL(); |
|
390 return self; |
|
391 } |
|
392 |
|
393 CResponseSizeVisitor* CResponseSizeVisitor::NewL() |
|
394 { |
|
395 CResponseSizeVisitor* self = CResponseSizeVisitor::NewLC(); |
|
396 CleanupStack::Pop(); |
|
397 return self; |
|
398 } |
|
399 |
|
400 void CResponseSizeVisitor::ConstructL() |
|
401 { |
|
402 iAdapter = new(ELeave) CSizeEncVisitorAdaptor(*this); |
|
403 iParser = CElementParser::NewL(iAdapter); |
|
404 } |
|
405 |
|
406 // Iterate thru attributes in record |
|
407 /* Search through all attributes in a record |
|
408 either to find if it matches the UUIDlist, |
|
409 or if the attributes match the AttrIdMatchList |
|
410 or both. If there is no UUIDList then the sizes |
|
411 of matched attributes is saved to the size collector |
|
412 */ |
|
413 void CResponseSizeVisitor::SearchRecordL(CSdpServRecord& aRec) |
|
414 { |
|
415 // could be in calling routine |
|
416 if (iSearchPattern) |
|
417 { |
|
418 if (iFoundIndex) |
|
419 { |
|
420 delete iFoundIndex; |
|
421 iFoundIndex = 0; |
|
422 } |
|
423 iFoundIndex = CBitMapAllocator::NewL(iSearchSize); |
|
424 iUseThis = EFalse; |
|
425 } |
|
426 else |
|
427 iUseThis = ETrue; |
|
428 // if (iCurrentRec) delete iCurrentRec; // I want a reset. |
|
429 iCurrentRec = CHandleItem::CHandleItemL(aRec.Handle(), &aRec); |
|
430 |
|
431 for(TServAttrIter attrIter(aRec.AttributeIter()); attrIter; attrIter++) |
|
432 { |
|
433 /* |
|
434 we are checking every attribute, searching for the UUIDs. We don't exit if |
|
435 we find them all because we also want to get the sizes of any attributes which |
|
436 match our list if we have one. |
|
437 The array of sizes is built, then thrown away if it doesn't match. |
|
438 |
|
439 */ |
|
440 if (iAtMatList) |
|
441 { |
|
442 TSdpAttributeID theAttrID = (*attrIter).AttributeID(); |
|
443 if(iAtMatList->InMatchList(theAttrID)) |
|
444 {// create a new array entry |
|
445 TUint size = (*attrIter).Value().DataSize(); |
|
446 TSdpElementType type = (*attrIter).Value().Type(); |
|
447 if (type != ETypeEncoded) |
|
448 { |
|
449 // some server records may be un-encoded |
|
450 size += TElementEncoder::HeaderSize(type, size); // add the header size |
|
451 } |
|
452 if(!(type==ETypeNil)&&!(type==ETypeEncoded&&size<=1)) |
|
453 { // only include attribute if not either null or encoded null ... |
|
454 // (size of encoded (which INCLUDES header) in all non-null cases is > 1 |
|
455 // because other attribute types either have |
|
456 // to have a header plus at least one byte, or they have at least a two byte header.) |
|
457 iCurrentRec->AddAttrItemL(theAttrID, size, attrIter); |
|
458 } |
|
459 } |
|
460 } |
|
461 // check if any UUIDs match only if we have a UUIDList. |
|
462 if (iSearchPattern) (*attrIter).AcceptVisitorL(*this); |
|
463 } |
|
464 if (iUseThis) |
|
465 { |
|
466 // now we have to copy the array(s) we've built up. |
|
467 iCollector->AddHandleL(iCurrentRec); |
|
468 iCurrentRec = 0; |
|
469 } |
|
470 else |
|
471 { |
|
472 delete iCurrentRec; // I don't want a heap fault. |
|
473 iCurrentRec = 0; |
|
474 } |
|
475 } |
|
476 |
|
477 |
|
478 // static void SizeRespSSL(CSdpDatabase& aDb, const CSdpSearchPattern &aPattern, const CSizeAccumulator& aCollector); |
|
479 // static void SizeRespARL(CSdpServRecord& aRec, CSdpAttrIdMatchList &aList, const CSizeAccumulator& aCollector); |
|
480 // static void SizeRespSAL(CSdpDatabase &aDb, const CSdpSearchPattern &aPattern, CSdpAttrIdMatchList &aList, const CSizeAccumulator& aCollector); |
|
481 // we need three of these calls, all slightly different |
|
482 EXPORT_C void CResponseSizeVisitor::SizeRespSSL(CSdpDatabase& aDb, const CSdpSearchPattern& aPattern, CSizeAccumulator& aCollector) |
|
483 { |
|
484 if (aPattern.Count() == 0) User::Leave(KErrArgument); // this is part of spec. |
|
485 // SDP_DEBUG(3, FPrint(_L("Sizing SDP DB for pattern with %d entries\n"), aPattern.Count())); |
|
486 CResponseSizeVisitor* theVisitor = CResponseSizeVisitor::NewLC(); |
|
487 theVisitor->iCollector = &aCollector; |
|
488 theVisitor->iAtMatList = NULL; // using it as a flag... |
|
489 theVisitor->iSearchPattern = &aPattern; |
|
490 theVisitor->iSearchSize = theVisitor->iSearchPattern->Count(); |
|
491 |
|
492 for(TServRecordIter recIter(aDb.RecordIter()); recIter; recIter++) |
|
493 {// Iterate thru records in Db |
|
494 theVisitor->SearchRecordL(*recIter); |
|
495 } |
|
496 CleanupStack::PopAndDestroy();//theVisitor |
|
497 } |
|
498 |
|
499 EXPORT_C void CResponseSizeVisitor::SizeRespARL(CSdpServRecord& aRec, const CSdpAttrIdMatchList& aList, CSizeAccumulator& aCollector) |
|
500 { |
|
501 // SDP_DEBUG(3, FPrint(_L("Sizing SDP DB for single record\n"))); |
|
502 CResponseSizeVisitor* theVisitor = CResponseSizeVisitor::NewLC(); |
|
503 theVisitor->iCollector = &aCollector; |
|
504 theVisitor->iAtMatList = &aList; // using it as a flag... |
|
505 theVisitor->iSearchPattern = NULL; |
|
506 theVisitor->iSearchSize = 0; |
|
507 theVisitor->SearchRecordL(aRec); |
|
508 CleanupStack::PopAndDestroy();//theVisitor |
|
509 } |
|
510 |
|
511 EXPORT_C void CResponseSizeVisitor::SizeRespSAL(CSdpDatabase &aDb, const CSdpSearchPattern &aPattern, const CSdpAttrIdMatchList& aList, CSizeAccumulator& aCollector) |
|
512 { |
|
513 if (aPattern.Count() == 0) User::Leave(KErrArgument); // this is part of spec. |
|
514 // SDP_DEBUG(3, FPrint(_L("Sizing SDP DB (and attribs) with %d UUIDs\n"), aPattern.Count())); |
|
515 CResponseSizeVisitor* theVisitor = CResponseSizeVisitor::NewLC(); |
|
516 theVisitor->iCollector = &aCollector; |
|
517 theVisitor->iAtMatList = &aList; // using it as a flag... |
|
518 theVisitor->iSearchPattern = &aPattern; |
|
519 theVisitor->iSearchSize = theVisitor->iSearchPattern->Count(); |
|
520 |
|
521 for(TServRecordIter recIter(aDb.RecordIter()); recIter; recIter++) |
|
522 {// Iterate thru records in Db |
|
523 theVisitor->SearchRecordL(*recIter); |
|
524 } |
|
525 CleanupStack::PopAndDestroy();//theVisitor |
|
526 } |
|
527 |
|
528 |
|
529 |
|
530 void CResponseSizeVisitor::VisitAttributeL(CSdpAttr& /*aAttribute*/) |
|
531 { |
|
532 } |
|
533 |
|
534 void CResponseSizeVisitor::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType) |
|
535 { |
|
536 switch (aType) |
|
537 { |
|
538 case ETypeUUID: |
|
539 FoundUUIDL(aValue.UUID()); |
|
540 break; |
|
541 case ETypeEncoded: |
|
542 // parse out any UUIDs in this encoded attribute |
|
543 iParser->Reset(); |
|
544 /*rem = */iParser->ParseElementsL(aValue.Des()); |
|
545 break; |
|
546 default: |
|
547 return; |
|
548 } |
|
549 } |
|
550 |
|
551 void CResponseSizeVisitor::StartListL(CSdpAttrValueList &/*aList*/) |
|
552 { |
|
553 } |
|
554 |
|
555 void CResponseSizeVisitor::EndListL() |
|
556 { |
|
557 } |
|
558 |
|
559 void CResponseSizeVisitor::FoundUUIDL(const TUUID& aUUID) |
|
560 { |
|
561 TInt pos; |
|
562 if (iSearchPattern->Find(aUUID, pos)==0 && |
|
563 iFoundIndex->IsFree(pos)) |
|
564 { |
|
565 iFoundIndex->AllocAt(pos); |
|
566 if (iFoundIndex->Avail() == 0) |
|
567 {// We've found what we were searching for. |
|
568 iUseThis = ETrue; |
|
569 } |
|
570 } |
|
571 } |