--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/cstdlib/USTLIB/GETENV.CPP Tue Feb 02 02:01:42 2010 +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 <string.h>
+
+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; i<aCount; ++i)
+ iVars[i].ConstructL(data);
+ }
+
+HBufC16* CEnvironment::ExternalizeLC(TUint& aCount, wchar_t** envp)
+ {
+ if (envp==0)
+ return ExternalizeLC(aCount); // get current environment
+ // Externalize supplied environment
+ TInt length=0;
+ wchar_t** ep=envp;
+ for (ep=envp; *ep; ++ep)
+ length+=wcslen(*ep)+1;
+ HBufC16* retBuf = HBufC16::NewLC(length);
+ TInt nvars=0;
+ TPtr16 hbuf16=retBuf->Des();
+ 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; i<iCount; ++i)
+ length+=iVars[i].Length();
+ HBufC16* retBuf = HBufC16::NewLC(length);
+ TInt nvars=0;
+ TPtr16 hbuf16=retBuf->Des();
+ for (i=0; i<iCount; i++)
+ nvars+=iVars[i].Externalize(hbuf16);
+ aCount=nvars;
+ return retBuf;
+ }
+
+// The interface used to support the STDLIB routines
+
+wchar_t * CEnvironment::getenv(const wchar_t* aName) const
+ {
+ TPtrC16 name((TText16*)aName);
+ for (TUint i=0; i<iCount; ++i)
+ {
+ HBufC16* value=iVars[i].Match(name);
+ if (value)
+ {
+ const wchar_t* vptr = (const wchar_t*)(value->Ptr());
+ 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; i<iCount; ++i,++ep)
+ {
+ if (ep->NotEmpty())
+ {
+ 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<iCount; ++i)
+ {
+ const TDesC16* value=iVars[i].Match(name);
+ if (value)
+ {
+ iVars[i].Release();
+ return;
+ }
+ }
+ }
+