Advertisement
AndrewHaxalot

MemSearch.cs

Jan 29th, 2014
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 76.63 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Windows.Forms;
  6. using Ionic.Zip;
  7.  
  8. using FTDIUSBGecko;
  9.  
  10. namespace GeckoApp
  11. {
  12.     public enum SearchSize
  13.     {
  14.         Bit8,
  15.         Bit16,
  16.         Bit32,
  17.         Single
  18.     }
  19.  
  20.     public enum SearchType
  21.     {
  22.         Exact,
  23.         Unknown,
  24.         Old,
  25.         Diff
  26.     }
  27.  
  28.     public enum ComparisonType
  29.     {
  30.         Equal,
  31.         NotEqual,
  32.         Lower,
  33.         LowerEqual,
  34.         Greater,
  35.         GreaterEqual,
  36.         DifferentBy,
  37.         DifferentByLess,
  38.         DifferentByMore
  39.     }
  40.  
  41.     public class SearchComparisonInfo
  42.     {
  43.         public ComparisonType comparisonType;
  44.         public UInt32 value;
  45.         public SearchType searchType;
  46.  
  47.         public SearchComparisonInfo()
  48.         {
  49.             comparisonType = ComparisonType.Equal;
  50.             value = 0;
  51.             searchType = SearchType.Exact;
  52.         }
  53.  
  54.         public SearchComparisonInfo(ComparisonType ctype, UInt32 searchValue, SearchType stype)
  55.         {
  56.             comparisonType = ctype;
  57.             value = searchValue;
  58.             searchType = stype;
  59.         }
  60.     }
  61.  
  62.     [Serializable()]
  63.     public class SearchResult
  64.     {
  65.         private UInt32 PAddress;
  66.         private UInt32 PValue;
  67.         private UInt32 POldValue;
  68.  
  69.         public UInt32 address { get { return PAddress; } }
  70.         public UInt32 value { get { return PValue; } }
  71.         public UInt32 oldValue { get { return POldValue; } }
  72.  
  73.         public SearchResult(UInt32 address,UInt32 value,UInt32 old)
  74.         {
  75.             PAddress = address;
  76.             PValue = value;
  77.             POldValue = old;
  78.         }
  79.     }
  80.  
  81.     public class DumpRange
  82.     {
  83.         public UInt32 rangeLength;
  84.         public UInt32 streamOffset;
  85.  
  86.         private UInt32 PStartAddress;
  87.         private UInt32 PEndAddress;
  88.  
  89.         public UInt32 startAddress
  90.         {
  91.             get
  92.             {
  93.                 return PStartAddress;
  94.             }
  95.             set
  96.             {
  97.                 PStartAddress = value;
  98.             }
  99.         }
  100.         public UInt32 endAddress {
  101.             get
  102.             {
  103.                 return PEndAddress;
  104.             }
  105.             set
  106.             {
  107.                 PEndAddress = value;
  108.             }
  109.         }
  110.  
  111.         public DumpRange()
  112.         {
  113.         }
  114.  
  115.         public DumpRange(UInt32 startAddress)
  116.         {
  117.             PStartAddress = startAddress;
  118.         }
  119.  
  120.         public DumpRange(UInt32 startAddress, UInt32 endAddress)
  121.         {
  122.             PStartAddress = startAddress;
  123.             PEndAddress = endAddress;
  124.         }
  125.     }
  126.  
  127.     public struct StringResult
  128.     {
  129.         public String SAddress;
  130.         public String SValue;
  131.         public String SOldValue;
  132.     }
  133.    
  134.     public class MemSearch
  135.     {
  136.         const int pageSize = 256;
  137.  
  138.         //private List<SearchResult> resList;
  139.         private List<UInt32> resultAddressList;
  140.         private SearchSize sSize;
  141.         private int cPage;
  142.         private int cPages;
  143.         private int oldSelectedRow;
  144.         private bool InitialSearch;
  145.  
  146.         public SearchSize searchSize
  147.             { get { return sSize; } }
  148.        
  149.         private bool UnknownStart;
  150.         private UInt32 UnknownLAddress;
  151.         private UInt32 UnknownHAddress;
  152.  
  153.         private USBGecko gecko;
  154.         private DataGridView gView;
  155.         private Button prvButton;
  156.         private Button nxButton;
  157.         private Label resLab;
  158.         private NumericUpDown pageUpDown;
  159.  
  160.         private MemoryStream orgStream;
  161.         private MemoryStream cmpStream;
  162.         public Dump oldDump;
  163.         public Dump newDump;
  164.         private Dump undoDump;
  165.         private List<UInt32> undoList;
  166.         private int dumpNum;
  167.         public int DumpNum
  168.         {
  169.             get { return dumpNum; }
  170.         }
  171.         private SearchHistoryManager searchHistory;
  172.  
  173.         private bool NewSearch = true;
  174.  
  175.         private ExceptionHandler exceptionHandling;
  176.  
  177.         private bool PBlockDump;
  178.         private UInt32 PTotalBlockSize;
  179.         private UInt32 PBlocksDumpedSize;
  180.         private int PBlockID;
  181.         private int PBlockCount;
  182.         private UInt32 PBlockStart;
  183.         private UInt32 PBlockEnd;
  184.         private String displayType;
  185.         public String DisplayType
  186.         {
  187.             get { return displayType; }
  188.             set { displayType = value; }
  189.         }
  190.         public bool blockDump
  191.         { get { return PBlockDump; } }
  192.         public UInt32 totalBlockSize
  193.         { get { return PTotalBlockSize; } }
  194.         public UInt32 blocksDumpedSize
  195.         { get { return PBlocksDumpedSize; } }
  196.         public int blockID
  197.         { get { return PBlockID; } }
  198.         public int blockCount
  199.         { get { return PBlockCount; } }
  200.         public UInt32 blockStart
  201.         { get { return PBlockStart; } }
  202.         public UInt32 blockEnd
  203.         { get { return PBlockEnd; } }
  204.        
  205.  
  206.         public MemSearch(USBGecko uGecko,DataGridView uGView,Button uPrvButton,Button uNxButton,
  207.             Label UResLab, NumericUpDown UPageUpDown, ExceptionHandler UEHandler)
  208.         {
  209.             exceptionHandling = UEHandler;
  210.  
  211.             gecko = uGecko;
  212.             gView = uGView;
  213.  
  214.             prvButton = uPrvButton;
  215.             nxButton = uNxButton;
  216.             resLab = UResLab;
  217.             pageUpDown = UPageUpDown;
  218.  
  219.             pageUpDown.ValueChanged += UpDownValueChanged;
  220.             nxButton.Click += nextPage;
  221.             prvButton.Click += previousPage;
  222.  
  223.             //resList = new List<SearchResult>();
  224.             resultAddressList = new List<uint>();
  225.             undoList = new List<uint>();
  226.  
  227.             PBlockDump = false;
  228.  
  229.             dumpNum = 0;
  230.  
  231.             searchHistory = new SearchHistoryManager();
  232.  
  233.         }
  234.  
  235.         void UpDownValueChanged(object sender, EventArgs e)
  236.         {
  237.             cPage = Convert.ToInt32(pageUpDown.Value) - 1;
  238.             PrintPageAlt();
  239.         }
  240.  
  241.         //private void PrintPage()
  242.         //{
  243.         //    // Make sure we don't go before the first page...
  244.         //    if (cPage <= 0)
  245.         //    {
  246.         //        cPage = 0;
  247.         //        prvButton.Enabled = false;
  248.         //    }
  249.         //    else
  250.         //    {
  251.         //        // Only enable previous button if current page is > 0
  252.         //        prvButton.Enabled = true;
  253.         //    }
  254.  
  255.         //    // ...or after the last page
  256.         //    if (cPage >= cPages - 1)
  257.         //    {
  258.         //        cPage = cPages - 1;
  259.         //        if (cPage < 0) cPage = 0;
  260.         //        nxButton.Enabled = false;
  261.         //    }
  262.         //    else
  263.         //    {
  264.         //        // Only enable next button if there are multiple pages and we aren't on the last page
  265.         //        nxButton.Enabled = (cPages > 1);
  266.         //    }
  267.  
  268.         //    resLab.Text = resList.Count.ToString() + " results (page "
  269.         //     + (cPage + 1).ToString() + "/"
  270.         //     + cPages.ToString() + ")";
  271.  
  272.         //    int i = 0;
  273.         //    String addr, value, oldv, diff;
  274.  
  275.         //    int strLength;
  276.         //    switch (sSize)
  277.         //    {
  278.         //        case SearchSize.Bit8: strLength = 2; break;
  279.         //        case SearchSize.Bit16: strLength = 4; break;
  280.         //        default: strLength = 8; break;
  281.         //    }
  282.  
  283.         //    //gView.Rows.Clear();
  284.         //    int start = cPage * pageSize;
  285.         //    int end = Math.Min(cPage * pageSize + pageSize, resList.Count);
  286.         //    int count = end - start;
  287.         //    if (count < gView.Rows.Count)
  288.         //    {
  289.         //        gView.Rows.Clear();
  290.         //    }
  291.         //    int addCount = count - gView.Rows.Count;
  292.         //    if (addCount > 0)
  293.         //    {
  294.         //        gView.Rows.Add(addCount);
  295.         //    }
  296.  
  297.         //    for (int j = start; j < end; j++)
  298.         //    {
  299.         //        SearchResult result = resList[j];
  300.  
  301.         //        addr = fixString(Convert.ToString(result.address, 16).ToUpper(), 8);
  302.         //        if (displayType == "Hex")
  303.         //        {
  304.         //            value = fixString(Convert.ToString(result.value, 16).ToUpper(), strLength);
  305.         //            oldv = fixString(Convert.ToString(result.oldValue, 16).ToUpper(), strLength);
  306.         //            diff = fixString(Convert.ToString(result.value - result.oldValue, 16).ToUpper(), strLength);
  307.         //        }
  308.         //        else if (displayType == "Dec")
  309.         //        {
  310.         //            value = ((int)result.value).ToString();
  311.         //            oldv = ((int)result.oldValue).ToString();
  312.         //            diff = ((int)(result.value - result.oldValue)).ToString();
  313.         //        }
  314.         //        else
  315.         //        {
  316.         //            value = GlobalFunctions.UIntToSingle(result.value).ToString("g5");
  317.         //            oldv = GlobalFunctions.UIntToSingle(result.oldValue).ToString("g5");
  318.         //            diff = GlobalFunctions.UIntToSingle(result.value - result.oldValue).ToString("g5");
  319.         //        }
  320.         //        gView.Rows[i].Cells[0].Value = addr;
  321.         //        if (!InitialSearch)
  322.         //        {
  323.         //            gView.Rows[i].Cells[1].Value = oldv;
  324.         //            gView.Rows[i].Cells[3].Value = diff;
  325.         //        }
  326.         //        else
  327.         //        {
  328.         //            gView.Rows[i].Cells[1].Value = "";
  329.         //            gView.Rows[i].Cells[3].Value = "";
  330.         //        }
  331.         //        gView.Rows[i].Cells[2].Value = value;
  332.         //        i++;
  333.         //    }
  334.         //}
  335.  
  336.         private void PrintPageAlt()
  337.         {
  338.             // Make sure we don't go before the first page...
  339.             if (cPage <= 0)
  340.             {
  341.                 cPage = 0;
  342.                 prvButton.Enabled = false;
  343.             }
  344.             else
  345.             {
  346.                 // Only enable previous button if current page is > 0
  347.                 prvButton.Enabled = true;
  348.             }
  349.  
  350.             // ...or after the last page
  351.             if (cPage >= cPages - 1)
  352.             {
  353.                 cPage = cPages - 1;
  354.                 if (cPage < 0) cPage = 0;
  355.                 nxButton.Enabled = false;
  356.             }
  357.             else
  358.             {
  359.                 // Only enable next button if there are multiple pages and we aren't on the last page
  360.                 nxButton.Enabled = (cPages > 1);
  361.             }
  362.  
  363.             resLab.Text = resultAddressList.Count.ToString() + " results ("
  364.              + cPages.ToString() + " pages)";
  365.  
  366.             int i = 0;
  367.             String addr, value, oldv, diff;
  368.  
  369.             int strLength;
  370.             switch (sSize)
  371.             {
  372.                 case SearchSize.Bit8: strLength = 2; break;
  373.                 case SearchSize.Bit16: strLength = 4; break;
  374.                 default: strLength = 8; break;
  375.             }
  376.  
  377.             int searchBytes = strLength / 2;
  378.  
  379.             //gView.Rows.Clear();
  380.             int start = cPage * pageSize;
  381.             int end = Math.Min(cPage * pageSize + pageSize, resultAddressList.Count);
  382.             int count = end - start;
  383.             if (count < gView.Rows.Count)
  384.             {
  385.                 gView.Rows.Clear();
  386.             }
  387.             int addCount = count - gView.Rows.Count;
  388.             if (addCount > 0)
  389.             {
  390.                 gView.Rows.Add(addCount);
  391.             }
  392.  
  393.             for (int j = start; j < end; j++)
  394.             {
  395.                 SearchResult result;
  396.                 if (oldDump == null)
  397.                 {
  398.                     result = new SearchResult(resultAddressList[j],
  399.                         newDump.ReadAddress(resultAddressList[j], searchBytes),
  400.                         0);
  401.                 }
  402.                 else
  403.                 {
  404.                     result = new SearchResult(resultAddressList[j],
  405.                         newDump.ReadAddress(resultAddressList[j], searchBytes),
  406.                         oldDump.ReadAddress(resultAddressList[j], searchBytes));
  407.                 }
  408.  
  409.                 addr = fixString(Convert.ToString(result.address, 16).ToUpper(), 8);
  410.                 if (displayType == "Hex")
  411.                 {
  412.                     value = fixString(Convert.ToString(result.value, 16).ToUpper(), strLength);
  413.                     oldv = fixString(Convert.ToString(result.oldValue, 16).ToUpper(), strLength);
  414.                     diff = fixString(Convert.ToString(result.value - result.oldValue, 16).ToUpper(), strLength);
  415.                 }
  416.                 else if (displayType == "Dec")
  417.                 {
  418.                     value = ((int)result.value).ToString();
  419.                     oldv = ((int)result.oldValue).ToString();
  420.                     diff = ((int)(result.value - result.oldValue)).ToString();
  421.                 }
  422.                 else
  423.                 {
  424.                     float floatVal = GlobalFunctions.UIntToSingle(result.value);
  425.                     float floatOldVal = GlobalFunctions.UIntToSingle(result.oldValue);
  426.  
  427.                     value = floatVal.ToString("g5");
  428.                     oldv = floatOldVal.ToString("g5");
  429.                     diff = (floatVal - floatOldVal).ToString("g5");
  430.                 }
  431.                 gView.Rows[i].Cells[0].Value = addr;
  432.  
  433.                 if (InitialSearch)
  434.                 {
  435.                     gView.Rows[i].Cells[1].Value = "";
  436.                     gView.Rows[i].Cells[3].Value = "";
  437.  
  438.                 }
  439.                 else if (resultAddressList[i] < oldDump.StartAddress || resultAddressList[i] > oldDump.EndAddress - searchBytes)
  440.                 {
  441.                     gView.Rows[i].Cells[1].Value = "N/A";
  442.                     gView.Rows[i].Cells[3].Value = "N/A";
  443.                 }
  444.                 else
  445.                 {
  446.                     gView.Rows[i].Cells[1].Value = oldv;
  447.                     gView.Rows[i].Cells[3].Value = diff;
  448.                 }
  449.                 gView.Rows[i].Cells[2].Value = value;
  450.                 i++;
  451.             }
  452.         }
  453.  
  454.         private void nextPage(object sender, EventArgs e)
  455.         {
  456.             //cPage++;
  457.             //PrintPage();
  458.             // Add 2, 1 because we're going to the next page,
  459.             // and another because the upDown is 1-based instead of 0-based like cPage
  460.             pageUpDown.Value = Convert.ToDecimal(cPage + 2);
  461.         }
  462.  
  463.         private void previousPage(object sender, EventArgs e)
  464.         {
  465.             //cPage--;
  466.             //PrintPage();
  467.             // Since cPage is 0-based, we don't need to subtract 1
  468.             pageUpDown.Value = Convert.ToDecimal(cPage);
  469.         }
  470.  
  471.         private String fixString(String input, int length)
  472.         {
  473.             String parse = input;
  474.             if (parse.Length > length)
  475.                 parse =
  476.                     parse.Substring(parse.Length - length, length);
  477.  
  478.             while (parse.Length < length)
  479.                 parse = "0" + parse;
  480.  
  481.             return parse;
  482.         }
  483.  
  484.         public UInt32 GetAddress(int index)
  485.         {
  486.             return resultAddressList[cPage * pageSize + index];
  487.         }
  488.  
  489.         public StringResult GetResult(int index)
  490.         {
  491.             UInt32 resultAddress = GetAddress(index);
  492.  
  493.             int strLength;
  494.             switch (sSize)
  495.             {
  496.                 case (SearchSize.Bit8): strLength = 2; break;
  497.                 case (SearchSize.Bit16): strLength = 4; break;
  498.                 default: strLength = 8; break;
  499.             }
  500.             StringResult result;
  501.             result.SAddress = fixString(Convert.ToString(resultAddress, 16).ToUpper(), 8);
  502.             result.SValue = fixString(Convert.ToString(newDump.ReadAddress32(resultAddress), 16).ToUpper(), strLength);
  503.             if (oldDump != null)
  504.             {
  505.                 result.SOldValue = fixString(Convert.ToString(oldDump.ReadAddress32(resultAddress), 16).ToUpper(), strLength);
  506.             }
  507.             else
  508.             {
  509.                 result.SOldValue = "";
  510.             }
  511.             return result;
  512.         }
  513.  
  514.         public UInt32 GetNewValueFromAddress(UInt32 resultAddress)
  515.         {
  516.             return newDump.ReadAddress(resultAddress, 4);
  517.         }
  518.  
  519.         public static UInt32 ReadStream(Stream input, int blength)
  520.         {
  521.             Byte[] buffer = new Byte[blength];
  522.             UInt32 result;
  523.  
  524.             input.Read(buffer, 0, blength);
  525.            
  526.             switch(blength)
  527.             {
  528.                  case 1: result = (UInt32)buffer[0]; break;
  529.                  case 2: result = (UInt32)ByteSwap.Swap((UInt16)BitConverter.ToUInt16(buffer, 0)); break;
  530.                 default: result = (UInt32)ByteSwap.Swap(BitConverter.ToUInt32(buffer, 0)); break;
  531.             }
  532.  
  533.             return result;
  534.         }
  535.  
  536.         private void PerformBlockSearch(Dump blockDump, List<DumpRange> dumpranges)
  537.         {
  538.             PBlockDump = true;
  539.  
  540.             PTotalBlockSize = 0;
  541.             PBlocksDumpedSize = 0;
  542.             for (int i = 0; i < dumpranges.Count; i++)
  543.                 PTotalBlockSize += dumpranges[i].rangeLength;
  544.  
  545.             PBlockCount = dumpranges.Count;
  546.  
  547.             // This is only here to satisfy the for loop condition, dump sets this to false too
  548.             gecko.CancelDump = false;
  549.  
  550.             //Stream backupStream = blockDump.getOutputStream();
  551.             //Stream[] streams = { stream, backupStream };
  552.             //Stream[] streams = { stream };
  553.  
  554.             //stream.Seek(0, SeekOrigin.Begin);
  555.  
  556.             for (int i = 0; i < dumpranges.Count && !gecko.CancelDump; i++)
  557.             {
  558.                 PBlockID = i + 1;
  559.                 PBlockStart = dumpranges[i].startAddress;
  560.                 PBlockEnd = dumpranges[i].endAddress;
  561.  
  562.                 // Seek in the seek-able stream...
  563.                 //stream.Seek(dumpranges[i].streamOffset, SeekOrigin.Begin);
  564.                 //int fillCount = (int)(dumpranges[i].streamOffset - backupStream.Position);
  565.                 //byte[] zeroes = new byte[fillCount];
  566.                
  567.                 // ZipOutputStream can't seek, so fill with zeroes
  568.                 //backupStream.Write(zeroes, 0, fillCount);
  569.  
  570.                 //gecko.Dump(dumpranges[i].startAddress, dumpranges[i].endAddress, streams);
  571.                 SafeDump(dumpranges[i].startAddress, dumpranges[i].endAddress, blockDump);
  572.  
  573.                
  574.  
  575.                 PBlocksDumpedSize += dumpranges[i].rangeLength;
  576.             }
  577.  
  578.             //backupStream.Dispose();
  579.  
  580.             PBlockDump = false;
  581.         }
  582.  
  583.         private List<DumpRange> FindDumpRanges(UInt32 startAddress, Byte valueLength, int lowIndex, int highIndex)
  584.         {
  585.             const UInt32 blockSize = 0x3E000;
  586.  
  587.             List<DumpRange> dumpranges = new List<DumpRange>();
  588.  
  589.             UInt32 lastAddress;
  590.  
  591.             if (resultAddressList.Count > 0)
  592.             {
  593.                 lastAddress = resultAddressList[lowIndex];
  594.             }
  595.             else
  596.             {
  597.                 lastAddress = startAddress;  
  598.             }
  599.            
  600.             DumpRange addRange = new DumpRange(lastAddress);
  601.             addRange.streamOffset = lastAddress - startAddress;
  602.  
  603.             // Check from lowIndex to highIndex in resultAddressList for dump ranges
  604.             for (int i = lowIndex + 1; i <= highIndex; i++)
  605.             {
  606.                 if (resultAddressList[i] >= lastAddress + blockSize)
  607.                 {
  608.                     addRange.endAddress = lastAddress + valueLength;
  609.                     addRange.rangeLength =
  610.                         addRange.endAddress - addRange.startAddress;
  611.                     dumpranges.Add(addRange);
  612.                     lastAddress = resultAddressList[i];
  613.                     addRange = new DumpRange(lastAddress);
  614.                     addRange.streamOffset = lastAddress - startAddress;
  615.                 }
  616.                 lastAddress = resultAddressList[i];
  617.             }
  618.             addRange.endAddress = lastAddress + valueLength;
  619.             addRange.rangeLength =
  620.                 addRange.endAddress - addRange.startAddress;
  621.             dumpranges.Add(addRange);
  622.             return dumpranges;
  623.         }
  624.  
  625.         private bool Compare(UInt32 given, UInt32 loExpected, UInt32 hiExpected, bool useHigh,
  626.             ComparisonType cType, UInt32 diffBy, bool floatCompare)
  627.         {
  628.             if (floatCompare)
  629.             {
  630.                 Single givenSingle = GlobalFunctions.UIntToSingle(given),
  631.                     loExpectedSingle = GlobalFunctions.UIntToSingle(loExpected),
  632.                     diffBySingle = GlobalFunctions.UIntToSingle(diffBy);
  633.                 // Bail if any of the inputs are Not a Number
  634.                 if (Single.IsNaN(givenSingle) || Single.IsNaN(loExpectedSingle) || Single.IsNaN(diffBySingle))
  635.                 {
  636.                     return false;
  637.                 }
  638.  
  639.                 switch (cType)
  640.                 {
  641.                     case ComparisonType.Equal: return (givenSingle == loExpectedSingle);
  642.                     case ComparisonType.NotEqual: return (givenSingle != loExpectedSingle);
  643.                     case ComparisonType.Greater: return (givenSingle > loExpectedSingle);
  644.                     case ComparisonType.GreaterEqual: return (givenSingle >= loExpectedSingle);
  645.                     case ComparisonType.Lower: return (givenSingle < loExpectedSingle);
  646.                     case ComparisonType.LowerEqual: return (givenSingle <= loExpectedSingle);
  647.                     case ComparisonType.DifferentBy: return (loExpectedSingle - diffBySingle == givenSingle || loExpectedSingle + diffBySingle == givenSingle);
  648.                     case ComparisonType.DifferentByLess: return (loExpectedSingle - diffBySingle < givenSingle && givenSingle < loExpectedSingle + diffBySingle);
  649.                     case ComparisonType.DifferentByMore: return (givenSingle < loExpectedSingle - diffBySingle || givenSingle > loExpectedSingle + diffBySingle);
  650.                     default: return (givenSingle == loExpectedSingle);
  651.                 }
  652.             }
  653.             else if (useHigh)
  654.             {
  655.                 switch (cType)
  656.                 {
  657.                     case ComparisonType.Equal: return (given >= loExpected && given <= hiExpected);
  658.                     case ComparisonType.NotEqual: return (given < loExpected || given > hiExpected);
  659.                     case ComparisonType.Greater: return (given > hiExpected);
  660.                     case ComparisonType.GreaterEqual: return (given >= hiExpected);
  661.                     case ComparisonType.Lower: return (given < loExpected);
  662.                     case ComparisonType.LowerEqual: return (given <= loExpected);
  663.                     default: return (given >= loExpected && given <= hiExpected);
  664.                 }
  665.             }
  666.             else
  667.             {
  668.                 switch (cType)
  669.                 {
  670.                     case ComparisonType.Equal: return (given == loExpected);
  671.                     case ComparisonType.NotEqual: return (given != loExpected);
  672.                     case ComparisonType.Greater: return (given > loExpected);
  673.                     case ComparisonType.GreaterEqual: return (given >= loExpected);
  674.                     case ComparisonType.Lower: return (given < loExpected);
  675.                     case ComparisonType.LowerEqual: return (given <= loExpected);
  676.                     case ComparisonType.DifferentBy: return (loExpected - diffBy == given || loExpected + diffBy == given);
  677.                     // Are these right?  How are they supposed to work?
  678.                     // Would ByLess with given 6 and expected 8 with diffBy 3 be true...
  679.                     // 8 - 3 = 5 < 6 OR 8 + 3 = 11 > 6 (shouldn't this be and?)
  680.                     // ByMore, using DiffBy 1 should be true...
  681.                     // 8 - 1 = 7 > 6 AND 8 + 1 = 9 < 6 (shouldn't this be or?)
  682.  
  683.                     // I'm changing these because I'm pretty sure I'm right...
  684.                     case ComparisonType.DifferentByLess: return (loExpected - diffBy < given && given < loExpected + diffBy);
  685.                     case ComparisonType.DifferentByMore: return (given < loExpected - diffBy || given > loExpected + diffBy);
  686.                     default: return (given == loExpected);
  687.                 }
  688.             }
  689.         }
  690.  
  691.         //private bool CompareRefactored(UInt32 given, UInt32 loExpected, List<SearchComparisonInfo> comparisons, bool floatCompare, SearchType sType)
  692.         private bool CompareRefactored(UInt32 newDumpVal, UInt32 oldDumpVal, UInt32 UndoDumpVal, List<SearchComparisonInfo> comparisons, bool floatCompare)
  693.         {
  694.             bool success = true;
  695.             int others = 0;    // 0 = did not run, -1 = ran and failed, 1 = ran and succeeded
  696.             int GT = 0;
  697.             int LT = 0;
  698.             bool reverseGTLT = false;
  699.             UInt32 GTValue = 0, LTValue = 0;
  700.             foreach (SearchComparisonInfo comp in comparisons)
  701.             {
  702.                 UInt32 LHS = newDumpVal;
  703.                 UInt32 RHS = comp.value;
  704.  
  705.                 SearchType sType = comp.searchType;
  706.  
  707.                 if (sType == SearchType.Unknown)
  708.                 {
  709.                     RHS = oldDumpVal;
  710.                 }
  711.                 else if (sType == SearchType.Old)
  712.                 {
  713.                     RHS = UndoDumpVal;
  714.                 }
  715.                 else if (sType == SearchType.Diff)
  716.                 {
  717.                     LHS = newDumpVal - oldDumpVal;
  718.                 }
  719.                
  720.                 success = CompareRefactored(LHS, RHS, comp.comparisonType, comp.value, floatCompare);
  721.  
  722.                 if (comp.comparisonType == ComparisonType.Equal)
  723.                 {
  724.                     // If any individual equals comparisons succeed, win immediately
  725.                     if (success) return true;
  726.                 }
  727.                 else if (comp.comparisonType == ComparisonType.GreaterEqual || comp.comparisonType == ComparisonType.Greater)
  728.                 {
  729.                     // Store this in case we need to do a reverseGTLT
  730.                     GTValue = comp.value;
  731.  
  732.                     // Indicate both that we tested (by being non-zero) and success (positive/negative)
  733.                     if (success) GT = 1;
  734.                     else GT = -1;
  735.  
  736.                     // If some LT test before us ran, and we're reversed, take note
  737.                     if (LT != 0 && GTValue > LTValue)
  738.                     {
  739.                         reverseGTLT = true;
  740.                     }
  741.                 }
  742.                 else if (comp.comparisonType == ComparisonType.Lower || comp.comparisonType == ComparisonType.LowerEqual)
  743.                 {
  744.                     LTValue = comp.value;
  745.  
  746.                     if (success) LT = 1;
  747.                     else LT = -1;
  748.  
  749.                     if (GT != 0 && GTValue > LTValue)
  750.                     {
  751.                         reverseGTLT = true;
  752.                     }
  753.                 }
  754.                 else
  755.                 {
  756.                     // all other comparisons must all be true
  757.                     // therefore, any failed fails them all
  758.  
  759.                     // as long as we didn't fail yet, and we are succeeding, note that we ran and were successful
  760.                     // however, if we ever fail once, then it will fail forever
  761.                     if (others != -1 && success) others = 1;
  762.                     else others = -1;
  763.                 }
  764.             }
  765.  
  766.             // if we got here, none of the equals have succeeded
  767.  
  768.             // if any of the others are ever false, fail
  769.             if (others < 0) return false;
  770.  
  771.             // if at least one LT or GT are true, we have some more checks to do...
  772.             if (LT > 0 || GT > 0)
  773.             {
  774.                 // if it was a reversed GTLT, then only one must be true
  775.                 // if it wasn't reversed, then both must not fail
  776.                 if (reverseGTLT)
  777.                 {
  778.                     return true;
  779.                 }
  780.                 else
  781.                 {
  782.                     return LT > -1 && GT > -1;
  783.                 }
  784.             }
  785.  
  786.             // if we got this far, then there were no GT/LT checks, or neither passed
  787.             // any failed GT/LT checks fail the compare, but untested checks can continue
  788.             if (LT < 0 || GT < 0) return false;
  789.  
  790.             // Now there are no GT/LT checks, pass or fail
  791.             // if there was any successful others tests, succeed, otherwise no tests ever succeeded
  792.             return (others > 0);
  793.         }
  794.  
  795.         private bool CompareRefactored(UInt32 given, UInt32 loExpected, ComparisonType cType, UInt32 diffBy, bool floatCompare)
  796.         {
  797.             if (floatCompare)
  798.             {
  799.                 Single givenSingle = GlobalFunctions.UIntToSingle(given),
  800.                     loExpectedSingle = GlobalFunctions.UIntToSingle(loExpected),
  801.                     diffBySingle = GlobalFunctions.UIntToSingle(diffBy);
  802.                 // Fail if any of the inputs are Not a Number
  803.                 if (Single.IsNaN(givenSingle) || Single.IsNaN(loExpectedSingle) || Single.IsNaN(diffBySingle))
  804.                 {
  805.                     return false;
  806.                 }
  807.  
  808.                 switch (cType)
  809.                 {
  810.                     case ComparisonType.Equal: return (givenSingle == loExpectedSingle);
  811.                     case ComparisonType.NotEqual: return (givenSingle != loExpectedSingle);
  812.                     case ComparisonType.Greater: return (givenSingle > loExpectedSingle);
  813.                     case ComparisonType.GreaterEqual: return (givenSingle >= loExpectedSingle);
  814.                     case ComparisonType.Lower: return (givenSingle < loExpectedSingle);
  815.                     case ComparisonType.LowerEqual: return (givenSingle <= loExpectedSingle);
  816.                     case ComparisonType.DifferentBy: return (loExpectedSingle - diffBySingle == givenSingle || loExpectedSingle + diffBySingle == givenSingle);
  817.                     case ComparisonType.DifferentByLess: return (loExpectedSingle - diffBySingle < givenSingle && givenSingle < loExpectedSingle + diffBySingle);
  818.                     case ComparisonType.DifferentByMore: return (givenSingle < loExpectedSingle - diffBySingle || givenSingle > loExpectedSingle + diffBySingle);
  819.                     default: return (givenSingle == loExpectedSingle);
  820.                 }
  821.             }
  822.             else
  823.             {
  824.                 switch (cType)
  825.                 {
  826.                     case ComparisonType.Equal: return (given == loExpected);
  827.                     case ComparisonType.NotEqual: return (given != loExpected);
  828.                     case ComparisonType.Greater: return (given > loExpected);
  829.                     case ComparisonType.GreaterEqual: return (given >= loExpected);
  830.                     case ComparisonType.Lower: return (given < loExpected);
  831.                     case ComparisonType.LowerEqual: return (given <= loExpected);
  832.                     case ComparisonType.DifferentBy: return (loExpected - diffBy == given || loExpected + diffBy == given);
  833.                     // Are these right?  How are they supposed to work?
  834.                     // Would ByLess with given 6 and expected 8 with diffBy 3 be true...
  835.                     // 8 - 3 = 5 < 6 OR 8 + 3 = 11 > 6 (shouldn't this be and?)
  836.                     // ByMore, using DiffBy 1 should be true...
  837.                     // 8 - 1 = 7 > 6 AND 8 + 1 = 9 < 6 (shouldn't this be or?)
  838.  
  839.                     // I'm changing these because I'm pretty sure I'm right...
  840.                     case ComparisonType.DifferentByLess: return (loExpected - diffBy < given && given < loExpected + diffBy);
  841.                     case ComparisonType.DifferentByMore: return (given < loExpected - diffBy || given > loExpected + diffBy);
  842.                     default: return (given == loExpected);
  843.                 }
  844.             }
  845.         }
  846.  
  847.         private void FindPairs(UInt32 sAddress, UInt32 eAddress, Byte valSize, out UInt32 firstAddress, out UInt32 lastAddress, out int firstAddressIndex, out int lastAddressIndex)
  848.         {
  849.             // TODO what is this function doing?
  850.             firstAddress = sAddress;
  851.             lastAddress = eAddress;
  852.             firstAddressIndex = 0;
  853.             lastAddressIndex = resultAddressList.Count - 1;
  854.             for (int i = 0; i < resultAddressList.Count; i++)
  855.             {
  856.                 if (sAddress <= resultAddressList[i])
  857.                 {
  858.                     firstAddress = resultAddressList[i];
  859.                     firstAddressIndex = i;
  860.                     break;
  861.                 }
  862.             }
  863.             for (int i = resultAddressList.Count - 1; i >= 0; i--)
  864.             {
  865.                 if (eAddress >= resultAddressList[i] + valSize)
  866.                 {
  867.                     lastAddress = resultAddressList[i] + valSize;
  868.                     lastAddressIndex = i;
  869.                     break;
  870.                 }
  871.             }
  872.         }
  873.  
  874.         public void Reset()
  875.         {
  876.             NewSearch = true;
  877.             InitialSearch = false;
  878.             nxButton.Enabled = false;
  879.             prvButton.Enabled = false;
  880.             resLab.Text = "";
  881.             //resList.Clear();
  882.             resultAddressList.Clear();
  883.             undoList.Clear();
  884.             gView.Rows.Clear();
  885.             if (newDump != null)
  886.             {
  887.                 //newDump.dumpStream.Close();
  888.                 //newDump.dumpStream.Dispose();
  889.                 newDump = null;
  890.             }
  891.             if (oldDump != null)
  892.             {
  893.                 //oldDump.dumpStream.Close();
  894.                 //oldDump.dumpStream.Dispose();
  895.                 oldDump = null;
  896.             }
  897.             if (undoDump != null)
  898.             {
  899.                 //undoDump.dumpStream.Close();
  900.                 //undoDump.dumpStream.Dispose();
  901.                 undoDump = null;
  902.             }
  903.  
  904.             dumpNum = 0;
  905.         }
  906.  
  907.         public bool Search(UInt32 sAddress, UInt32 eAddress, UInt32 lValue, UInt32 hValue,
  908.             bool useHValue, SearchType sType, SearchSize sSize, ComparisonType cType,
  909.             UInt32 differentBy)
  910.         {
  911.             PBlockDump = false;
  912.  
  913.             resLab.Text = "Searching";
  914.             Byte bufferlength = 0;
  915.  
  916.             switch (sSize)
  917.             {
  918.                 case (SearchSize.Bit8): bufferlength = 1; break;
  919.                 case (SearchSize.Bit16): bufferlength = 2; break;
  920.                 default: bufferlength = 4; break;
  921.             }
  922.  
  923.             bool floatCompare = sSize == SearchSize.Single;
  924.  
  925.             int oldSortedColumn = 0;
  926.             SortOrder oldSortOrder = SortOrder.Ascending;
  927.             SearchResultComparer comparer = new SearchResultComparer();
  928.             // Search process requires list to be in order by address
  929.             // We will restore the sort order afterward
  930.             if (gView.SortedColumn != null)
  931.             {
  932.                 oldSortedColumn = gView.SortedColumn.Index;
  933.                 oldSortOrder = gView.SortOrder;
  934.             }
  935.             if (oldSortedColumn != 0 || oldSortOrder != SortOrder.Ascending)
  936.             {
  937.                 comparer.sortedColumn = 0;
  938.                 comparer.descending = false;
  939.                 resultAddressList.Sort(comparer);
  940.             }
  941.  
  942.             // Do we need to do this?  Clearing the grid view makes it suck...
  943.             //gView.Rows.Clear();
  944.             this.sSize = sSize;
  945.  
  946.             // Pause Gecko - while changing blocks during block search
  947.             // the game will sometimes move forward a few frames
  948.             //bool WasRunning = (gecko.status() == WiiStatus.Running);
  949.             //bool WTF = WasRunning;
  950.             //while (WTF)
  951.             //{
  952.             //    gecko.Pause();
  953.             //    System.Threading.Thread.Sleep(100);
  954.             //    // Sometimes, the game doesn't actually pause...
  955.             //    // So loop repeatedly until it does!
  956.             //    WTF = (gecko.status() == WiiStatus.Running);
  957.             //}
  958.             //gecko.SafePause();
  959.  
  960.             bool doBlockSearch = false;
  961.             bool doCompare = false;
  962.  
  963.             Dump searchDump;
  964.             UInt32 dumpStart, dumpEnd, dumpOffset;
  965.  
  966.             dumpStart = sAddress;
  967.             dumpEnd = eAddress;
  968.             dumpOffset = 0;
  969.  
  970.             if (NewSearch || (UnknownStart && sType == SearchType.Exact))
  971.             {
  972.                 // if an unknown search is followed by an exact search, it should be treated as an initial search
  973.                 InitialSearch = true;
  974.                 dumpNum = 0;
  975.  
  976.                 // Dispose of any old dumps and lists
  977.                 if (newDump != null)
  978.                 {
  979.                     //newDump.dumpStream.Dispose();
  980.                     newDump = null;
  981.                 }
  982.                 resultAddressList.Clear();
  983.                 if (oldDump != null)
  984.                 {
  985.                     //oldDump.dumpStream.Dispose();
  986.                     oldDump = null;
  987.                 }
  988.  
  989.                 // only do compares if it's an exact search
  990.                 if (sType == SearchType.Exact)
  991.                 {
  992.                     doCompare = true;
  993.                 }
  994.                 else
  995.                 {
  996.                     // Otherwise, it's an unknown search
  997.                     UnknownLAddress = sAddress;
  998.                     UnknownHAddress = eAddress;
  999.                     UnknownStart = true;
  1000.                     NewSearch = false;      // I don't think we need this...
  1001.                 }
  1002.             }
  1003.             else
  1004.             {
  1005.                 // This is a second search...
  1006.                 InitialSearch = false;
  1007.                 doCompare = true;   // will always do a comparison
  1008.                 if (UnknownStart)
  1009.                 {
  1010.                     // if it's the search after an unknown search, check every address
  1011.                     // although double-check the start and end addresses, just in case they changed
  1012.                     dumpStart = Math.Max(UnknownLAddress, sAddress);
  1013.                     dumpEnd = Math.Min(UnknownHAddress, eAddress);
  1014.                     dumpOffset = dumpStart - UnknownLAddress;
  1015.                 }
  1016.                 else
  1017.                 {
  1018.                     // otherwise, do a block search to avoid transferring useless data
  1019.                     doBlockSearch = true;
  1020.                 }
  1021.             }
  1022.  
  1023.             // Clear out any old dumps before caching the current dumps
  1024.             if (undoDump != null)
  1025.             {
  1026.                 //undoDump.dumpStream.Dispose();
  1027.             }
  1028.             undoDump = oldDump;
  1029.             oldDump = newDump;
  1030.  
  1031.             if (undoList != resultAddressList)
  1032.             {
  1033.                 undoList.Clear();
  1034.             }
  1035.             undoList = resultAddressList;
  1036.  
  1037.             // Dump the contents of memory for the search, by either using a full dump or a block-search-dump
  1038.             try
  1039.             {
  1040.                 if (doBlockSearch)
  1041.                 {
  1042.                     UInt32 startAddress, endAddress;
  1043.                     int startAddressIndex, endAddressIndex;
  1044.                     FindPairs(sAddress, eAddress, bufferlength, out startAddress, out endAddress, out startAddressIndex, out endAddressIndex);
  1045.                     List<DumpRange> dumpRanges = FindDumpRanges(startAddress, bufferlength, startAddressIndex, endAddressIndex);
  1046.                     //orgStream = new MemoryStream((int)(fAddr - sAddr));
  1047.                     newDump = new Dump(startAddress, endAddress, dumpNum);
  1048.                     PerformBlockSearch(newDump, dumpRanges);
  1049.                     //newDump.WriteStreamToDisk();
  1050.                 }
  1051.                 else
  1052.                 {
  1053.                     newDump = new Dump(dumpStart, dumpEnd, dumpNum);
  1054.                     gecko.Dump(newDump);
  1055.                 }
  1056.             }
  1057.             catch (EUSBGeckoException e)
  1058.             {
  1059.                 exceptionHandling.HandleException(e);
  1060.             }
  1061.  
  1062.             if (doCompare)
  1063.             {
  1064.                 // The "original stream" is always the one we just read from the USB Gecko
  1065.                 //Stream originalStream, compareStream;
  1066.                 //originalStream = newDump.dumpStream;
  1067.                 //compareStream = newDump.dumpStream;
  1068.                 //// dumpOffset is 0 if sType = exact
  1069.                 //originalStream.Seek(dumpOffset, SeekOrigin.Begin);
  1070.  
  1071.                 // if sType != exact, compare against the previous dump
  1072.                 if (sType != SearchType.Exact && sType != SearchType.Diff)
  1073.                 {
  1074.                     //compareStream = oldDump.dumpStream;
  1075.                     //compareStream.Seek(0, SeekOrigin.Begin);
  1076.                     hValue = 0;
  1077.                     useHValue = false;
  1078.                 }
  1079.  
  1080.                 UInt32 val, cmpVal;
  1081.                 // assume that it's exact and change it if not
  1082.                 cmpVal = lValue;
  1083.  
  1084.                 if (resultAddressList.Count > 0)
  1085.                 {
  1086.                     // We have a working list so we will only check the values in that list
  1087.                     // Create a temporary list to write to while we read from the old one
  1088.                     List<UInt32> tempAddressList = new List<uint>();
  1089.                     foreach (UInt32 compareAddress in resultAddressList)
  1090.                     {
  1091.                         val = newDump.ReadAddress(compareAddress, bufferlength);
  1092.                         if (sType == SearchType.Unknown)
  1093.                         {
  1094.                             cmpVal = oldDump.ReadAddress(compareAddress, bufferlength);
  1095.                         }
  1096.                         else if (sType == SearchType.Old)
  1097.                         {
  1098.                             cmpVal = undoDump.ReadAddress(compareAddress, bufferlength);
  1099.                         }
  1100.                         else if (sType == SearchType.Diff)
  1101.                         {
  1102.                             val = val - oldDump.ReadAddress(compareAddress, bufferlength);
  1103.                         }
  1104.  
  1105.                         if (Compare(val, cmpVal, hValue, useHValue, cType, differentBy, floatCompare))
  1106.                         {
  1107.                             tempAddressList.Add(compareAddress);
  1108.                         }
  1109.                     }
  1110.  
  1111.                     // Copy the temporary list over
  1112.                     resultAddressList = tempAddressList;
  1113.                 }
  1114.                 else
  1115.                 {
  1116.                     for (UInt32 i = newDump.StartAddress; i < newDump.EndAddress; i += bufferlength)
  1117.                     {
  1118.                         //// There are no pre-existing addresses to compare to!  compare all addresses
  1119.                         //while (originalStream.Position + bufferlength < originalStream.Length)
  1120.                         //{
  1121.                         //    val = ReadStream(originalStream, bufferlength);
  1122.  
  1123.                         // This will either happen on the very first search if it is specific,
  1124.                         // or the second search if the first search was unknown
  1125.                         // In either case, there cannot be an Old or Diff passed in
  1126.                         val = newDump.ReadAddress(i, bufferlength);
  1127.                         if (sType != SearchType.Exact)
  1128.                         {
  1129.                             //cmpVal = ReadStream(compareStream, bufferlength);
  1130.                             cmpVal = oldDump.ReadAddress(i, bufferlength);
  1131.                         }
  1132.  
  1133.                         if (Compare(val, cmpVal, hValue, useHValue, cType, differentBy, floatCompare))
  1134.                         {
  1135.                             resultAddressList.Add(i);
  1136.                         }
  1137.                     }
  1138.                 }
  1139.             }
  1140.  
  1141.  
  1142.             //SearchHistoryItem item = new SearchHistoryItem();
  1143.  
  1144.             //item.searchDump = newDump;
  1145.             //item.resultsList = resultAddressList;
  1146.  
  1147.  
  1148.             //DateTime startTime = Logger.WriteLineTimedStarted("serializing search items");
  1149.  
  1150.             //searchHistory.SaveSearchBackground(dumpNum, resultAddressList, newDump);
  1151.             ////item.WriteCompressedZipBackground("foo.zip");
  1152.  
  1153.             //Logger.WriteLineTimedFinished("serializing search items", startTime);
  1154.  
  1155.             //startTime = Logger.WriteLineTimedStarted("deserializing search items");
  1156.  
  1157.             ////item.ReadCompressedZip("foo.zip");
  1158.  
  1159.             //Dump testDump = searchHistory.LoadSearchDump(dumpNum);
  1160.  
  1161.             //List<UInt32> testList = searchHistory.LoadSearchList(dumpNum);
  1162.  
  1163.             //Logger.WriteLineTimedFinished("deserializing search items", startTime);
  1164.  
  1165.  
  1166.             if (UnknownStart && !InitialSearch)
  1167.             {
  1168.                 // clear UnknownStart if InitialSearch is false
  1169.                 UnknownStart = false;
  1170.             }
  1171.  
  1172.             dumpNum++;
  1173.  
  1174.  
  1175.             //if (NewSearch || (UnknownStart && sType == SearchType.Exact))
  1176.             //{
  1177.             //    bool abort = false;
  1178.             //    InitialSearch = true;
  1179.             //    //orgStream = new MemoryStream((int)(eAddress - sAddress));
  1180.             //    Dump myDump = new Dump(sAddress, eAddress);
  1181.             //    resList.Clear();
  1182.             //    resultAddressList.Clear();
  1183.             //    try
  1184.             //    {
  1185.             //        gecko.CancelDump = false;
  1186.             //        //gecko.Dump(sAddress, eAddress, orgStream);
  1187.             //        gecko.Dump(myDump);
  1188.             //        orgStream = myDump.dumpStream;
  1189.             //        FileStream foo = new FileStream(Environment.CurrentDirectory + @"\searchdumps\dump0.ful", FileMode.Create);
  1190.             //        orgStream.WriteTo(foo);
  1191.             //        foo.Close();
  1192.             //        foo.Dispose();
  1193.             //        oldDump = null;
  1194.             //        newDump = myDump;
  1195.             //        orgStream.Seek(0, SeekOrigin.Begin);
  1196.             //        if (!gecko.CancelDump)
  1197.             //        {
  1198.             //            if (sType == SearchType.Exact)
  1199.             //            {
  1200.             //                //                         orgStream.Seek(0, SeekOrigin.Begin);
  1201.             //                UInt32 val;
  1202.             //                while (orgStream.Position + bufferlength < orgStream.Length)
  1203.             //                {
  1204.             //                    val = ReadStream(orgStream, bufferlength);
  1205.             //                    if (Compare(val, lValue, hValue, useHValue, cType, differentBy, floatCompare))
  1206.             //                    {
  1207.             //                        //resList.Add(new SearchResult(sAddress + (UInt32)orgStream.Position - bufferlength, val, 0));
  1208.             //                        resultAddressList.Add(sAddress + (UInt32)orgStream.Position - bufferlength);
  1209.             //                    }
  1210.             //                }
  1211.             //            }
  1212.             //            else
  1213.             //            {
  1214.             //                UnknownLAddress = sAddress;
  1215.             //                UnknownHAddress = eAddress;
  1216.             //                UnknownStart = true;
  1217.             //                NewSearch = false;
  1218.             //                abort = true;
  1219.             //            }
  1220.             //        }
  1221.             //        orgStream = null;
  1222.             //    }
  1223.             //    catch (EUSBGeckoException e)
  1224.             //    {
  1225.             //        Reset();
  1226.             //        exceptionHandling.HandleException(e);
  1227.             //        abort = true;
  1228.             //    }
  1229.             //}
  1230.             //else
  1231.             //{
  1232.             //    InitialSearch = false;
  1233.             //    try
  1234.             //    {
  1235.             //        // This branch is only executed once, the search after an unknown search
  1236.             //        if (UnknownStart)
  1237.             //        {
  1238.             //            UnknownStart = false;
  1239.             //            UInt32 sAddr = Math.Max(UnknownLAddress, sAddress);
  1240.             //            UInt32 fAddr = Math.Min(UnknownHAddress, eAddress);
  1241.             //            UInt32 offset = sAddr - UnknownLAddress;
  1242.  
  1243.             //            cmpStream = new MemoryStream((int)(fAddr - sAddr));
  1244.             //            try
  1245.             //            {
  1246.             //                gecko.CancelDump = false;
  1247.             //                gecko.Dump(sAddr, fAddr, cmpStream);
  1248.             //                if (!gecko.CancelDump)
  1249.             //                {
  1250.             //                    orgStream.Seek(offset, SeekOrigin.Begin);
  1251.             //                    cmpStream.Seek(0, SeekOrigin.Begin);
  1252.  
  1253.             //                    UInt32 oldValue, newValue;
  1254.             //                    while (cmpStream.Position + bufferlength < cmpStream.Length)
  1255.             //                    {
  1256.             //                        newValue = ReadStream(cmpStream, bufferlength);
  1257.             //                        oldValue = ReadStream(orgStream, bufferlength);
  1258.             //                        if (Compare(newValue, oldValue, 0, false, cType, differentBy, floatCompare))
  1259.             //                            resList.Add(new SearchResult(sAddr + (UInt32)cmpStream.Position - bufferlength, newValue, oldValue));
  1260.             //                    }
  1261.             //                }
  1262.             //                else
  1263.             //                {
  1264.             //                    UnknownStart = true;
  1265.             //                    NewSearch = false;
  1266.             //                    return true;
  1267.             //                }
  1268.             //            }
  1269.             //            finally
  1270.             //            {
  1271.             //                cmpStream.Close();
  1272.             //                cmpStream = null;
  1273.             //            }
  1274.             //        }
  1275.             //        else
  1276.             //        {
  1277.             //            UInt32 sAddr, fAddr;
  1278.             //            UInt32 cmpV = lValue;
  1279.             //            bool useUpper = useHValue;
  1280.             //            bool lastV = false;
  1281.             //            List<SearchResult> tempList = new List<SearchResult>();
  1282.             //            if (sType == SearchType.Unknown)
  1283.             //            {
  1284.             //                useUpper = false;
  1285.             //                lastV = true;
  1286.             //            }
  1287.             //            int lV, hV;
  1288.             //            FindPairs(sAddress, eAddress, bufferlength, out sAddr, out fAddr, out lV, out hV);
  1289.             //            orgStream = new MemoryStream((int)(fAddr - sAddr));
  1290.             //            //Insert block based search here
  1291.             //            PerformBlockSearch(sAddr, fAddr, bufferlength, lV, hV, orgStream);
  1292.             //            //gecko.Dump(sAddr, fAddr, orgStream);
  1293.             //            //end
  1294.             //            UInt32 val;
  1295.  
  1296.             //            // Compare the two dumps
  1297.             //            for (int i = lV; i <= hV && !gecko.CancelDump; i++)
  1298.             //            {
  1299.             //                if (lastV)
  1300.             //                    cmpV = resList[i].value;
  1301.             //                orgStream.Seek(resList[i].address - sAddr, SeekOrigin.Begin);
  1302.             //                val = ReadStream(orgStream, bufferlength);
  1303.             //                if (Compare(val, cmpV, hValue, useUpper, cType, differentBy, floatCompare))
  1304.             //                    tempList.Add(
  1305.             //                        new SearchResult(sAddr + (UInt32)orgStream.Position - bufferlength, val, resList[i].value));
  1306.             //            }
  1307.  
  1308.             //            // If this was canceled, don't update the results list
  1309.             //            if (!gecko.CancelDump)
  1310.             //            {
  1311.             //                resList.Clear();
  1312.             //                resList = null;
  1313.             //                resList = tempList;
  1314.             //            }
  1315.             //        }
  1316.             //    }
  1317.             //    catch (EUSBGeckoException e)
  1318.             //    {
  1319.             //        Reset();
  1320.             //        exceptionHandling.HandleException(e);
  1321.             //        return false;
  1322.             //    }
  1323.             //}
  1324.  
  1325.             //// If we were running, go back to running
  1326.             //// If we *weren't* running, *don't* go back to running
  1327.             //if (WasRunning)
  1328.             //{
  1329.             //    gecko.SafeResume();
  1330.             //}
  1331.  
  1332.             //if (orgStream != null)
  1333.             //{
  1334.             //    orgStream.Close();
  1335.             //}
  1336.             //orgStream = null;
  1337.  
  1338.             //if (resList.Count == 0 && resultAddressList.Count == 0)
  1339.             if (resultAddressList.Count == 0 && !UnknownStart)
  1340.             {
  1341.                 NewSearch = true;
  1342.                 nxButton.Enabled = false;
  1343.                 prvButton.Enabled = false;
  1344.                 resLab.Text = "No results found";
  1345.                 Reset();
  1346.                 return false;
  1347.             }
  1348.  
  1349.             NewSearch = false;
  1350.  
  1351.             //int PageCount = resList.Count / 256;
  1352.             //if (resList.Count % 256 != 0) PageCount++;
  1353.  
  1354.             //cPage = 0;
  1355.             //cPages = PageCount;
  1356.  
  1357.             //PrintPage();
  1358.  
  1359.             UpdateGridViewPage(true);
  1360.  
  1361.             return true;
  1362.         }
  1363.  
  1364.         public bool SearchRefactored(UInt32 sAddress, UInt32 eAddress, List<SearchComparisonInfo> comparisons, SearchSize searchSize)
  1365.         {
  1366.             PBlockDump = false;
  1367.  
  1368.             resLab.Text = "Searching";
  1369.             Byte bufferlength = 0;
  1370.  
  1371.             switch (searchSize)
  1372.             {
  1373.                 case (SearchSize.Bit8): bufferlength = 1; break;
  1374.                 case (SearchSize.Bit16): bufferlength = 2; break;
  1375.                 default: bufferlength = 4; break;
  1376.             }
  1377.  
  1378.             this.sSize = searchSize;
  1379.  
  1380.             bool floatCompare = searchSize == SearchSize.Single;
  1381.  
  1382.             int oldSortedColumn = 0;
  1383.             SortOrder oldSortOrder = SortOrder.Ascending;
  1384.             SearchResultComparer comparer = new SearchResultComparer();
  1385.             // Search process requires list to be in order by address
  1386.             // We will restore the sort order afterward
  1387.             if (gView.SortedColumn != null)
  1388.             {
  1389.                 oldSortedColumn = gView.SortedColumn.Index;
  1390.                 oldSortOrder = gView.SortOrder;
  1391.             }
  1392.             if (oldSortedColumn != 0 || oldSortOrder != SortOrder.Ascending)
  1393.             {
  1394.                 comparer.sortedColumn = 0;
  1395.                 comparer.descending = false;
  1396.                 resultAddressList.Sort(comparer);
  1397.             }
  1398.  
  1399.             SearchType sType = comparisons[0].searchType;
  1400.  
  1401.             bool doBlockSearch = false;
  1402.             bool doCompare = false;
  1403.  
  1404.             Dump searchDump;
  1405.             UInt32 dumpStart, dumpEnd, dumpOffset;
  1406.  
  1407.             dumpStart = sAddress;
  1408.             dumpEnd = eAddress;
  1409.             dumpOffset = 0;
  1410.  
  1411.             if (NewSearch || (UnknownStart && sType == SearchType.Exact))
  1412.             {
  1413.                 // if an unknown search is followed by an exact search, it should be treated as an initial search
  1414.                 InitialSearch = true;
  1415.                 dumpNum = 0;
  1416.  
  1417.                 // Dispose of any old dumps and lists
  1418.                 if (newDump != null)
  1419.                 {
  1420.                     //newDump.dumpStream.Dispose();
  1421.                     newDump = null;
  1422.                 }
  1423.                 resultAddressList.Clear();
  1424.                 if (oldDump != null)
  1425.                 {
  1426.                     //oldDump.dumpStream.Dispose();
  1427.                     oldDump = null;
  1428.                 }
  1429.  
  1430.                 // only do compares if it's an exact search
  1431.                 if (sType == SearchType.Exact)
  1432.                 {
  1433.                     doCompare = true;
  1434.                 }
  1435.                 else
  1436.                 {
  1437.                     // Otherwise, it's an unknown search
  1438.                     UnknownLAddress = sAddress;
  1439.                     UnknownHAddress = eAddress;
  1440.                     UnknownStart = true;
  1441.                     NewSearch = false;      // I don't think we need this...
  1442.                 }
  1443.             }
  1444.             else
  1445.             {
  1446.                 // This is a second search...
  1447.                 InitialSearch = false;
  1448.                 doCompare = true;   // will always do a comparison
  1449.                 if (UnknownStart)
  1450.                 {
  1451.                     // if it's the search after an unknown search, check every address
  1452.                     // although double-check the start and end addresses, just in case they changed
  1453.                     dumpStart = Math.Max(UnknownLAddress, sAddress);
  1454.                     dumpEnd = Math.Min(UnknownHAddress, eAddress);
  1455.                     dumpOffset = dumpStart - UnknownLAddress;
  1456.                 }
  1457.                 else
  1458.                 {
  1459.                     // otherwise, do a block search to avoid transferring useless data
  1460.                     doBlockSearch = true;
  1461.                 }
  1462.             }
  1463.  
  1464.             // Clear out any old dumps before caching the current dumps
  1465.             undoDump = oldDump;
  1466.             oldDump = newDump;
  1467.             undoList = resultAddressList;
  1468.  
  1469.             // Dump the contents of memory for the search, by either using a full dump or a block-search-dump
  1470.             if (doBlockSearch)
  1471.             {
  1472.                 UInt32 startAddress, endAddress;
  1473.                 int startAddressIndex, endAddressIndex;
  1474.                 FindPairs(dumpStart, dumpEnd, bufferlength, out startAddress, out endAddress, out startAddressIndex, out endAddressIndex);
  1475.                 List<DumpRange> dumpRanges = FindDumpRanges(startAddress, bufferlength, startAddressIndex, endAddressIndex);
  1476.                 newDump = new Dump(startAddress, endAddress, dumpNum);
  1477.                 PerformBlockSearch(newDump, dumpRanges);
  1478.             }
  1479.             else
  1480.             {
  1481.                 newDump = new Dump(dumpStart, dumpEnd, dumpNum);
  1482.                 SafeDump(dumpStart, dumpEnd, newDump);
  1483.             }
  1484.  
  1485.             if (doCompare)
  1486.             {
  1487.                 UInt32 val, cmpVal;
  1488.                 // assume that it's exact and change it if not
  1489.                 cmpVal = comparisons[0].value;
  1490.  
  1491.                 if (resultAddressList.Count > 0)
  1492.                 {
  1493.                     // We have a working list so we will only check the values in that list
  1494.                     // Create a temporary list to write to while we read from the old one
  1495.                     List<UInt32> tempAddressList = new List<uint>();
  1496.                     foreach (UInt32 compareAddress in resultAddressList)
  1497.                     {
  1498.                         UInt32 newDumpVal = newDump.ReadAddress(compareAddress, bufferlength);
  1499.                         UInt32 oldDumpVal = oldDump.ReadAddress(compareAddress, bufferlength);
  1500.                         UInt32 UndoDumpVal;
  1501.                         if (undoDump != null)
  1502.                         {
  1503.                             UndoDumpVal = undoDump.ReadAddress(compareAddress, bufferlength);
  1504.                         }
  1505.                         else
  1506.                         {
  1507.                             UndoDumpVal = oldDumpVal;
  1508.                         }
  1509.                         if (CompareRefactored(newDumpVal, oldDumpVal, UndoDumpVal, comparisons, floatCompare))
  1510.                         {
  1511.                             tempAddressList.Add(compareAddress);
  1512.                         }
  1513.                     }
  1514.  
  1515.                     // Copy the temporary list over
  1516.                     resultAddressList = tempAddressList;
  1517.                 }
  1518.                 else
  1519.                 {
  1520.                     for (UInt32 i = newDump.StartAddress; i < newDump.EndAddress; i += bufferlength)
  1521.                     {
  1522.                         // There are no pre-existing addresses to compare to!  compare all addresses
  1523.  
  1524.                         // This will either happen on the very first search if it is specific,
  1525.                         // or the second search if the first search was unknown
  1526.                         // In either case, there cannot be an Old or Diff passed in
  1527.                         UInt32 newDumpVal = newDump.ReadAddress(i, bufferlength);
  1528.                         UInt32 oldDumpVal = newDumpVal;
  1529.                         UInt32 UndoDumpVal = newDumpVal;
  1530.                         if (sType != SearchType.Exact)
  1531.                         {
  1532.                             oldDumpVal = oldDump.ReadAddress(i, bufferlength);
  1533.                             UndoDumpVal = oldDumpVal;
  1534.                         }
  1535.  
  1536.                         //if (Compare(val, cmpVal, hValue, useHValue, cType, differentBy, floatCompare))
  1537.                         if (CompareRefactored(newDumpVal, oldDumpVal, UndoDumpVal, comparisons, floatCompare))
  1538.                         {
  1539.                             resultAddressList.Add(i);
  1540.                         }
  1541.                     }
  1542.                 }
  1543.             }
  1544.  
  1545.             if (UnknownStart && !InitialSearch)
  1546.             {
  1547.                 // clear UnknownStart if InitialSearch is false
  1548.                 UnknownStart = false;
  1549.             }
  1550.  
  1551.             dumpNum++;
  1552.  
  1553.             if (resultAddressList.Count == 0 && !UnknownStart)
  1554.             {
  1555.                 DialogResult result = MessageBox.Show(null, "No search results!\n\nTo undo, press Yes\nTo restart, press No", "No search results!", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
  1556.                 bool UndoSuccess = false;
  1557.                 if (result == DialogResult.Yes)
  1558.                 {
  1559.                     UndoSuccess = UndoSearch();
  1560.                     if (!UndoSuccess)
  1561.                     {
  1562.                         MessageBox.Show("Could not undo!  Restarting search");
  1563.                     }
  1564.                 }
  1565.  
  1566.                 if (!UndoSuccess)
  1567.                 {
  1568.                     NewSearch = true;
  1569.                     nxButton.Enabled = false;
  1570.                     prvButton.Enabled = false;
  1571.                     resLab.Text = "No results found";
  1572.                     Reset();
  1573.                     return false;
  1574.                 }
  1575.             }
  1576.  
  1577.             NewSearch = false;
  1578.  
  1579.             UpdateGridViewPage(true);
  1580.  
  1581.             return true;
  1582.         }
  1583.  
  1584.         public void SafeDump(UInt32 startdump, UInt32 enddump, Dump memdump)
  1585.         {
  1586.             bool finished = false;
  1587.             while (!finished)
  1588.             {
  1589.                 try
  1590.                 {
  1591.                     gecko.Dump(startdump, enddump, memdump);
  1592.                     finished = true;
  1593.                 }
  1594.                 catch (EUSBGeckoException e)
  1595.                 {
  1596.                     exceptionHandling.HandleException(e);
  1597.                     if (startdump == memdump.ReadCompletedAddress)
  1598.                     {
  1599.                         // failed to get any more data; something is probably really wrong so let's just quit
  1600.                         finished = true;
  1601.                     }
  1602.                     else
  1603.                     {
  1604.                         startdump = memdump.ReadCompletedAddress;
  1605.                     }
  1606.                 }
  1607.             }
  1608.         }
  1609.  
  1610.  
  1611.  
  1612.         public bool UndoSearch()
  1613.         {
  1614.             if (newDump == null || oldDump == null || undoDump == null)
  1615.             {
  1616.                 return false;
  1617.             }
  1618.             //newDump.dumpStream.Dispose();
  1619.             newDump = oldDump;
  1620.             oldDump = undoDump;
  1621.             undoDump = null;
  1622.             resultAddressList.Clear();
  1623.             resultAddressList = new List<uint>(undoList);
  1624.  
  1625.             UpdateGridViewPage(true);
  1626.             return true;
  1627.         }
  1628.  
  1629.         public bool SaveSearch(string path)
  1630.         {
  1631.             return SaveSearch(path, true);
  1632.         }
  1633.  
  1634.         public bool SaveSearch(string path, bool compressed)
  1635.         {
  1636.             System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializeResults = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1637.  
  1638.             if (!compressed)
  1639.             {
  1640.                 FileStream resultFile = new FileStream(path, FileMode.Create);
  1641.                 serializeResults.Serialize(resultFile, sSize);
  1642.                 //serializeResults.Serialize(resultFile, resList);
  1643.                 // TODO SAVING SEARCHES TO FILE
  1644.                 resultFile.Close();
  1645.                 return true;
  1646.             }
  1647.  
  1648.             ZipOutputStream resultStream = new ZipOutputStream(path);
  1649.             resultStream.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed;
  1650.             resultStream.PutNextEntry("ResList");
  1651.  
  1652.             // good first guess
  1653.             //MemoryStream resultStream = new MemoryStream(12 * resList.Count);
  1654.            
  1655.             serializeResults.Serialize(resultStream, sSize);
  1656.             //serializeResults.Serialize(resultStream, resList);
  1657.  
  1658.             // TODO SAVING SEARCHES TO FILE
  1659.  
  1660.             //ZipFile outfile = new ZipFile(path);
  1661.             //outfile.AddEntry("ResList", resultStream);
  1662.             //outfile.Save();
  1663.             //outfile.Dispose();
  1664.             resultStream.Close();
  1665.             resultStream.Dispose();
  1666.             return true;
  1667.         }
  1668.  
  1669.         public void LoadIndexIntoOldSearchDump(int index)
  1670.         {
  1671.             oldDump = searchHistory.LoadSearchDump(index);
  1672.         }
  1673.  
  1674.         public void LoadIndexIntoNewSearchDump(int index)
  1675.         {
  1676.             newDump = searchHistory.LoadSearchDump(index);
  1677.         }
  1678.  
  1679.         public void LoadIndexIntoSearchList(int index)
  1680.         {
  1681.             resultAddressList = searchHistory.LoadSearchList(index);
  1682.         }
  1683.  
  1684.         public void SaveSearchToIndex(int index)
  1685.         {
  1686.             searchHistory.SaveSearchBackground(index, resultAddressList, newDump);
  1687.         }
  1688.  
  1689.         public bool LoadSearchHistory(string path)
  1690.         {
  1691.             searchHistory.LoadHistory(path, out dumpNum, out sSize);
  1692.             if (dumpNum > 0)
  1693.             {
  1694.                 newDump = searchHistory.LoadSearchDump(dumpNum);
  1695.                 resultAddressList = searchHistory.LoadSearchList(dumpNum);
  1696.             }
  1697.             if (dumpNum > 1)
  1698.                 oldDump = searchHistory.LoadSearchDump(dumpNum - 1);
  1699.             if (dumpNum > 2)
  1700.                 undoDump = searchHistory.LoadSearchDump(dumpNum - 2);
  1701.             return dumpNum == 0;
  1702.         }
  1703.  
  1704.         public bool SaveSearchHistory(string path)
  1705.         {
  1706.             searchHistory.SaveHistory(path, dumpNum, sSize);
  1707.             return true;
  1708.         }
  1709.  
  1710.         public bool LoadSearch(string path, bool compressed)
  1711.         {
  1712.  
  1713.             // TODO LOADING SEARCHES FROM FILE
  1714.             int oldSortedColumn = 0;
  1715.             SortOrder oldSortOrder = SortOrder.Ascending;
  1716.             if (gView.SortedColumn != null)
  1717.             {
  1718.                 oldSortedColumn = gView.SortedColumn.Index;
  1719.                 oldSortOrder = gView.SortOrder;
  1720.             }
  1721.  
  1722.             System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializeResults = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
  1723.  
  1724.             if (!compressed)
  1725.             {
  1726.                 FileStream resultFile = new FileStream(path, FileMode.Open);
  1727.                 sSize = (SearchSize)serializeResults.Deserialize(resultFile);
  1728.                 //resList = (List<SearchResult>)serializeResults.Deserialize(resultFile);
  1729.                 resultFile.Close();
  1730.             }
  1731.             else
  1732.             {
  1733.                 ZipFile infile = ZipFile.Read(path);
  1734.                 MemoryStream resultStream = new MemoryStream();
  1735.                 infile["ResList"].Extract(resultStream);
  1736.                 sSize = (SearchSize)serializeResults.Deserialize(resultStream);
  1737.                 //resList = (List<SearchResult>)serializeResults.Deserialize(resultStream);
  1738.                 infile.Dispose();
  1739.                 resultStream.Close();
  1740.                 resultStream.Dispose();
  1741.             }
  1742.  
  1743.             //if (resList.Count == 0)
  1744.             {
  1745.                 NewSearch = true;
  1746.                 nxButton.Enabled = false;
  1747.                 prvButton.Enabled = false;
  1748.                 resLab.Text = "No results found";
  1749.                 return false;
  1750.             }
  1751.  
  1752.             //int PageCount = resList.Count / 256;
  1753.             //if (resList.Count % 256 != 0) PageCount++;
  1754.  
  1755.             //NewSearch = false;
  1756.  
  1757.             //cPage = 0;
  1758.             //cPages = PageCount;
  1759.  
  1760.             // Restore sort
  1761.             // EDIT: User should restore sort on their own
  1762.             //       Sorting a large list can take a lot of time
  1763.             //if (oldSortOrder == SortOrder.Ascending)
  1764.             //{
  1765.             //    gView.Sort(gView.Columns[oldSortedColumn], System.ComponentModel.ListSortDirection.Ascending);
  1766.             //}
  1767.             //else
  1768.             //{
  1769.             //    gView.Sort(gView.Columns[oldSortedColumn], System.ComponentModel.ListSortDirection.Descending);
  1770.             //}
  1771.             //SortResults();
  1772.  
  1773.             //PrintPage();
  1774.  
  1775.             UpdateGridViewPage(true);
  1776.  
  1777.             return true;
  1778.         }
  1779.  
  1780.         public void DeleteResults(DataGridViewSelectedRowCollection deletingCollection)
  1781.         {
  1782.             int pageOffset = cPage * pageSize;
  1783.             List<int> deletedIndices = new List<int>();
  1784.            
  1785.             // Get all the indices
  1786.             foreach (DataGridViewRow row in gView.SelectedRows)
  1787.             {
  1788.                 deletedIndices.Add(row.Index);
  1789.             }
  1790.  
  1791.             // Sort them, descending
  1792.             deletedIndices.Sort();
  1793.             deletedIndices.Reverse();
  1794.  
  1795.             // Delete, starting from the last one
  1796.             for (int i = 0; i < deletedIndices.Count; i++)
  1797.             {
  1798.                 resultAddressList.RemoveAt(pageOffset + deletedIndices[i]);
  1799.             }
  1800.  
  1801.             //int start = pageOffset + deletingCollection[0].Index;
  1802.             //// Supposedly this GetRowCount is faster...
  1803.             //int endIndex = gView.Rows.GetRowCount(DataGridViewElementStates.Selected) - 1;
  1804.             //int end = pageOffset + deletingCollection[endIndex].Index;
  1805.             //if (end < start)
  1806.             //{
  1807.             //    int temp = end;
  1808.             //    end = start;
  1809.             //    start = temp;
  1810.             //}
  1811.             //int deletingCount = (end - start) + 1;  // if end = start (because we only have one row to delete), we want 1
  1812.             //resList.RemoveRange(start, deletingCount);
  1813.  
  1814.             UpdateGridViewPage();
  1815.         }
  1816.  
  1817.         public void DeleteResult(int index)
  1818.         {
  1819.             // Deleting results can potentially change the page count
  1820.             resultAddressList.RemoveAt(cPage * pageSize + index);
  1821.  
  1822.             UpdateGridViewPage();
  1823.         }
  1824.  
  1825.         public void UpdateGridViewPage()
  1826.         {
  1827.             UpdateGridViewPage(false);
  1828.         }
  1829.  
  1830.         public void UpdateGridViewPage(bool ResizeGridView)
  1831.         {
  1832.             //int PageCount = resList.Count / 256;
  1833.             //if (resList.Count % 256 != 0) PageCount++;
  1834.  
  1835.             //if (resList.Count == 0)
  1836.             //{
  1837.             int PageCount = resultAddressList.Count / 256;
  1838.             if (resultAddressList.Count % 256 != 0) PageCount++;
  1839.             //}
  1840.             cPages = PageCount;
  1841.             pageUpDown.Maximum = Convert.ToDecimal(cPages);
  1842.  
  1843.             bool HadSelectedCells = gView.Rows.GetRowCount(DataGridViewElementStates.Selected) > 0;
  1844.             if (HadSelectedCells)
  1845.             {
  1846.                 // Remember what row was selected in case we need to restore it
  1847.                 // Depending on the order of selection, the earliest index may be first or last
  1848.                 oldSelectedRow = Math.Min(gView.SelectedRows[0].Index, gView.SelectedRows[gView.SelectedRows.Count - 1].Index);
  1849.             }
  1850.  
  1851.             //if (resList.Count == 0)
  1852.             //{
  1853.                 PrintPageAlt();
  1854.             //}
  1855.             //else
  1856.             //{
  1857.             //    PrintPage();
  1858.             //}
  1859.  
  1860.             if (HadSelectedCells && gView.Rows.Count > 0)
  1861.             {
  1862.                 if (oldSelectedRow >= gView.Rows.Count)
  1863.                 {
  1864.                     oldSelectedRow = gView.Rows.Count - 1;
  1865.                 }
  1866.  
  1867.                 // PrintPage selects the first row...
  1868.                 // This creates a multi-selected row issue
  1869.                 gView.Rows[0].Selected = false;
  1870.                 foreach (DataGridViewRow row in gView.SelectedRows)
  1871.                 {
  1872.                     // If multiple rows were selected (for instance, for deleting)
  1873.                     // Turn off all those rows
  1874.                     row.Selected = false;
  1875.                 }
  1876.  
  1877.                 // Must activate old row after deactivating other rows,
  1878.                 // otherwise when the old row _is_ the other row, nothing happens
  1879.                 gView.Rows[oldSelectedRow].Selected = true;
  1880.  
  1881.                 // All of this selection changing doesn't move the "current cell" box
  1882.                 // So if the user uses the arrow keys, the selected cell won't be where they expect it to be
  1883.                 // So let's move that current cell to the selected row
  1884.                 gView.CurrentCell = gView.SelectedRows[0].Cells[0];
  1885.             }
  1886.  
  1887.             if (ResizeGridView)
  1888.             {
  1889.                 int col1Width = gView.Columns[1].Width, col2Width = gView.Columns[2].Width, col3Width = gView.Columns[3].Width;
  1890.                 gView.AutoResizeColumn(1, DataGridViewAutoSizeColumnMode.AllCells);
  1891.                 gView.AutoResizeColumn(2, DataGridViewAutoSizeColumnMode.AllCells);
  1892.                 gView.AutoResizeColumn(3, DataGridViewAutoSizeColumnMode.AllCells);
  1893.  
  1894.                 // Choose the larger of the previous column width or the resized column width
  1895.                 gView.Columns[1].Width = Math.Max(col1Width, gView.Columns[1].Width);
  1896.                 gView.Columns[2].Width = Math.Max(col2Width, gView.Columns[2].Width);
  1897.                 gView.Columns[3].Width = Math.Max(col3Width, gView.Columns[3].Width);
  1898.             }
  1899.  
  1900.             // If the user holds delete down, it's possible the control never gets a chance to update
  1901.             // So we force the control to update
  1902.             gView.Update();
  1903.         }
  1904.  
  1905.         //public void RestoreSelectedRow()
  1906.         //{
  1907.         //    // We don't want multiple rows selected...
  1908.         //    while (gView.SelectedRows.Count > 0)
  1909.         //    {
  1910.         //        gView.SelectedRows[0].Selected = false;
  1911.         //    }
  1912.  
  1913.         //    if (oldSelectedRow >= gView.Rows.Count)
  1914.         //    {
  1915.         //        oldSelectedRow = gView.Rows.Count - 1;
  1916.         //    }
  1917.         //    gView.Rows[oldSelectedRow].Selected = true;
  1918.         //}
  1919.  
  1920.         public bool CanUndo()
  1921.         {
  1922.             return undoDump != null;
  1923.         }
  1924.  
  1925.         public void SortResults()
  1926.         {
  1927.             // We want the list to match the sorting of the grid view
  1928.             // This way if they, say, delete an element on the grid view, it finds the right index in the list
  1929.             SearchResultComparer comparer = new SearchResultComparer();
  1930.             comparer.sortedColumn = gView.SortedColumn.Index;
  1931.             if (gView.SortOrder == SortOrder.Descending)
  1932.             {
  1933.                 comparer.descending = true;
  1934.             }
  1935.  
  1936.             comparer.oldDump = oldDump;
  1937.             comparer.newDump = newDump;
  1938.  
  1939.             //DateTime SortStart = Logger.WriteLineTimedStarted("sorting column " + comparer.sortedColumn.ToString());
  1940.  
  1941.             // TODO: reverse if possible?
  1942.  
  1943.             resultAddressList.Sort(comparer);
  1944.  
  1945.             //Logger.WriteLineTimedFinished("sorting", SortStart);
  1946.  
  1947.             PrintPageAlt();
  1948.         }
  1949.  
  1950.         // This class is used when sorting the search results list
  1951.         public class SearchResultComparer : IComparer<UInt32>
  1952.         {
  1953.             public int sortedColumn = 0;
  1954.             public bool descending = false;
  1955.             public Dump oldDump, newDump;
  1956.             //public bool viewModeFloat;
  1957.             // TODO: if float, do the cast before comparing
  1958.  
  1959.             public int Compare(UInt32 x, UInt32 y)
  1960.             {
  1961.                 if (x == null || y == null)
  1962.                 {
  1963.                     return 0;
  1964.                 }
  1965.                 else
  1966.                 {
  1967.                     int retval = 0;
  1968.                     // Compare by column
  1969.                     switch (sortedColumn)
  1970.                     {
  1971.                         case 0: retval = x.CompareTo(y);    break;
  1972.                         case 1: if (oldDump != null) retval = oldDump.ReadAddress32(x).CompareTo(oldDump.ReadAddress32(y));  break;
  1973.                         case 2: if (newDump != null) retval = newDump.ReadAddress32(x).CompareTo(newDump.ReadAddress32(y)); break;
  1974.                         case 3: if (oldDump != null && newDump != null) retval = (newDump.ReadAddress32(x) - oldDump.ReadAddress32(x)).CompareTo(newDump.ReadAddress32(y) - oldDump.ReadAddress32(y)); break;
  1975.                         default: retval = 0;                                break;
  1976.                     }
  1977.                     // If the values are equal, compare them by address
  1978.                     if (retval == 0)
  1979.                     {
  1980.                         retval = x.CompareTo(y);
  1981.                     }
  1982.  
  1983.                     // Reverse if descending
  1984.                     if (descending)
  1985.                     {
  1986.                         retval *= -1;
  1987.                     }
  1988.                     return retval;
  1989.                 }
  1990.             }
  1991.         }
  1992.     }
  1993.  
  1994. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement