imagingandcamerafws/imagingfws/ImageDisplay/src/Resolver/ImageDisplayResolvrUtils.cpp
branchRCL_3
changeset 50 948c7f65f6d4
parent 0 40261b775718
equal deleted inserted replaced
49:735348f59235 50:948c7f65f6d4
       
     1 /*
       
     2 * Copyright (c) 2004-2005 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 /**    @file
       
    19    @internalComponent */
       
    20 
       
    21 #include "ImageDisplayResolvrUtils.h"
       
    22 
       
    23 //
       
    24 // COpaqueDataParse
       
    25 //    Class for reading and processing opaque data from the ECOM resource file
       
    26 //    We store this as follows:
       
    27 //		Version (1 byte)
       
    28 // 		flags (2 bytes)
       
    29 //		Main Uid (4 bytes)
       
    30 //		Sub Uid (4 bytes)
       
    31 //		Number extensions (1 byte)
       
    32 //		{ ".XXX" \r } (x number extensions)
       
    33 //		Number mime types (1 byte)
       
    34 //		[ "mimetype" \r ] (for each mimetype)
       
    35 //
       
    36 
       
    37 // Note to avoid overhead, we only read the extensions and mime types on demand
       
    38 // Until EnsureExtnsReadL() is called, ExtnsCount() and Extn is invalid. Similarly
       
    39 // for mime types.
       
    40 
       
    41 COpaqueDataParse* COpaqueDataParse::NewL(const TDesC8& aOpaqueData)
       
    42 	{
       
    43 	COpaqueDataParse* result = COpaqueDataParse::NewLC(aOpaqueData);
       
    44 	CleanupStack::Pop(result);
       
    45 	return result;
       
    46 	}
       
    47 
       
    48 COpaqueDataParse* COpaqueDataParse::NewLC(const TDesC8& aOpaqueData)
       
    49 	{
       
    50 	COpaqueDataParse* result = new (ELeave) COpaqueDataParse(aOpaqueData);
       
    51 	CleanupStack::PushL(result);
       
    52 	result->ConstructL();
       
    53 	return result;
       
    54 	}
       
    55 
       
    56 COpaqueDataParse::COpaqueDataParse(const TDesC8& aOpaqueData):
       
    57 	iOpaqueData(aOpaqueData)
       
    58 	{
       
    59 	}
       
    60 
       
    61 void COpaqueDataParse::ConstructL()
       
    62 	{
       
    63 	ReadVersion();
       
    64 	if (iVersion < KIclPluginFrameworkVersionOne || 
       
    65 		iVersion > KIclPluginFrameworkVersionMax)
       
    66 		User::Leave(KErrNotSupported);
       
    67 	ReadFlags();
       
    68 	ReadUids();
       
    69 	}
       
    70 
       
    71 COpaqueDataParse::~COpaqueDataParse()
       
    72 	{
       
    73 	iArray.Close();
       
    74 	}
       
    75 
       
    76 // Extract the Version number 
       
    77 void COpaqueDataParse::ReadVersion()
       
    78 	{
       
    79 	ASSERT(iState<=EVersionProcessed); // should only call this on construction
       
    80 	ASSERT(iOpaqueData.Length() >= KIndexForVersion + 1);
       
    81 	//The version is one byte
       
    82 	iVersion = iOpaqueData[KIndexForVersion];
       
    83 	iState = EVersionProcessed;
       
    84 	}
       
    85 
       
    86 
       
    87 // Extract the (optional) flags
       
    88 void COpaqueDataParse::ReadFlags()
       
    89 	{
       
    90 	ASSERT(iState<EFlagsProcessed);
       
    91 
       
    92 	switch(iVersion)
       
    93 		{
       
    94 		case KIclPluginFrameworkVersionOne:
       
    95 			ASSERT(iOpaqueData.Length() >= KIndexForFlags + 2); // opaque data not valid otherwise
       
    96 			iFlags = (iOpaqueData[KIndexForFlags+0] << 8) | (iOpaqueData[KIndexForFlags+1]);
       
    97 			iLenOfFlags = 2;
       
    98 			break;
       
    99 		}
       
   100 
       
   101 	iStartOfUids = 1 + iLenOfFlags;
       
   102 	iStartOfNumberOfExtns = 1 + iLenOfFlags + 8;
       
   103 	iState = EFlagsProcessed;
       
   104 	}
       
   105 
       
   106 // Extract the two Uids 
       
   107 void COpaqueDataParse::ReadUids()
       
   108 	{
       
   109 	ASSERT(iState<EUidsProcessed);
       
   110 	ASSERT(iOpaqueData.Length() >= iStartOfUids + 4); // opaque data not valid otherwise
       
   111 	// A given OpaqueData should either contain one Uid, in 4 bytes,
       
   112 	// highest to lowest, with an implied second Uid set to KNullUid,
       
   113 	// or two consecutive Uids, in 4 bytes each - 8 in all - main type followed by sub-type.
       
   114 	// The 8 bytes may be followed, for basic types, by info on the file extensions
       
   115 	// and MIME typesassociated with this plugin but this info is ignored here.
       
   116 	iImageTypeUid.iUid = (iOpaqueData[iStartOfUids] << 24) | (iOpaqueData[iStartOfUids+1] << 16) | (iOpaqueData[iStartOfUids+2] << 8) | (iOpaqueData[iStartOfUids+3]);
       
   117 	if (iOpaqueData.Length() == iStartOfUids + 4)
       
   118 		{
       
   119 		iImageSubTypeUid = KNullUid;
       
   120 		}
       
   121 	else
       
   122 		{
       
   123 		ASSERT(iOpaqueData.Length() >= iStartOfUids + 8);
       
   124 		iImageSubTypeUid.iUid = (iOpaqueData[iStartOfUids+4] << 24) | (iOpaqueData[iStartOfUids+5] << 16) + (iOpaqueData[iStartOfUids+6] << 8) + (iOpaqueData[iStartOfUids+7]);
       
   125 		}
       
   126 	iState = EUidsProcessed;
       
   127 	}
       
   128 
       
   129 // read in the Extns from the opaque data
       
   130 void COpaqueDataParse::EnsureExtnsReadL()
       
   131 	{
       
   132 	// if we've already read in the extensions, is a NOP
       
   133 	if (iState>=EExtnsProcessed)
       
   134 		{
       
   135 		return;
       
   136 		}
       
   137 
       
   138 	ASSERT(iArray.Count()==0); // assume nothing in there at the moment
       
   139 
       
   140 	iExtnCount = iOpaqueData[iStartOfNumberOfExtns];
       
   141 	TInt pos = iStartOfNumberOfExtns+1; // start just after the extn count byte	
       
   142 
       
   143 	for (TInt index=0; index<iExtnCount; index++)
       
   144 		{
       
   145 		TPtrC8 restOfData = iOpaqueData.Mid(pos);
       
   146 		TInt endPos = restOfData.Locate(TChar('\r')); // \r is used to terminate each suffix
       
   147 		ASSERT(endPos != KErrNotFound); // if we have -1, would not have found the CR
       
   148 		TPtrC8 extn = restOfData.Left(endPos);
       
   149 		User::LeaveIfError(iArray.Append(extn));
       
   150 		pos += endPos + 1; // skip over the CR
       
   151 		}
       
   152 	iStartOfMimeTypes = pos;
       
   153 	iState = EExtnsProcessed;
       
   154 	ASSERT(iArray.Count()==iExtnCount);
       
   155 	}
       
   156 
       
   157 void COpaqueDataParse::EnsureMIMETypesReadL()
       
   158 	{
       
   159 	// if we've already read in the mime types, is a NOP
       
   160 	if (iState>=EMIMETypesProcessed)
       
   161 		return;
       
   162 
       
   163 	EnsureExtnsReadL();
       
   164 	ASSERT(iState==EExtnsProcessed);
       
   165 
       
   166 	TInt pos = iStartOfMimeTypes;
       
   167 	const TInt numMimeTypes = iOpaqueData[pos];
       
   168 	pos += 1;
       
   169 
       
   170 	for (TInt index=0; index<numMimeTypes; index++)
       
   171 		{
       
   172 		TPtrC8 restOfData = iOpaqueData.Mid(pos);
       
   173 		TInt endPos = restOfData.Locate(TChar('\r')); // \r is used to terminate each suffix
       
   174 		ASSERT(endPos != KErrNotFound); // if we have -1, would not have found the CR
       
   175 		TPtrC8 mimeType = restOfData.Left(endPos);
       
   176 		User::LeaveIfError(iArray.Append(mimeType));
       
   177 		pos += endPos + 1; // skip over the CR
       
   178 		}
       
   179 	iState = EMIMETypesProcessed;
       
   180 	ASSERT(iArray.Count()==iExtnCount+numMimeTypes);
       
   181 	}
       
   182 
       
   183 TBool COpaqueDataParse::CompareMIMETypes(const TDesC8& aMimeType1, const TDesC8& aMimeType2)
       
   184 	{
       
   185 	if (aMimeType1.Length() != aMimeType2.Length())
       
   186 		{
       
   187 		return EFalse;
       
   188 		}
       
   189 	return aMimeType1.CompareF(aMimeType2)==0; // true if exactly the same, if we ignore the case
       
   190 	}
       
   191 
       
   192 TBool COpaqueDataParse::CompareFileSuffixL(const TDesC& aFileSuffix1, const TDesC8& aFileSuffix2)
       
   193 	{
       
   194 	//First do a quick compare
       
   195 	if (aFileSuffix1.Length() != aFileSuffix2.Length())
       
   196 		{
       
   197 		return EFalse;
       
   198 		}
       
   199 
       
   200 	//Change aFileSuffix2 from TDesC8 to TDesC
       
   201 	HBufC* fileSuffix = HBufC::NewL(aFileSuffix2.Length()); //Not on CleanupStack since nothing can leave
       
   202 	TPtr fileSuffixPtr(fileSuffix->Des());
       
   203 	fileSuffixPtr.Copy(aFileSuffix2);
       
   204 
       
   205 	const TBool result = aFileSuffix1.CompareF(*fileSuffix)==0; // true if exactly the same, if we ignore the case
       
   206 	delete fileSuffix;
       
   207 
       
   208 	return result;
       
   209 	}
       
   210 
       
   211 /*
       
   212  * 
       
   213  * Searches for a match of aPluginString in aClientString. Match returns ETrue
       
   214  * if aPluginString is found within aImplementationType according to the
       
   215  * following rules:
       
   216  * 1) All bytes in aClientString are exact but instances of '?' (0x3F) in
       
   217  *    aPluginString are treated as wildcards - matching any byte value at that
       
   218  *    position in aClientString.
       
   219  * 2) If aClientString is longer than aPluginString, ignore any excess bytes.
       
   220  * 3) aClientString is treated as a single descriptor - the '||' delimiters
       
   221  *    are not recognised.
       
   222  * 4) ETrue is returned if aPluginString matches the start of aClientString
       
   223  *    exactly, subject to wildcards.
       
   224  * 5) aBytesMatched will be filled in with the number of non-wildcard bytes in
       
   225  *    aPluginString. This is used to rank matches.
       
   226  *
       
   227  * @param     "const TDesC8& aClientString"
       
   228  *            The string from the client to search for a match
       
   229  * @param     "const TDesC8& aPluginString"
       
   230  *            The data to search for from the plugin
       
   231  * @param     "TInt& aBytesMatched"
       
   232  *            The number of non-wildcard bytes matched, or "1" if the match pattern contains only "?"
       
   233 				i.e. should match any data
       
   234  * @return    "TBool"
       
   235  *            ETrue if a match was found, EFalse otherwise
       
   236  */
       
   237 TBool CImageDisplayResolverUtils::Match(const TDesC8& aClientString, const TDesC8& aPluginString, TInt& aBytesMatched)
       
   238 	{
       
   239 	TInt pluginStringLength = aPluginString.Length();
       
   240 	aBytesMatched = 0;
       
   241 	while (pluginStringLength>1 && (aPluginString[pluginStringLength - 1] == '?'))
       
   242 		{ // Clip extraneous '?' wildcards off the end of the plugin match string
       
   243 		pluginStringLength--;
       
   244 		}
       
   245 	if (pluginStringLength == 0)
       
   246 		{ // Plugin has no match string
       
   247 		return EFalse;
       
   248 		}
       
   249 	if (aClientString.Length() < pluginStringLength)
       
   250 		{ // Client string too short - can't match
       
   251 		return EFalse;
       
   252 		}
       
   253 	// Now let's run along the string
       
   254 	for (TInt index = 0; index < pluginStringLength; index++)
       
   255 		{
       
   256 		const TUint8 pluginChar = aPluginString[index];
       
   257 		if (pluginChar=='?') // just ignore a wildchar
       
   258 			{
       
   259 			continue;
       
   260 			}
       
   261 		if (aClientString[index] != pluginChar)
       
   262 			{
       
   263 			return EFalse;
       
   264 			}
       
   265 		// else we've matched expected byte, so keep going
       
   266 		aBytesMatched += 1;
       
   267 		}
       
   268 	aBytesMatched += (aPluginString[0]=='?' && pluginStringLength==1);
       
   269 	ASSERT(aBytesMatched>0); // if we get this far, must have matched something - since we no match string can't be empty
       
   270 	return ETrue;
       
   271 	}
       
   272