Пример #1
0
        /// <summary>
        ///		Read in offsets. Converting to Int32 because .NET Stream.Read method takes Int32s.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="trailer"></param>
        /// <returns></returns>
        private static int[] ReadNodeOffsets(Stream stream, PListTrailer trailer)
        {
            // the bitconverter library we use only knows how to deal with integer offsets
            if (trailer.NumObjects > int.MaxValue)
            {
                throw new PListFormatException($"Offset table contains too many entries: {trailer.NumObjects}.");
            }

            var converter = EndianBitConverter.BigEndian;

            // position the stream at the start of the offset table
            if (stream.Seek((long)trailer.OffsetTableOffset, SeekOrigin.Begin) != (long)trailer.OffsetTableOffset)
            {
                throw new PListFormatException("Invalid plist file: unable to seek to start of the offset table.");
            }

            var offsetSize  = trailer.OffsetIntSize;
            var buffer      = new byte[offsetSize];
            var nodeOffsets = new int[trailer.NumObjects];

            for (ulong i = 0; i < trailer.NumObjects; i++)
            {
                if (stream.Read(buffer, 0, buffer.Length) != buffer.Length)
                {
                    throw new PListFormatException($"Invalid plist file: unable to read value {i} in the offset table.");
                }

                nodeOffsets[i] = ReadNumber(buffer, converter);
            }

            return(nodeOffsets);
        }
Пример #2
0
        private static PListTrailer ReadTrailer(Stream stream)
        {
            // trailer is 32 bytes long, at the end of the file
            var buffer = new byte[32];

            stream.Seek(-32, SeekOrigin.End);
            if (stream.Read(buffer, 0, buffer.Length) != buffer.Length)
            {
                throw new PListFormatException("Invalid plist file: unable to read trailer.");
            }

            // all data in a binary plist file is big-endian
            var converter = EndianBitConverter.BigEndian;
            var trailer   = new PListTrailer
            {
                Unused            = new byte[5],
                SortVersionl      = buffer[5],
                OffsetIntSize     = buffer[6],
                ObjectRefSize     = buffer[7],
                NumObjects        = converter.ToUInt64(buffer, 8),
                TopObject         = converter.ToUInt64(buffer, 16),
                OffsetTableOffset = converter.ToUInt64(buffer, 24)
            };

            return(trailer);
        }