sl@0
|
1 |
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// Abstraction for "an environment" holding pairs of C strings (name, value)
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
#include "ENVIRON.H"
|
sl@0
|
19 |
#include "LPOSIX.H"
|
sl@0
|
20 |
#include <string.h>
|
sl@0
|
21 |
|
sl@0
|
22 |
TPtrC16 TEnvVar::ValuePtr(const wchar_t* aValue)
|
sl@0
|
23 |
//
|
sl@0
|
24 |
// Turn a zero-terminated string into a descriptor which contains the terminator
|
sl@0
|
25 |
//
|
sl@0
|
26 |
{
|
sl@0
|
27 |
TText16* value = (TText16*)aValue;
|
sl@0
|
28 |
return TPtrC16(value, User::StringLength(value)+1);
|
sl@0
|
29 |
}
|
sl@0
|
30 |
|
sl@0
|
31 |
void TEnvVar::ConstructL(const TDesC16& aName, const wchar_t* aValue)
|
sl@0
|
32 |
{
|
sl@0
|
33 |
TPtrC16 valueZ = ValuePtr(aValue);
|
sl@0
|
34 |
HBufC16* valueCopy = valueZ.AllocLC();
|
sl@0
|
35 |
iName = aName.AllocL();
|
sl@0
|
36 |
iValue = valueCopy;
|
sl@0
|
37 |
CleanupStack::Pop();
|
sl@0
|
38 |
}
|
sl@0
|
39 |
|
sl@0
|
40 |
void TEnvVar::Release()
|
sl@0
|
41 |
{
|
sl@0
|
42 |
delete iName;
|
sl@0
|
43 |
iName=0;
|
sl@0
|
44 |
delete iValue;
|
sl@0
|
45 |
iValue=0;
|
sl@0
|
46 |
}
|
sl@0
|
47 |
|
sl@0
|
48 |
TInt TEnvVar::SetValue(const wchar_t* aValue)
|
sl@0
|
49 |
//
|
sl@0
|
50 |
// Change the value - if this returns an error then the original value is still intact
|
sl@0
|
51 |
//
|
sl@0
|
52 |
{
|
sl@0
|
53 |
TPtrC16 valueZ = ValuePtr(aValue);
|
sl@0
|
54 |
HBufC16* valueCopy=valueZ.Alloc();
|
sl@0
|
55 |
if (valueCopy==0)
|
sl@0
|
56 |
return KErrNoMemory;
|
sl@0
|
57 |
delete iValue;
|
sl@0
|
58 |
iValue = valueCopy;
|
sl@0
|
59 |
return KErrNone;
|
sl@0
|
60 |
}
|
sl@0
|
61 |
|
sl@0
|
62 |
|
sl@0
|
63 |
HBufC16* TEnvVar::Match(const TDesC16& aName)
|
sl@0
|
64 |
//
|
sl@0
|
65 |
// return value if the name matches
|
sl@0
|
66 |
//
|
sl@0
|
67 |
{
|
sl@0
|
68 |
if (iName!=0 && iName->Compare(aName)==0)
|
sl@0
|
69 |
return iValue;
|
sl@0
|
70 |
return 0;
|
sl@0
|
71 |
}
|
sl@0
|
72 |
|
sl@0
|
73 |
TUint TEnvVar::Length() const
|
sl@0
|
74 |
//
|
sl@0
|
75 |
// How much space do we need to externalize this pair?
|
sl@0
|
76 |
// The format is name followed by '\0' followed by value followed by '\0'
|
sl@0
|
77 |
//
|
sl@0
|
78 |
{
|
sl@0
|
79 |
if (iName==0)
|
sl@0
|
80 |
return 0;
|
sl@0
|
81 |
return iName->Length()+iValue->Length()+2;
|
sl@0
|
82 |
}
|
sl@0
|
83 |
|
sl@0
|
84 |
TInt TEnvVar::Externalize(const wchar_t* aPair, TDes16& aBuffer)
|
sl@0
|
85 |
//
|
sl@0
|
86 |
// static function to externalize a "name=value" definition
|
sl@0
|
87 |
//
|
sl@0
|
88 |
{
|
sl@0
|
89 |
const wchar_t* cp=aPair;
|
sl@0
|
90 |
for (cp=aPair; *cp; ++cp)
|
sl@0
|
91 |
{
|
sl@0
|
92 |
if (*cp==L'=')
|
sl@0
|
93 |
break;
|
sl@0
|
94 |
}
|
sl@0
|
95 |
if (*cp!=L'=')
|
sl@0
|
96 |
return 0; // malformed
|
sl@0
|
97 |
|
sl@0
|
98 |
TPtrC16 name((TText16*)aPair,cp-aPair);
|
sl@0
|
99 |
TPtrC16 value((TText16*)(cp+1));
|
sl@0
|
100 |
aBuffer.Append(name);
|
sl@0
|
101 |
aBuffer.Append(TChar(0));
|
sl@0
|
102 |
aBuffer.Append(value);
|
sl@0
|
103 |
aBuffer.Append(TChar(0));
|
sl@0
|
104 |
return 1;
|
sl@0
|
105 |
}
|
sl@0
|
106 |
|
sl@0
|
107 |
TInt TEnvVar::Externalize(TDes16& aBuffer)
|
sl@0
|
108 |
{
|
sl@0
|
109 |
if (iName==0)
|
sl@0
|
110 |
return 0;
|
sl@0
|
111 |
aBuffer.Append(*iName);
|
sl@0
|
112 |
aBuffer.Append(TChar(0));
|
sl@0
|
113 |
aBuffer.Append(*iValue);
|
sl@0
|
114 |
aBuffer.Append(TChar(0));
|
sl@0
|
115 |
return 1;
|
sl@0
|
116 |
}
|
sl@0
|
117 |
|
sl@0
|
118 |
void TEnvVar::ConstructL(const TText16*& aPtr)
|
sl@0
|
119 |
{
|
sl@0
|
120 |
TPtrC16 name(aPtr);
|
sl@0
|
121 |
aPtr+=name.Length()+1;
|
sl@0
|
122 |
ConstructL(name,(const wchar_t*)aPtr);
|
sl@0
|
123 |
aPtr+=iValue->Length()+1;
|
sl@0
|
124 |
}
|
sl@0
|
125 |
|
sl@0
|
126 |
CEnvironment::~CEnvironment()
|
sl@0
|
127 |
{
|
sl@0
|
128 |
while (iCount>0)
|
sl@0
|
129 |
{
|
sl@0
|
130 |
--iCount;
|
sl@0
|
131 |
iVars[iCount].Release();
|
sl@0
|
132 |
}
|
sl@0
|
133 |
User::Free(iVars);
|
sl@0
|
134 |
}
|
sl@0
|
135 |
|
sl@0
|
136 |
|
sl@0
|
137 |
void CEnvironment::ConstructL(TUint aCount, TDes16& aBuffer)
|
sl@0
|
138 |
//
|
sl@0
|
139 |
// Set up the environment from a descriptor. If this leaves then
|
sl@0
|
140 |
// the CEnvironment destructor will be able to clean up properly.
|
sl@0
|
141 |
//
|
sl@0
|
142 |
{
|
sl@0
|
143 |
// always allocate at least one slot - makes life easier elsewhere
|
sl@0
|
144 |
TInt bytes = (aCount+1)*sizeof(TEnvVar);
|
sl@0
|
145 |
iVars=(TEnvVar*) User::AllocL(bytes);
|
sl@0
|
146 |
Mem::FillZ(iVars,bytes);
|
sl@0
|
147 |
iCount=aCount+1;
|
sl@0
|
148 |
|
sl@0
|
149 |
const TText16* data=aBuffer.Ptr();
|
sl@0
|
150 |
for (TUint i=0; i<aCount; ++i)
|
sl@0
|
151 |
iVars[i].ConstructL(data);
|
sl@0
|
152 |
}
|
sl@0
|
153 |
|
sl@0
|
154 |
HBufC16* CEnvironment::ExternalizeLC(TUint& aCount, wchar_t** envp)
|
sl@0
|
155 |
{
|
sl@0
|
156 |
if (envp==0)
|
sl@0
|
157 |
return ExternalizeLC(aCount); // get current environment
|
sl@0
|
158 |
// Externalize supplied environment
|
sl@0
|
159 |
TInt length=0;
|
sl@0
|
160 |
wchar_t** ep=envp;
|
sl@0
|
161 |
for (ep=envp; *ep; ++ep)
|
sl@0
|
162 |
length+=wcslen(*ep)+1;
|
sl@0
|
163 |
HBufC16* retBuf = HBufC16::NewLC(length);
|
sl@0
|
164 |
TInt nvars=0;
|
sl@0
|
165 |
TPtr16 hbuf16=retBuf->Des();
|
sl@0
|
166 |
for (ep=envp; *ep; ++ep)
|
sl@0
|
167 |
nvars+=TEnvVar::Externalize(*ep, hbuf16);
|
sl@0
|
168 |
aCount=nvars;
|
sl@0
|
169 |
return retBuf;
|
sl@0
|
170 |
}
|
sl@0
|
171 |
|
sl@0
|
172 |
HBufC16* CEnvironment::ExternalizeLC(TUint& aCount)
|
sl@0
|
173 |
{
|
sl@0
|
174 |
TInt length=0;
|
sl@0
|
175 |
TUint i=0;
|
sl@0
|
176 |
for (i=0; i<iCount; ++i)
|
sl@0
|
177 |
length+=iVars[i].Length();
|
sl@0
|
178 |
HBufC16* retBuf = HBufC16::NewLC(length);
|
sl@0
|
179 |
TInt nvars=0;
|
sl@0
|
180 |
TPtr16 hbuf16=retBuf->Des();
|
sl@0
|
181 |
for (i=0; i<iCount; i++)
|
sl@0
|
182 |
nvars+=iVars[i].Externalize(hbuf16);
|
sl@0
|
183 |
aCount=nvars;
|
sl@0
|
184 |
return retBuf;
|
sl@0
|
185 |
}
|
sl@0
|
186 |
|
sl@0
|
187 |
// The interface used to support the STDLIB routines
|
sl@0
|
188 |
|
sl@0
|
189 |
wchar_t * CEnvironment::getenv(const wchar_t* aName) const
|
sl@0
|
190 |
{
|
sl@0
|
191 |
TPtrC16 name((TText16*)aName);
|
sl@0
|
192 |
for (TUint i=0; i<iCount; ++i)
|
sl@0
|
193 |
{
|
sl@0
|
194 |
HBufC16* value=iVars[i].Match(name);
|
sl@0
|
195 |
if (value)
|
sl@0
|
196 |
{
|
sl@0
|
197 |
const wchar_t* vptr = (const wchar_t*)(value->Ptr());
|
sl@0
|
198 |
return CONST_CAST(wchar_t*,vptr); // I hope nobody modifies this data...
|
sl@0
|
199 |
}
|
sl@0
|
200 |
}
|
sl@0
|
201 |
return 0;
|
sl@0
|
202 |
}
|
sl@0
|
203 |
|
sl@0
|
204 |
int CEnvironment::setenv(const wchar_t* aName, const wchar_t* aValue, int aReplace, int& anErrno)
|
sl@0
|
205 |
{
|
sl@0
|
206 |
TPtrC16 name((TText16*)aName);
|
sl@0
|
207 |
TUint freeSlot=iCount;
|
sl@0
|
208 |
TEnvVar* ep=iVars;
|
sl@0
|
209 |
for (TUint i=0; i<iCount; ++i,++ep)
|
sl@0
|
210 |
{
|
sl@0
|
211 |
if (ep->NotEmpty())
|
sl@0
|
212 |
{
|
sl@0
|
213 |
const TDesC16* existing=ep->Match(name);
|
sl@0
|
214 |
if (existing)
|
sl@0
|
215 |
{
|
sl@0
|
216 |
TInt err=KErrNone;
|
sl@0
|
217 |
if (aReplace)
|
sl@0
|
218 |
ep->SetValue(aValue);
|
sl@0
|
219 |
return MapError(err,anErrno);
|
sl@0
|
220 |
}
|
sl@0
|
221 |
}
|
sl@0
|
222 |
else
|
sl@0
|
223 |
freeSlot=i;
|
sl@0
|
224 |
}
|
sl@0
|
225 |
if (freeSlot==iCount)
|
sl@0
|
226 |
{
|
sl@0
|
227 |
// no free slots, time to grow the array
|
sl@0
|
228 |
ep=(TEnvVar*)User::ReAlloc(iVars,(iCount+1)*sizeof(TEnvVar));
|
sl@0
|
229 |
if (ep==0)
|
sl@0
|
230 |
return KErrNoMemory;
|
sl@0
|
231 |
iVars=ep;
|
sl@0
|
232 |
++iCount;
|
sl@0
|
233 |
}
|
sl@0
|
234 |
TRAPD(ret,iVars[freeSlot].ConstructL(name,aValue));
|
sl@0
|
235 |
return MapError(ret,anErrno);
|
sl@0
|
236 |
}
|
sl@0
|
237 |
|
sl@0
|
238 |
void CEnvironment::unsetenv(const wchar_t* aName)
|
sl@0
|
239 |
{
|
sl@0
|
240 |
TPtrC16 name((TText16*)aName);
|
sl@0
|
241 |
for (TUint i=0; i<iCount; ++i)
|
sl@0
|
242 |
{
|
sl@0
|
243 |
const TDesC16* value=iVars[i].Match(name);
|
sl@0
|
244 |
if (value)
|
sl@0
|
245 |
{
|
sl@0
|
246 |
iVars[i].Release();
|
sl@0
|
247 |
return;
|
sl@0
|
248 |
}
|
sl@0
|
249 |
}
|
sl@0
|
250 |
}
|
sl@0
|
251 |
|