bluetooth/btsdp/database/ServiceSearchVisitor.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     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 // cservicesearchvisitor.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <btsdp.h>
       
    19 #include "SDPDatabase.h"
       
    20 #include "ServiceSearchVisitor.h"
       
    21 #include "mignorer.h"
       
    22 
       
    23 EXPORT_C CSdpSearchPattern* CSdpSearchPattern::NewL()
       
    24 /** Allocates and constructs a new CSdpSearchPattern object.
       
    25 
       
    26 @return New CSdpSearchPattern object */
       
    27 	{
       
    28 	CSdpSearchPattern* self = new(ELeave) CSdpSearchPattern();
       
    29 	CleanupStack::PushL(self);
       
    30 	self->ConstructL();
       
    31 	CleanupStack::Pop();
       
    32 	return self;
       
    33 	}
       
    34 
       
    35 EXPORT_C void CSdpSearchPattern::ConstructL()
       
    36 /** Allocates a new UUID array. */
       
    37 	{
       
    38 	iUUIDArray = new(ELeave) CArrayFixFlat<TUUID>(1);
       
    39 	}
       
    40 
       
    41 EXPORT_C CSdpSearchPattern::~CSdpSearchPattern()
       
    42 /** Destructor
       
    43 
       
    44 Destroys the UUID array. */
       
    45 	{
       
    46 	delete iUUIDArray;
       
    47 	}
       
    48 
       
    49 CSdpSearchPattern::CSdpSearchPattern()
       
    50 	{
       
    51 	}
       
    52 
       
    53 EXPORT_C TInt CSdpSearchPattern::AddL(const TUUID& aUUID)
       
    54 /** Adds a UID to the list.
       
    55 
       
    56 @param aUUID UUID to add
       
    57 @return Position in the list that the UUID is inserted at, or KErrAlreadyExists 
       
    58 if it's already in the list */
       
    59 	{
       
    60 	TInt pos;
       
    61 	if(Find(aUUID, pos) != 0)
       
    62 		{
       
    63 		// The UUID is not currently in the pattern.  Try to add it.
       
    64 		iUUIDArray->InsertL(pos, aUUID);
       
    65 		}
       
    66 	else
       
    67 		{
       
    68 		pos = KErrAlreadyExists;
       
    69 		}
       
    70 
       
    71 	return pos;
       
    72 	}
       
    73 
       
    74 EXPORT_C TInt CSdpSearchPattern::Count() const
       
    75 /** Gets the number of UUIDs in the list.
       
    76 
       
    77 @return Number of UUIDs in the list */
       
    78 	{
       
    79 	return iUUIDArray->Count();
       
    80 	}
       
    81 
       
    82 EXPORT_C const TUUID CSdpSearchPattern::At(TInt anIndex) const
       
    83 /** Gets the UUID at the specified position in the list.
       
    84 
       
    85 @param anIndex Position of the UUID to get
       
    86 @return UUID at specified position */
       
    87 	{
       
    88 	return iUUIDArray->At(anIndex);
       
    89 	}
       
    90 
       
    91 EXPORT_C void CSdpSearchPattern::Reset()
       
    92 /** Removes all UUIDs from the list. */
       
    93 	{
       
    94 	iUUIDArray->Reset();
       
    95 	}
       
    96 
       
    97 EXPORT_C TInt CSdpSearchPattern::Remove(const TUUID& aUUID)
       
    98 /** Removes a UUID from the list.
       
    99 
       
   100 @param aUUID UUID to remove
       
   101 @return Position in the list of the UUID, or KErrNotFound if it's not in the 
       
   102 list */
       
   103 	{
       
   104 	TInt pos;
       
   105 	if (Find(aUUID, pos)==0)
       
   106 		{
       
   107 		iUUIDArray->Delete(pos);
       
   108 		return pos;
       
   109 		}
       
   110 	return KErrNotFound;
       
   111 	}
       
   112 
       
   113 EXPORT_C TInt CSdpSearchPattern::Find(const TUUID& aUUID, TInt &aPos) const
       
   114 /** Gets the position of the specified UUID in the list.
       
   115 
       
   116 @param aUUID UUID to find
       
   117 @param aPos Position of the UUID if it is in the list, otherwise the position 
       
   118 where it would be inserted
       
   119 @return 0 if aUUID is found, otherwise non-zero */
       
   120 	{ // first parameter is Offset of data in UUID
       
   121 	TInt result;
       
   122 	for(TInt i=0;i<iUUIDArray->Count();i++)
       
   123 		{
       
   124 		result = aUUID.LongForm().Compare(iUUIDArray->At(i).LongForm());
       
   125 		
       
   126 		if(result == 0)
       
   127 			{
       
   128 			aPos = i;
       
   129 			return 0;	// Inicates that the UUID was found.
       
   130 			}
       
   131 		else
       
   132 			{
       
   133 			// The UUID being search for is less than the UUID at the
       
   134 			// current array index (i).  The search is over.  Set the
       
   135 			// position reference (aPos) to reflect that the current
       
   136 			// index is where the UUID should be inserted if required.
       
   137 			if(result < 0)
       
   138 				{
       
   139 				aPos = i;
       
   140 				return KErrNotFound;
       
   141 				}
       
   142 			}
       
   143 		}
       
   144 		
       
   145 	// Either the UUID array is empty, or the search UUID is greater than
       
   146 	// all the UUIDs in the array.
       
   147 	aPos = iUUIDArray->Count();
       
   148 	return KErrNotFound;
       
   149 	}
       
   150 
       
   151 EXPORT_C TBool CSdpSearchPattern::IsEmpty()
       
   152 	{
       
   153 	return Count()==0;
       
   154 	}
       
   155 	
       
   156 MSdpElementBuilder* CSdpSearchPattern::BuildUUIDL(const TUUID& aUUID)
       
   157 	{
       
   158 	AddL(aUUID);
       
   159 	// Could error on repeated UUIDs (we ignore them anyway though)
       
   160 	return this;
       
   161 	}
       
   162 
       
   163 MSdpElementBuilder* CSdpSearchPattern::BuildDESL()
       
   164 	{
       
   165 	return this;
       
   166 	}
       
   167 
       
   168 MSdpElementBuilder* CSdpSearchPattern::StartListL()
       
   169 	{
       
   170 	return this;
       
   171 	}
       
   172 
       
   173 MSdpElementBuilder* CSdpSearchPattern::EndListL()
       
   174 	{//Service search pattern is complete, so terminate this parse
       
   175 	return 0;
       
   176 	}
       
   177 
       
   178 class CEncodedVisitorAdapter : public CBase, public MIgnorer
       
   179 	{
       
   180 public:
       
   181 	CEncodedVisitorAdapter(CServiceSearchVisitor& aVisitor)
       
   182 		:iVisitor(aVisitor)
       
   183 		{}
       
   184 	virtual MSdpElementBuilder* BuildUUIDL(const TUUID& aUUID)
       
   185 		{
       
   186 		iVisitor.FoundUUIDL(aUUID);
       
   187 		return this;
       
   188 		}
       
   189 private:
       
   190 	CServiceSearchVisitor& iVisitor;
       
   191 	};
       
   192 
       
   193 
       
   194 // Class CServiceSearchVisitor 
       
   195 
       
   196 CServiceSearchVisitor::CServiceSearchVisitor()
       
   197 	{
       
   198 	}
       
   199 
       
   200 CServiceSearchVisitor::~CServiceSearchVisitor()
       
   201 	{
       
   202 //	delete iSearchPattern;
       
   203 	delete iFoundIndexs;
       
   204 	delete iAdapter;
       
   205 	delete iParser;
       
   206 	}
       
   207 
       
   208 EXPORT_C CServiceSearchVisitor* CServiceSearchVisitor::NewLC(const CSdpSearchPattern& aPattern)
       
   209 	{
       
   210 	CServiceSearchVisitor* self = new(ELeave)CServiceSearchVisitor();
       
   211 	CleanupStack::PushL(self);
       
   212 	self->ConstructL(aPattern);
       
   213 	return self;
       
   214 	}
       
   215 
       
   216 EXPORT_C CServiceSearchVisitor* CServiceSearchVisitor::NewL(const CSdpSearchPattern& aPattern)
       
   217 	{
       
   218 	CServiceSearchVisitor* self = CServiceSearchVisitor::NewLC(aPattern);
       
   219 	CleanupStack::Pop();
       
   220 	return self;
       
   221 	}
       
   222 
       
   223 void CServiceSearchVisitor::ConstructL(const CSdpSearchPattern& aPattern)
       
   224 /** 2nd phase constructor. */
       
   225 	{
       
   226 	iSearchPattern = &aPattern;
       
   227 	iAdapter = new(ELeave) CEncodedVisitorAdapter(*this);
       
   228 	iParser = CElementParser::NewL(iAdapter);
       
   229 	}
       
   230 
       
   231 void CServiceSearchVisitor::SearchRecordL(CSdpServRecord& aRec)
       
   232 	{
       
   233 	if (iFoundIndexs)
       
   234 		{
       
   235 		delete iFoundIndexs;
       
   236 		iFoundIndexs = 0;
       
   237 		}
       
   238 	iFoundIndexs = CBitMapAllocator::NewL(iSearchPattern->Count());
       
   239 	for(TServAttrIter attrIter(aRec.AttributeIter()); attrIter; attrIter++)
       
   240 		{// Iterate thru attributes in record
       
   241 		(*attrIter).AcceptVisitorL(*this);
       
   242 		}
       
   243 	}
       
   244 
       
   245 EXPORT_C void CServiceSearchVisitor::SearchDbL(CSdpDatabase &aDb, const CSdpSearchPattern &aPattern, MServiceSearchHandler& aObserver)
       
   246    	{
       
   247 	__ASSERT_DEBUG(aPattern.Count() > 0, DbPanic(ESdpDbBadSearchPattern));
       
   248 //	SDP_DEBUG(3, FPrint(_L("Searching SDP DB for pattern with %d entries\n"), aPattern.Count()));
       
   249 	CServiceSearchVisitor* theVisitor = CServiceSearchVisitor::NewLC(aPattern);
       
   250 
       
   251 	for(TServRecordIter recIter(aDb.RecordIter()); recIter; recIter++)
       
   252 		{// Iterate thru records in Db
       
   253 		TRAPD(err, theVisitor->SearchRecordL(*recIter));
       
   254 		if (err == KErrCompletion)
       
   255 			{// Found!
       
   256 //			SDP_DEBUG(3, FPrint(_L("Match found in record 0x%x\n"), (*recIter).Handle()));
       
   257 			aObserver.RecordFoundL(*recIter);
       
   258 			}
       
   259 		else if(err != KErrNone)
       
   260 			{
       
   261 			User::Leave(err);
       
   262 			}
       
   263 		}
       
   264 	CleanupStack::PopAndDestroy();//theVisitor
       
   265 	}
       
   266 
       
   267 void CServiceSearchVisitor::VisitAttributeL(CSdpAttr &/*aAttribute*/)
       
   268 	{
       
   269 	}
       
   270 
       
   271 void CServiceSearchVisitor::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType)
       
   272 	{
       
   273 	switch (aType)
       
   274 		{
       
   275 	case ETypeUUID:
       
   276 		FoundUUIDL(aValue.UUID());
       
   277 		break;
       
   278 	case ETypeEncoded:
       
   279 		{
       
   280 // parse out any UUIDs in this encoded attribute
       
   281 //		TInt rem;
       
   282 		iParser->Reset();
       
   283 		/*rem = */iParser->ParseElementsL(aValue.Des());
       
   284 		break;
       
   285 		}
       
   286 	default:
       
   287 		break;
       
   288 		}
       
   289 	}
       
   290 
       
   291 void CServiceSearchVisitor::StartListL(CSdpAttrValueList &/*aList*/)
       
   292 	{
       
   293 	}
       
   294 
       
   295 void CServiceSearchVisitor::EndListL()
       
   296 	{
       
   297 	}
       
   298 
       
   299 
       
   300 void CServiceSearchVisitor::FoundUUIDL(const TUUID& aUUID)
       
   301 	{
       
   302 	TInt pos;
       
   303 	if (iSearchPattern->Find(aUUID, pos)==0 &&
       
   304 		iFoundIndexs->IsFree(pos))
       
   305 		{
       
   306 		iFoundIndexs->AllocAt(pos);
       
   307 		if (iFoundIndexs->Avail() == 0)
       
   308 			{// We've found what we were searching for. Quick complete with a leave
       
   309 			User::Leave(KErrCompletion); //Hmmmm!!!
       
   310 			}
       
   311 		}
       
   312 	}