This repository has been archived on 2025-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
RomVault/ROMVault2/DBHelper.cs
2014-09-23 12:06:15 -07:00

508 lines
17 KiB
C#

/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2013 *
******************************************************/
using System;
using System.Collections.Generic;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2
{
public enum EFile
{
Keep,
Delete
}
public static class DBHelper
{
private static readonly byte[] ZeroByteMD5;
private static readonly byte[] ZeroByteSHA1;
private static readonly byte[] ZeroByteCRC;
static DBHelper()
{
ZeroByteMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32);
ZeroByteSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40);
ZeroByteCRC = VarFix.CleanMD5SHA1("00000000", 8);
}
public static void GetSelectedDirList(ref List<RvDir> lstDir)
{
GetSelectedDirList(ref lstDir, DB.DirTree);
}
private static void GetSelectedDirList(ref List<RvDir> lstDir, RvDir thisDir)
{
for (int i = 0; i < thisDir.ChildCount; i++)
{
if (thisDir.DatStatus != DatStatus.InDatCollect) continue;
RvDir tDir = thisDir.Child(i) as RvDir;
if (tDir == null) continue;
if (tDir.Tree == null) continue;
if (tDir.Tree.Checked == RvTreeRow.TreeSelect.Selected)
lstDir.Add(tDir);
GetSelectedDirList(ref lstDir, tDir);
}
}
public static int CompareName(RvBase var1, RvBase var2)
{
int retv = TrrntZipStringCompare(var1.Name, var2.Name);
if (retv != 0) return retv;
FileType f1 = var1.FileType;
FileType f2 = var2.FileType;
if (f1 == FileType.ZipFile)
{
if (f2 != FileType.ZipFile)
ReportError.SendAndShow("Incompatible Compare type");
return Math.Sign(String.Compare(var1.Name, var2.Name, StringComparison.Ordinal));
}
return f1.CompareTo(f2);
}
private static int TrrntZipStringCompare(string string1, string string2)
{
char[] bytes1 = string1.ToCharArray();
char[] bytes2 = string2.ToCharArray();
int pos1 = 0;
int pos2 = 0;
for (; ; )
{
if (pos1 == bytes1.Length)
return ((pos2 == bytes2.Length) ? 0 : -1);
if (pos2 == bytes2.Length)
return 1;
int byte1 = bytes1[pos1++];
int byte2 = bytes2[pos2++];
if (byte1 >= 65 && byte1 <= 90) byte1 += 0x20;
if (byte2 >= 65 && byte2 <= 90) byte2 += 0x20;
if (byte1 < byte2)
return -1;
if (byte1 > byte2)
return 1;
}
}
public static int DatCompare(RvDat var1, RvDat var2)
{
int retv = Math.Sign(string.Compare(var1.GetData(RvDat.DatData.DatFullName), var2.GetData(RvDat.DatData.DatFullName), StringComparison.CurrentCultureIgnoreCase));
if (retv != 0) return retv;
retv = Math.Sign(var1.TimeStamp.CompareTo(var2.TimeStamp));
if (retv != 0) return retv;
retv = Math.Sign(var1.AutoAddDirectory.CompareTo(var2.AutoAddDirectory));
if (retv != 0) return retv;
return 0;
}
public static string GetRealPath(string rootPath)
{
string strFullPath = "";
int lenFound = 0;
foreach (DirMap dirPathMap in Settings.DirPathMap)
{
string dirKey = dirPathMap.DirKey;
int dirKeyLen = dirKey.Length;
if (rootPath.Length >= dirKeyLen)
if (String.Compare(rootPath.Substring(0, dirKeyLen), dirKey, StringComparison.Ordinal) == 0)
{
if (lenFound < dirKeyLen)
{
string dirPath = dirPathMap.DirPath;
lenFound = dirKeyLen;
strFullPath = rootPath == dirKey ? dirPath : IO.Path.Combine(dirPath, rootPath.Substring(dirKeyLen + 1));
}
}
}
return strFullPath;
}
public static string GetDatPath(string rootPath)
{
if (rootPath == "")
return Settings.DatRoot;
if (rootPath.Substring(0, 6) == "ToSort")
return "Error";
if (rootPath.Substring(0, 8) == "RomVault")
return Settings.DatRoot + rootPath.Substring(8);
return Settings.DatRoot;
}
public static void GetSelectedFilesSortCRCSize(out List<RvFile> lstFiles)
{
lstFiles = new List<RvFile>();
GetSelectedFilesSortCRCSize(ref lstFiles, DB.DirTree, true);
RomSortCRCSize(lstFiles);
}
private static void GetSelectedFilesSortCRCSize(ref List<RvFile> lstFiles, RvBase val, bool selected)
{
if (selected)
{
RvFile rvFile = val as RvFile;
if (rvFile != null)
{
if ((rvFile.Size != null && rvFile.CRC != null) || rvFile.Size == 0)
lstFiles.Add(rvFile);
}
}
RvDir rvVal = val as RvDir;
if (rvVal == null) return;
for (int i = 0; i < rvVal.ChildCount; i++)
{
bool nextSelect = selected;
if (rvVal.Tree != null)
nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected;
GetSelectedFilesSortCRCSize(ref lstFiles, rvVal.Child(i), nextSelect);
}
}
private static void RomSortCRCSize(List<RvFile> lstFiles)
{
RomSortCRCSize(0, lstFiles.Count, lstFiles);
}
private static void RomSortCRCSize(int intBase, int intTop, List<RvFile> lstFiles)
{
if ((intTop - intBase) <= 1) return;
int intMiddle = (intTop + intBase) / 2;
if ((intMiddle - intBase) > 1)
RomSortCRCSize(intBase, intMiddle, lstFiles);
if ((intTop - intMiddle) > 1)
RomSortCRCSize(intMiddle, intTop, lstFiles);
int intBottomSize = intMiddle - intBase;
int intTopSize = intTop - intMiddle;
RvFile[] lstBottom = new RvFile[intBottomSize];
RvFile[] lstTop = new RvFile[intTopSize];
for (int intloop = 0; intloop < intBottomSize; intloop++)
lstBottom[intloop] = lstFiles[intBase + intloop];
for (int intloop = 0; intloop < intTopSize; intloop++)
lstTop[intloop] = lstFiles[intMiddle + intloop];
int intBottomCount = 0;
int intTopCount = 0;
int intCount = intBase;
while (intBottomCount < intBottomSize && intTopCount < intTopSize)
{
if (RomSortCRCSizeFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
else
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
while (intBottomCount < intBottomSize)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
while (intTopCount < intTopSize)
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
private static int RomSortCRCSizeFunc(RvFile a, RvFile b)
{
int retv = ArrByte.iCompare(a.CRC, b.CRC);
if (retv == 0)
retv = ULong.iCompare(a.Size, b.Size);
return retv;
}
public static int RomSearchCRCSize(RvFile tRom, List<RvFile> lstFiles, out int index)
{
if (lstFiles.Count == 0)
{
index = 0;
return -1;
}
// this one below method will always return the first item in a list if there is more than one matching result.
int intBottom = -1;
int intTop = lstFiles.Count - 1;
while (intBottom + 1 < intTop)
{
int intMid = (intBottom + intTop + 1) / 2;
int intRes = RomSortCRCSizeFunc(lstFiles[intMid], tRom);
if (intRes >= 0)
intTop = intMid;
else
intBottom = intMid;
}
intBottom++;
index = intBottom;
return RomSortCRCSizeFunc(lstFiles[intBottom], tRom);
}
// find all of the files that we think we have that match the needed CRC and Size.
public static void RomSearchFindFixes(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut)
{
lstFilesOut = new List<RvFile>();
if (tRom.CRC == null || tRom.Size == null)
return;
int intIndex;
int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex);
while (intRes == 0)
{
if (lstFiles[intIndex].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(tRom, lstFiles[intIndex]))
lstFilesOut.Add(lstFiles[intIndex]);
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1;
}
}
// find all of the files that we think we have that match the needed CRC and Size.
public static void RomSearchFindMatchingFiles(RvFile tRom, List<RvFile> lstFiles, out int startIndex, out int length)
{
int intIndex;
int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex);
startIndex = intIndex;
while (intRes == 0)
{
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1;
}
length = intIndex - startIndex;
}
public static bool IsZeroLengthFile(RvFile tFile)
{
if (tFile.MD5 != null)
{
if (!ArrByte.bCompare(tFile.MD5, ZeroByteMD5))
return false;
}
if (tFile.SHA1 != null)
{
if (!ArrByte.bCompare(tFile.SHA1, ZeroByteSHA1))
return false;
}
if (tFile.CRC != null)
if (!ArrByte.bCompare(tFile.CRC, ZeroByteCRC))
return false;
return tFile.Size == 0;
}
public static bool RomFromSameGame(RvFile a, RvFile b)
{
if (a.Parent == null)
return false;
if (b.Parent == null)
return false;
return a.Parent == b.Parent;
}
public static void GetSelectedFilesSortSHA1CHD(out List<RvFile> lstFiles)
{
lstFiles = new List<RvFile>();
GetSelectedFilesSortSHA1CHD(ref lstFiles, DB.DirTree, true);
RomSortSHA1CHD(lstFiles);
}
private static void GetSelectedFilesSortSHA1CHD(ref List<RvFile> lstFiles, RvBase val, bool selected)
{
if (selected)
{
RvFile rvFile = val as RvFile;
if (rvFile != null)
{
if (rvFile.SHA1CHD != null)
lstFiles.Add(rvFile);
}
}
RvDir rvVal = val as RvDir;
if (rvVal == null) return;
for (int i = 0; i < rvVal.ChildCount; i++)
{
bool nextSelect = selected;
if (rvVal.Tree != null)
nextSelect = rvVal.Tree.Checked == RvTreeRow.TreeSelect.Selected;
GetSelectedFilesSortSHA1CHD(ref lstFiles, rvVal.Child(i), nextSelect);
}
}
private static void RomSortSHA1CHD(List<RvFile> lstFiles)
{
RomSortSHA1CHD(0, lstFiles.Count, lstFiles);
}
private static void RomSortSHA1CHD(int intBase, int intTop, List<RvFile> lstFiles)
{
if ((intTop - intBase) <= 1) return;
int intMiddle = (intTop + intBase) / 2;
if ((intMiddle - intBase) > 1)
RomSortSHA1CHD(intBase, intMiddle, lstFiles);
if ((intTop - intMiddle) > 1)
RomSortSHA1CHD(intMiddle, intTop, lstFiles);
int intBottomSize = intMiddle - intBase;
int intTopSize = intTop - intMiddle;
RvFile[] lstBottom = new RvFile[intBottomSize];
RvFile[] lstTop = new RvFile[intTopSize];
for (int intloop = 0; intloop < intBottomSize; intloop++)
lstBottom[intloop] = lstFiles[intBase + intloop];
for (int intloop = 0; intloop < intTopSize; intloop++)
lstTop[intloop] = lstFiles[intMiddle + intloop];
int intBottomCount = 0;
int intTopCount = 0;
int intCount = intBase;
while (intBottomCount < intBottomSize && intTopCount < intTopSize)
{
if (RomSortSHA1CHDFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
else
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
while (intBottomCount < intBottomSize)
{
lstFiles[intCount] = lstBottom[intBottomCount];
intCount++;
intBottomCount++;
}
while (intTopCount < intTopSize)
{
lstFiles[intCount] = lstTop[intTopCount];
intCount++;
intTopCount++;
}
}
private static int RomSortSHA1CHDFunc(RvFile a, RvFile b)
{
int retv = ArrByte.iCompare(a.SHA1CHD, b.SHA1CHD);
return retv;
}
private static int RomSearchSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out int index)
{
if (lstFiles.Count == 0)
{
index = 0;
return -1;
}
// this one below method will always return the first item in a list if there is more than one matching result.
int intBottom = -1;
int intTop = lstFiles.Count - 1;
while (intBottom + 1 < intTop)
{
int intMid = (intBottom + intTop + 1) / 2;
int intRes = RomSortSHA1CHDFunc(lstFiles[intMid], tRom);
if (intRes >= 0)
intTop = intMid;
else
intBottom = intMid;
}
intBottom++;
index = intBottom;
return RomSortSHA1CHDFunc(lstFiles[intBottom], tRom);
}
// find all of the files that we have that match the needed SHA1 CHD.
public static void RomSearchFindFixesSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut)
{
lstFilesOut = new List<RvFile>();
if (tRom.SHA1CHD == null)
return;
int intIndex;
int intRes = RomSearchSHA1CHD(tRom, lstFiles, out intIndex);
while (intRes == 0)
{
if (lstFiles[intIndex].GotStatus == GotStatus.Got)
lstFilesOut.Add(lstFiles[intIndex]);
intIndex++;
intRes = intIndex < lstFiles.Count ? RomSortSHA1CHDFunc(lstFiles[intIndex], tRom) : 1;
}
}
}
}