/**
This method should only be used by CImapAtomParser.
During parsing, a ReAllocL() may be required on the heap buffer that this atom and its 
descendants' string data descriptor points at.
This happens when the heap buffer needs to be expanded.
If this causes the heap buffer's address to change, then this atom and its descendants' 
pointer descriptors need updating.
@param The address of the new heap buffer
@param The address of the data within the heap buffer before the ReAllocL took place.
*/
void CImapAtom::FixupL(const HBufC8 *aNewBuffer, const TText8 *aOldBuffer)
	{
   // Fixup descriptor pointers
	CArrayFixFlat<CImapAtom*>* atomStack = new (ELeave) CArrayFixFlat<CImapAtom*>(10);
	CleanupStack::PushL(atomStack);

	atomStack->AppendL(this);
	CImapAtom* currentAtom;
	while (atomStack->Count() != 0)
   		{
		// Pop the top atom off of the stack
		currentAtom = (*atomStack)[atomStack->Count() - 1];
 		atomStack->ResizeL(atomStack->Count() - 1);
 
		// Fix up the current atom
		if (currentAtom->iAtom.Length()>0)
			{
			// Find offset from start of old buffer
			TInt start=(currentAtom->iAtom.Ptr()-aOldBuffer);

 			// Make new descriptor & assign it
			TPtrC8 bufptr(aNewBuffer->Ptr()+start,currentAtom->iAtom.Length());
			currentAtom->iAtom.Set(bufptr); // Note that we are setting the real iAtom not the copy returned by Atom()
			}
 
		// Add the first sibling to the stack,
		// subsequent siblings are added when this sibling is visited
		CImapAtom* siblingAtom = currentAtom->Next();
		if (siblingAtom)
			{
			atomStack->AppendL(siblingAtom);
			}
   
		// Add child to the stack
		CImapAtom* childAtom = currentAtom->Child();
		if (childAtom)
			{
			atomStack->AppendL(childAtom);
			}			
   		}
   
	CleanupStack::PopAndDestroy(atomStack);
   	}
示例#2
0
CArrayFixFlat<struct sadb_alg> *CIpsecCryptoManager::SupportedAlgorithms
	(TInt &aNumAuth, TInt &aNumEncrypt)
	/**
	* Ask the supported algorithms of a library.
	*
	* This function has a very specialized use: return supported
	* algorithms, when a PFKEY reply to the REGISTER message is generated
	* (CProtocolKey::ExecRegister). The format of the return value is tailored
	* for that purpose.
	*
	* Return a dynamically alloated (heap) array of 'sadb_alg'
	* descriptions. The first aNumAuth descriptors are authentication
	* algorithms, and the tail aNumEncrypt are encryption
	* algorithms.
	*
	* @retval aNumAuth Count of authentication algorithms
	* @retval aNumEncrypt Count of cipher algorithms
	* return Algorithm descriptions
	*
	* The return is guaranteed to be non-NULL, if aNumAuth + aNumEncrypt > 0. 
	*/
	{
	CArrayFixFlat<struct sadb_alg> *algs;
	TInt n;

	aNumAuth = 0;
	aNumEncrypt = 0;

	if (iAlgorithmList == NULL ||
		iLibraryList == NULL ||
		(n = iAlgorithmList->Count()) == 0)
		return NULL;		// No algorithms supported!
	//
	// Allocate all the space that is needed
	//
	// Sets 'aNumEncrypt' in case the heap allocations
	// fail (a NULL return with non-zero count is used
	// to indicate Memory Allocation error).
	aNumEncrypt = n;
	algs = new CArrayFixFlat<struct sadb_alg>(n);
	if (!algs)
		return NULL;
	TRAPD(left, algs->ResizeL(n));
	if (left)
		{
		delete algs;
		return NULL;
		}
	aNumEncrypt = 0;
	//
	// -- All requred heap space has now been allocated --
	// (The space is contigous in memory)
	struct sadb_alg *auth = algs->Back(0);
	struct sadb_alg *encrypt = algs->End(0);

	for (TInt i = 0; i < n; ++i)
		{
		struct sadb_alg *alg;
		TAlgorithmMap &p = iAlgorithmList->At(i);
		if (p.iAlgorithm.Length() == 0 && p.iClass == EAlgorithmClass_Cipher )
			{
			// The NULL encryption is indicated by empty string in the
			// algorithm name. NULL encryption is supported, if the
			// mapping has such entry configured...
			alg = encrypt - ++aNumEncrypt;
			alg->sadb_alg_id = (TUint8)p.iId;
			alg->sadb_alg_ivlen = 0;
			alg->sadb_alg_minbits = 0;
			alg->sadb_alg_maxbits = 0;
			alg->sadb_alg_reserved = 0;
			continue;
			}
		TLibraryPtr *lib;
		TInt j = iLibraryList->Lookup(p, &lib);
		if (lib != NULL)
			{
			// A matching library instance and algorithm
			// located, fill in the algorithm description.
			if (p.iClass == EAlgorithmClass_Digest)
				{
				alg = auth + aNumAuth++;
				alg->sadb_alg_ivlen = 0;
				}
			else if (p.iClass == EAlgorithmClass_Cipher)
				{
				alg = encrypt - ++aNumEncrypt;
				alg->sadb_alg_ivlen = (TUint8)lib->iAlgs[j].iVector;
				}
#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
			else if (p.iClass == EAlgorithmClass_Mac )	
				{	
				alg = auth + aNumAuth++;
				alg->sadb_alg_ivlen = 0;
				}
#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
			else 
				continue;	// Some unknown algorithm class, that
							// cannot be used by this implementation.
			alg->sadb_alg_id = (TUint8)p.iId;
			alg->sadb_alg_minbits = (TUint16)lib->iAlgs[j].iMinBits;
			alg->sadb_alg_maxbits = (TUint16)lib->iAlgs[j].iMaxBits;
			alg->sadb_alg_reserved = 0;
			}
		}
	return algs;
	}