|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 using System; |
|
18 using System.IO; |
|
19 using System.Collections; |
|
20 using System.Collections.Generic; |
|
21 using System.Text; |
|
22 using SymbianUtils; |
|
23 using CrashItemLib.PluginAPI; |
|
24 using CrashItemLib.Crash.Source; |
|
25 using CrashItemLib.Crash.Container; |
|
26 |
|
27 namespace CrashItemLib.Engine.Sources.Types |
|
28 { |
|
29 internal sealed class CIEngineSourceReaderTrace : CIEngineSourceReader |
|
30 { |
|
31 #region Constructors |
|
32 public CIEngineSourceReaderTrace( CIEngineSource aSource, CFFSource[] aPluginSources ) |
|
33 : base( aSource ) |
|
34 { |
|
35 iPluginSources.AddRange( aPluginSources ); |
|
36 } |
|
37 #endregion |
|
38 |
|
39 #region From CIEngineSourceReader |
|
40 public override CIEngineSource.TState Read() |
|
41 { |
|
42 CIEngineSource.TState ret = CIEngineSource.TState.EStateReadyCorrupt; |
|
43 |
|
44 // Listen to container creation events in all plugin reader objects |
|
45 foreach ( CFFSource source in iPluginSources ) |
|
46 { |
|
47 CFFReader reader = source.Reader; |
|
48 reader.Observer += new CFFReader.ReaderObserver( CFFReader_Observer ); |
|
49 reader.ExceptionHandler += new CFFReader.ReaderExceptionHandler( CFFReader_ExceptionHandler ); |
|
50 } |
|
51 // |
|
52 try |
|
53 { |
|
54 CIEngineTraceReader traceReader = new CIEngineTraceReader( this ); |
|
55 traceReader.Read( TSynchronicity.ESynchronous ); |
|
56 } |
|
57 finally |
|
58 { |
|
59 ret = CalculateFinalState(); |
|
60 |
|
61 // Stop listening to container creation events in all plugin reader objects |
|
62 foreach ( CFFSource source in iPluginSources ) |
|
63 { |
|
64 CFFReader reader = source.Reader; |
|
65 reader.Observer -= new CFFReader.ReaderObserver( CFFReader_Observer ); |
|
66 reader.ExceptionHandler -= new CFFReader.ReaderExceptionHandler( CFFReader_ExceptionHandler ); |
|
67 } |
|
68 } |
|
69 // |
|
70 return ret; |
|
71 } |
|
72 |
|
73 public override CFFSource.TReaderOperationType OpType |
|
74 { |
|
75 get { return CFFSource.TReaderOperationType.EReaderOpTypeTrace; } |
|
76 } |
|
77 #endregion |
|
78 |
|
79 #region API |
|
80 #endregion |
|
81 |
|
82 #region Event handlers |
|
83 private void CFFReader_Observer( CFFReader.TEvent aEvent, CFFReader aReader, object aContext ) |
|
84 { |
|
85 base.Trace( "[CIEngineSourceReaderTrace] CFFReader_Observer() - START - aEvent: " + aEvent + ", file: " + base.Source.FileName ); |
|
86 |
|
87 // This method is called for both native and trace based events |
|
88 if ( aEvent == CFFReader.TEvent.EReadingContainerCreated ) |
|
89 { |
|
90 CIContainer container = aContext as CIContainer; |
|
91 if ( container != null ) |
|
92 { |
|
93 base.SaveCrash( container ); |
|
94 } |
|
95 } |
|
96 else if ( aEvent == CFFReader.TEvent.EReadingProgress ) |
|
97 { |
|
98 int progress = ( aContext != null && aContext is int ) ? (int) aContext : 0; |
|
99 base.Source.OnSourceReadingProgress( progress ); |
|
100 } |
|
101 |
|
102 base.Trace( "[CIEngineSourceReaderTrace] CFFReader_Observer() - END - aEvent: " + aEvent + ", file: " + base.Source.FileName ); |
|
103 } |
|
104 |
|
105 private void CFFReader_ExceptionHandler( Exception aException, CFFReader aReader ) |
|
106 { |
|
107 base.AddException( aException ); |
|
108 } |
|
109 #endregion |
|
110 |
|
111 #region Multiplexing methods |
|
112 internal void OnTraceReadInit() |
|
113 { |
|
114 lock ( iPluginSources ) |
|
115 { |
|
116 foreach ( CFFSource entry in iPluginSources ) |
|
117 { |
|
118 entry.Reader.OnTraceReadInit(); |
|
119 } |
|
120 } |
|
121 } |
|
122 |
|
123 internal void OnTraceReadComplete() |
|
124 { |
|
125 lock ( iPluginSources ) |
|
126 { |
|
127 foreach ( CFFSource entry in iPluginSources ) |
|
128 { |
|
129 entry.Reader.OnTraceReadComplete(); |
|
130 } |
|
131 } |
|
132 } |
|
133 |
|
134 internal void OnTraceReadOffer( CFFTraceLine aLine ) |
|
135 { |
|
136 lock ( iPluginSources ) |
|
137 { |
|
138 foreach ( CFFSource entry in iPluginSources ) |
|
139 { |
|
140 CFFTraceLine line = new CFFTraceLine( aLine.Line, aLine.LineNumber, entry ); |
|
141 entry.Reader.OnTraceReadOffer( line ); |
|
142 } |
|
143 } |
|
144 } |
|
145 |
|
146 internal void OnTraceReadException( Exception aException ) |
|
147 { |
|
148 base.AddException( aException ); |
|
149 } |
|
150 |
|
151 internal void OnTraceReaderProgress( int aProgress ) |
|
152 { |
|
153 base.Source.OnSourceReadingProgress( aProgress ); |
|
154 } |
|
155 #endregion |
|
156 |
|
157 #region Internal methods |
|
158 private CIEngineSource.TState CalculateFinalState() |
|
159 { |
|
160 CIEngineSource.TState ret = CIEngineSource.TState.EStateReadyCorrupt; |
|
161 |
|
162 // For trace-based operations we'll potentially be firing each trace |
|
163 // line at multiple readers, in which case we only mark the file as |
|
164 // corrupt if no readers completed successfully. |
|
165 int countCorrupt = 0; |
|
166 int countReady = 0; |
|
167 int countContainers = base.CrashItemCount; |
|
168 |
|
169 // Count number of ready vs corrupt readers |
|
170 foreach ( CFFSource source in iPluginSources ) |
|
171 { |
|
172 CFFReader reader = source.Reader; |
|
173 CFFReader.TState readerState = reader.State; |
|
174 // |
|
175 switch ( readerState ) |
|
176 { |
|
177 case CFFReader.TState.EStateCorrupt: |
|
178 ++countCorrupt; |
|
179 break; |
|
180 case CFFReader.TState.EStateReady: |
|
181 ++countReady; |
|
182 break; |
|
183 default: |
|
184 case CFFReader.TState.EStateProcessing: |
|
185 case CFFReader.TState.EStateUninitialised: |
|
186 SymbianUtils.SymDebug.SymDebugger.Assert( false ); |
|
187 break; |
|
188 } |
|
189 } |
|
190 |
|
191 // If we created at least one container, then we did still manage to create |
|
192 // some kind of crash output irrespective of how many of the readers indicated |
|
193 // the source was corrupt. In that case, the underlying source file is treated |
|
194 // as valid. |
|
195 base.Trace( "[CIEngineSourceReaderTrace] CalculateFinalState() - total: {0}, ready: {1}, corrupt: {2}", countContainers, countReady, countCorrupt ); |
|
196 if ( countContainers > 0 ) |
|
197 { |
|
198 ret = CIEngineSource.TState.EStateReady; |
|
199 } |
|
200 else |
|
201 { |
|
202 // We didn't manage to create any crash items at all from this source |
|
203 // file. |
|
204 if ( countCorrupt > 0 ) |
|
205 { |
|
206 // At least one reader indicated that the source file was corrupt, |
|
207 // and since no other reader could create any kind of valid output |
|
208 // we'll treat the source file as entirely corrupt. |
|
209 ret = CIEngineSource.TState.EStateReadyCorrupt; |
|
210 } |
|
211 else |
|
212 { |
|
213 // No crash container created, but nobody said the file was corrupt |
|
214 // either. It's just a "no items" file. |
|
215 ret = CIEngineSource.TState.EStateReadyNoItems; |
|
216 } |
|
217 |
|
218 } |
|
219 |
|
220 base.Trace( "[CIEngineSourceReaderTrace] CalculateFinalState() - END - ret: {0}, file: {1}", ret, base.Source.FileName ); |
|
221 return ret; |
|
222 } |
|
223 #endregion |
|
224 |
|
225 #region Internal class - actual trace file reader |
|
226 internal class CIEngineTraceReader : AsyncTextFileReader |
|
227 { |
|
228 #region Constructors |
|
229 public CIEngineTraceReader( CIEngineSourceReaderTrace aMultiplexer ) |
|
230 : base( aMultiplexer.Source.FileName ) |
|
231 { |
|
232 iMultiplexer = aMultiplexer; |
|
233 } |
|
234 #endregion |
|
235 |
|
236 #region API |
|
237 public void Read( TSynchronicity aSynchronicity ) |
|
238 { |
|
239 base.StartRead( aSynchronicity ); |
|
240 } |
|
241 #endregion |
|
242 |
|
243 #region From AsyncTextFileReader |
|
244 protected override void HandleReadStarted() |
|
245 { |
|
246 try |
|
247 { |
|
248 base.HandleReadStarted(); |
|
249 } |
|
250 finally |
|
251 { |
|
252 iMultiplexer.OnTraceReadInit(); |
|
253 } |
|
254 } |
|
255 |
|
256 protected override void HandleReadCompleted() |
|
257 { |
|
258 try |
|
259 { |
|
260 base.HandleReadCompleted(); |
|
261 } |
|
262 finally |
|
263 { |
|
264 iMultiplexer.OnTraceReadComplete(); |
|
265 } |
|
266 } |
|
267 |
|
268 protected override void HandleFilteredLine( string aLine ) |
|
269 { |
|
270 CFFTraceLine line = new CFFTraceLine( aLine, LineNumber, null ); |
|
271 iMultiplexer.OnTraceReadOffer( line ); |
|
272 } |
|
273 |
|
274 protected override void HandleReadException( Exception aException ) |
|
275 { |
|
276 try |
|
277 { |
|
278 base.HandleReadException( aException ); |
|
279 } |
|
280 finally |
|
281 { |
|
282 iMultiplexer.OnTraceReadException( aException ); |
|
283 } |
|
284 } |
|
285 |
|
286 protected override void OnProgressChanged( int aProgress ) |
|
287 { |
|
288 iMultiplexer.OnTraceReaderProgress( aProgress ); |
|
289 } |
|
290 #endregion |
|
291 |
|
292 #region Data members |
|
293 private readonly CIEngineSourceReaderTrace iMultiplexer; |
|
294 #endregion |
|
295 } |
|
296 #endregion |
|
297 |
|
298 #region Data members |
|
299 private List<CFFSource> iPluginSources = new List<CFFSource>(); |
|
300 #endregion |
|
301 } |
|
302 } |