Beispiel #1
0
        public override CriHcaFormat EncodeFromPcm16(Pcm16Format pcm16, CriHcaParameters config)
        {
            config.ChannelCount = pcm16.ChannelCount;
            config.SampleRate   = pcm16.SampleRate;
            config.SampleCount  = pcm16.SampleCount;
            config.Looping      = pcm16.Looping;
            config.LoopStart    = pcm16.LoopStart;
            config.LoopEnd      = pcm16.LoopEnd;
            IProgressReport progress = config.Progress;

            CriHcaEncoder encoder = CriHcaEncoder.InitializeNew(config);

            short[][] pcm       = pcm16.Channels;
            var       pcmBuffer = Helpers.CreateJaggedArray <short[][]>(pcm16.ChannelCount, SamplesPerFrame);

            progress?.SetTotal(encoder.Hca.FrameCount);

            var audio = Helpers.CreateJaggedArray <byte[][]>(encoder.Hca.FrameCount, encoder.FrameSize);

            int frameNum = 0;

            for (int i = 0; frameNum < encoder.Hca.FrameCount; i++)
            {
                int samplesToCopy = Math.Min(pcm16.SampleCount - i * SamplesPerFrame, SamplesPerFrame);
                for (int c = 0; c < pcm.Length; c++)
                {
                    Array.Copy(pcm[c], SamplesPerFrame * i, pcmBuffer[c], 0, samplesToCopy);
                }

                int framesWritten = encoder.Encode(pcmBuffer, audio[frameNum]);
                if (framesWritten == 0)
                {
                    throw new NotSupportedException("Encoder returned no audio. This should not happen.");
                }

                if (framesWritten > 0)
                {
                    frameNum++;
                    framesWritten--;
                    progress?.ReportAdd(1);
                }

                while (framesWritten > 0)
                {
                    audio[frameNum] = encoder.GetPendingFrame();
                    frameNum++;
                    framesWritten--;
                    progress?.ReportAdd(1);
                }
            }
            var builder = new CriHcaFormatBuilder(audio, encoder.Hca);

            return(builder.Build());
        }
Beispiel #2
0
        public IEnumerable <byte[]> EnumerateFiles(IProgressReport progress = null)
        {
            FileListTab[] fileListTabs = Table20.FileList;

            progress?.SetTotal(fileListTabs.Length);

            for (int i = 0; i < fileListTabs.Length; i++)
            {
                bool   success = false;
                byte[] data    = new byte[0];

                try
                {
                    data    = GetFileFromIndex(i);
                    success = true;
                }
                catch (Exception)
                {
                    progress?.LogMessage($"Error getting file {i}");
                }

                if (success)
                {
                    yield return(data);
                }
                progress?.ReportAdd(1);
            }
        }
        public static void CopyTo(this IFile file, IFile dest, IProgressReport logger = null)
        {
            const int bufferSize = 0x8000;

            logger?.SetTotal(file.GetSize());

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                long inOffset = 0;

                int bytesRead;
                while ((bytesRead = file.Read(buffer, inOffset)) != 0)
                {
                    dest.Write(buffer.AsSpan(0, bytesRead), inOffset);
                    inOffset += bytesRead;
                    logger?.ReportAdd(bytesRead);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);

                logger?.SetTotal(0);
            }
        }
Beispiel #4
0
        public static void CopyFileWithProgress(FileSystemManager fs, string sourcePath, string destPath, IProgressReport logger = null)
        {
            using (FileHandle sourceHandle = fs.OpenFile(sourcePath, OpenMode.Read))
                using (FileHandle destHandle = fs.OpenFile(destPath, OpenMode.Write | OpenMode.Append))
                {
                    const int maxBufferSize = 1024 * 1024;

                    long fileSize   = fs.GetFileSize(sourceHandle);
                    int  bufferSize = (int)Math.Min(maxBufferSize, fileSize);

                    byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

                    try
                    {
                        for (long offset = 0; offset < fileSize; offset += bufferSize)
                        {
                            int         toRead = (int)Math.Min(fileSize - offset, bufferSize);
                            Span <byte> buf    = buffer.AsSpan(0, toRead);

                            fs.ReadFile(sourceHandle, buf, offset);
                            fs.WriteFile(destHandle, buf, offset);

                            logger?.ReportAdd(toRead);
                        }
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(buffer);
                    }

                    fs.FlushFile(destHandle);
                }
        }
Beispiel #5
0
        public static void PrintAllTables(BdatStringCollection bdats, string jsonDir, IProgressReport progress = null)
        {
            progress?.LogMessage("Writing BDAT tables as JSON");
            progress?.SetTotal(bdats.Tables.Count);
            string bdatHtmlDir = Path.Combine(jsonDir, "json");

            Directory.CreateDirectory(bdatHtmlDir);

            foreach (string tableName in bdats.Tables.Keys)
            {
                string outDir        = bdatHtmlDir;
                string tableFilename = bdats[tableName].Filename;

                string json = PrintTable(bdats[tableName]);

                if (tableFilename != null)
                {
                    outDir = Path.Combine(outDir, tableFilename);
                }

                string filename = Path.Combine(outDir, tableName + ".json");
                Directory.CreateDirectory(outDir);
                File.WriteAllText(filename, json);
                progress?.ReportAdd(1);
            }
        }
Beispiel #6
0
        public static void CopyTo(this IStorage input, IStorage output, IProgressReport progress = null, int bufferSize = 81920)
        {
            input.GetSize(out long inputSize).ThrowIfFailure();
            output.GetSize(out long outputSize).ThrowIfFailure();

            long remaining = Math.Min(inputSize, outputSize);

            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = 0;

            using var buffer = new RentedArray <byte>(bufferSize);
            int rentedBufferSize = buffer.Array.Length;

            while (remaining > 0)
            {
                int         toCopy = (int)Math.Min(rentedBufferSize, remaining);
                Span <byte> buf    = buffer.Array.AsSpan(0, toCopy);
                input.Read(pos, buf);
                output.Write(pos, buf);

                remaining -= toCopy;
                pos       += toCopy;

                progress?.ReportAdd(toCopy);
            }

            progress?.SetTotal(0);
        }
Beispiel #7
0
        private static void FillLarge(this IStorage input, byte value, long offset, long count, IProgressReport progress = null)
        {
            const int bufferSize = 0x4000;

            long remaining = count;

            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = offset;

            using var buffer = new RentedArray <byte>(bufferSize);
            int rentedBufferSize = buffer.Array.Length;

            buffer.Array.AsSpan(0, (int)Math.Min(remaining, rentedBufferSize)).Fill(value);

            while (remaining > 0)
            {
                int         toFill = (int)Math.Min(rentedBufferSize, remaining);
                Span <byte> buf    = buffer.Array.AsSpan(0, toFill);

                input.Write(pos, buf);

                remaining -= toFill;
                pos       += toFill;

                progress?.ReportAdd(toFill);
            }

            progress?.SetTotal(0);
        }
        public static void CopyTo(this IFile file, IFile dest, IProgressReport logger = null)
        {
            const int bufferSize = 0x8000;

            file.GetSize(out long fileSize).ThrowIfFailure();

            logger?.SetTotal(fileSize);

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                long inOffset = 0;

                // todo: use result for loop condition
                while (true)
                {
                    file.Read(out long bytesRead, inOffset, buffer).ThrowIfFailure();
                    if (bytesRead == 0)
                    {
                        break;
                    }

                    dest.Write(inOffset, buffer.AsSpan(0, (int)bytesRead)).ThrowIfFailure();
                    inOffset += bytesRead;
                    logger?.ReportAdd(bytesRead);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);

                logger?.SetTotal(0);
            }
        }
Beispiel #9
0
        public static void PrintSeparateTables(BdatStringCollection bdats, string htmlDir, IProgressReport progress = null)
        {
            progress?.LogMessage("Writing BDAT tables as HTML");
            progress?.SetTotal(bdats.Tables.Count);
            string bdatHtmlDir = Path.Combine(htmlDir, "bdat");

            Directory.CreateDirectory(bdatHtmlDir);

            if (bdats.Game == Game.XB2)
            {
                PrintIndex(bdats, htmlDir);
            }
            PrintBdatIndex(bdats, bdatHtmlDir);
            foreach (string tableName in bdats.Tables.Keys)
            {
                string outDir        = bdatHtmlDir;
                string tableFilename = bdats[tableName].Filename;
                string indexPath     = tableFilename == null ? "index.html" : "../index.html";

                var sb = new Indenter(2);
                sb.AppendLine("<!DOCTYPE html>");
                sb.AppendLineAndIncrease("<html>");
                sb.AppendLineAndIncrease("<head>");
                sb.AppendLine("<meta charset=\"utf-8\" />");
                sb.AppendLine($"<title>{tableName}</title>");
                sb.AppendLineAndIncrease("<style>");
                sb.AppendLine(CssSticky);
                sb.AppendLine(CssSortable);
                sb.DecreaseAndAppendLine("</style>");
                sb.DecreaseAndAppendLine("</head>");

                sb.AppendLineAndIncrease("<body>");
                sb.AppendLine($"<a href=\"{indexPath}\">Return to BDAT index</a><br/>");
                sb.AppendLine("<input type=\"button\" value=\"Open all references\" onclick=\"openAll(true)\" />");
                sb.AppendLine("<input type=\"button\" value=\"Close all references\" onclick=\"openAll(false)\" />");
                PrintTable(bdats[tableName], sb);
                sb.AppendLineAndIncrease("<script>");
                sb.AppendLine(JsOpenAll);
                sb.AppendLine(JsSortable);
                sb.AppendLine(JsAnchor);
                sb.DecreaseAndAppendLine("</script>");
                sb.DecreaseAndAppendLine("</body>");
                sb.DecreaseAndAppendLine("</html>");

                if (tableFilename != null)
                {
                    outDir = Path.Combine(outDir, tableFilename);
                }

                string filename = Path.Combine(outDir, tableName + ".html");
                Directory.CreateDirectory(outDir);
                File.WriteAllText(filename, sb.ToString());
                progress?.ReportAdd(1);
            }
        }
Beispiel #10
0
        // Benchmarks encrypting each block separately, initializing a new cipher object for each one
        private static void CipherBenchmarkSeparate(ReadOnlySpan <byte> src, Span <byte> dst, CipherTaskSeparate function,
                                                    int iterations, string label, bool dotNetCrypto, IProgressReport logger)
        {
            Debug.Assert(src.Length == dst.Length);

            var watch = new Stopwatch();

            double[] runTimes = new double[iterations];

            ReadOnlySpan <byte> key1 = stackalloc byte[0x10];
            ReadOnlySpan <byte> key2 = stackalloc byte[0x10];
            ReadOnlySpan <byte> iv   = stackalloc byte[0x10];

            logger.SetTotal(iterations);

            const int blockSize  = BlockSizeSeparate;
            int       blockCount = src.Length / blockSize;

            for (int i = 0; i < iterations; i++)
            {
                watch.Restart();

                for (int b = 0; b < blockCount; b++)
                {
                    function(src.Slice(b * blockSize, blockSize), dst.Slice(b * blockSize, blockSize),
                             key1, key2, iv, dotNetCrypto);
                }

                watch.Stop();

                logger.ReportAdd(1);
                runTimes[i] = watch.Elapsed.TotalSeconds;
            }

            logger.SetTotal(0);

            long srcSize = src.Length;

            double fastestRun = runTimes.Min();
            double averageRun = runTimes.Average();
            double slowestRun = runTimes.Max();

            string fastestRate = Utilities.GetBytesReadable((long)(srcSize / fastestRun));
            string averageRate = Utilities.GetBytesReadable((long)(srcSize / averageRun));
            string slowestRate = Utilities.GetBytesReadable((long)(srcSize / slowestRun));

            logger.LogMessage($"{label}{averageRate}/s, fastest run: {fastestRate}/s, slowest run: {slowestRate}/s");
        }
Beispiel #11
0
        public static BdatStringCollection DeserializeTables(BdatTables tables, IProgressReport progress = null)
        {
            var collection = new BdatStringCollection {
                Bdats = tables
            };

            progress?.LogMessage("Parsing BDAT tables");
            progress?.SetTotal(tables.Tables.Length);

            foreach (BdatTable table in tables.Tables)
            {
                var items = new BdatStringItem[table.ItemCount];

                var stringTable = new BdatStringTable
                {
                    Collection = collection,
                    Name       = table.Name,
                    BaseId     = table.BaseId,
                    Members    = table.Members,
                    Items      = items,
                    Filename   = table.Filename
                };

                if (tables.DisplayFields.TryGetValue(table.Name, out string displayMember))
                {
                    stringTable.DisplayMember = displayMember;
                }

                for (int i = 0; i < table.ItemCount; i++)
                {
                    BdatStringItem item = ReadItem(table, i);
                    item.Table = stringTable;
                    item.Id    = table.BaseId + i;

                    if (displayMember != null)
                    {
                        item.Display = item[displayMember];
                    }

                    items[i] = item;
                }

                collection.Add(stringTable);
                progress?.ReportAdd(1);
            }

            return(collection);
        }
Beispiel #12
0
        public static BdatCollection DeserializeTables(BdatTables files, IProgressReport progress = null)
        {
            progress?.LogMessage("Deserializing BDAT tables");
            progress?.SetTotal(files.Tables.Length);
            var tables = new BdatCollection();

            foreach (BdatTable table in files.Tables)
            {
                ReadTable(table, tables);
                progress?.ReportAdd(1);
            }

            ReadFunctions.SetReferences(tables);

            return(tables);
        }
Beispiel #13
0
        public static void CopyStream(this Stream input, Stream output, long length, IProgressReport progress = null)
        {
            const int bufferSize = 0x8000;
            long      remaining  = length;
            var       buffer     = new byte[bufferSize];

            progress?.SetTotal(length);

            int read;

            while ((read = input.Read(buffer, 0, (int)Math.Min(buffer.Length, remaining))) > 0)
            {
                output.Write(buffer, 0, read);
                remaining -= read;
                progress?.ReportAdd(read);
            }
        }
Beispiel #14
0
        private void Encode(EncodeParams encode, IProgressReport progress)
        {
            var process = new Process
            {
                StartInfo =
                {
                    FileName               = At9ToolPath,
                    Arguments              = encode.BuildCommand(InFile, OutDir),
                    UseShellExecute        = false,
                    RedirectStandardOutput = true
                }
            };

            process.Start();
            process.WaitForExit();
            progress.ReportAdd(1);
        }
Beispiel #15
0
        private static void CipherBenchmarkBlocked(ReadOnlySpan <byte> src, Span <byte> dst, Func <ICipher> cipherGenerator,
                                                   int iterations, string label, IProgressReport logger)
        {
            cipherGenerator().Transform(src, dst);

            var watch = new Stopwatch();

            double[] runTimes = new double[iterations];

            logger.SetTotal(iterations);

            int blockCount = src.Length / BlockSizeBlocked;

            for (int i = 0; i < iterations; i++)
            {
                ICipher cipher = cipherGenerator();

                watch.Restart();

                for (int b = 0; b < blockCount; b++)
                {
                    cipher.Transform(src.Slice(b * BlockSizeBlocked, BlockSizeBlocked),
                                     dst.Slice(b * BlockSizeBlocked, BlockSizeBlocked));
                }

                watch.Stop();

                logger.ReportAdd(1);
                runTimes[i] = watch.Elapsed.TotalSeconds;
            }

            logger.SetTotal(0);

            long srcSize = src.Length;

            double fastestRun = runTimes.Min();
            double averageRun = runTimes.Average();
            double slowestRun = runTimes.Max();

            string fastestRate = Utilities.GetBytesReadable((long)(srcSize / fastestRun));
            string averageRate = Utilities.GetBytesReadable((long)(srcSize / averageRun));
            string slowestRate = Utilities.GetBytesReadable((long)(srcSize / slowestRun));

            logger.LogMessage($"{label}{averageRate}/s, fastest run: {fastestRate}/s, slowest run: {slowestRate}/s");
        }
Beispiel #16
0
        public void ExtractFiles(string outDir, IProgressReport progress = null)
        {
            var sb = new StringBuilder();

            sb.AppendLine("name, file flags, dir offset, file offset, offset, size comp, size, file offset flags, offsetToFile, F1, F9, F17, Is link, F21, Is comp, OF3, OF4, OF5, OF6, bad");

            FileListTab[] fileListTabs = Table20.FileList;

            progress?.SetTotal(fileListTabs.Length);

            for (int i = 0; i < fileListTabs.Length; i++)
            {
                //ExtractFileIndex(i, outDir, progress, sb);
                ExtractFileIndex(i, outDir, progress);
                progress?.ReportAdd(1);
            }

            //File.WriteAllText("list2.csv", sb.ToString());
        }
Beispiel #17
0
        public static void Extract(FileArchive archive, string outDir, IProgressReport progress = null)
        {
            FileInfo[] fileInfos = archive.FileInfo.Where(x => !string.IsNullOrWhiteSpace(x.Filename)).ToArray();
            progress?.SetTotal(fileInfos.Length);
            progress?.LogMessage("Extracting ARD archive");

            foreach (FileInfo fileInfo in fileInfos)
            {
                string filename = Path.Combine(outDir, fileInfo.Filename.TrimStart('/'));
                string dir      = Path.GetDirectoryName(filename) ?? throw new InvalidOperationException();
                Directory.CreateDirectory(dir);

                using (var outStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    archive.OutputFile(fileInfo, outStream);
                }
                progress?.ReportAdd(1);
            }
        }
Beispiel #18
0
        public static void CopyTo(this IStorage input, IStorage output, IProgressReport progress = null)
        {
            const int bufferSize = 81920;
            long      remaining  = input.GetSize();
            long      outsize    = output.GetSize();

            if (outsize > 0)
            {
                remaining = Math.Min(remaining, outsize);
            }
            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = 0;

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                while (remaining > 0)
                {
                    int         toCopy = (int)Math.Min(bufferSize, remaining);
                    Span <byte> buf    = buffer.AsSpan(0, toCopy);
                    input.Read(buf, pos);
                    output.Write(buf, pos);

                    remaining -= toCopy;
                    pos       += toCopy;

                    progress?.ReportAdd(toCopy);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }

            progress?.SetTotal(0);
        }
Beispiel #19
0
        public static void ExtractTextures(string[] filenames, string outDir, IProgressReport progress = null)
        {
            progress?.SetTotal(filenames.Length);

            foreach (string filename in filenames)
            {
                try
                {
                    byte[] file = File.ReadAllBytes(filename);
                    string name = Path.GetFileNameWithoutExtension(filename);

                    ExportWilayTextures(file, name, outDir, progress);
                }
                catch (Exception ex)
                {
                    progress?.LogMessage($"{ex.Message} {filename}");
                }
                progress?.ReportAdd(1);
            }
        }
Beispiel #20
0
        public static void CopyToStream(this IStorage input, Stream output, long length, IProgressReport progress = null)
        {
            const int bufferSize = 0x8000;
            long      remaining  = length;
            long      inOffset   = 0;
            var       buffer     = new byte[bufferSize];

            progress?.SetTotal(length);

            while (remaining > 0)
            {
                int toWrite = (int)Math.Min(buffer.Length, remaining);
                input.Read(inOffset, buffer.AsSpan(0, toWrite));

                output.Write(buffer, 0, toWrite);
                remaining -= toWrite;
                inOffset  += toWrite;
                progress?.ReportAdd(toWrite);
            }
        }
Beispiel #21
0
        public static void ExtractTextures(FileArchive archive, string texDir, string outDir, IProgressReport progress = null)
        {
            FileInfo[] fileInfos = archive.GetChildFileInfos(texDir);
            progress?.SetTotal(fileInfos.Length);

            foreach (FileInfo info in fileInfos)
            {
                try
                {
                    byte[] file     = archive.ReadFile(info);
                    string filename = Path.GetFileNameWithoutExtension(info.Filename);

                    ExportWilayTextures(file, filename, outDir, progress);
                }
                catch (Exception ex)
                {
                    progress?.LogMessage($"{ex.Message} {info.Filename}");
                }
                progress?.ReportAdd(1);
            }
        }
Beispiel #22
0
        private static void CopyBenchmark(IStorage src, IStorage dst, int iterations, string label, IProgressReport logger)
        {
            // Warmup
            src.CopyTo(dst);

            logger.SetTotal(iterations);

            Stopwatch encryptWatch = Stopwatch.StartNew();

            for (int i = 0; i < iterations; i++)
            {
                src.CopyTo(dst);
                logger.ReportAdd(1);
            }
            encryptWatch.Stop();
            logger.SetTotal(0);

            string rate = Util.GetBytesReadable((long)(src.Length * iterations / encryptWatch.Elapsed.TotalSeconds));

            logger.LogMessage($"{label}{rate}/s");
        }
Beispiel #23
0
        public static void CopyToStream(this IStorage input, Stream output, long length, IProgressReport progress = null, int bufferSize = 0x8000)
        {
            long remaining = length;
            long inOffset  = 0;

            using var buffer = new RentedArray <byte>(bufferSize);
            int rentedBufferSize = buffer.Array.Length;

            progress?.SetTotal(length);

            while (remaining > 0)
            {
                int toWrite = (int)Math.Min(rentedBufferSize, remaining);
                input.Read(inOffset, buffer.Array.AsSpan(0, toWrite));

                output.Write(buffer.Array, 0, toWrite);
                remaining -= toWrite;
                inOffset  += toWrite;
                progress?.ReportAdd(toWrite);
            }
        }
Beispiel #24
0
        private short[][] Decode(CodecParameters parameters)
        {
            IProgressReport progress = parameters?.Progress;

            progress?.SetTotal(AudioData.Length);

            var decoder = new Atrac9Decoder();

            decoder.Initialize(Config.ConfigData);
            Atrac9Config config    = decoder.Config;
            var          pcmOut    = CreateJaggedArray <short[][]>(config.ChannelCount, SampleCount);
            var          pcmBuffer = CreateJaggedArray <short[][]>(config.ChannelCount, config.SuperframeSamples);

            for (int i = 0; i < AudioData.Length; i++)
            {
                decoder.Decode(AudioData[i], pcmBuffer);
                CopyBuffer(pcmBuffer, pcmOut, EncoderDelay, i);
                progress?.ReportAdd(1);
            }
            return(pcmOut);
        }
Beispiel #25
0
        private static void FillLarge(this IStorage input, byte value, long offset, long count, IProgressReport progress = null)
        {
            const int bufferSize = 0x4000;

            long remaining = count;

            if (remaining < 0)
            {
                throw new ArgumentException("Storage must have an explicit length");
            }
            progress?.SetTotal(remaining);

            long pos = offset;

            byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

            try
            {
                buffer.AsSpan(0, (int)Math.Min(remaining, bufferSize)).Fill(value);

                while (remaining > 0)
                {
                    int         toFill = (int)Math.Min(bufferSize, remaining);
                    Span <byte> buf    = buffer.AsSpan(0, toFill);

                    input.Write(pos, buf);

                    remaining -= toFill;
                    pos       += toFill;

                    progress?.ReportAdd(toFill);
                }
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }

            progress?.SetTotal(0);
        }
Beispiel #26
0
        /// <summary>
        /// Checks the hashes of any unchecked blocks and returns the <see cref="Validity"/> of the data.
        /// </summary>
        /// <param name="returnOnError">If <see langword="true"/>, return as soon as an invalid block is found.</param>
        /// <param name="logger">An optional <see cref="IProgressReport"/> for reporting progress.</param>
        /// <returns>The <see cref="Validity"/> of the data of the specified hash level.</returns>
        public Validity Validate(bool returnOnError, IProgressReport logger = null)
        {
            Validity[] validities = LevelValidities[LevelValidities.Length - 1];
            IntegrityVerificationStream stream = IntegrityStreams[IntegrityStreams.Length - 1];

            // Restore the original position of the stream when we're done validating
            long initialPosition = stream.Position;

            long blockSize  = stream.SectorSize;
            int  blockCount = (int)Util.DivideByRoundUp(Length, blockSize);

            var buffer = new byte[blockSize];
            var result = Validity.Valid;

            logger?.SetTotal(blockCount);

            for (int i = 0; i < blockCount; i++)
            {
                if (validities[i] == Validity.Unchecked)
                {
                    stream.Position = blockSize * i;
                    stream.Read(buffer, 0, buffer.Length, IntegrityCheckLevel.IgnoreOnInvalid);
                }

                if (validities[i] == Validity.Invalid)
                {
                    result = Validity.Invalid;
                    if (returnOnError)
                    {
                        break;
                    }
                }

                logger?.ReportAdd(1);
            }

            logger?.SetTotal(0);
            stream.Position = initialPosition;
            return(result);
        }
Beispiel #27
0
        /// <summary>
        /// Checks the hashes of any unchecked blocks and returns the <see cref="Validity"/> of the data.
        /// </summary>
        /// <param name="returnOnError">If <see langword="true"/>, return as soon as an invalid block is found.</param>
        /// <param name="logger">An optional <see cref="IProgressReport"/> for reporting progress.</param>
        /// <returns>The <see cref="Validity"/> of the data of the specified hash level.</returns>
        public Validity Validate(bool returnOnError, IProgressReport logger = null)
        {
            Validity[] validities = LevelValidities[LevelValidities.Length - 1];
            IntegrityVerificationStorage storage = IntegrityStorages[IntegrityStorages.Length - 1];

            long blockSize  = storage.SectorSize;
            int  blockCount = (int)Utilities.DivideByRoundUp(Length, blockSize);

            var buffer = new byte[blockSize];
            var result = Validity.Valid;

            logger?.SetTotal(blockCount);

            for (int i = 0; i < blockCount; i++)
            {
                if (validities[i] == Validity.Unchecked)
                {
                    storage.GetSize(out long storageSize).ThrowIfFailure();
                    int toRead = (int)Math.Min(storageSize - blockSize * i, buffer.Length);

                    storage.Read(blockSize * i, buffer.AsSpan(0, toRead), IntegrityCheckLevel.IgnoreOnInvalid);
                }

                if (validities[i] == Validity.Invalid)
                {
                    result = Validity.Invalid;
                    if (returnOnError)
                    {
                        break;
                    }
                }

                logger?.ReportAdd(1);
            }

            logger?.SetTotal(0);
            return(result);
        }
Beispiel #28
0
        public static void PrintAllTables(BdatStringCollection bdats, string schemaName, IProgressReport progress = null)
        {
            string dbName;
            string dbUsername;
            string dbPassword;

            Console.Write("Enter Database Name: ");
            dbName = Console.ReadLine();

            Console.Write("Enter User Name: ");
            dbUsername = Console.ReadLine();

            Console.Write("Enter User Password: "******"Host=localhost;Username={dbUsername};Password={dbPassword};Database={dbName};";

            using (NpgsqlConnection conn = new NpgsqlConnection(connString))
            {
                try
                {
                    conn.Open();
                }
                catch (PostgresException exception)
                {
                    if (exception.SqlState == "28P01")
                    {
                        Console.WriteLine($"Password authentication for user {dbUsername} failed.");
                    }
                    if (exception.SqlState == "3D000")
                    {
                        Console.WriteLine($"Database {dbName} does not exist.");
                    }
                    Environment.Exit(1);
                }

                using (NpgsqlCommand cmd = new NpgsqlCommand())
                {
                    cmd.Connection  = conn;
                    cmd.CommandText = $"CREATE SCHEMA {schemaName};";
                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (PostgresException exception)
                    {
                        if (exception.SqlState == "42P06")
                        {
                            Console.WriteLine($"Schema name {schemaName} is already in use. Delete the schema and retry or provide a different schema name.");
                            Environment.Exit(1);
                        }
                    }
                }

                progress?.LogMessage("Writing BDAT tables to postgresql database");
                progress?.SetTotal(bdats.Tables.Count);

                foreach (string tableName in bdats.Tables.Keys)
                {
                    BdatStringTable table = bdats[tableName];

                    string createQuery = CreateTableQuery(schemaName, table);

                    using (var cmd = new NpgsqlCommand())
                    {
                        cmd.Connection  = conn;
                        cmd.CommandText = createQuery;
                        cmd.ExecuteNonQuery();
                    }

                    PrintTable(table, conn, schemaName);
                    progress?.ReportAdd(1);
                }
            }
        }
Beispiel #29
0
        public static Result CopyFileWithProgress(FileSystemClient fs, U8Span sourcePath, U8Span destPath, IProgressReport logger = null)
        {
            Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath, OpenMode.Read);

            if (rc.IsFailure())
            {
                return(rc);
            }

            try
            {
                rc = fs.OpenFile(out FileHandle destHandle, destPath, OpenMode.Write | OpenMode.AllowAppend);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                try
                {
                    const int maxBufferSize = 1024 * 1024;

                    rc = fs.GetFileSize(out long fileSize, sourceHandle);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    int bufferSize = (int)Math.Min(maxBufferSize, fileSize);

                    byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

                    try
                    {
                        for (long offset = 0; offset < fileSize; offset += bufferSize)
                        {
                            int         toRead = (int)Math.Min(fileSize - offset, bufferSize);
                            Span <byte> buf    = buffer.AsSpan(0, toRead);

                            rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
                            if (rc.IsFailure())
                            {
                                return(rc);
                            }

                            rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None);
                            if (rc.IsFailure())
                            {
                                return(rc);
                            }

                            logger?.ReportAdd(toRead);
                        }
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(buffer);
                    }

                    rc = fs.FlushFile(destHandle);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }
                finally
                {
                    if (destHandle.IsValid)
                    {
                        fs.CloseFile(destHandle);
                    }
                }
            }
            finally
            {
                if (sourceHandle.IsValid)
                {
                    fs.CloseFile(sourceHandle);
                }
            }

            return(Result.Success);
        }
        public static Result CopyFile(this FileSystemClient fs, string sourcePath, string destPath, IProgressReport logger = null)
        {
            Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read);

            if (rc.IsFailure())
            {
                return(rc);
            }

            using (sourceHandle)
            {
                rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                using (destHandle)
                {
                    const int maxBufferSize = 0x10000;

                    rc = fs.GetFileSize(out long fileSize, sourceHandle);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    int bufferSize = (int)Math.Min(maxBufferSize, fileSize);

                    logger?.SetTotal(fileSize);

                    byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize);

                    try
                    {
                        for (long offset = 0; offset < fileSize; offset += bufferSize)
                        {
                            int         toRead = (int)Math.Min(fileSize - offset, bufferSize);
                            Span <byte> buf    = buffer.AsSpan(0, toRead);

                            rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
                            if (rc.IsFailure())
                            {
                                return(rc);
                            }

                            rc = fs.WriteFile(destHandle, offset, buf);
                            if (rc.IsFailure())
                            {
                                return(rc);
                            }

                            logger?.ReportAdd(toRead);
                        }
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(buffer);

                        logger?.SetTotal(0);
                    }

                    rc = fs.FlushFile(destHandle);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }
            }

            return(Result.Success);
        }