|
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.Generic; |
|
20 using System.Text; |
|
21 using System.Text.RegularExpressions; |
|
22 using SymbianUtils.DataBuffer.Entry; |
|
23 using SymbianUtils.Range; |
|
24 |
|
25 namespace SymbianUtils.DataBuffer |
|
26 { |
|
27 public class DataBuffer : IEnumerable<byte> |
|
28 { |
|
29 #region Constructors |
|
30 public DataBuffer() |
|
31 { |
|
32 } |
|
33 #endregion |
|
34 |
|
35 #region API |
|
36 public void Add( byte aByte ) |
|
37 { |
|
38 uint address = 0; |
|
39 // |
|
40 if ( Count > 0 ) |
|
41 { |
|
42 address = ( Last.Address - AddressOffset ) + 1; |
|
43 } |
|
44 // |
|
45 DataBufferByte entry = new DataBufferByte( aByte, address ); |
|
46 Add( entry ); |
|
47 } |
|
48 |
|
49 public void Add( IEnumerable<byte> aBytes ) |
|
50 { |
|
51 foreach ( byte b in aBytes ) |
|
52 { |
|
53 Add( b ); |
|
54 } |
|
55 } |
|
56 |
|
57 public void Add( uint aDWord ) |
|
58 { |
|
59 // Make 4 bytes |
|
60 byte b0 = (byte) (( aDWord & 0x000000FF ) >> 00); |
|
61 byte b1 = (byte) (( aDWord & 0x0000FF00 ) >> 08); |
|
62 byte b2 = (byte) (( aDWord & 0x00FF0000 ) >> 16); |
|
63 byte b3 = (byte) (( aDWord & 0xFF000000 ) >> 24); |
|
64 // |
|
65 Add( b0 ); |
|
66 Add( b1 ); |
|
67 Add( b2 ); |
|
68 Add( b3 ); |
|
69 } |
|
70 |
|
71 public void Add( DataBufferByte aEntry ) |
|
72 { |
|
73 aEntry.Buffer = this; |
|
74 iData.Add( aEntry ); |
|
75 } |
|
76 |
|
77 public void Set( DataBuffer aCopyFrom ) |
|
78 { |
|
79 iAddressOffset = aCopyFrom.AddressOffset; |
|
80 iData = aCopyFrom.iData; |
|
81 } |
|
82 |
|
83 public void Save( Stream aStream ) |
|
84 { |
|
85 byte[] bytes = this; |
|
86 aStream.Write( bytes, 0, bytes.Length ); |
|
87 } |
|
88 |
|
89 public void Read( Stream aStream ) |
|
90 { |
|
91 } |
|
92 |
|
93 public void Read( Stream aStream, int aOffset, int aLength ) |
|
94 { |
|
95 byte[] bytes = new byte[ aLength ]; |
|
96 aStream.Seek( aOffset, SeekOrigin.Begin ); |
|
97 aStream.Read( bytes, 0, bytes.Length ); |
|
98 Add( bytes ); |
|
99 } |
|
100 |
|
101 public void Clear() |
|
102 { |
|
103 iData.Clear(); |
|
104 iAddressOffset = 0; |
|
105 } |
|
106 |
|
107 public byte[] ToArray() |
|
108 { |
|
109 List<byte> ret = new List<byte>( iData.Count + 1 ); |
|
110 // |
|
111 int count = iData.Count; |
|
112 for ( int i = 0; i < count; i++ ) |
|
113 { |
|
114 ret.Add( iData[ i ].Byte ); |
|
115 } |
|
116 // |
|
117 return ret.ToArray(); |
|
118 } |
|
119 #endregion |
|
120 |
|
121 #region Properties |
|
122 public int Count |
|
123 { |
|
124 get { return iData.Count; } |
|
125 } |
|
126 |
|
127 public uint AddressOffset |
|
128 { |
|
129 get { return iAddressOffset; } |
|
130 set { iAddressOffset = value; } |
|
131 } |
|
132 |
|
133 public DataBufferByte First |
|
134 { |
|
135 get |
|
136 { |
|
137 DataBufferByte ret = new DataBufferByte( 0, 0 ); |
|
138 // |
|
139 if ( Count > 0 ) |
|
140 { |
|
141 ret = iData[ 0 ]; |
|
142 } |
|
143 // |
|
144 return ret; |
|
145 } |
|
146 } |
|
147 |
|
148 public DataBufferByte Last |
|
149 { |
|
150 get |
|
151 { |
|
152 DataBufferByte ret = new DataBufferByte( 0, 0 ); |
|
153 // |
|
154 if ( Count > 0 ) |
|
155 { |
|
156 ret = iData[ Count - 1 ]; |
|
157 } |
|
158 // |
|
159 return ret; |
|
160 } |
|
161 } |
|
162 |
|
163 public AddressRange Range |
|
164 { |
|
165 get |
|
166 { |
|
167 AddressRange ret = new AddressRange(); |
|
168 if ( First != null ) |
|
169 { |
|
170 ret.Min = First.Address; |
|
171 } |
|
172 if ( Last != null ) |
|
173 { |
|
174 ret.Max = Last.Address; |
|
175 } |
|
176 return ret; |
|
177 } |
|
178 } |
|
179 |
|
180 public DataBufferUint this[ uint aAddress ] |
|
181 { |
|
182 get |
|
183 { |
|
184 DataBufferUint ret = new DataBufferUint( 0, aAddress ); |
|
185 // |
|
186 foreach ( DataBufferUint uintEntry in GetUintEnumerator() ) |
|
187 { |
|
188 if ( uintEntry.Address == aAddress ) |
|
189 { |
|
190 ret = uintEntry; |
|
191 break; |
|
192 } |
|
193 } |
|
194 // |
|
195 return ret; |
|
196 } |
|
197 } |
|
198 #endregion |
|
199 |
|
200 #region Enumerator API |
|
201 public IEnumerable<DataBufferUint> GetUintEnumerator() |
|
202 { |
|
203 // This iterator works from the bottom of the stack |
|
204 // upwards, just like Symbian OS/ARM stack allocation |
|
205 // |
|
206 // |
|
207 // Count = 12 |
|
208 // |
|
209 // [0123][4567][89AB] |
|
210 // |
|
211 int count = iData.Count; |
|
212 // |
|
213 for ( int i = count - 4; i >= 0; i -= 4 ) |
|
214 { |
|
215 DataBufferByte e0 = iData[ i + 0 ]; |
|
216 DataBufferByte e1 = iData[ i + 1 ]; |
|
217 DataBufferByte e2 = iData[ i + 2 ]; |
|
218 DataBufferByte e3 = iData[ i + 3 ]; |
|
219 // |
|
220 uint value = Combine( e0, e1, e2, e3 ); |
|
221 DataBufferUint ret = new DataBufferUint( value, e0.Address ); |
|
222 yield return ret; |
|
223 } |
|
224 } |
|
225 |
|
226 public IEnumerable<DataBufferByte> GetByteEnumerator() |
|
227 { |
|
228 int count = iData.Count; |
|
229 for ( int i = count - 1; i >= 0; i-- ) |
|
230 { |
|
231 DataBufferByte entry = iData[ i ]; |
|
232 yield return entry; |
|
233 } |
|
234 } |
|
235 #endregion |
|
236 |
|
237 #region From IEnumerable<byte> |
|
238 public IEnumerator<byte> GetEnumerator() |
|
239 { |
|
240 foreach ( DataBufferByte b in iData ) |
|
241 { |
|
242 yield return b.Byte; |
|
243 } |
|
244 } |
|
245 |
|
246 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
247 { |
|
248 foreach ( DataBufferByte b in iData ) |
|
249 { |
|
250 yield return b.Byte; |
|
251 } |
|
252 } |
|
253 #endregion |
|
254 |
|
255 #region Operators |
|
256 public static implicit operator byte[]( DataBuffer aBuffer ) |
|
257 { |
|
258 byte[] ret = aBuffer.ToArray(); |
|
259 return ret; |
|
260 } |
|
261 #endregion |
|
262 |
|
263 #region Internal methods |
|
264 private List<byte> GetRawBytes() |
|
265 { |
|
266 List<byte> ret = new List<byte>( iData.Count + 1 ); |
|
267 // |
|
268 foreach ( DataBufferByte b in iData ) |
|
269 { |
|
270 ret.Add( b.Byte ); |
|
271 } |
|
272 // |
|
273 return ret; |
|
274 } |
|
275 |
|
276 private uint Combine( params DataBufferByte[] aItems ) |
|
277 { |
|
278 if ( aItems.Length != 4 ) |
|
279 { |
|
280 throw new ArgumentException( "Expected 4 items" ); |
|
281 } |
|
282 // |
|
283 uint ret = |
|
284 ( (uint) aItems[ 0 ].Byte ) + |
|
285 ( (uint) aItems[ 1 ].Byte << 8 ) + |
|
286 ( (uint) aItems[ 2 ].Byte << 16 ) + |
|
287 ( (uint) aItems[ 3 ].Byte << 24 ) |
|
288 ; |
|
289 return ret; |
|
290 } |
|
291 #endregion |
|
292 |
|
293 #region From System.Object |
|
294 public override string ToString() |
|
295 { |
|
296 string ret = string.Empty; |
|
297 // |
|
298 List<byte> rawBytes = GetRawBytes(); |
|
299 if ( rawBytes.Count > 0 ) |
|
300 { |
|
301 DataBufferByte firstByte = First; |
|
302 uint startingAddress = firstByte.Address; |
|
303 // |
|
304 ret = SymbianUtils.Utilities.RawByteUtility.ConvertDataToText( rawBytes, true, ref startingAddress ); |
|
305 } |
|
306 // |
|
307 return ret; |
|
308 } |
|
309 #endregion |
|
310 |
|
311 #region Data members |
|
312 private uint iAddressOffset = 0; |
|
313 private List<DataBufferByte> iData = new List<DataBufferByte>(); |
|
314 #endregion |
|
315 } |
|
316 } |