os/ossrv/genericopenlibs/cstdlib/USTLIB/GETENV.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/USTLIB/GETENV.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,251 @@
     1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Abstraction for "an environment" holding pairs of C strings (name, value)
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "ENVIRON.H"
    1.22 +#include "LPOSIX.H"
    1.23 +#include <string.h>
    1.24 +
    1.25 +TPtrC16 TEnvVar::ValuePtr(const wchar_t* aValue)
    1.26 +//
    1.27 +// Turn a zero-terminated string into a descriptor which contains the terminator
    1.28 +//
    1.29 +	{
    1.30 +	TText16* value = (TText16*)aValue;
    1.31 +	return TPtrC16(value, User::StringLength(value)+1);
    1.32 +	}
    1.33 +
    1.34 +void TEnvVar::ConstructL(const TDesC16& aName, const wchar_t* aValue)
    1.35 +	{
    1.36 +	TPtrC16 valueZ = ValuePtr(aValue);
    1.37 +	HBufC16* valueCopy = valueZ.AllocLC();
    1.38 +	iName = aName.AllocL();
    1.39 +	iValue = valueCopy;
    1.40 +	CleanupStack::Pop();
    1.41 +	}
    1.42 +
    1.43 +void TEnvVar::Release()
    1.44 +	{
    1.45 +	delete iName;
    1.46 +	iName=0;
    1.47 +	delete iValue;
    1.48 +	iValue=0;
    1.49 +	}
    1.50 +
    1.51 +TInt TEnvVar::SetValue(const wchar_t* aValue)
    1.52 +//
    1.53 +// Change the value - if this returns an error then the original value is still intact
    1.54 +//
    1.55 +	{
    1.56 +	TPtrC16 valueZ = ValuePtr(aValue);
    1.57 +	HBufC16* valueCopy=valueZ.Alloc();
    1.58 +	if (valueCopy==0)
    1.59 +		return KErrNoMemory;
    1.60 +	delete iValue;
    1.61 +	iValue = valueCopy;
    1.62 +	return KErrNone;
    1.63 +	}
    1.64 +
    1.65 +
    1.66 +HBufC16* TEnvVar::Match(const TDesC16& aName)
    1.67 +//
    1.68 +// return value if the name matches
    1.69 +//
    1.70 +	{
    1.71 +	if (iName!=0 && iName->Compare(aName)==0)
    1.72 +		return iValue;
    1.73 +	return 0;
    1.74 +	}
    1.75 +
    1.76 +TUint TEnvVar::Length() const
    1.77 +//
    1.78 +// How much space do we need to externalize this pair?
    1.79 +// The format is name followed by '\0' followed by value followed by '\0'
    1.80 +//
    1.81 +	{
    1.82 +	if (iName==0) 
    1.83 +		return 0;
    1.84 +	return iName->Length()+iValue->Length()+2;
    1.85 +	}
    1.86 +
    1.87 +TInt TEnvVar::Externalize(const wchar_t* aPair, TDes16& aBuffer)
    1.88 +//
    1.89 +// static function to externalize a "name=value" definition
    1.90 +//
    1.91 +	{
    1.92 +	const wchar_t* cp=aPair;
    1.93 +	for (cp=aPair; *cp; ++cp)
    1.94 +		{
    1.95 +		if (*cp==L'=')
    1.96 +			break;
    1.97 +		}
    1.98 +	if (*cp!=L'=')
    1.99 +		return 0;	// malformed
   1.100 +
   1.101 +	TPtrC16 name((TText16*)aPair,cp-aPair);
   1.102 +	TPtrC16 value((TText16*)(cp+1));
   1.103 +	aBuffer.Append(name);
   1.104 +	aBuffer.Append(TChar(0));
   1.105 +	aBuffer.Append(value);
   1.106 +	aBuffer.Append(TChar(0));
   1.107 +	return 1;
   1.108 +	}
   1.109 +
   1.110 +TInt TEnvVar::Externalize(TDes16& aBuffer)
   1.111 +	{
   1.112 +	if (iName==0) 
   1.113 +		return 0;
   1.114 +	aBuffer.Append(*iName);
   1.115 +	aBuffer.Append(TChar(0));
   1.116 +	aBuffer.Append(*iValue);
   1.117 +	aBuffer.Append(TChar(0));
   1.118 +	return 1;
   1.119 +	}
   1.120 +
   1.121 +void TEnvVar::ConstructL(const TText16*& aPtr)
   1.122 +	{
   1.123 +	TPtrC16 name(aPtr);
   1.124 +	aPtr+=name.Length()+1;
   1.125 +	ConstructL(name,(const wchar_t*)aPtr);
   1.126 +	aPtr+=iValue->Length()+1;
   1.127 +	}
   1.128 +
   1.129 +CEnvironment::~CEnvironment()
   1.130 +	{
   1.131 +	while (iCount>0)
   1.132 +		{
   1.133 +		--iCount;
   1.134 +		iVars[iCount].Release();
   1.135 +		}
   1.136 +	User::Free(iVars);
   1.137 +	}
   1.138 +
   1.139 +
   1.140 +void CEnvironment::ConstructL(TUint aCount, TDes16& aBuffer)
   1.141 +//
   1.142 +// Set up the environment from a descriptor. If this leaves then
   1.143 +// the CEnvironment destructor will be able to clean up properly.
   1.144 +//
   1.145 +	{
   1.146 +	// always allocate at least one slot - makes life easier elsewhere
   1.147 +	TInt bytes = (aCount+1)*sizeof(TEnvVar);
   1.148 +	iVars=(TEnvVar*) User::AllocL(bytes);
   1.149 +	Mem::FillZ(iVars,bytes);
   1.150 +	iCount=aCount+1;
   1.151 +
   1.152 +	const TText16* data=aBuffer.Ptr();
   1.153 +	for (TUint i=0; i<aCount; ++i)
   1.154 +		iVars[i].ConstructL(data);
   1.155 +	}
   1.156 +
   1.157 +HBufC16* CEnvironment::ExternalizeLC(TUint& aCount, wchar_t** envp)
   1.158 +	{
   1.159 +	if (envp==0)
   1.160 +		return ExternalizeLC(aCount);	// get current environment
   1.161 +	// Externalize supplied environment
   1.162 +	TInt length=0;
   1.163 +	wchar_t** ep=envp;
   1.164 +	for (ep=envp; *ep; ++ep)
   1.165 +		length+=wcslen(*ep)+1;
   1.166 +	HBufC16* retBuf = HBufC16::NewLC(length);
   1.167 +	TInt nvars=0;
   1.168 +	TPtr16 hbuf16=retBuf->Des();
   1.169 +	for (ep=envp; *ep; ++ep)
   1.170 +		nvars+=TEnvVar::Externalize(*ep, hbuf16);
   1.171 +	aCount=nvars;
   1.172 +	return retBuf;
   1.173 +	}
   1.174 +
   1.175 +HBufC16* CEnvironment::ExternalizeLC(TUint& aCount)
   1.176 +	{
   1.177 +	TInt length=0;
   1.178 +	TUint i=0;
   1.179 +	for (i=0; i<iCount; ++i)
   1.180 +		length+=iVars[i].Length();
   1.181 +	HBufC16* retBuf = HBufC16::NewLC(length);
   1.182 +	TInt nvars=0;
   1.183 +	TPtr16 hbuf16=retBuf->Des();
   1.184 +	for (i=0; i<iCount; i++)
   1.185 +		nvars+=iVars[i].Externalize(hbuf16);
   1.186 +	aCount=nvars;
   1.187 +	return retBuf;
   1.188 +	}
   1.189 +
   1.190 +// The interface used to support the STDLIB routines
   1.191 +
   1.192 +wchar_t * CEnvironment::getenv(const wchar_t* aName) const
   1.193 +	{
   1.194 +	TPtrC16 name((TText16*)aName);
   1.195 +	for (TUint i=0; i<iCount; ++i)
   1.196 +		{
   1.197 +		HBufC16* value=iVars[i].Match(name);
   1.198 +		if (value)
   1.199 +			{
   1.200 +			const wchar_t* vptr = (const wchar_t*)(value->Ptr());
   1.201 +			return CONST_CAST(wchar_t*,vptr);	// I hope nobody modifies this data...
   1.202 +			}
   1.203 +		}
   1.204 +	return 0;
   1.205 +	}
   1.206 +
   1.207 +int CEnvironment::setenv(const wchar_t* aName, const wchar_t* aValue, int aReplace, int& anErrno)
   1.208 +	{
   1.209 +	TPtrC16 name((TText16*)aName);
   1.210 +	TUint freeSlot=iCount;
   1.211 +	TEnvVar* ep=iVars;
   1.212 +	for (TUint i=0; i<iCount; ++i,++ep)
   1.213 +		{
   1.214 +		if (ep->NotEmpty())
   1.215 +			{
   1.216 +			const TDesC16* existing=ep->Match(name);
   1.217 +			if (existing)
   1.218 +				{
   1.219 +				TInt err=KErrNone;
   1.220 +				if (aReplace)
   1.221 +					ep->SetValue(aValue);
   1.222 +				return MapError(err,anErrno);
   1.223 +				}
   1.224 +			}
   1.225 +		else
   1.226 +			freeSlot=i;
   1.227 +		}
   1.228 +	if (freeSlot==iCount)	
   1.229 +		{
   1.230 +		// no free slots, time to grow the array
   1.231 +		ep=(TEnvVar*)User::ReAlloc(iVars,(iCount+1)*sizeof(TEnvVar));
   1.232 +		if (ep==0)
   1.233 +			return KErrNoMemory;
   1.234 +		iVars=ep;
   1.235 +		++iCount;
   1.236 +		}
   1.237 +	TRAPD(ret,iVars[freeSlot].ConstructL(name,aValue));
   1.238 +	return MapError(ret,anErrno);
   1.239 +	}
   1.240 +
   1.241 +void CEnvironment::unsetenv(const wchar_t* aName)
   1.242 +	{
   1.243 +	TPtrC16 name((TText16*)aName);
   1.244 +	for (TUint i=0; i<iCount; ++i)
   1.245 +		{
   1.246 +		const TDesC16* value=iVars[i].Match(name);
   1.247 +		if (value)
   1.248 +			{
   1.249 +			iVars[i].Release();
   1.250 +			return;
   1.251 +			}
   1.252 +		}
   1.253 +	}
   1.254 +