applicationinterworkingfw/ServiceHandler/src/AiwResolver.cpp
author William Roberts <williamr@symbian.org>
Wed, 10 Nov 2010 12:08:34 +0000
branchRCL_3
changeset 76 5c9f0ba5102a
parent 0 2f259fa3e83a
permissions -rw-r--r--
Improve debug tracing of AknGlobalNote::StartL - Bug 2673

/*
* Copyright (c) 2003-2005 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:     Implementation of Custom ECom Resolver for AIW.
*
*/




#include "AiwResolver.h"

const TInt KMaxDataItemSize = 150;
_LIT8(KContentTag, "<CONTENT>");
_LIT8(KOpaqueTag, "<OPAQUE>");


CAiwResolver* CAiwResolver::NewL(MPublicRegistry& aRegistry)
    {
    return new (ELeave) CAiwResolver(aRegistry);
    }


CAiwResolver::CAiwResolver(MPublicRegistry& aRegistry) : CResolver(aRegistry)
    {
    // Nothing to do.
    }


CAiwResolver::~CAiwResolver()
    {
    if (iImplementationInfoArray)
        {
        iImplementationInfoArray->Reset();  
        delete iImplementationInfoArray;
        }
    }



TUid CAiwResolver::IdentifyImplementationL(TUid aInterfaceUid, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    RImplInfoArray& implementationsInfo = iRegistry.ListImplementationsL(aInterfaceUid);
    TUid found = KNullUid;

    if(implementationsInfo.Count())
        {
        found = Resolve(implementationsInfo, aAdditionalParameters);
        }

    return found;
    }



RImplInfoArray* CAiwResolver::ListAllL(TUid aInterfaceUid, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    // Use the member var to create the array so that we get proper cleanup behaviour
    delete iImplementationInfoArray;
    iImplementationInfoArray = NULL;
    iImplementationInfoArray = new (ELeave) RImplInfoArray;
    RImplInfoArray* retList = iImplementationInfoArray;

    RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid);

    const TBool useWildcards = aAdditionalParameters.IsWildcardMatch();
    TBuf8<KMaxDataItemSize> content;
    TBuf8<KMaxDataItemSize> opaque;

    ParseInput(aAdditionalParameters.DataType(), content, opaque);
    const TInt numImps = fullList.Count();

    for (TInt index = 0; index < numImps; ++index)
        {
        if (Match(fullList[index]->DataType(), content, useWildcards) &&
            MatchServiceCmd(fullList[index]->OpaqueData(), opaque))
            {
            User::LeaveIfError(retList->Append(fullList[index]));
            }
        }

    // Reset the member variable because we are passing ownership back
    iImplementationInfoArray = NULL;

    return retList;
    }



void CAiwResolver::ParseInput(const TDesC8& aParam, TDes8& aContent, TDes8& aOpaque) const
    {
    TInt cind = aParam.Find(KContentTag);
    TInt oind = aParam.Find(KOpaqueTag);
        
    if (cind != KErrNotFound)
        {
        if (oind != KErrNotFound)
            {
            aContent.Copy(aParam.Mid(cind + (&KContentTag)->Length(), 
                                     oind - (cind + (&KContentTag)->Length())));
            }
        else
            {
            aContent.Copy(aParam.Mid(cind + (&KContentTag)->Length()));
            }
        }

    if (oind != KErrNotFound)
        {
        aOpaque.Copy(aParam.Mid(oind + (&KOpaqueTag)->Length()));
        }
    }



TUid CAiwResolver::Resolve(const RImplInfoArray& aImplementationsInfo, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    // Loop through the implementations matching on type
    const TInt count = aImplementationsInfo.Count();

    for (TInt index = 0; index < count; ++index)
        {
        const CImplementationInformation& impData = *aImplementationsInfo[index];
        // As soon as we get a match on the datatype then return uid of the
        // implementation found.
        if (Match(impData.DataType(),                   // The Datatype of this implementation
            aAdditionalParameters.DataType(),           // The type we are trying to find
            aAdditionalParameters.IsWildcardMatch()))   // If wildcards should be used
            {
            return impData.ImplementationUid();
            }
        }

    return KNullUid;
    }


TBool CAiwResolver::Match(const TDesC8& aImplementationType, const TDesC8& aMatchType, 
    TBool aUseWildcards) const
    {
    TInt matchPos = KErrNotFound;

    _LIT8(dataSeparator, "||");
    const TInt separatorLength = dataSeparator().Length();

    // Look for the section separator marker '||'
    TInt separatorPos = aImplementationType.Find(dataSeparator);

    if (separatorPos == KErrNotFound)
        {
        // Match against the whole string
        if (aUseWildcards)
            {
            matchPos = aImplementationType.Match(aMatchType);
            }
        else
            {
            if (aImplementationType.Compare(aMatchType) == 0)
                {
                matchPos = KErrNone;    
                }
            }
        }
    else
        {
        // Find the first section, up to the separator
        TPtrC8 dataSection = aImplementationType.Left(separatorPos);
        TPtrC8 remainingData = aImplementationType.Mid(separatorPos + separatorLength);

        // Match against each section in turn
        while (separatorPos != KErrNotFound)
            {
            // Search this section
            if (aUseWildcards)
                {          
                matchPos = dataSection.Match(aMatchType);
                }
            else
                {
                if (dataSection.Compare(aMatchType) == 0)
                    {
                    matchPos = KErrNone;
                    }
                }

            // If we found it then no need to continue, so return
            if (matchPos != KErrNotFound)
                {
                return ETrue;
                }

            // Move on to the next section
            separatorPos = remainingData.Find(dataSeparator);

            if (separatorPos != KErrNotFound)
                {
                dataSection.Set(remainingData.Left(separatorPos));
                remainingData.Set(remainingData.Mid(separatorPos + separatorLength));
                }
            else
                {
                dataSection.Set(remainingData);
                }   
            }

        // Check the final part
        if (aUseWildcards)
            {
            matchPos = dataSection.Match(aMatchType);
            }
        else
            {
            if (dataSection.Compare(aMatchType) == 0)
                {
                matchPos = KErrNone;
                }
            }
        }

    return matchPos != KErrNotFound;
    }




TBool CAiwResolver::MatchServiceCmd(const TDesC8& aOpaqueData, const TDesC8& aServiceCmd) const
    {
    _LIT8(dataSeparator, "||");
    const TInt separatorLength = dataSeparator().Length();

    // Look for the section separator marker '||'
    TInt separatorPos = aOpaqueData.Find(dataSeparator);

    if (separatorPos == KErrNotFound)
        {
         if (aServiceCmd.Compare(aOpaqueData) == 0)
            {
            return ETrue;   
            }
        }
    else
        {
         // Find the first section, up to the separator
        TPtrC8 dataSection = aOpaqueData.Left(separatorPos);
        TPtrC8 remainingData = aOpaqueData.Mid(separatorPos + separatorLength);

        // Match against each section in turn
        while (separatorPos != KErrNotFound)
            {
            if (dataSection.Compare(aServiceCmd) == 0)
                {
                return ETrue;
                }

            // Move on to the next section
            separatorPos = remainingData.Find(dataSeparator);

            if (separatorPos != KErrNotFound)
                {
                dataSection.Set(remainingData.Left(separatorPos));
                remainingData.Set(remainingData.Mid(separatorPos + separatorLength));
                }
            else
                {
                dataSection.Set(remainingData);
                }   
            }

        if (dataSection.Compare(aServiceCmd) == 0)
            {
            return ETrue;   
            }       
        }

    return EFalse;
    }


// Map the interface UIDs
const TImplementationProxy ImplementationTable[] =
    {
    IMPLEMENTATION_PROXY_ENTRY(KAiwResolverImplUidValue, CAiwResolver::NewL)
    };

// Exported proxy for instantiation method resolution
// ---------------------------------------------------------
//
//
// ---------------------------------------------------------
//
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
    {
    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
    return ImplementationTable;
    }

// End of file