/[RomCheater]/trunk/RomCheater/Serialization/SearchResultReader.cs
ViewVC logotype

Contents of /trunk/RomCheater/Serialization/SearchResultReader.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 551 - (show annotations) (download)
Thu Jun 6 01:54:53 2013 UTC (8 years, 2 months ago) by william
File size: 20936 byte(s)

1 #define READ_RESULTS_ON_CREATION // when defined will call GetResults() from ReadHeader()
2 #region Logging Defines
3 // include this any class or method that required logging, and comment-out what is not needed
4
5 #region Enabled logging levels
6 #define LOGGING_ENABLE_INFO
7 #define LOGGING_ENABLE_WARN
8 #define LOGGING_ENABLE_DEBUG
9 #define LOGGING_ENABLE_VERBOSEDEBUG
10 #define LOGGING_ENABLE_ERROR
11 #define LOGGING_ENABLE_VERBOSEERROR
12 #define LOGGING_ENABLE_PROFILER
13 #endregion
14 #endregion
15 using System;
16 using System.Collections.Generic;
17 using System.Linq;
18 using System.Text;
19 using RomCheater.Docking.MemorySearch;
20 using RomCheater.Logging;
21 using System.IO;
22 using Utilities.TransparentControls;
23 using Sojaner.MemoryScanner.MemoryProviers;
24 using RomCheater.PluginFramework.Interfaces;
25 using System.Windows.Forms;
26 using RomCheater.Core;
27 using System.Diagnostics;
28
29 namespace RomCheater.Serialization
30 {
31 public interface ISearchResultReader : ISerializedResult
32 {
33 //ResultType<TValue> GetNextResult<TValue>() where TValue : IConvertible;
34 }
35
36 public interface ISerializedResult : ISerializedResult<ulong> { }
37 public interface ISerializedResult<T> where T: IConvertible
38 {
39 ResultReaderCollection GetResultCollection();
40 bool ContainsAddress(uint address);
41 bool ContainsAddress(uint address,out int index);
42 void GetResultAtIndex(int index, out StructResultType<T> result);
43 void UpdateResultValuesFromMemory(ref StructResultType<T>[] results, IAcceptsProcessAndConfig iapc);
44 }
45
46
47
48 #region public class ResultReaderEnumerator : IEnumerator<StructResultType<ulong>>
49 public class ResultReaderEnumerator : IEnumerator<StructResultType<ulong>>
50 {
51 //private IEnumerator<StructResultType<ulong>> _enumerator;
52
53 private int _index = 0;
54 private int index { get { return _index; } set { _index = value; } }
55 private SearchResultReader _reader;
56 private SearchResultReader reader { get { CheckReaderNull(); return _reader; } set { _reader = value; CheckReaderNull(); } }
57
58
59
60 private int MinimumIndex { get { return this.reader.MinimumIndex; } }
61 private int MaximumIndex { get { return this.reader.MaximumIndex; } }
62
63
64 #region Exceptions
65 private void CheckReaderNull()
66 {
67 if (_reader == null)
68 {
69 throw new ArgumentNullException("reader", "Reader cannot be null");
70 }
71 }
72 private void CheckIndexLessThanMin()
73 {
74 if (_index < MinimumIndex)
75 {
76 throw new ArgumentOutOfRangeException("index", string.Format("index cannot be less than {0}", MinimumIndex));
77 }
78 }
79 private void CheckIndexGreaterThanMax()
80 {
81 if (_index > MaximumIndex)
82 {
83 throw new ArgumentOutOfRangeException("index", string.Format("index cannot be greater than {0}", MaximumIndex));
84 }
85 }
86 #endregion
87
88 public ResultReaderEnumerator(SearchResultReader reader)
89 {
90 this.reader = reader;
91 this.index = -1;
92 }
93
94 public StructResultType<ulong> Current
95 {
96 get
97 {
98 // result the current entry (at position)
99 //throw new NotImplementedException();
100 CheckIndexLessThanMin();
101 CheckIndexGreaterThanMax();
102 StructResultType<ulong> result = StructResultType<ulong>.Empty;
103 reader.GetResultAtIndex(this.index, out result);
104 return result;
105 }
106 }
107
108 public void Dispose()
109 {
110 //throw new NotImplementedException();
111 }
112
113 object System.Collections.IEnumerator.Current
114 {
115 get { return this.Current; }
116 }
117
118 public bool MoveNext()
119 {
120 this.index++; // increment after processing index at MinimumIndex
121 if (this.index >= this.MinimumIndex && this.index <= this.MaximumIndex)
122 {
123 return true;
124 }
125 Reset();
126 return false;
127
128 }
129
130 public void Reset()
131 {
132 this.index = -1;
133 }
134 }
135 #endregion
136
137 #region public class ResultReaderCollection : IEnumerable<StructResultType<ulong>>
138 public class ResultReaderCollection : IEnumerable<StructResultType<ulong>>
139 {
140 private SearchResultReader _reader;
141 private SearchResultReader reader { get { CheckReaderNull(); return _reader; } set { _reader = value; CheckReaderNull(); } }
142
143
144 public ResultReaderCollection(SearchResultReader reader)
145 {
146 this.reader = reader;
147 }
148
149 #region Exceptions
150 private void CheckReaderNull()
151 {
152 if (_reader == null)
153 {
154 throw new ArgumentNullException("reader", "Reader cannot be null");
155 }
156 }
157 #endregion
158
159 public IEnumerator<StructResultType<ulong>> GetEnumerator()
160 {
161 return new ResultReaderEnumerator(_reader);
162 }
163
164 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
165 {
166 return GetEnumerator();
167 }
168 }
169 #endregion
170
171
172
173 #region public class SearchResultReader : SerializationReader, ISearchResultReader, ISerializedResult
174 public class SearchResultReader : SerializationReader, ISearchResultReader, ISerializedResult<ulong>
175 {
176 private Guid _ResultGuid;
177 private Guid ResultGuid { get { return _ResultGuid; } set { _ResultGuid = value; } }
178 public int MinimumIndex { get { return 0; } }
179 public int MaximumIndex { get { return this.ResultCount - 1; } }
180
181 private long ResultDataOffset = 0;
182 ////private long CurrentResultOffset = 0;
183 ////public SearchResultReader() : base() { ReadHeader(); }
184 //[Obsolete("SearchResultReader(Guid guid) should not be used")]
185 //public SearchResultReader(Guid guid) : base(guid, false) { ResultGuid = guid; ReadHeader(); }
186 //[Obsolete("SearchResultReader(Guid guid, bool delete) should not be used")]
187 //public SearchResultReader(Guid guid, bool delete) : base(guid, delete) { ResultGuid = guid; ReadHeader(); }
188
189
190 #region ISerializedResult<T> members
191 public ResultReaderCollection GetResultCollection()
192 {
193 ResultReaderCollection collection = new ResultReaderCollection(this);
194 return collection;
195 }
196 public bool ContainsAddress(uint address)
197 {
198 int index = 0;
199 return ContainsAddress(address, out index);
200 }
201 public bool ContainsAddress(uint address, out int index)
202 {
203 bool contains = false;
204 index = 0;
205 foreach (var k in this.results)
206 {
207 if (k.Address == address)
208 {
209 contains = true;
210 break;
211 }
212 index++;
213 }
214 return contains;
215
216
217 //#error ContainsAddress - Not Implemented - need update for change to GetResults()
218
219 // foreach (var result in GetResults())
220 // {
221 // if (cancel_method.Invoke()) { break; }
222 // if (result.Address == address)
223 // {
224 // if (contains)
225 // {
226 // throw new ArgumentOutOfRangeException("address", string.Format("Found more than one result that matched address: 0x{0} - index={1}", address.ToString("X"), index));
227 // }
228 // contains = true;
229 // break; // should never throw the exception, if we break here (only returning/checking the first found address
230 // }
231 // index++;
232 // }
233
234 }
235 public void GetResultAtIndex(int index, out StructResultType<ulong> result)
236 {
237 result = StructResultType<ulong>.Empty;
238 result = this.results[index];
239 //#error GetResultAtIndex - Not Implemented - need update for change to GetResults()
240 // int count = 0;
241 // foreach (var entry in GetResults())
242 // {
243 // if (index == count)
244 // {
245 // result = entry;
246 // break;
247 // }
248 // count++;
249 // }
250 }
251
252 public void UpdateResultValuesFromMemory(ref StructResultType<ulong>[] results, IAcceptsProcessAndConfig iapc)
253 {
254 Stopwatch st = new Stopwatch();
255 st.Start();
256 List<uint> addresses = new List<uint>();
257 results.ToList().ForEach(s => addresses.Add(s.Address));
258 using (GenericMemoryProvider provider = new GenericMemoryProvider(iapc))
259 {
260 byte[][] values;
261 provider.OpenProvider();
262 provider.UpdateAddressArray(addresses.ToArray(), BitTools.SizeOf<uint>(datatype), out values);
263 provider.CloseProvider();
264
265 for (int i = 0; i < results.Length; i++)
266 {
267 if (this.cancel_method.Invoke())
268 {
269 logger.Warn.WriteLine("UpdateResultValuesFromMemory - operation cancelled at [ResultIndex=0x{0} ChunkCount=0x{1}]", i.ToString("X"), results.Length.ToString("X"));
270 break;
271 }
272 ulong value = 0;
273 byte[] data = values[i];
274 switch (datatype)
275 {
276 case SearchDataTypes._8bits: value = data[0]; break;
277 case SearchDataTypes._16bits: value = BitConverter.ToUInt16(data, 0); break;
278 case SearchDataTypes._32bits: value = BitConverter.ToUInt32(data, 0); break;
279 case SearchDataTypes._64bits: value = BitConverter.ToUInt64(data, 0); break;
280 }
281 results[i].Value = value;
282 logger.Profiler.WriteLine("UpdateResultValuesFromMemory [ResultIndex=0x{0} ChunkCount=0x{1}] has taken a total of {2} seconds to complete", i.ToString("X"), results.Length.ToString("X"), st.Elapsed.TotalSeconds.ToString());
283
284
285 string message = string.Format(" -> Updateing values [ResultIndex=0x{0} of ChunkCount=0x{1}]", i.ToString("X"), results.Length.ToString("X"));
286 double double_percent_done = 100.0 * (double)((double)i / (double)results.Length);
287 if (((double)i % ((double)results.Length) * 0.25) == 0)
288 {
289 update_progress.Invoke((int)double_percent_done, message);
290 }
291 }
292 st.Stop();
293 logger.Profiler.WriteLine("UpdateResultValuesFromMemory [ChunkCount=0x{0}] took a total of {1} seconds to complete", results.Length.ToString("X"), st.Elapsed.TotalSeconds.ToString());
294 }
295 }
296
297 #endregion
298
299 private StructResultType<ulong>[] results = new StructResultType<ulong>[0];
300
301 private bool _unsigned;
302 private bool unsigned { get { return _unsigned; } set { _unsigned = value; } }
303 private SearchDataTypes _datatype;
304 private SearchDataTypes datatype { get { return _datatype; } set { _datatype = value; } }
305 private Action<int, string> _update_progress;
306 private Action<int, string> update_progress { get { return _update_progress; } set { _update_progress = value; } }
307 private Func<bool> _cancel_method;
308 private Func<bool> cancel_method { get { return _cancel_method; } set { _cancel_method = value; } }
309
310 public SearchResultReader(Guid guid, bool unsigned, SearchDataTypes datatype, Action<int, string> update_progress, Func<bool> cancelmethod) : this(guid, false, unsigned, datatype, update_progress, cancelmethod) { }
311 public SearchResultReader(Guid guid, bool delete, bool unsigned, SearchDataTypes datatype, Action<int, string> update_progress, Func<bool> cancelmethod)
312 : base(guid, delete)
313 {
314 this.unsigned = unsigned;
315 this.datatype = datatype;
316 this.update_progress = update_progress;
317 this.cancel_method = cancel_method;
318 ReaderGuid = guid;
319 ReadHeader();
320 }
321 protected override string TemporaryFolder { get { return SearchResultsConstants.SearchResultsFolder; } }
322 private void ReadHeader()
323 {
324 try
325 {
326 using (FileStream fs = CreateReader())
327 {
328 using (BinaryReader binReader = new BinaryReader(fs))
329 {
330 //int ResultsRead = 0;
331 // SRD (string)
332 string magic = Encoding.UTF8.GetString(binReader.ReadBytes(3));
333 string SRD = "SRD";
334 if (magic != SRD)
335 {
336 throw new InvalidOperationException(string.Format("Encountered unexpected magic: {0} expected: {1}", magic, SRD));
337 }
338 // version (int)
339 int version = binReader.ReadInt32();
340
341 if (version == 1)
342 {
343 // do nothing
344 }
345 else if (version == 2)
346 {
347 int guid_array_length = binReader.ReadInt32();
348 byte[] guid_array = new byte[guid_array_length];
349 binReader.Read(guid_array, 0, guid_array_length);
350 Guid g = new Guid(guid_array);
351 if (g != ResultGuid)
352 {
353 throw new InvalidOperationException(string.Format("Encountered wrong search results guid: read '{1}' excpected '{2}'", g.ToString(), ResultGuid.ToString()));
354 }
355 }
356 else
357 {
358 throw new InvalidOperationException(string.Format("Encountered unexpected version: {0} expected: {1} or {2}", version, 1, 2));
359 }
360 // resultcount
361 int resultcount = binReader.ReadInt32();
362 if (resultcount == 0)
363 {
364 throw new InvalidOperationException(string.Format("Result Count is zero"));
365 }
366 ResultCount = resultcount;
367 ResultDataOffset = binReader.BaseStream.Position;
368
369
370 #if READ_RESULTS_ON_CREATION
371 // this opperation may use alot of memory
372 GetResults(binReader);
373 #endif
374
375 binReader.Close();
376 }
377 fs.Close();
378 }
379 }
380 catch (System.IO.EndOfStreamException) { }
381 }
382 #region ISearchResultReader members
383 public bool ReadCurrentAddess { get; private set; }
384 public bool ReadCurrentValue { get; private set; }
385
386 //[Obsolete("GetNextResult has been replaced by GetResults")]
387 //public ResultType<TValue> GetNextResult<TValue>() where TValue : IConvertible
388 //{
389 // return new ResultType<TValue>();
390 //}
391 #endregion
392
393
394 #region
395 private void GetResults(BinaryReader br)
396 {
397 results = new StructResultType<ulong>[this.ResultCount];
398 try
399 {
400 for (int i = 0; i < ResultCount; i++)
401 {
402 StructResultType<ulong> result = StructResultType<ulong>.Empty;
403 uint Address = br.ReadUInt32();
404 ulong Value = 0;
405 switch (datatype)
406 {
407 case SearchDataTypes._8bits:
408 if (unsigned) { Value = br.ReadByte(); } else { Value = (ulong)br.ReadSByte(); }
409 break;
410 case SearchDataTypes._16bits:
411 if (unsigned) { Value = br.ReadUInt16(); } else { Value = (ulong)br.ReadInt16(); }
412 break;
413 case SearchDataTypes._32bits:
414 if (unsigned) { Value = br.ReadUInt32(); } else { Value = (ulong)br.ReadInt32(); }
415 break;
416 case SearchDataTypes._64bits:
417 if (unsigned) { Value = br.ReadUInt64(); } else { Value = (ulong)br.ReadInt64(); }
418 break;
419 }
420 result = new StructResultType<ulong>(Address, Value);
421 results[i] = result;
422 }
423 }
424 catch (Exception ex)
425 {
426 logger.Error.WriteLine("Failed to reader results...");
427 logger.VerboseError.WriteLine(ex.ToString());
428 results = new StructResultType<ulong>[this.ResultCount];
429 throw ex;
430 }
431 }
432 #endregion
433
434 //#region private StructResultType<ulong> GetResultAtIndex(int index)
435 //private StructResultType<ulong> GetResultAtIndex(int index)
436 //{
437 // try
438 // {
439 // //update_progress.Invoke(0, string.Empty);
440 // int data_size = sizeof(uint); // address size ... should be 4 bytes (could be 8, if we have a 64-bit address)
441 // StructResultType<ulong> result = StructResultType<ulong>.Empty;
442 // if (cancel_method.Invoke()) { return result; }
443 // using (FileStream fs = this.CreateReader())
444 // {
445 // using (BinaryReader binReader = new BinaryReader(fs))
446 // {
447 // binReader.BaseStream.Seek(this.ResultDataOffset, SeekOrigin.Begin); // seek to start of result data
448 // data_size += (int)datatype / 8;
449 // long offset = data_size * index;
450 // binReader.BaseStream.Seek(offset, SeekOrigin.Current);
451 // uint Address = binReader.ReadUInt32();
452 // ulong Value = 0;
453 // switch (datatype)
454 // {
455 // case SearchDataTypes._8bits:
456 // if (unsigned) { Value = binReader.ReadByte(); } else { Value = (ulong)binReader.ReadSByte(); }
457 // break;
458 // case SearchDataTypes._16bits:
459 // if (unsigned) { Value = binReader.ReadUInt16(); } else { Value = (ulong)binReader.ReadInt16(); }
460 // break;
461 // case SearchDataTypes._32bits:
462 // if (unsigned) { Value = binReader.ReadUInt32(); } else { Value = (ulong)binReader.ReadInt32(); }
463 // break;
464 // case SearchDataTypes._64bits:
465 // if (unsigned) { Value = binReader.ReadUInt64(); } else { Value = (ulong)binReader.ReadInt64(); }
466 // break;
467 // }
468 // result = new StructResultType<ulong>(Address, Value);
469 // }
470 // }
471 // //double percent_done = 100.0 * ((double)index / (double)reader.ResultCount);
472 // //string message = string.Format("-> Reading Result at index: 0x{0}", index.ToString("X"));
473 // //update_progress((int)percent_done, message);
474 // return result;
475 // }
476 // catch (Exception ex)
477 // {
478 // logger.Error.WriteLine("GetResultAtIndex...Failed to read the stream at index: 0x{0}", index.ToString("X"));
479 // logger.VerboseError.WriteLine(ex.ToString());
480 // return StructResultType<ulong>.Empty;
481 // }
482 //}
483 //#endregion
484
485 }
486 #endregion
487 }

  ViewVC Help
Powered by ViewVC 1.1.22