|
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // $Header$ |
|
15 // The CTEngine is the class that manages the test infrastructure |
|
16 // It knows how to process scripts and where to find command knowledge |
|
17 // The plan is: |
|
18 // Process console command line or command line supplied script |
|
19 // read in each line (or command) and process that (if appropriate) |
|
20 // rev: mjdavey, symbian@mjdss.com, July 2002 |
|
21 // for: Typhoon (7.0s) & JetStream (8.0) |
|
22 // Include Module Definition & Files |
|
23 // |
|
24 // |
|
25 |
|
26 #include "CCmdFile.h" |
|
27 |
|
28 //----------------------------------------------------------------------------- |
|
29 |
|
30 CCmdFile *CCmdFile::NewL( ) |
|
31 { |
|
32 CCmdFile* self = NewLC( ); |
|
33 CleanupStack::Pop(); |
|
34 return self; |
|
35 } |
|
36 |
|
37 //----------------------------------------------------------------------------- |
|
38 |
|
39 CCmdFile *CCmdFile::NewLC() |
|
40 { |
|
41 CCmdFile* self = new (ELeave) CCmdFile(); |
|
42 CleanupStack::PushL(self); |
|
43 self->ConstructL( ); |
|
44 return self; |
|
45 } |
|
46 |
|
47 //----------------------------------------------------------------------------- |
|
48 |
|
49 CCmdFile::~CCmdFile() |
|
50 { |
|
51 Close(); |
|
52 iArgs->ResetAndDestroy(); |
|
53 delete iArgs; |
|
54 iArgs = NULL; |
|
55 } |
|
56 |
|
57 //----------------------------------------------------------------------------- |
|
58 |
|
59 void CCmdFile::ConstructL() |
|
60 { |
|
61 iFileName.Zero(); |
|
62 iBuf.Set( NULL, 0 ); |
|
63 iLine = 0; |
|
64 iArgs = new (ELeave) CArrayPtrSeg<HBufC>(32); |
|
65 } |
|
66 |
|
67 //----------------------------------------------------------------------------- |
|
68 // Reads the whole file into memory |
|
69 // Not necessarily ideal - really want to read in line by line as required... |
|
70 |
|
71 TInt CCmdFile::Open(const TDesC& aPath, const TDesC& aFile) |
|
72 { |
|
73 // Construct full file name and open the file. |
|
74 TInt error = iParse.Set( aFile, NULL, &aPath ); |
|
75 if (error == KErrNone) |
|
76 error = Open(iParse.FullName()); |
|
77 return error; |
|
78 } |
|
79 |
|
80 //----------------------------------------------------------------------------- |
|
81 |
|
82 TInt CCmdFile::Open(const TDesC& aFile) |
|
83 { |
|
84 // Close if file is open. Note: the Close() resets the member data. |
|
85 Close(); |
|
86 |
|
87 // Connect to file server. |
|
88 RFs fs; |
|
89 TInt error; |
|
90 error = fs.Connect(); |
|
91 if ( error != KErrNone ) |
|
92 return error; |
|
93 |
|
94 // Open the file. |
|
95 RFile file; |
|
96 error = file.Open( fs, aFile, EFileStreamText|EFileRead ); |
|
97 if ( error != KErrNone ) |
|
98 { |
|
99 fs.Close(); |
|
100 return error; |
|
101 } |
|
102 |
|
103 // Get file size. |
|
104 TInt size; |
|
105 error = file.Size( size ); |
|
106 if ( error != KErrNone ) |
|
107 { |
|
108 file.Close(); |
|
109 fs.Close(); |
|
110 return error; |
|
111 } |
|
112 |
|
113 // Tackle an empty file => nothing in the iBuf buffer. |
|
114 if ( size == 0 ) |
|
115 { |
|
116 file.Close(); |
|
117 fs.Close(); |
|
118 iFileName.Copy( aFile ); |
|
119 return error; // = KErrNone |
|
120 } |
|
121 |
|
122 // Allocate buffer, read in whole file and close it. |
|
123 TUint8* buf = (TUint8*)User::Alloc( size ); |
|
124 if ( buf == NULL ) |
|
125 // No memory. |
|
126 { |
|
127 file.Close(); |
|
128 fs.Close(); |
|
129 return ( error = KErrNoMemory ); |
|
130 } |
|
131 |
|
132 TPtr8 ptr( buf, size ); |
|
133 error = file.Read( ptr ); |
|
134 file.Close(); |
|
135 fs.Close(); |
|
136 if ( error != KErrNone ) |
|
137 // Read error. |
|
138 { |
|
139 delete buf; |
|
140 file.Close(); |
|
141 fs.Close(); |
|
142 return error; |
|
143 } |
|
144 |
|
145 file.Close(); // Close file |
|
146 fs.Close(); // Close session |
|
147 |
|
148 #ifndef _UNICODE |
|
149 // Set iBuf from which to give lines in Read. |
|
150 iBuf.Set( (TText*)buf, size/sizeof(TText) ); |
|
151 #else |
|
152 // Tackle UNICODE and NON-UNICODE Text files. |
|
153 // the cast is necessary in order to remove a warning. |
|
154 // It's safe because a size variable it's always positive |
|
155 if ( (TUint)size >= sizeof(TText) && buf[0] == 0xFF && buf[1] == 0xFE ) |
|
156 { |
|
157 // UNICODE: loose 0xFF,0xFE from beginning of the file. |
|
158 Mem::Move( buf, buf+sizeof(TText), size-sizeof(TText) ); |
|
159 iBuf.Set( (TText*)buf, size/sizeof(TText)-1 ); |
|
160 } |
|
161 else |
|
162 // Remark: the size is known to be greater than zero here. |
|
163 { |
|
164 // NON-UNICODE: convert and replace the original buffer. |
|
165 // a) make new buffer |
|
166 TText* newbuf = (TText*)User::Alloc( size*sizeof(TText) ); |
|
167 if ( newbuf == NULL ) |
|
168 // No memory. |
|
169 { |
|
170 delete buf; |
|
171 return ( error = KErrNoMemory ); |
|
172 } |
|
173 // b) convert from old to new buffer |
|
174 TInt i; |
|
175 for ( i = 0; i < size; i++ ) newbuf[i] = buf[i]; |
|
176 // c) replace and delete the old one |
|
177 iBuf.Set( newbuf, size ); |
|
178 delete buf; |
|
179 } |
|
180 #endif |
|
181 // Set file name, rewind and return Ok (error = KErrNone). |
|
182 iFileName.Copy( aFile ); |
|
183 Rewind(); |
|
184 return error; // = KErrNone |
|
185 } |
|
186 |
|
187 //----------------------------------------------------------------------------- |
|
188 // reads a line in |
|
189 |
|
190 TInt CCmdFile::Read(TDes& aDes) |
|
191 { |
|
192 |
|
193 // No data. |
|
194 aDes.Zero(); |
|
195 |
|
196 // Return End-of-file if there's nothing; also if no file open. |
|
197 if ( iBuf.Ptr() == NULL || iBuf.Length() == 0 ) |
|
198 return KErrEof; |
|
199 |
|
200 // Return End-of-file also after giving everything from buffer. |
|
201 iLex.Mark(); |
|
202 if (iLex.Eos()) |
|
203 return KErrEof; |
|
204 |
|
205 // Otherwise eat characters up to the end of the line/file and hand over the characters into the descriptor. |
|
206 // The following skips CRs and handles every LF as end-of-line and hopefully |
|
207 // works right with LF, CRLF and LFCR terminated lines. The CR alone will not do as the end-of-line. |
|
208 TChar ch; |
|
209 while ( !iLex.Eos() && ( ch = iLex.Get(), ch != '\n' ) ) |
|
210 { |
|
211 if ( (ch != '\r') && (aDes.Length() < aDes.MaxLength()) ) |
|
212 aDes.Append(ch); |
|
213 } |
|
214 |
|
215 // Increment line number (read counter) and return KErrNone. |
|
216 ++iLine; |
|
217 return KErrNone; |
|
218 } |
|
219 |
|
220 //----------------------------------------------------------------------------- |
|
221 |
|
222 TInt CCmdFile::Rewind() |
|
223 { |
|
224 iLex = iBuf; |
|
225 iLine = 0; |
|
226 return KErrNone; |
|
227 } |
|
228 |
|
229 //----------------------------------------------------------------------------- |
|
230 |
|
231 void CCmdFile::Close() |
|
232 { |
|
233 // |
|
234 // Reset member data. |
|
235 if (iBuf.Ptr() != NULL) |
|
236 delete (TText*)iBuf.Ptr(); |
|
237 |
|
238 iBuf.Set( NULL, 0 ); |
|
239 iLine = 0; |
|
240 iFileName.Zero(); |
|
241 } |
|
242 |
|
243 //----------------------------------------------------------------------------- |
|
244 // Add more arguments (makes copies). L E A V E S on failure. |
|
245 |
|
246 void CCmdFile::AddArgsL( const TDesC& aArgs ) |
|
247 { |
|
248 TLex parse(aArgs); |
|
249 TPtrC argv; |
|
250 while (argv.Set(TfrLex::GetL(parse)), argv.Length() > 0) |
|
251 { |
|
252 argv.Set(TfrLex::Peel(argv)); |
|
253 HBufC* buf = argv.AllocL(); |
|
254 iArgs->AppendL( buf ); |
|
255 } |
|
256 } |
|
257 |
|
258 //----------------------------------------------------------------------------- |
|
259 // Get argument count. |
|
260 |
|
261 TInt CCmdFile::Argc() const |
|
262 { |
|
263 return iArgs->Count(); |
|
264 } |
|
265 |
|
266 //----------------------------------------------------------------------------- |
|
267 // get the i'th argument, legal i assumed. |
|
268 |
|
269 TPtrC CCmdFile::Argv(TInt aIndex) const |
|
270 { |
|
271 TPtrC argv ((iArgs->At(aIndex))->Des()); |
|
272 return argv; |
|
273 } |
|
274 |
|
275 //----------------------------------------------------------------------------- |
|
276 // Get file name. Having no file does no harm (returns empty name). |
|
277 |
|
278 TPtrC CCmdFile::FileName() const |
|
279 { |
|
280 TPtrC filename(iFileName); |
|
281 return filename; |
|
282 } |
|
283 |
|
284 //----------------------------------------------------------------------------- |
|
285 // Get line number (= count of lines read so fat). Having no file does no |
|
286 // harm (returns line number 0). |
|
287 |
|
288 TInt CCmdFile::Line() |
|
289 { |
|
290 return iLine; |
|
291 } |
|
292 |
|
293 //----------------------------------------------------------------------------- |