|
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 // |
|
15 |
|
16 // EPOC includes |
|
17 #include <e32base.h> |
|
18 |
|
19 // Test system includes |
|
20 #include "LogFile.h" |
|
21 |
|
22 |
|
23 /* |
|
24 * destructor for CFileLogger. |
|
25 */ |
|
26 CFileLogger::~CFileLogger() |
|
27 { |
|
28 // make sure session to file server is closed |
|
29 Close(); |
|
30 } |
|
31 |
|
32 |
|
33 /** |
|
34 * |
|
35 * Static constructor for CFileLogger. |
|
36 * |
|
37 * @return "CFileLogger*" |
|
38 * The constructed CFileLogger |
|
39 * |
|
40 * @xxxx |
|
41 * |
|
42 */ |
|
43 CFileLogger* CFileLogger::NewL() |
|
44 { |
|
45 CFileLogger* s = new(ELeave) CFileLogger; |
|
46 return s; |
|
47 } |
|
48 |
|
49 /** |
|
50 * |
|
51 * Create and open a log file. The file is shareable, and a mutex |
|
52 * and file seeks employed in case more than one session is using |
|
53 * the file. |
|
54 * |
|
55 * @param "const TDesC& aDir" |
|
56 * The file path of the logfile to be created. If the path |
|
57 * does not exist, the logfile will not be created. |
|
58 * |
|
59 * @param "const TDesC& aName" |
|
60 * The file name of same. |
|
61 * |
|
62 * @xxxx |
|
63 * |
|
64 */ |
|
65 void CFileLogger::CreateLog(const TDesC& aDir, const TDesC& aName) |
|
66 { |
|
67 // if aDir or aName are empty, then panic |
|
68 __ASSERT_ALWAYS(aDir.Ptr() != NULL, User::Panic(_L("CFileLogger"), 0)); |
|
69 __ASSERT_ALWAYS(aName.Ptr() != NULL, User::Panic(_L("CFileLogger"), 1)); |
|
70 |
|
71 |
|
72 // if aDir doesn't exist, create it anyway |
|
73 TUint aAttValue; |
|
74 if (iFs.Att(aDir, aAttValue) != KErrNone) |
|
75 { |
|
76 TInt returnCode = iFs.MkDirAll(aDir); |
|
77 if (returnCode != KErrNone) |
|
78 { |
|
79 iEnabled = EFalse; |
|
80 User::Panic(_L("CFileLogger"), 2); |
|
81 } |
|
82 } |
|
83 |
|
84 iEnabled = ETrue; |
|
85 iLogName = aName; |
|
86 |
|
87 // create logfile mutex |
|
88 RMutex logMutex; |
|
89 logMutex.CreateGlobal(iLogName); |
|
90 |
|
91 // make the correct file name |
|
92 TFileName logFile; |
|
93 logFile.Format(_L("%S%S"), &aDir, &aName); // aDir will be \\-terminated |
|
94 |
|
95 // If the file does not exist, create it. If it does, truncate it |
|
96 // Open it for sharing |
|
97 TInt returnCode=iLogfile.Replace(iFs, logFile, EFileWrite | EFileStreamText | EFileShareAny); |
|
98 |
|
99 // check if open fails |
|
100 if (returnCode==KErrNone) |
|
101 { |
|
102 //file has opened ok |
|
103 //add the start to the HTML |
|
104 iLogfile.Write(_L8("<html><body><pre>\n")); |
|
105 TInt dummy; |
|
106 iLogfile.Seek(ESeekEnd, dummy); |
|
107 } |
|
108 else |
|
109 iEnabled = EFalse; |
|
110 } |
|
111 |
|
112 /** |
|
113 * |
|
114 * Close the logfile. The flag iEnabled will be clear if there |
|
115 * is no logfile to close. |
|
116 * |
|
117 * @xxxx |
|
118 * |
|
119 */ |
|
120 void CFileLogger::CloseLog() |
|
121 { |
|
122 |
|
123 // this should be mutex-safe as each thread has its own handle to |
|
124 // the log file |
|
125 // if logging enabled, flush buffers |
|
126 if (iEnabled) |
|
127 { |
|
128 iLogfile.Flush(); |
|
129 iLogfile.Close(); |
|
130 iEnabled = EFalse; |
|
131 } |
|
132 |
|
133 // disconnect from the file server |
|
134 iFs.Close(); |
|
135 } |
|
136 |
|
137 /** |
|
138 * |
|
139 * Write output to the logfile. |
|
140 * |
|
141 * @param "const TDesC& aMsg" |
|
142 * The message (string) to be written. |
|
143 * |
|
144 * @xxxx |
|
145 * |
|
146 */ |
|
147 void CFileLogger::WriteLog(const TDesC& aMsg) |
|
148 { |
|
149 |
|
150 if (!iEnabled) |
|
151 return; |
|
152 |
|
153 // convert from unicode to 8 bit |
|
154 TBuf8<KMaxLogLineLength> lineBuf8; |
|
155 const TText* msgBuf = aMsg.Ptr(); |
|
156 for (TInt i = 0; i < aMsg.Length() ;i++) |
|
157 lineBuf8.Append(STATIC_CAST(TText, msgBuf[i])); |
|
158 |
|
159 // wait on mutex |
|
160 RMutex logMutex; |
|
161 logMutex.OpenGlobal(iLogName); |
|
162 |
|
163 logMutex.Wait(); |
|
164 |
|
165 // write to log file |
|
166 TInt dummy=0; |
|
167 iLogfile.Seek(ESeekEnd, dummy); |
|
168 iLogfile.Write(lineBuf8); |
|
169 // seek to end after write - in case another process or thread is also using the file |
|
170 dummy=0; //dummy is updated after a seek to contain the new file position. With ESeekEnd |
|
171 //it is used as an offest value to control the seek. |
|
172 iLogfile.Seek(ESeekEnd, dummy); |
|
173 |
|
174 logMutex.Signal(); |
|
175 logMutex.Close(); |
|
176 } |
|
177 |
|
178 /** |
|
179 * |
|
180 * Connect to the file server. Used as a helper function |
|
181 * by classes owning a CFileLogger, to ensure that a |
|
182 * file server session can be opened |
|
183 * |
|
184 * @return "TInt" |
|
185 * standard EPOC error code |
|
186 * |
|
187 * @xxxx |
|
188 * |
|
189 */ |
|
190 TInt CFileLogger::Connect() |
|
191 { |
|
192 TInt err = iFs.Connect(); |
|
193 if (err == KErrNone) |
|
194 iFsOpen = ETrue; |
|
195 return err; |
|
196 } |
|
197 |
|
198 /** |
|
199 * |
|
200 * Close a file server session. Used as a helper function |
|
201 * by classes owning a CFileLogger. |
|
202 * |
|
203 * @xxxx |
|
204 * |
|
205 */ |
|
206 void CFileLogger::Close() |
|
207 { |
|
208 if (iFsOpen) |
|
209 { |
|
210 iFs.Close(); |
|
211 iFsOpen = EFalse; |
|
212 } |
|
213 } |