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);
        }