diff -r 000000000000 -r bde4ae8d615e os/ossrv/genericopenlibs/cstdlib/USTLIB/GETENV.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/genericopenlibs/cstdlib/USTLIB/GETENV.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,251 @@ +// Copyright (c) 1998-2009 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: +// Abstraction for "an environment" holding pairs of C strings (name, value) +// +// + +#include "ENVIRON.H" +#include "LPOSIX.H" +#include + +TPtrC16 TEnvVar::ValuePtr(const wchar_t* aValue) +// +// Turn a zero-terminated string into a descriptor which contains the terminator +// + { + TText16* value = (TText16*)aValue; + return TPtrC16(value, User::StringLength(value)+1); + } + +void TEnvVar::ConstructL(const TDesC16& aName, const wchar_t* aValue) + { + TPtrC16 valueZ = ValuePtr(aValue); + HBufC16* valueCopy = valueZ.AllocLC(); + iName = aName.AllocL(); + iValue = valueCopy; + CleanupStack::Pop(); + } + +void TEnvVar::Release() + { + delete iName; + iName=0; + delete iValue; + iValue=0; + } + +TInt TEnvVar::SetValue(const wchar_t* aValue) +// +// Change the value - if this returns an error then the original value is still intact +// + { + TPtrC16 valueZ = ValuePtr(aValue); + HBufC16* valueCopy=valueZ.Alloc(); + if (valueCopy==0) + return KErrNoMemory; + delete iValue; + iValue = valueCopy; + return KErrNone; + } + + +HBufC16* TEnvVar::Match(const TDesC16& aName) +// +// return value if the name matches +// + { + if (iName!=0 && iName->Compare(aName)==0) + return iValue; + return 0; + } + +TUint TEnvVar::Length() const +// +// How much space do we need to externalize this pair? +// The format is name followed by '\0' followed by value followed by '\0' +// + { + if (iName==0) + return 0; + return iName->Length()+iValue->Length()+2; + } + +TInt TEnvVar::Externalize(const wchar_t* aPair, TDes16& aBuffer) +// +// static function to externalize a "name=value" definition +// + { + const wchar_t* cp=aPair; + for (cp=aPair; *cp; ++cp) + { + if (*cp==L'=') + break; + } + if (*cp!=L'=') + return 0; // malformed + + TPtrC16 name((TText16*)aPair,cp-aPair); + TPtrC16 value((TText16*)(cp+1)); + aBuffer.Append(name); + aBuffer.Append(TChar(0)); + aBuffer.Append(value); + aBuffer.Append(TChar(0)); + return 1; + } + +TInt TEnvVar::Externalize(TDes16& aBuffer) + { + if (iName==0) + return 0; + aBuffer.Append(*iName); + aBuffer.Append(TChar(0)); + aBuffer.Append(*iValue); + aBuffer.Append(TChar(0)); + return 1; + } + +void TEnvVar::ConstructL(const TText16*& aPtr) + { + TPtrC16 name(aPtr); + aPtr+=name.Length()+1; + ConstructL(name,(const wchar_t*)aPtr); + aPtr+=iValue->Length()+1; + } + +CEnvironment::~CEnvironment() + { + while (iCount>0) + { + --iCount; + iVars[iCount].Release(); + } + User::Free(iVars); + } + + +void CEnvironment::ConstructL(TUint aCount, TDes16& aBuffer) +// +// Set up the environment from a descriptor. If this leaves then +// the CEnvironment destructor will be able to clean up properly. +// + { + // always allocate at least one slot - makes life easier elsewhere + TInt bytes = (aCount+1)*sizeof(TEnvVar); + iVars=(TEnvVar*) User::AllocL(bytes); + Mem::FillZ(iVars,bytes); + iCount=aCount+1; + + const TText16* data=aBuffer.Ptr(); + for (TUint i=0; iDes(); + for (ep=envp; *ep; ++ep) + nvars+=TEnvVar::Externalize(*ep, hbuf16); + aCount=nvars; + return retBuf; + } + +HBufC16* CEnvironment::ExternalizeLC(TUint& aCount) + { + TInt length=0; + TUint i=0; + for (i=0; iDes(); + for (i=0; iPtr()); + return CONST_CAST(wchar_t*,vptr); // I hope nobody modifies this data... + } + } + return 0; + } + +int CEnvironment::setenv(const wchar_t* aName, const wchar_t* aValue, int aReplace, int& anErrno) + { + TPtrC16 name((TText16*)aName); + TUint freeSlot=iCount; + TEnvVar* ep=iVars; + for (TUint i=0; iNotEmpty()) + { + const TDesC16* existing=ep->Match(name); + if (existing) + { + TInt err=KErrNone; + if (aReplace) + ep->SetValue(aValue); + return MapError(err,anErrno); + } + } + else + freeSlot=i; + } + if (freeSlot==iCount) + { + // no free slots, time to grow the array + ep=(TEnvVar*)User::ReAlloc(iVars,(iCount+1)*sizeof(TEnvVar)); + if (ep==0) + return KErrNoMemory; + iVars=ep; + ++iCount; + } + TRAPD(ret,iVars[freeSlot].ConstructL(name,aValue)); + return MapError(ret,anErrno); + } + +void CEnvironment::unsetenv(const wchar_t* aName) + { + TPtrC16 name((TText16*)aName); + for (TUint i=0; i