Пример #1
0
        private PackerTables CreatePackResult()
        {
            int indexSize = Util.GetIndexSize((uint)_files.Count);
            RebuildBuckets((uint) indexSize);

            int[] hashTable = new int[indexSize];
            Bucket[] bucktetTable = new Bucket[_files.Count];

            int currentIndex = 0;
            for (int i = 0; i < indexSize; i++)
            {
                if (_buckets.ContainsKey((uint) i))
                {
                    hashTable[i] = currentIndex;
                    foreach (Bucket bucket in _buckets[(uint)i])
                    {
                        bucktetTable[currentIndex++] = bucket;
                    }
                }
                else
                {
                    hashTable[i] = -1;
                }
            }

            PackerTables result = new PackerTables
            {
                Directory = _directory.GetBuffer(),
                FileRegistry = Util.StructureArrayToByteArray(_files),
                HashTable = Util.StructureArrayToByteArray(hashTable),
                BucketTable = Util.StructureArrayToByteArray(bucktetTable),
                FileCount = _files.Count
            };

            return result;
        }
Пример #2
0
        private ushort PackFolder(string path)
        {
            long pos = _directory.Position;
            DirectoryListingEntryHeader dleh = new DirectoryListingEntryHeader();
            string[] folders = Directory.GetDirectories(path);
            string[] files = Directory.GetFiles(path);
            dleh.numDirectories = (ushort)folders.Length;
            dleh.numFiles = (ushort)files.Length;
            string dlehName = Path.GetFileName(path.Substring(_pathPrefixLength));
            byte[] folderNameBytes = Encoding.UTF8.GetBytes(dlehName);
            ushort headerSize = (ushort)(Marshal.SizeOf(dleh) + folderNameBytes.Length);
            dleh.nameLength = (ushort)(folderNameBytes.Length);
            _directory.Position += headerSize;
            ushort foldersSize = Directory.GetDirectories(path).Aggregate<string, ushort>(0, (current, folder) => (ushort)(current + PackFolder(folder)));

            ushort filesSize = 0;
            foreach (string file in files)
            {
                Console.WriteLine(file);
                string shortName = file.Substring(_pathPrefixLength).Replace("\\","/");
                byte[] nameBytes = Encoding.UTF8.GetBytes(shortName);
                Bucket bucket = new Bucket
                {
                    Index = _fileCounter++,
                    IndexHash = Util.Murmur2(nameBytes, 0),
                    BucketHash = Util.Murmur2(nameBytes, BitConverter.ToUInt32(Encoding.UTF8.GetBytes("AMIT"), 0))
                };
                _buckets.AddOrUpdate(bucket.IndexHash, (new[] {bucket}).ToList(), (hash, list) =>
                {
                    list.Add(bucket);
                    return list;
                });
                uint fileSize = (uint)(new FileInfo(file)).Length;
                FileRegistryEntry fre = new FileRegistryEntry
                {
                    uncompressed = fileSize,
                    fileOffset = (ulong) _fs.Position
                };
                byte[] fileData = File.ReadAllBytes(file);
                CompressionParameters p = new CompressionParameters
                {
                    DictionarySize = Util.GetDictLength(fileSize),
                    UpdateRate = TableUpdateRate.Fastest,
                    Level = _level
                };
                byte[] compressedData = new byte[fileSize];
                int compressedSize = (int)fileSize;
                uint addler = 0;

                //Yikes!!!!
                GC.Collect();
                GC.WaitForFullGCComplete();

                CompressStatus status = Lzham.CompressMemory(p, fileData, fileData.Length, 0, compressedData, ref compressedSize, 0, ref addler);
                if (status != CompressStatus.Success && status != CompressStatus.OutputBufferTooSmall)
                {
                    Console.WriteLine($"Error compressing file {file}. ({status})");
                    Environment.FailFast($"Error compressing file {file}. ({status})");
                }
                if (status != CompressStatus.OutputBufferTooSmall)
                {

                    fre.flag = 1;
                    fre.compressed = (uint)compressedSize;
                    _fs.Write(compressedData, 0, compressedSize);
                }
                else
                {
                    fre.flag = 0;
                    fre.compressed = fileSize;
                    using (FileStream f = File.OpenRead(file))
                    {
                        f.CopyTo(_fs);
                    }
                }
                _files.Add(fre);
                string justTheName = Path.GetFileName(file);
                byte[] fileNameBytes = Encoding.UTF8.GetBytes(justTheName);
                _directory.Write(BitConverter.GetBytes((ushort)fileNameBytes.Length), 0, 2);
                _directory.Write(fileNameBytes, 0, fileNameBytes.Length);
                filesSize += (ushort)(fileNameBytes.Length + 2);
            }

            dleh.size = (ushort)(headerSize + foldersSize + filesSize);

            long savePos = _directory.Position;
            _directory.Position = pos;
            byte[] data = Util.StructureToByteArray(dleh);
            _directory.Write(data,0, data.Length);
            _directory.Write(folderNameBytes, 0, folderNameBytes.Length);
            _directory.Position = savePos;

            return dleh.size;
        }