Пример #1
0
        public byte[] ExtractFile(int file_index)
        {
            if (file_index >= GetFileCount())
            {
                return(null);
            }

            IndexFile.Seek(file_index * 6, SeekOrigin.Begin);
            int file_size    = (IndexFile.ReadByte() << 16) + (IndexFile.ReadByte() << 8) + IndexFile.ReadByte();
            int chunk_offset = (IndexFile.ReadByte() << 16) + (IndexFile.ReadByte() << 8) + IndexFile.ReadByte();

            if (chunk_offset < 0 || chunk_offset > DataFile.Length / 520L)
            {
                return(null);
            }

            byte[] out_buffer   = new byte[file_size];
            int    write_offset = 0;

            for (int chunk_index = 0; write_offset < file_size; chunk_index++)
            {
                if (chunk_offset == 0)
                {
                    return(null);
                }
                int chunk_size = Math.Min(512, file_size - write_offset);

                DataFile.Seek(chunk_offset * 520L, SeekOrigin.Begin);
                if (DataFile.Position + chunk_size + 8 > DataFile.Length)
                {
                    return(null);
                }

                int checksum_file_index    = (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                int checksum_chunk_index   = (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                int next_chunk_offset      = (DataFile.ReadByte() << 16) + (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                int checksum_archive_index = DataFile.ReadByte();

                if (checksum_file_index != file_index || checksum_chunk_index != chunk_index || checksum_archive_index - 1 != ArchiveIndex)
                {
                    return(null);
                }
                if (next_chunk_offset < 0 || next_chunk_offset * 520L > DataFile.Length)
                {
                    return(null);
                }
                DataFile.Read(out_buffer, write_offset, chunk_size);
                write_offset += chunk_size;
                chunk_offset  = next_chunk_offset;
            }

            if (ArchiveIndex > 0)
            {
                int i = 0;
                try
                {
                    GZipStream gzipinputstream = new GZipStream(new MemoryStream(out_buffer), CompressionMode.Decompress);
                    do
                    {
                        if (i == gzip_buffer.Length)
                        {
                            return(null);
                        }
                        int k = gzipinputstream.Read(gzip_buffer, i, gzip_buffer.Length - i);
                        if (k == 0)
                        {
                            break;
                        }
                        i += k;
                    } while (true);
                    out_buffer = new byte[i];
                    Array.Copy(gzip_buffer, out_buffer, out_buffer.Length);
                }
                catch (Exception)
                {
                    return(null);
                }
            }

            return(out_buffer);
        }
Пример #2
0
 public int GetFileSize(int file_index)
 {
     IndexFile.Seek(file_index * 6, SeekOrigin.Begin);
     return((IndexFile.ReadByte() << 16) + (IndexFile.ReadByte() << 8) + IndexFile.ReadByte());
 }
Пример #3
0
 public int GetChunkOffset(int file_index)
 {
     IndexFile.Seek(file_index * 6 + 3, SeekOrigin.Begin);
     return((IndexFile.ReadByte() << 16) + (IndexFile.ReadByte() << 8) + IndexFile.ReadByte());
 }
Пример #4
0
        public bool WriteFile(bool exists, int file_index, int file_size, byte[] data)
        {
            try
            {
                int chunk_offset = 0;
                if (exists)
                {
                    IndexFile.Seek(file_index * 6 + 3, SeekOrigin.Begin);
                    chunk_offset = (IndexFile.ReadByte() << 16) + (IndexFile.ReadByte() << 8) + IndexFile.ReadByte();

                    if (chunk_offset <= 0 || (long)chunk_offset > DataFile.Length / 520L)
                    {
                        return(false);
                    }
                }
                else
                {
                    chunk_offset = (int)((DataFile.Length + 519L) / 520L);
                    if (chunk_offset == 0)
                    {
                        chunk_offset = 1;
                    }
                }
                IndexFile.Seek(file_index * 6, SeekOrigin.Begin);
                IndexFile.WriteByte((byte)(file_size >> 16));
                IndexFile.WriteByte((byte)(file_size >> 8));
                IndexFile.WriteByte((byte)file_size);
                IndexFile.WriteByte((byte)(chunk_offset >> 16));
                IndexFile.WriteByte((byte)(chunk_offset >> 8));
                IndexFile.WriteByte((byte)chunk_offset);
                int write_offset = 0;
                for (int chunk_index = 0; write_offset < file_size; chunk_index++)
                {
                    int next_chunk_offset = 0;
                    if (exists)
                    {
                        DataFile.Seek(chunk_offset * 520L, SeekOrigin.Begin);
                        if (DataFile.Position + 8 >= DataFile.Length)
                        {
                            int checksum_file_index  = (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                            int checksum_chunk_index = (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                            next_chunk_offset = (DataFile.ReadByte() << 16) + (DataFile.ReadByte() << 8) + DataFile.ReadByte();
                            int checksum_archive_index = DataFile.ReadByte();
                            if (checksum_file_index != file_index || checksum_chunk_index != chunk_index || checksum_archive_index - 1 != ArchiveIndex)
                            {
                                return(false);
                            }
                            if (next_chunk_offset < 0 || (long)next_chunk_offset > DataFile.Length / 520L)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            DataFile.Position = DataFile.Length - 1;
                        }
                    }
                    if (next_chunk_offset == 0)
                    {
                        exists            = false;
                        next_chunk_offset = (int)((DataFile.Length + 519L) / 520L);
                        if (next_chunk_offset == 0)
                        {
                            next_chunk_offset++;
                        }
                        if (next_chunk_offset == chunk_offset)
                        {
                            next_chunk_offset++;
                        }
                    }
                    if (file_size - write_offset <= 512)
                    {
                        next_chunk_offset = 0;
                    }
                    DataFile.Seek(chunk_offset * 520L, SeekOrigin.Begin);
                    DataFile.WriteByte((byte)(file_index >> 8));
                    DataFile.WriteByte((byte)file_index);
                    DataFile.WriteByte((byte)(chunk_index >> 8));
                    DataFile.WriteByte((byte)chunk_index);
                    DataFile.WriteByte((byte)(next_chunk_offset >> 16));
                    DataFile.WriteByte((byte)(next_chunk_offset >> 8));
                    DataFile.WriteByte((byte)next_chunk_offset);
                    DataFile.WriteByte((byte)(ArchiveIndex + 1));
                    int chunk_size = file_size - write_offset;
                    if (chunk_size > 512)
                    {
                        chunk_size = 512;
                    }
                    DataFile.Write(data, write_offset, chunk_size);
                    write_offset += chunk_size;
                    chunk_offset  = next_chunk_offset;
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }