|
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.Collections.Generic; |
|
19 using System.Text; |
|
20 using System.Text.RegularExpressions; |
|
21 using System.IO; |
|
22 using SymbianUtils.DataBuffer.Entry; |
|
23 |
|
24 namespace SymbianUtils.DataBuffer.Primer |
|
25 { |
|
26 public class DataBufferPrimer |
|
27 { |
|
28 #region Delegates & Events |
|
29 public delegate void DataBufferPrimerUnhandledLine( DataBufferPrimer aPrimer, DataBuffer aBuffer, string aLine ); |
|
30 public event DataBufferPrimerUnhandledLine LineNotHandled; |
|
31 |
|
32 public delegate void DataBufferPrimerCompleteHandler( DataBufferPrimer aPrimer, DataBuffer aBuffer, uint aFirstByteAddress, uint aLastByteAddress ); |
|
33 public event DataBufferPrimerCompleteHandler PrimerComplete; |
|
34 #endregion |
|
35 |
|
36 #region Constructors |
|
37 public DataBufferPrimer( DataBuffer aBuffer ) |
|
38 { |
|
39 iDataBuffer = aBuffer; |
|
40 } |
|
41 #endregion |
|
42 |
|
43 #region API |
|
44 public void Prime( IEnumerable<string> aLines ) |
|
45 { |
|
46 iDataBuffer.Clear(); |
|
47 // |
|
48 foreach ( string line in aLines ) |
|
49 { |
|
50 PrimeLine( line ); |
|
51 } |
|
52 |
|
53 Primed = true; |
|
54 } |
|
55 |
|
56 public void PrimeLine( string aLine ) |
|
57 { |
|
58 Match m = iRawDataRegEx.Match( aLine ); |
|
59 // |
|
60 if ( m.Success ) |
|
61 { |
|
62 uint startOfLineAddress = ExtractDataSourceEntryFromMatch( m ); |
|
63 |
|
64 // If the data buffer has never had an address applied to it, then set it now |
|
65 if ( iHaveSetFirstAddress == false ) |
|
66 { |
|
67 iDataBuffer.AddressOffset = startOfLineAddress; |
|
68 iHaveSetFirstAddress = true; |
|
69 } |
|
70 } |
|
71 else if ( LineNotHandled != null ) |
|
72 { |
|
73 LineNotHandled( this, iDataBuffer, aLine ); |
|
74 } |
|
75 } |
|
76 |
|
77 public void Prime( string aBinaryFileName ) |
|
78 { |
|
79 Prime( aBinaryFileName, 0 ); |
|
80 } |
|
81 |
|
82 public void Prime( string aBinaryFileName, uint aAddressOfFirstByte ) |
|
83 { |
|
84 FileInfo info = new FileInfo( aBinaryFileName ); |
|
85 if ( info.Exists ) |
|
86 { |
|
87 int length = (int) info.Length; |
|
88 // |
|
89 byte[] bytes = new byte[ length ]; |
|
90 using ( FileStream stream = new FileStream( aBinaryFileName, FileMode.Open, FileAccess.Read, FileShare.Read ) ) |
|
91 { |
|
92 stream.Read( bytes, 0, length ); |
|
93 } |
|
94 // |
|
95 Prime( bytes, aAddressOfFirstByte ); |
|
96 } |
|
97 } |
|
98 |
|
99 public void Prime( IEnumerable<byte> aBytes, uint aAddressOfFirstByte ) |
|
100 { |
|
101 iDataBuffer.Clear(); |
|
102 |
|
103 // Set the starting address |
|
104 iDataBuffer.AddressOffset = aAddressOfFirstByte; |
|
105 |
|
106 // Read bytes |
|
107 uint offset = 0; |
|
108 foreach ( byte b in aBytes ) |
|
109 { |
|
110 DataBufferByte entry = new DataBufferByte( b, offset++ ); |
|
111 iDataBuffer.Add( entry ); |
|
112 } |
|
113 |
|
114 Primed = true; |
|
115 } |
|
116 |
|
117 public void Prime( DataBuffer aBuffer ) |
|
118 { |
|
119 iDataBuffer.Clear(); |
|
120 iDataBuffer.Set( aBuffer ); |
|
121 Primed = true; |
|
122 } |
|
123 #endregion |
|
124 |
|
125 #region Properties |
|
126 public bool Primed |
|
127 { |
|
128 get { return iPrimed; } |
|
129 private set |
|
130 { |
|
131 iPrimed = value; |
|
132 if ( Primed ) |
|
133 { |
|
134 uint firstByte = ( iDataBuffer.Count > 0 ) ? iDataBuffer.First.Address : 0; |
|
135 uint lastByte = ( iDataBuffer.Count > 0 ) ? iDataBuffer.Last.Address : 0; |
|
136 // |
|
137 if ( PrimerComplete != null ) |
|
138 { |
|
139 PrimerComplete( this, iDataBuffer, firstByte, lastByte ); |
|
140 } |
|
141 } |
|
142 } |
|
143 } |
|
144 #endregion |
|
145 |
|
146 #region Internal methods |
|
147 private uint ExtractDataSourceEntryFromMatch( Match aMatch ) |
|
148 { |
|
149 System.Diagnostics.Debug.Assert( aMatch.Success ); |
|
150 |
|
151 uint address = 0; |
|
152 uint nextExpectedAddress = 0; |
|
153 if ( iDataBuffer.Count > 0 ) |
|
154 { |
|
155 nextExpectedAddress = iDataBuffer.Last.Address + 1; |
|
156 } |
|
157 // |
|
158 GroupCollection groups = aMatch.Groups; |
|
159 CaptureCollection data = groups[ "Data" ].Captures; |
|
160 |
|
161 if ( data.Count > 0 ) |
|
162 { |
|
163 address = System.Convert.ToUInt32( groups[ "Address" ].Value, 16 ); |
|
164 |
|
165 // Validate the address |
|
166 if ( nextExpectedAddress != 0 && address != nextExpectedAddress ) |
|
167 { |
|
168 throw new Exception( string.Format( "Data is corrupt - expected: 0x{0:x8}, actual: 0x{1:x8}", nextExpectedAddress, address ) ); |
|
169 } |
|
170 else |
|
171 { |
|
172 foreach ( Capture capture in data ) |
|
173 { |
|
174 string val = capture.Value.Trim(); |
|
175 byte b = System.Convert.ToByte( val, 16 ); |
|
176 DataBufferByte entry = new DataBufferByte( b, (uint) iDataBuffer.Count ); |
|
177 iDataBuffer.Add( entry ); |
|
178 } |
|
179 } |
|
180 } |
|
181 |
|
182 return address; |
|
183 } |
|
184 #endregion |
|
185 |
|
186 #region Data members |
|
187 private static readonly Regex iRawDataRegEx = new Regex( "(?:.*)\r\n(?<Address>[a-fA-F0-9]{8})\r\n\\:\\s{1}\r\n(?<Data>(?:[a-fA-F0-9]{2})\\s{1}){1,16}\r\n(?:.*)", RegexOptions.CultureInvariant | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled ); |
|
188 private readonly DataBuffer iDataBuffer; |
|
189 private bool iPrimed = false; |
|
190 private bool iHaveSetFirstAddress = false; |
|
191 #endregion |
|
192 } |
|
193 } |