private static bool PackageDiff(string file_a, string file_b)
        {
            var a = new Package();
            var b = new Package();
            if (a.TryOpen(file_a) && b.TryOpen(file_b))
            {
                if (a.header.Count != b.header.Count)
                    return false;

                int count = a.header.Count;
                for (int i = 0; i < count; i++)
                {
                    if (a.header[i].Item1 != b.header[i].Item1 || // file name
                        a.header[i].Item2 != b.header[i].Item2 || // file offset
                        a.header[i].Item3 != b.header[i].Item3)  // file length
                        return false;
                }

                using (var sw = new StreamWriter(file_b + "_patch.txt"))
                {
                    for (int i = 0; i < count; i++)
                    {
                        var ba = a.blocks[i];
                        var bb = b.blocks[i];
                        var dataend = ba.Length - 2; // ignore CRC at end of block

                        CompareBlock(ba, bb, i, dataend, sw);
                    }
                }

                return true;
            }

            return false;
        }
        private static bool PackageDiff(string file_a, string file_b)
        {
            var a = new Package();
            var b = new Package();

            if (a.TryOpen(file_a) && b.TryOpen(file_b))
            {
                if (a.header.Count != b.header.Count)
                {
                    return(false);
                }

                int count = a.header.Count;
                for (int i = 0; i < count; i++)
                {
                    if (a.header[i].Item1 != b.header[i].Item1 || // file name
                        a.header[i].Item2 != b.header[i].Item2 || // file offset
                        a.header[i].Item3 != b.header[i].Item3)   // file length
                    {
                        return(false);
                    }
                }

                using (var sw = new StreamWriter(file_b + "_patch.txt"))
                {
                    List <Tuple <byte, byte> > chunk = new List <Tuple <byte, byte> >();

                    for (int i = 0; i < count; i++)
                    {
                        var ba = a.blocks[i];
                        var bb = b.blocks[i];

                        var dataend = ba.Length - 2; // ignore CRC at end of block
                        int last    = -1;
                        for (int j = 0; j < dataend; j++)
                        {
                            if (ba[j] != bb[j])
                            {
                                if (j != last + 1)
                                {
                                    OutputChunk(sw, i, chunk, last);
                                    chunk.Clear();
                                }

                                chunk.Add(new Tuple <byte, byte>(ba[j], bb[j]));
                                last = j;
                            }
                        }
                        OutputChunk(sw, i, chunk, last);
                        chunk.Clear();
                    }
                }
            }

            return(false);
        }
        private static bool PackageDiff(string file_a, string file_b)
        {
            var a = new Package();
            var b = new Package();

            if (a.TryOpen(file_a) && b.TryOpen(file_b))
            {
                if (a.header.Count != b.header.Count)
                {
                    return(false);
                }

                int count = a.header.Count;
                for (int i = 0; i < count; i++)
                {
                    if (a.header[i].Item1 != b.header[i].Item1 || // file name
                        a.header[i].Item2 != b.header[i].Item2 || // file offset
                        a.header[i].Item3 != b.header[i].Item3)   // file length
                    {
                        return(false);
                    }
                }

                using (var sw = new StreamWriter(file_b + "_patch.txt"))
                {
                    for (int i = 0; i < count; i++)
                    {
                        var ba      = a.blocks[i];
                        var bb      = b.blocks[i];
                        var dataend = ba.Length - 2; // ignore CRC at end of block

                        CompareBlock(ba, bb, i, dataend, sw);
                    }
                }

                return(true);
            }

            return(false);
        }