sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Abstraction for "an environment" holding pairs of C strings (name, value) sl@0: // sl@0: // sl@0: sl@0: #include "ENVIRON.H" sl@0: #include "LPOSIX.H" sl@0: #include sl@0: sl@0: TPtrC16 TEnvVar::ValuePtr(const wchar_t* aValue) sl@0: // sl@0: // Turn a zero-terminated string into a descriptor which contains the terminator sl@0: // sl@0: { sl@0: TText16* value = (TText16*)aValue; sl@0: return TPtrC16(value, User::StringLength(value)+1); sl@0: } sl@0: sl@0: void TEnvVar::ConstructL(const TDesC16& aName, const wchar_t* aValue) sl@0: { sl@0: TPtrC16 valueZ = ValuePtr(aValue); sl@0: HBufC16* valueCopy = valueZ.AllocLC(); sl@0: iName = aName.AllocL(); sl@0: iValue = valueCopy; sl@0: CleanupStack::Pop(); sl@0: } sl@0: sl@0: void TEnvVar::Release() sl@0: { sl@0: delete iName; sl@0: iName=0; sl@0: delete iValue; sl@0: iValue=0; sl@0: } sl@0: sl@0: TInt TEnvVar::SetValue(const wchar_t* aValue) sl@0: // sl@0: // Change the value - if this returns an error then the original value is still intact sl@0: // sl@0: { sl@0: TPtrC16 valueZ = ValuePtr(aValue); sl@0: HBufC16* valueCopy=valueZ.Alloc(); sl@0: if (valueCopy==0) sl@0: return KErrNoMemory; sl@0: delete iValue; sl@0: iValue = valueCopy; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: HBufC16* TEnvVar::Match(const TDesC16& aName) sl@0: // sl@0: // return value if the name matches sl@0: // sl@0: { sl@0: if (iName!=0 && iName->Compare(aName)==0) sl@0: return iValue; sl@0: return 0; sl@0: } sl@0: sl@0: TUint TEnvVar::Length() const sl@0: // sl@0: // How much space do we need to externalize this pair? sl@0: // The format is name followed by '\0' followed by value followed by '\0' sl@0: // sl@0: { sl@0: if (iName==0) sl@0: return 0; sl@0: return iName->Length()+iValue->Length()+2; sl@0: } sl@0: sl@0: TInt TEnvVar::Externalize(const wchar_t* aPair, TDes16& aBuffer) sl@0: // sl@0: // static function to externalize a "name=value" definition sl@0: // sl@0: { sl@0: const wchar_t* cp=aPair; sl@0: for (cp=aPair; *cp; ++cp) sl@0: { sl@0: if (*cp==L'=') sl@0: break; sl@0: } sl@0: if (*cp!=L'=') sl@0: return 0; // malformed sl@0: sl@0: TPtrC16 name((TText16*)aPair,cp-aPair); sl@0: TPtrC16 value((TText16*)(cp+1)); sl@0: aBuffer.Append(name); sl@0: aBuffer.Append(TChar(0)); sl@0: aBuffer.Append(value); sl@0: aBuffer.Append(TChar(0)); sl@0: return 1; sl@0: } sl@0: sl@0: TInt TEnvVar::Externalize(TDes16& aBuffer) sl@0: { sl@0: if (iName==0) sl@0: return 0; sl@0: aBuffer.Append(*iName); sl@0: aBuffer.Append(TChar(0)); sl@0: aBuffer.Append(*iValue); sl@0: aBuffer.Append(TChar(0)); sl@0: return 1; sl@0: } sl@0: sl@0: void TEnvVar::ConstructL(const TText16*& aPtr) sl@0: { sl@0: TPtrC16 name(aPtr); sl@0: aPtr+=name.Length()+1; sl@0: ConstructL(name,(const wchar_t*)aPtr); sl@0: aPtr+=iValue->Length()+1; sl@0: } sl@0: sl@0: CEnvironment::~CEnvironment() sl@0: { sl@0: while (iCount>0) sl@0: { sl@0: --iCount; sl@0: iVars[iCount].Release(); sl@0: } sl@0: User::Free(iVars); sl@0: } sl@0: sl@0: sl@0: void CEnvironment::ConstructL(TUint aCount, TDes16& aBuffer) sl@0: // sl@0: // Set up the environment from a descriptor. If this leaves then sl@0: // the CEnvironment destructor will be able to clean up properly. sl@0: // sl@0: { sl@0: // always allocate at least one slot - makes life easier elsewhere sl@0: TInt bytes = (aCount+1)*sizeof(TEnvVar); sl@0: iVars=(TEnvVar*) User::AllocL(bytes); sl@0: Mem::FillZ(iVars,bytes); sl@0: iCount=aCount+1; sl@0: sl@0: const TText16* data=aBuffer.Ptr(); sl@0: for (TUint i=0; iDes(); sl@0: for (ep=envp; *ep; ++ep) sl@0: nvars+=TEnvVar::Externalize(*ep, hbuf16); sl@0: aCount=nvars; sl@0: return retBuf; sl@0: } sl@0: sl@0: HBufC16* CEnvironment::ExternalizeLC(TUint& aCount) sl@0: { sl@0: TInt length=0; sl@0: TUint i=0; sl@0: for (i=0; iDes(); sl@0: for (i=0; iPtr()); sl@0: return CONST_CAST(wchar_t*,vptr); // I hope nobody modifies this data... sl@0: } sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: int CEnvironment::setenv(const wchar_t* aName, const wchar_t* aValue, int aReplace, int& anErrno) sl@0: { sl@0: TPtrC16 name((TText16*)aName); sl@0: TUint freeSlot=iCount; sl@0: TEnvVar* ep=iVars; sl@0: for (TUint i=0; iNotEmpty()) sl@0: { sl@0: const TDesC16* existing=ep->Match(name); sl@0: if (existing) sl@0: { sl@0: TInt err=KErrNone; sl@0: if (aReplace) sl@0: ep->SetValue(aValue); sl@0: return MapError(err,anErrno); sl@0: } sl@0: } sl@0: else sl@0: freeSlot=i; sl@0: } sl@0: if (freeSlot==iCount) sl@0: { sl@0: // no free slots, time to grow the array sl@0: ep=(TEnvVar*)User::ReAlloc(iVars,(iCount+1)*sizeof(TEnvVar)); sl@0: if (ep==0) sl@0: return KErrNoMemory; sl@0: iVars=ep; sl@0: ++iCount; sl@0: } sl@0: TRAPD(ret,iVars[freeSlot].ConstructL(name,aValue)); sl@0: return MapError(ret,anErrno); sl@0: } sl@0: sl@0: void CEnvironment::unsetenv(const wchar_t* aName) sl@0: { sl@0: TPtrC16 name((TText16*)aName); sl@0: for (TUint i=0; i