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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 558 - (show annotations) (download)
Thu Jun 6 03:33:46 2013 UTC (8 years, 3 months ago) by william
File size: 23547 byte(s)
+ custom enumerator support

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

  ViewVC Help
Powered by ViewVC 1.1.22