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 +