|
1 /* |
|
2 * Copyright (c) 2004-2008 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 |
|
18 using System; |
|
19 using System.IO; |
|
20 using System.Collections.Generic; |
|
21 using System.Text; |
|
22 using System.Threading; |
|
23 using System.ComponentModel; |
|
24 using SymbianUtils; |
|
25 using SymbianUtils.Tracer; |
|
26 using SymbianUtils.FileTypes; |
|
27 using SymbianUtils.TextUtilities.Readers.Types.Array; |
|
28 using SymbianStructuresLib.Debug.Symbols; |
|
29 using SymbianStructuresLib.Debug.Symbols.Utilities; |
|
30 using SymbianSymbolLib.SourceManagement.Source; |
|
31 using SymbianSymbolLib.SourceManagement.Provisioning; |
|
32 using SLPluginSymbol.Data; |
|
33 using SLPluginSymbol.Source; |
|
34 |
|
35 namespace SLPluginSymbol.Reader |
|
36 { |
|
37 internal class SymbolFileSegmentReader : DisposableObject |
|
38 { |
|
39 #region Delegates & events |
|
40 public delegate void ProgressHandler( SymbolFileSegmentReader aReader, long aTotalNumberOfLines, long aNumberProcessed ); |
|
41 public event ProgressHandler Progress; |
|
42 |
|
43 public delegate void OperationHandler( SymbolFileSegmentReader aReader ); |
|
44 public event OperationHandler OperationStarted; |
|
45 public event OperationHandler OperationCompleted; |
|
46 #endregion |
|
47 |
|
48 #region Constructors |
|
49 public SymbolFileSegmentReader( SymbolFileSegment aSegment ) |
|
50 { |
|
51 iSegment = aSegment; |
|
52 } |
|
53 #endregion |
|
54 |
|
55 #region API |
|
56 public void Read( TSynchronicity aSynchronicity ) |
|
57 { |
|
58 switch ( aSynchronicity ) |
|
59 { |
|
60 default: |
|
61 case TSynchronicity.EAsynchronous: |
|
62 ThreadPool.QueueUserWorkItem( new WaitCallback( InitiateReadAsync ) ); |
|
63 break; |
|
64 case TSynchronicity.ESynchronous: |
|
65 InitiateRead(); |
|
66 break; |
|
67 } |
|
68 } |
|
69 #endregion |
|
70 |
|
71 #region Properties |
|
72 public SymbolSource Source |
|
73 { |
|
74 get { return iSegment.Source; } |
|
75 } |
|
76 |
|
77 public SymbolFileSegment FileSegment |
|
78 { |
|
79 get { return iSegment; } |
|
80 } |
|
81 #endregion |
|
82 |
|
83 #region Internal methods |
|
84 private void InitiateReadAsync( object aNotUsed ) |
|
85 { |
|
86 InitiateRead(); |
|
87 } |
|
88 |
|
89 private void InitiateRead() |
|
90 { |
|
91 if ( OperationStarted != null ) |
|
92 { |
|
93 OperationStarted( this ); |
|
94 } |
|
95 // |
|
96 int count = iSegment.Count; |
|
97 for ( int i = count - 1; i >= 0; i-- ) |
|
98 { |
|
99 SymbolCollectionSegment segment = iSegment[ i ]; |
|
100 // |
|
101 ReadLines( segment ); |
|
102 } |
|
103 // |
|
104 if ( OperationCompleted != null ) |
|
105 { |
|
106 OperationCompleted( this ); |
|
107 } |
|
108 } |
|
109 |
|
110 private void ReadLines( SymbolCollectionSegment aSegment ) |
|
111 { |
|
112 long count = 0; |
|
113 |
|
114 // Make a new collection to which we'll add symbols |
|
115 SymbolCollection collection = aSegment.Collection; |
|
116 collection.TransactionBegin(); |
|
117 |
|
118 // We'll use this to filter out bad symbols |
|
119 try |
|
120 { |
|
121 using ( SymbolCollectionHarmoniser harmoniser = new SymbolCollectionHarmoniser( collection, SymbolCollectionHarmoniser.TCollectionType.EPossiblyXIP ) ) |
|
122 { |
|
123 // Then create symbols |
|
124 SymbolCreator creator = new SymbolCreator(); |
|
125 foreach ( string line in aSegment ) |
|
126 { |
|
127 Symbol symbol = creator.Parse( line, collection ); |
|
128 if ( symbol != null ) |
|
129 { |
|
130 harmoniser.Add( symbol ); |
|
131 } |
|
132 // |
|
133 ++count; |
|
134 } |
|
135 } |
|
136 } |
|
137 finally |
|
138 { |
|
139 collection.TransactionEnd(); |
|
140 |
|
141 // Collection is now complete - run final validation in |
|
142 // background thread |
|
143 ValidateAndSaveCollection( collection ); |
|
144 } |
|
145 |
|
146 ReportProgress( count ); |
|
147 |
|
148 #if INSPECT_SYMBOL_DATA |
|
149 using ( StreamWriter writer = new StreamWriter( @"C:\Temp\NewSymbols\" + Path.GetFileName( collection.FileName.FileNameInHost ) + ".symbol" ) ) |
|
150 { |
|
151 WriteToStream( collection, writer ); |
|
152 } |
|
153 #endif |
|
154 } |
|
155 |
|
156 private void ValidateAndSaveCollection( SymbolCollection aCollection ) |
|
157 { |
|
158 // We don't save empty collections since they have no size |
|
159 bool isEmpty = aCollection.IsEmptyApartFromDefaultSymbol; |
|
160 if ( !isEmpty ) |
|
161 { |
|
162 // Make sure that the collection contains at least one entry with a valid size |
|
163 bool save = false; |
|
164 |
|
165 int count = aCollection.Count; |
|
166 for ( int i = 0; i < count; i++ ) |
|
167 { |
|
168 Symbol sym = aCollection[ i ]; |
|
169 if ( sym.Size > 0 ) |
|
170 { |
|
171 save = true; |
|
172 break; |
|
173 } |
|
174 } |
|
175 |
|
176 if ( save ) |
|
177 { |
|
178 try |
|
179 { |
|
180 // If the source does not accept the collection then just continue to the next |
|
181 // entry in the file. |
|
182 aCollection.SortAsync(); |
|
183 Source.Add( aCollection ); |
|
184 } |
|
185 catch |
|
186 { |
|
187 } |
|
188 } |
|
189 } |
|
190 } |
|
191 |
|
192 private void ReportProgress( long aChunkSize ) |
|
193 { |
|
194 if ( Progress != null ) |
|
195 { |
|
196 Progress( this, iSegment.NumberOfLines, aChunkSize ); |
|
197 } |
|
198 } |
|
199 |
|
200 #if INSPECT_SYMBOL_DATA |
|
201 private void WriteToStream( SymbolCollection aCollection, StreamWriter aWriter ) |
|
202 { |
|
203 // First write the binary name |
|
204 aWriter.WriteLine( string.Empty ); |
|
205 aWriter.WriteLine( "From " + aCollection.FileName.FileNameInHost ); |
|
206 aWriter.WriteLine( string.Empty ); |
|
207 |
|
208 foreach ( Symbol symbol in aCollection ) |
|
209 { |
|
210 StringBuilder ret = new StringBuilder(); |
|
211 // |
|
212 ret.Append( symbol.Address.ToString( "x8" ) ); |
|
213 ret.Append( " " ); |
|
214 ret.Append( symbol.Size.ToString( "x4" ) ); |
|
215 ret.Append( " " ); |
|
216 ret.Append( symbol.Name.PadRight( 40, ' ' ) ); |
|
217 ret.Append( " " ); |
|
218 ret.Append( symbol.Object ); |
|
219 // |
|
220 aWriter.WriteLine( ret.ToString() ); |
|
221 } |
|
222 } |
|
223 #endif |
|
224 #endregion |
|
225 |
|
226 #region From DisposableObject |
|
227 protected override void CleanupManagedResources() |
|
228 { |
|
229 try |
|
230 { |
|
231 base.CleanupManagedResources(); |
|
232 } |
|
233 finally |
|
234 { |
|
235 } |
|
236 } |
|
237 #endregion |
|
238 |
|
239 #region Data members |
|
240 private readonly SymbolFileSegment iSegment; |
|
241 #endregion |
|
242 } |
|
243 } |