ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater/Serialization/SearchResultReader.cs
Revision: 812
Committed: Tue Apr 15 14:52:10 2014 UTC (9 years, 5 months ago) by william
File size: 23986 byte(s)
Log Message:
+ update logging to use Enterpise.Logging -- more work is still needed

File Contents

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