Esempio n. 1
0
            private void SaveFile(string filename, bool enableNewCode = true)
            {
                using (FileStream strWriter = new FileStream(filename, System.IO.FileMode.Create))
                {
                    UInt32 stElemSize = stElemAddr.Size();
                    UInt32 ElemsNum = (UInt32)Elems.Count;

                    UInt32 cur_block_addr = stFileHeader.Size() + stBlockHeader.Size();
                    if (stElemAddr.Size() * ElemsNum < V8_DEFAULT_PAGE_SIZE)
                        cur_block_addr += V8_DEFAULT_PAGE_SIZE; // 512 - стандартный размер страницы 0x200
                    else
                        cur_block_addr += stElemAddr.Size() * ElemsNum;

                    byte[] pTempElemsAddrs = new byte[Elems.Count * stElemSize];
                    foreach (CV8Elem elem in Elems)
                    {
                        int elIndex = Elems.IndexOf(elem);
                        stElemAddr curAddr = new stElemAddr();

                        curAddr.elem_header_addr = cur_block_addr;
                        cur_block_addr += stBlockHeader.Size() + elem.HeaderSize;

                        curAddr.elem_data_addr = cur_block_addr;
                        cur_block_addr += stBlockHeader.Size();

                        if (elem.DataSize > V8_DEFAULT_PAGE_SIZE)
                            cur_block_addr += elem.DataSize;
                        else
                            cur_block_addr += V8_DEFAULT_PAGE_SIZE;

                        curAddr.fffffff = 0x7fffffff;

                        byte[] tmpAddrBytes = curAddr.ToBytes();
                        Array.Copy(tmpAddrBytes, 0, pTempElemsAddrs, elIndex * stElemSize, stElemSize);
                    }

                    UInt32 cur_pos = 0;

                    // записываем заголовок
                    strWriter.Write(FileHeader.ToBytes(), 0, (int)stFileHeader.Size());
                    cur_pos += stFileHeader.Size();

                    // записываем адреса элементов
                    byte[] buffer;
                    if (pTempElemsAddrs.Length < V8_DEFAULT_PAGE_SIZE)
                    {
                        buffer = new byte[V8_DEFAULT_PAGE_SIZE + stBlockHeader.Size()];
                    }
                    else
                    {
                        buffer = new byte[pTempElemsAddrs.Length + stBlockHeader.Size()];
                    }

                    UInt32 bufCurPos = 0;
                    SaveBlockDataToBuffer(ref buffer, ref bufCurPos, pTempElemsAddrs);
                    strWriter.Write(buffer, 0, buffer.Length);
                    cur_pos += bufCurPos;

                    // записываем элементы (заголовок и данные)
                    foreach (CV8Elem elem in Elems)
                    {
                        using (MemoryTributary memBuffer = new MemoryTributary())
                        {
                            BinaryWriter binMemBuffer = new BinaryWriter(memBuffer);

                            memBuffer.Position = 0;
                            SaveBlockDataToBuffer(ref binMemBuffer, elem.GetHeaderLikeMemStream(), elem.HeaderSize);

                            // Переносим данные из memBuffer в файл
                            binMemBuffer.BaseStream.Position = 0;
                            for (int i = 0; i < binMemBuffer.BaseStream.Length; i++)
                            {
                                strWriter.WriteByte(Convert.ToByte(binMemBuffer.BaseStream.ReadByte()));
                            }
                        }

                        using (MemoryTributary memBuffer = new MemoryTributary())
                        {
                            BinaryWriter binMemBuffer = new BinaryWriter(memBuffer);

                            memBuffer.Position = 0;
                            bufCurPos = 0;

                            SaveBlockDataToBuffer(ref binMemBuffer, elem.GetDataLikeMemStream());
                            cur_pos += bufCurPos;

                            // Переносим данные из memBuffer в файл
                            binMemBuffer.BaseStream.Position = 0;
                            for (int i = 0; i < binMemBuffer.BaseStream.Length; i++)
                            {
                                strWriter.WriteByte(Convert.ToByte(binMemBuffer.BaseStream.ReadByte()));
                            }
                        }
                    }
                }
            }
Esempio n. 2
0
            private void LoadFile(BinaryReader inputFileStream, bool boolInflate = true, bool UnpackWhenNeed = true)
            {
                long prevPosition = inputFileStream.BaseStream.Position;
                inputFileStream.BaseStream.Position = 0;

                bool useTempFiles = false;
                if(OperationMode == Mode.FileSystem)                
                    useTempFiles = true;
                else if (OperationMode == Mode.Optimal)
                {
                    // В оптимальном режиме, если обрабатываемый файл больше 200 МБ,
                    // то автоматически включается режим использования файловой системы
                    if (inputFileStream.BaseStream.Length > MAX_FILE_SIZE)
                        OperationMode = Mode.FileSystem;
                }

                MemoryTributary InflateBufferStream;
                UInt32 InflateSize = 0;

                this.FileHeader = new stFileHeader(inputFileStream.ReadBytes((int)stFileHeader.Size()), 0);

                stBlockHeader pBlockHeader = new stBlockHeader(inputFileStream.ReadBytes((int)stBlockHeader.Size()), 0);

                UInt32 ElemsAddrsSize;
                MemoryTributary pElemsAddrsStream;
                ReadBlockData(inputFileStream, pBlockHeader, stFileHeader.Size(), out pElemsAddrsStream, out ElemsAddrsSize);

                UInt32 ElemsNum = ElemsAddrsSize / stElemAddr.Size();

                Elems.Clear();
                ElemsAddrs.Clear();

                for (UInt32 i = 0; i < ElemsNum; i++)
                {

                    stElemAddr pElemsAddrs = new stElemAddr(pElemsAddrsStream, (int)(i * stElemAddr.Size()));
                    ElemsAddrs.Add(pElemsAddrs);

                    if (pElemsAddrs.fffffff != V8_FF_SIGNATURE)
                    {
                        ElemsNum = i;
                        break;
                    }

                    inputFileStream.BaseStream.Position = pElemsAddrs.elem_header_addr;
                    pBlockHeader = new stBlockHeader(inputFileStream.ReadBytes((int)stBlockHeader.Size()), 0);

                    if (pBlockHeader.EOL_0D != 0x0d ||
                        pBlockHeader.EOL_0A != 0x0a ||
                        pBlockHeader.space1 != 0x20 ||
                        pBlockHeader.space2 != 0x20 ||
                        pBlockHeader.space3 != 0x20 ||
                        pBlockHeader.EOL2_0D != 0x0d ||
                        pBlockHeader.EOL2_0A != 0x0a)
                    {
                        throw new Exception("Header is not correct!");
                    }

                    UInt32 ElemsAddrsSizeHeader = 0;
                    MemoryTributary pHeaderStream;
                    UInt32 DataSize = 0;
                    MemoryTributary pDataStream;
                    ReadBlockData(inputFileStream, pBlockHeader, pElemsAddrs.elem_header_addr, out pHeaderStream, out ElemsAddrsSizeHeader);

                    //080228 Блока данных может не быть, тогда адрес блока данных равен 0x7fffffff
                    if (pElemsAddrs.elem_data_addr != V8_FF_SIGNATURE)
                    {
                        inputFileStream.BaseStream.Position = pElemsAddrs.elem_data_addr;
                        pBlockHeader = new stBlockHeader(inputFileStream.ReadBytes((int)stBlockHeader.Size()), 0);
                        ReadBlockData(inputFileStream, pBlockHeader, pElemsAddrs.elem_data_addr, out pDataStream, out DataSize);
                    }
                    else
                    {
                        throw new Exception("Incorrect data block!");
                    }

                    CV8Elem elem = new CV8Elem(pHeaderStream, ElemsAddrsSizeHeader, pDataStream, (UInt32)pDataStream.Length, this, false, false, useTempFiles);

                    if (boolInflate && IsDataPacked)
                    {
                        bool success = Inflate(elem.GetDataLikeMemStream(), out InflateBufferStream);

                        if (!success)
                        {
                            IsDataPacked = false;
                            elem.SetDataFromMemStream(InflateBufferStream);
                            elem.DataSize = (UInt32)InflateBufferStream.Length;
                            elem.IsV8File = false;
                        }
                        else
                        {
                            elem.NeedUnpack = false; // отложенная распаковка не нужна
                            elem.pData = null; //нераспакованные данные больше не нужны
                            if (IsV8File(InflateBufferStream))
                            {
                                elem.UnpackedData = new V8File(this, InflateBufferStream, (int)InflateSize, boolInflate, this.OperationMode);
                                elem.pData = null;
                                elem.IsV8File = true;
                            }
                            else
                            {
                                elem.SetDataFromMemStream(InflateBufferStream);
                                elem.DataSize = InflateSize;
                                elem.IsV8File = false;
                            }
                        }
                    }

                    elem.InitElemName(inputFileStream, pElemsAddrs);
                    Elems.Add(elem);

                }

                inputFileStream.BaseStream.Position = prevPosition;
            }
Esempio n. 3
0
                public void InitElemName(BinaryReader inputFileStream, stElemAddr ElemAddr)
                {
                    this.elemNameLen = (ElemAddr.elem_data_addr - 4 - ElemAddr.elem_header_addr - stBlockHeader.Size() - stElemHeaderBegin.Size()) / 2;

                    char[] invalidChars = Path.GetInvalidFileNameChars();
                    char[] ElemName = new char[0];
                    char[] ElemNameBuf = new char[this.elemNameLen];

                    int validChars = 0;
                    for (UInt32 j = 0; j < this.elemNameLen * 2; j += 2)
                    {
                        inputFileStream.BaseStream.Position = j + ElemAddr.elem_header_addr + stBlockHeader.Size() + stElemHeaderBegin.Size();
                        char curChar = Convert.ToChar(inputFileStream.ReadByte());

                        if (invalidChars.Where(ch => ch == curChar).Count() != 0)
                        {
                            ElemName = new char[validChars];
                            break;
                        }

                        ElemNameBuf[j / 2] = curChar;
                        validChars++;
                    }

                    if (ElemName.Length != 0)
                    {
                        for (int i = 0; i < ElemName.Length; i++)
                            ElemName[i] = ElemNameBuf[i];
                    }
                    else
                    {
                        ElemName = ElemNameBuf;
                    }

                    this.elemName = new string(ElemName);
                }
Esempio n. 4
0
            private void GetData(out MemoryTributary dataStream)
            {
                UInt32 stElemSize = stElemAddr.Size();
                UInt32 NeedDataBufferSize = 0;
                NeedDataBufferSize += stFileHeader.Size();

                // заголовок блока и данные блока - адреса элементов с учетом минимальной страницы 512 байт
                NeedDataBufferSize += stBlockHeader.Size() + (UInt32)Math.Max(stElemSize * Elems.Count, V8_DEFAULT_PAGE_SIZE);

                foreach (CV8Elem elem in Elems)
                {
                    // заголовок блока и данные блока - заголовок элемента
                    NeedDataBufferSize += stBlockHeader.Size() + elem.HeaderSize;

                    // заголовок блока и данные блока - данные элемента с учетом минимальной страницы 512 байт
                    NeedDataBufferSize += stBlockHeader.Size() + (UInt32)Math.Max(elem.DataSize, V8_DEFAULT_PAGE_SIZE);
                }

                // Создаем и заполняем данные по адресам элементов
                byte[] pTempElemsAddrs = new byte[Elems.Count * stElemSize];
                UInt32 cur_block_addr = stFileHeader.Size() + stBlockHeader.Size();
                if (stElemSize * Elems.Count < V8_DEFAULT_PAGE_SIZE)
                    cur_block_addr += V8_DEFAULT_PAGE_SIZE; // 512 - стандартный размер страницы 0x200
                else
                    cur_block_addr += stElemSize * (UInt32)Elems.Count;

                foreach (CV8Elem elem in Elems)
                {
                    UInt32 elNum = (UInt32)Elems.IndexOf(elem);

                    stElemAddr tmpAdrr = new stElemAddr();

                    tmpAdrr.elem_header_addr = cur_block_addr;
                    cur_block_addr += stBlockHeader.Size() + elem.HeaderSize;

                    tmpAdrr.elem_data_addr = cur_block_addr;
                    cur_block_addr += stBlockHeader.Size();

                    if (elem.DataSize > V8_DEFAULT_PAGE_SIZE)
                        cur_block_addr += elem.DataSize;
                    else
                        cur_block_addr += V8_DEFAULT_PAGE_SIZE;

                    tmpAdrr.fffffff = 0x7fffffff;

                    byte[] tmpAddrBytes = tmpAdrr.ToBytes();
                    Array.Copy(tmpAddrBytes, 0, pTempElemsAddrs, elNum * stElemSize, stElemSize);
                }

                dataStream = new MemoryTributary();
                dataStream.SetLength(NeedDataBufferSize);
                BinaryWriter dataStreamBin = new BinaryWriter(dataStream);
                //DataBuffer = new byte[NeedDataBufferSize];
                UInt32 cur_pos = 0;

                // записываем заголовок
                byte[] fileHeader = FileHeader.ToBytes();

                dataStreamBin.Write(fileHeader);
                //Array.Copy(fileHeader, 0, DataBuffer, cur_pos, fileHeader.Length);
                cur_pos += stFileHeader.Size();

                // записываем адреса элементов
                SaveBlockDataToBuffer(ref dataStreamBin, ref cur_pos, pTempElemsAddrs);

                // записываем элементы (заголовок и данные)
                foreach (CV8Elem elem in Elems)
                {
                    SaveBlockDataToBuffer(ref dataStreamBin, ref cur_pos, elem.pHeader, elem.HeaderSize);
                    SaveBlockDataToBuffer(ref dataStreamBin, ref cur_pos, elem.pData);
                }

                pTempElemsAddrs = null;
            }
Esempio n. 5
0
            byte[] GetBinaryOfFile()
            {
                using (MemoryStream strWriter = new MemoryStream())
                {
                    UInt32 stElemSize = stElemAddr.Size();
                    UInt32 ElemsNum = (UInt32)Elems.Count;

                    UInt32 cur_block_addr = stFileHeader.Size() + stBlockHeader.Size();
                    if (stElemAddr.Size() * ElemsNum < V8_DEFAULT_PAGE_SIZE)
                        cur_block_addr += V8_DEFAULT_PAGE_SIZE; // 512 - стандартный размер страницы 0x200
                    else
                        cur_block_addr += stElemAddr.Size() * ElemsNum;

                    byte[] pTempElemsAddrs = new byte[Elems.Count * stElemSize];
                    foreach (CV8Elem elem in Elems)
                    {
                        int elIndex = Elems.IndexOf(elem);
                        stElemAddr curAddr = new stElemAddr();

                        curAddr.elem_header_addr = cur_block_addr;
                        cur_block_addr += stBlockHeader.Size() + elem.HeaderSize;

                        curAddr.elem_data_addr = cur_block_addr;
                        cur_block_addr += stBlockHeader.Size();

                        if (elem.DataSize > V8_DEFAULT_PAGE_SIZE)
                            cur_block_addr += elem.DataSize;
                        else
                            cur_block_addr += V8_DEFAULT_PAGE_SIZE;

                        curAddr.fffffff = 0x7fffffff;

                        byte[] tmpAddrBytes = curAddr.ToBytes();
                        Array.Copy(tmpAddrBytes, 0, pTempElemsAddrs, elIndex * stElemSize, stElemSize);
                    }

                    UInt32 cur_pos = 0;

                    // записываем заголовок
                    strWriter.Write(FileHeader.ToBytes(), 0, (int)stFileHeader.Size());
                    cur_pos += stFileHeader.Size();

                    // записываем адреса элементов
                    byte[] buffer;
                    if (pTempElemsAddrs.Length < V8_DEFAULT_PAGE_SIZE)
                    {
                        buffer = new byte[V8_DEFAULT_PAGE_SIZE + stBlockHeader.Size()];
                    }
                    else
                    {
                        buffer = new byte[pTempElemsAddrs.Length + stBlockHeader.Size()];
                    }

                    UInt32 bufCurPos = 0;
                    SaveBlockDataToBuffer(ref buffer, ref bufCurPos, pTempElemsAddrs);
                    strWriter.Write(buffer, 0, buffer.Length);
                    cur_pos += bufCurPos;

                    // записываем элементы (заголовок и данные)
                    foreach (CV8Elem elem in Elems)
                    {
                        buffer = new byte[elem.HeaderSize + stBlockHeader.Size()];
                        bufCurPos = 0;
                        SaveBlockDataToBuffer(ref buffer, ref bufCurPos, elem.pHeader, elem.HeaderSize);
                        strWriter.Write(buffer, 0, buffer.Length);
                        cur_pos += bufCurPos;

                        if (elem.DataSize < V8_DEFAULT_PAGE_SIZE)
                        {
                            buffer = new byte[V8_DEFAULT_PAGE_SIZE + stBlockHeader.Size()];
                        }
                        else
                        {
                            buffer = new byte[elem.DataSize + stBlockHeader.Size()];
                        }

                        bufCurPos = 0;
                        SaveBlockDataToBuffer(ref buffer, ref bufCurPos, elem.pData);
                        strWriter.Write(buffer, 0, buffer.Length);
                        cur_pos += bufCurPos;
                    }

                    return strWriter.ToArray();
                }                
            }
Esempio n. 6
0
            int LoadFile(byte[] pFileData, int FileDataSize, bool boolInflate = true, bool UnpackWhenNeed = true)
            {
                int ret = 0;

                if (pFileData.Length == 0) {
                    return V8UNPACK_ERROR;
                }

                bool isV8File = IsV8File(pFileData, FileDataSize);
                if (!isV8File)
                {
                    return V8UNPACK_NOT_V8_FILE;
                }

                byte[] InflateBuffer = new byte[0];
                UInt32 InflateSize = 0;

                this.FileHeader = new stFileHeader(pFileData, 0);

                stBlockHeader pBlockHeader = new stBlockHeader(pFileData, stFileHeader.Size());

                UInt32 ElemsAddrsSize;                
                byte[] pElemsAddrsBytes;
                ReadBlockData(pFileData, pBlockHeader, stFileHeader.Size(), out pElemsAddrsBytes, out ElemsAddrsSize);

                UInt32 ElemsNum = ElemsAddrsSize / stElemAddr.Size();

                Elems.Clear();
                ElemsAddrs.Clear();
                                
                for (UInt32 i = 0; i < ElemsNum; i++) {

                    stElemAddr pElemsAddrs = new stElemAddr(pElemsAddrsBytes, (int)(i * stElemAddr.Size()));
                    ElemsAddrs.Add(pElemsAddrs);

                    if (pElemsAddrs.fffffff != V8_FF_SIGNATURE)
                    {
                        ElemsNum = i;
                        break;
                    }

                    pBlockHeader = new stBlockHeader(pFileData, pElemsAddrs.elem_header_addr);

                    if (pBlockHeader.EOL_0D != 0x0d ||
                            pBlockHeader.EOL_0A != 0x0a ||
                            pBlockHeader.space1 != 0x20 ||
                            pBlockHeader.space2 != 0x20 ||
                            pBlockHeader.space3 != 0x20 ||
                            pBlockHeader.EOL2_0D != 0x0d ||
                            pBlockHeader.EOL2_0A != 0x0a)
                    {

                        ret = V8UNPACK_HEADER_ELEM_NOT_CORRECT;
                        break;
                    }

                    UInt32 ElemsAddrsSizeHeader = 0;
                    byte[] pElemsAddrsBytesHeader = new byte[0];
                    UInt32 DataSize = 0;
                    byte[] pData = new byte[0];
                    ReadBlockData(pFileData, pBlockHeader, pElemsAddrs.elem_header_addr, out pElemsAddrsBytesHeader, out ElemsAddrsSizeHeader);                    

                    //080228 Блока данных может не быть, тогда адрес блока данных равен 0x7fffffff
                    if (pElemsAddrs.elem_data_addr != V8_FF_SIGNATURE)
                    {
                        pBlockHeader = new stBlockHeader(pFileData, pElemsAddrs.elem_data_addr);
                        ReadBlockData(pFileData, pBlockHeader, pElemsAddrs.elem_data_addr, out pData, out DataSize);
                    }
                    else
                    {
                        throw new Exception("Ебать копать!!!");
                        //ReadBlockData(pFileData, null, out pData, out DataSize);
                    }

                    CV8Elem elem = new CV8Elem(pElemsAddrsBytesHeader, ElemsAddrsSizeHeader, pData, (UInt32)pData.Length, new V8Formats.V8File(), false, false);

                    if (boolInflate && IsDataPacked) {
                        ret = Inflate(pData, out InflateBuffer, DataSize, out InflateSize);

                        if (ret != 0)
                        {
                            IsDataPacked = false;
                            elem.pData = new byte[InflateSize];
                            elem.DataSize = InflateSize;
                            InflateBuffer.CopyTo(elem.pData, 0);
                            elem.IsV8File = false;
                            }
                        else {
                            elem.NeedUnpack = false; // отложенная распаковка не нужна
                            elem.pData = null; //нераспакованные данные больше не нужны
                            if (IsV8File(InflateBuffer, (int)InflateSize)) {
                                elem.UnpackedData = new V8File(InflateBuffer, (int)InflateSize, boolInflate);
                                elem.pData = null;
                                elem.IsV8File = true;
                            } else {
                                elem.pData = new byte[InflateSize];
                                elem.DataSize = InflateSize;
                                InflateBuffer.CopyTo(elem.pData, 0);
                                elem.IsV8File = false;
                            }
                            ret = 0;
                        }
                    }

                    elem.InitElemName(pFileData, pElemsAddrs);
                    Elems.Add(elem);

                }


                if (InflateBuffer.Length != 0)
                    InflateBuffer = new byte[0];

                return ret;
            }