public static void ParseASCII(PBLFile pbl, BinaryReader reader) { byte[] longBytes = new byte[4]; byte[] intBytes = new byte[2]; int blockOffset = 0; int lastReadBlockSize = BLOCK_SIZE; byte[] block = null; do { blockOffset += lastReadBlockSize; block = reader.ReadBytes(BLOCK_SIZE); lastReadBlockSize = BLOCK_SIZE; if (block == null || block.Length < 4) break; byte[] blockHdr = new byte[4]; Array.Copy(block, 0, blockHdr, 0, 4); string prefix = ASCIIEncoding.ASCII.GetString(blockHdr); switch (prefix) { case FREE_USED_BLOCK_PREFIX: PBLBitmap bmp = new PBLBitmap(); bmp.OffsetOfNextBlock = System.BitConverter.ToInt32(block, 4); byte[] dataBlockBitMap = new byte[504]; Array.Copy(block, 8, dataBlockBitMap, 0, 504); bmp.Bitmap = new BitArray(dataBlockBitMap); pbl.Bitmaps[blockOffset] = bmp; break; case OBJECT_DATA_BLOCK_PREFIX: PBLData data = new PBLData(); pbl.Data[blockOffset] = data; data.OffsetOfNextBlock = System.BitConverter.ToInt32(block, 4); data.LengthOfData = System.BitConverter.ToInt16(block, 8); byte[] objDataBytes = new byte[data.LengthOfData]; Array.Copy(block, 10, objDataBytes, 0, data.LengthOfData); data.Data = objDataBytes; break; case NODE_BLOCK_PREFIX: byte[] bigChunk = new byte[BLOCK_SIZE * NODE_BLOCK_COUNT]; byte[] secondPart = reader.ReadBytes(BLOCK_SIZE * (NODE_BLOCK_COUNT - 1)); lastReadBlockSize += BLOCK_SIZE * (NODE_BLOCK_COUNT - 1); block.CopyTo(bigChunk, 0); secondPart.CopyTo(bigChunk, BLOCK_SIZE); pbl.Node.OffsetOfNextLeftBlock = System.BitConverter.ToInt32(block, 4); pbl.Node.OffsetOfParentBlock = System.BitConverter.ToInt32(block, 8); pbl.Node.OffsetOfNextRightBlock = System.BitConverter.ToInt32(block, 12); pbl.Node.SpaceLeftInBlock = System.BitConverter.ToInt16(block, 16); pbl.Node.EntryCount = System.BitConverter.ToInt16(block, 20); int index = 32; for (int i = 0; i < 7; i++) { PBLNodeEntry nodeEntry = new PBLNodeEntry(pbl.Node); pbl.Node.Entries[blockOffset + index] = nodeEntry; Array.Copy(block, index, longBytes, 0, 4); string childPrefix = ASCIIEncoding.ASCII.GetString(longBytes).TrimEnd('\0'); index += 4; Array.Copy(block, index, longBytes, 0, 4); nodeEntry.Version = ASCIIEncoding.ASCII.GetString(longBytes).TrimEnd('\0'); index += 4; Array.Copy(block, index, longBytes, 0, 4); nodeEntry.OffsetOfFirstDataBlock = System.BitConverter.ToInt32(longBytes, 0); index += 4; Array.Copy(block, index, longBytes, 0, 4); nodeEntry.ObjectSize = System.BitConverter.ToInt32(longBytes, 0); index += 4; Array.Copy(block, index, longBytes, 0, 4); int dateLong = System.BitConverter.ToInt32(longBytes, 0); nodeEntry.Date = ConvertFromUnixTimestamp(dateLong); index += 4; Array.Copy(block, index, intBytes, 0, 2); nodeEntry.CommentLength = System.BitConverter.ToInt16(intBytes, 0); index += 2; Array.Copy(block, index, intBytes, 0, 2); nodeEntry.ObjectNameLength = System.BitConverter.ToInt16(intBytes, 0); index += 2; byte[] objNameBytes = new byte[nodeEntry.ObjectNameLength.Value]; Array.Copy(block, index, objNameBytes, 0, nodeEntry.ObjectNameLength.Value); nodeEntry.ObjectName = ASCIIEncoding.ASCII.GetString(objNameBytes).TrimEnd('\0'); index += nodeEntry.ObjectNameLength.Value; } break; } } while (block != null); }
public static void ParseUnicode(PBLFile pbl, BinaryReader reader) { byte[] eightBytes = new byte[8]; byte[] longBytes = new byte[4]; byte[] intBytes = new byte[2]; int blockOffset = 0; int lastReadBlockSize = BLOCK_SIZE_UNICODE; byte[] block = null; do { blockOffset += lastReadBlockSize; block = reader.ReadBytes(BLOCK_SIZE); lastReadBlockSize = BLOCK_SIZE; if (block == null || block.Length < 4) { break; } byte[] blockHdr = new byte[4]; Array.Copy(block, 0, blockHdr, 0, 4); string prefix = ASCIIEncoding.ASCII.GetString(blockHdr); switch (prefix) { case FREE_USED_BLOCK_PREFIX: PBLBitmap bmp = new PBLBitmap(); bmp.OffsetOfNextBlock = System.BitConverter.ToInt32(block, 4); byte[] dataBlockBitMap = new byte[504]; Array.Copy(block, 8, dataBlockBitMap, 0, 504); bmp.Bitmap = new BitArray(dataBlockBitMap); pbl.Bitmaps[blockOffset] = bmp; break; case OBJECT_DATA_BLOCK_PREFIX: PBLData data = new PBLData(); pbl.Data[blockOffset] = data; data.OffsetOfNextBlock = System.BitConverter.ToInt32(block, 4); data.LengthOfData = System.BitConverter.ToInt16(block, 8); byte[] objDataBytes = new byte[data.LengthOfData]; Array.Copy(block, 10, objDataBytes, 0, data.LengthOfData); data.Data = objDataBytes; break; case NODE_BLOCK_PREFIX: byte[] bigChunk = new byte[BLOCK_SIZE * NODE_BLOCK_COUNT]; byte[] secondPart = reader.ReadBytes(BLOCK_SIZE * (NODE_BLOCK_COUNT - 1)); lastReadBlockSize += BLOCK_SIZE * (NODE_BLOCK_COUNT - 1); block.CopyTo(bigChunk, 0); secondPart.CopyTo(bigChunk, BLOCK_SIZE); block = bigChunk; pbl.Node.OffsetOfNextLeftBlock = System.BitConverter.ToInt32(block, 4); pbl.Node.OffsetOfParentBlock = System.BitConverter.ToInt32(block, 8); pbl.Node.OffsetOfNextRightBlock = System.BitConverter.ToInt32(block, 12); pbl.Node.SpaceLeftInBlock = System.BitConverter.ToInt16(block, 16); pbl.Node.EntryCount = System.BitConverter.ToInt16(block, 20); int index = 32; for (int i = 0; i < pbl.Node.EntryCount; i++) { PBLNodeEntry nodeEntry = new PBLNodeEntry(pbl.Node); pbl.Node.Entries[blockOffset + index] = nodeEntry; Array.Copy(block, index, longBytes, 0, 4); string childPrefix = ASCIIEncoding.ASCII.GetString(longBytes).TrimEnd('\0'); index += 4; Array.Copy(block, index, eightBytes, 0, 8); nodeEntry.Version = UnicodeEncoding.Unicode.GetString(eightBytes).TrimEnd('\0'); index += 8; Array.Copy(block, index, longBytes, 0, 4); nodeEntry.OffsetOfFirstDataBlock = System.BitConverter.ToInt32(longBytes, 0); index += 4; Array.Copy(block, index, longBytes, 0, 4); nodeEntry.ObjectSize = System.BitConverter.ToInt32(longBytes, 0); index += 4; Array.Copy(block, index, longBytes, 0, 4); int dateLong = System.BitConverter.ToInt32(longBytes, 0); nodeEntry.Date = ConvertFromUnixTimestamp(dateLong); index += 4; Array.Copy(block, index, intBytes, 0, 2); nodeEntry.CommentLength = System.BitConverter.ToInt16(intBytes, 0); index += 2; Array.Copy(block, index, intBytes, 0, 2); nodeEntry.ObjectNameLength = System.BitConverter.ToInt16(intBytes, 0); index += 2; int len = nodeEntry.ObjectNameLength.Value; if (len > block.Length - index) { len = (block.Length - index); } byte[] objNameBytes = new byte[len]; Array.Copy(block, index, objNameBytes, 0, len); nodeEntry.ObjectName = UnicodeEncoding.Unicode.GetString(objNameBytes).TrimEnd('\0'); index += len; } break; } } while (block != null); }