public static stBlockHeader create(int block_data_size, int page_size, int next_page_addr) { stBlockHeader blockHeader = new stBlockHeader(); blockHeader.set_data_size(block_data_size); blockHeader.set_page_size(page_size); blockHeader.set_next_page_addr(next_page_addr); return(blockHeader); }
public static stBlockHeader ReadBlockHeaderFromData(Stream Data, int offset = 0) { stBlockHeader bh = new stBlockHeader(); BinaryReader reader = new BinaryReader(Data, Encoding.ASCII); //byte[] ttt = reader.ReadBytes(offset); if (offset != 0) { Data.Seek(offset, SeekOrigin.Begin); } bh.EOL_0D = (char)reader.ReadByte(); bh.EOL_0A = (char)reader.ReadByte(); bh.data_size_hex = reader.ReadChars(8); bh.space1 = (char)reader.ReadByte(); bh.page_size_hex = reader.ReadChars(8); bh.space2 = (char)reader.ReadByte(); bh.next_page_addr_hex = reader.ReadChars(8); bh.space3 = (char)reader.ReadByte(); bh.EOL2_0D = (char)reader.ReadByte(); bh.EOL2_0A = (char)reader.ReadByte(); return(bh); }
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; }
////// //--------------------------------------------------------------------------- ////// // читает блок из потока каталога stream_from, собирая его по страницам ////// TStream* read_block(TStream* stream_from, int start, TStream* stream_to = nullptr) ////// { ////// stBlockHeader block_header; ////// ////// if (!stream_to) ////// { ////// stream_to = new TMemoryStream; ////// } ////// ////// stream_to->Seek(0, soFromBeginning); ////// stream_to->SetSize(0); ////// ////// if (start < 0 ////// || start == LAST_BLOCK ////// || start > stream_from->GetSize()) ////// { ////// return stream_to; ////// } ////// ////// stream_from->Seek(start, soFromBeginning); ////// stream_from->Read(&block_header, stBlockHeader::size()); ////// ////// int32_t len = block_header.get_data_size(); ////// ////// if (len == 0) ////// { ////// return stream_to; ////// } ////// ////// int32_t curlen = block_header.get_page_size(); ////// start = block_header.get_next_page_addr(); ////// ////// int32_t readlen = std::min(len, curlen); ////// stream_to->CopyFrom(stream_from, readlen); ////// ////// int32_t pos = readlen; ////// ////// while (start != LAST_BLOCK) ////// { ////// stream_from->Seek(start, soFromBeginning); ////// stream_from->Read(&block_header, block_header.size()); ////// ////// curlen = block_header.get_page_size(); ////// ////// start = block_header.get_next_page_addr(); ////// ////// readlen = std::min(len - pos, curlen); ////// stream_to->CopyFrom(stream_from, readlen); ////// pos += readlen; ////// } ////// ////// return stream_to; ////// ////// } #endregion // читает блок из потока каталога stream_from, собирая его по страницам public static Stream Read_Block(Stream stream_from, int start, ref int rlen, Stream stream_to = null) { //char temp_buf[32]; - оригинал byte[] temp_buf = new byte[32]; stBlockHeader block_header = new stBlockHeader(); int len, curlen, pos, readlen; if (stream_to == null) { stream_to = new MemoryStream(); } stream_to.Seek(0, SeekOrigin.Begin); stream_to.SetLength(0); if (start < 0 || start == 0x7fffffff || start > stream_from.Length) { return(stream_to); } // спозиционироваться надо на start stream_from.Seek(start, SeekOrigin.Begin); block_header = ReadBlockHeaderFromData(stream_from); len = block_header.get_data_size(); if (len == 0) { return(stream_to); } curlen = block_header.get_page_size(); start = block_header.get_next_page_addr(); readlen = Math.Min(len, curlen); byte[] tmp_buf = new byte[readlen]; //((MemoryStream)stream_to).Capacity = readlen; rlen = readlen; stream_from.CopyTo(stream_to, readlen); pos = readlen; while (start != 0x7fffffff) { stream_from.Seek(start, SeekOrigin.Begin); block_header = ReadBlockHeaderFromData(stream_from); curlen = block_header.get_page_size(); start = block_header.get_next_page_addr(); readlen = Math.Min(len - pos, curlen); if (readlen != 0) { stream_from.CopyTo(stream_to, readlen); } pos += readlen; } return(stream_to); }
private void ReadBlockData(BinaryReader inputFileStream, stBlockHeader? pBlockHeader, UInt32 elemHeaderAddr, out MemoryTributary pBlockDataStream, out UInt32 BlockDataSize) { pBlockDataStream = new MemoryTributary(); if (pBlockHeader == null) pBlockHeader = new stBlockHeader(); UInt32 data_size = 0, page_size = 0, next_page_addr = 0; UInt32 read_in_bytes = 0, bytes_to_read = 0; BlockDataSize = 0; if (pBlockHeader != null) { data_size = _httoi(((stBlockHeader)pBlockHeader).data_size_hex); if (data_size == 0) { throw new Exception("ReadBlockData. Block мData == NULL."); } } read_in_bytes = 0; UInt32 adr = elemHeaderAddr + stBlockHeader.Size(); // Конец header while (read_in_bytes < data_size) { page_size = _httoi(((stBlockHeader)pBlockHeader).page_size_hex); next_page_addr = _httoi(((stBlockHeader)pBlockHeader).next_page_addr_hex); bytes_to_read = Math.Min(page_size, data_size - read_in_bytes); inputFileStream.BaseStream.Position = adr; pBlockDataStream.Write(inputFileStream.ReadBytes((int)bytes_to_read), 0, (int)bytes_to_read); read_in_bytes += bytes_to_read; if (next_page_addr != V8Formats.V8File.V8_FF_SIGNATURE) // есть следующая страница { adr = next_page_addr + stBlockHeader.Size(); inputFileStream.BaseStream.Position = next_page_addr; pBlockHeader = new stBlockHeader(inputFileStream.ReadBytes((int)stBlockHeader.Size()), 0); } else break; } BlockDataSize = data_size; }
private static bool IsV8File(BinaryReader inputFileStream) { if (inputFileStream.BaseStream.Length == 0) { return false; } // проверим чтобы длина файла не была меньше длины заголовка файла и заголовка блока адресов if (inputFileStream.BaseStream.Length < stFileHeader.Size() + stBlockHeader.Size()) return false; long prevPosition = inputFileStream.BaseStream.Position; inputFileStream.BaseStream.Position = 0; stBlockHeader pBlockHeader = new stBlockHeader(inputFileStream.ReadBytes((int)stBlockHeader.Size() + 16), 16); inputFileStream.BaseStream.Position = prevPosition; 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) { return false; } return true; }
private void SaveBlockDataToBuffer(ref byte[] DataBuffer, ref UInt32 cur_pos, byte[] pBlockData, UInt32 PageSize = 512) { UInt32 BlockDataSize = (UInt32)pBlockData.Length; if (PageSize < BlockDataSize) PageSize = BlockDataSize; stBlockHeader CurBlockHeader = new stBlockHeader(); CurBlockHeader.EOL_0D = 0xd; CurBlockHeader.EOL_0A = 0xa; CurBlockHeader.EOL2_0D = 0xd; CurBlockHeader.EOL2_0A = 0xa; CurBlockHeader.data_size_hex = _intTo_BytesChar(BlockDataSize); CurBlockHeader.page_size_hex = _intTo_BytesChar(PageSize); CurBlockHeader.next_page_addr_hex = _intTo_BytesChar(0x7fffffff); CurBlockHeader.space1 = 0x20; CurBlockHeader.space2 = 0x20; CurBlockHeader.space3 = 0x20; Array.Copy(CurBlockHeader.ToBytes(), 0, DataBuffer, cur_pos, stBlockHeader.Size()); cur_pos += stBlockHeader.Size(); Array.Copy(pBlockData, 0, DataBuffer, cur_pos, BlockDataSize); cur_pos += BlockDataSize; for (UInt32 i = 0; i < PageSize - BlockDataSize; i++) { DataBuffer[cur_pos] = 0; cur_pos++; } }
private void SaveBlockDataToBuffer(ref BinaryWriter DataBufferStream, MemoryTributary pBlockDataStream, UInt32 PageSize = 512) { UInt32 BlockDataSize = (UInt32)pBlockDataStream.Length; if (PageSize < BlockDataSize) PageSize = BlockDataSize; stBlockHeader CurBlockHeader = new stBlockHeader(); CurBlockHeader.EOL_0D = 0xd; CurBlockHeader.EOL_0A = 0xa; CurBlockHeader.EOL2_0D = 0xd; CurBlockHeader.EOL2_0A = 0xa; CurBlockHeader.data_size_hex = _intTo_BytesChar(BlockDataSize); CurBlockHeader.page_size_hex = _intTo_BytesChar(PageSize); CurBlockHeader.next_page_addr_hex = _intTo_BytesChar(0x7fffffff); CurBlockHeader.space1 = 0x20; CurBlockHeader.space2 = 0x20; CurBlockHeader.space3 = 0x20; DataBufferStream.BaseStream.Position = 0; DataBufferStream.Write(CurBlockHeader.ToBytes()); pBlockDataStream.Position = 0; for (int i = 0; i < pBlockDataStream.Length; i++) { DataBufferStream.Write(Convert.ToByte(pBlockDataStream.ReadByte())); } DataBufferStream.BaseStream.SetLength(DataBufferStream.BaseStream.Length + (PageSize - BlockDataSize)); }
bool IsV8File(byte[] pFileData, int FileDataSize) { if (pFileData.Length == 0) { return false; } // проверим чтобы длина файла не была меньше длины заголовка файла и заголовка блока адресов if (FileDataSize < stFileHeader.Size() + stBlockHeader.Size()) return false; stBlockHeader pBlockHeader = new stBlockHeader(pFileData, 16); 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) { return false; } return true; }
int ReadBlockData(byte[] pFileData, stBlockHeader? pBlockHeader, UInt32 elemHeaderAddr, out byte[] pBlockData, out UInt32 BlockDataSize) { if (pBlockHeader == null) pBlockHeader = new stBlockHeader(); UInt32 data_size = 0, page_size = 0, next_page_addr = 0; UInt32 read_in_bytes = 0, bytes_to_read = 0; BlockDataSize = 0; pBlockData = new byte[0]; if (pBlockHeader != null) { data_size = _httoi(((stBlockHeader)pBlockHeader).data_size_hex); if (data_size == 0) { Console.WriteLine("ReadBlockData. Block мData == NULL."); return -1; } else { pBlockData = new byte[data_size]; } } read_in_bytes = 0; UInt32 adr = elemHeaderAddr + stBlockHeader.Size(); // Конец header while (read_in_bytes < data_size) { page_size = _httoi(((stBlockHeader)pBlockHeader).page_size_hex); next_page_addr = _httoi(((stBlockHeader)pBlockHeader).next_page_addr_hex); bytes_to_read = Math.Min(page_size, data_size - read_in_bytes); Array.Copy(pFileData, adr, pBlockData, read_in_bytes, bytes_to_read); read_in_bytes += bytes_to_read; if (next_page_addr != V8Formats.V8File.V8_FF_SIGNATURE) // есть следующая страница { adr = next_page_addr + stBlockHeader.Size(); pBlockHeader = new stBlockHeader(pFileData, next_page_addr); } else break; } BlockDataSize = data_size; return 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; }