private PropertyContext CreatePropertyContext(long position, int count, int size, PropertyType type, object value)
        {
#if TRACE_BINARYPROPERTYLISTREADER
            Trace.TraceInformation("position:{0:x4},type:{1},value:{2}", position, type, value);
#endif

            var result = new PropertyContext(position, count, size, type, value);

            return(result);
        }
        public static object LoadFrom(this BinaryPropertyListReader item, Stream stream)
        {
            PropertyContext result = default;

            using (var reader = new BinaryReader(stream))
            {
                result = item.LoadFrom(reader);
            }

            return(result.Value);
        }
        internal PropertyContext LoadFrom(BinaryReader reader)
        {
            PropertyContext result = default;

            if (reader.BaseStream.Length >= MinimumViableFileSize)
            {
                var context = new PropertyListContext()
                              .HeaderFromBinaryReader(reader);

                if (context.IsSupportedBinaryPropertyList())
                {
                    context = context.TrailerFromBinaryReader(reader)
                              .OffsetTableFromBinaryReader(reader);

                    result = ParseObjectByOffsetIndex(reader, context, (int)context.TopObjectOffset);
                }
            }

            return(result);
        }
        private PropertyContext ParseObject(BinaryReader reader, PropertyListContext ctx, long position)
        {
            PropertyContext result;

            var marker = reader.ReadByte();
            var msn    = marker & 0xf0;
            var lsn    = marker & 0x0f;

            switch (msn)
            {
            case 0b0000_0000:
                switch (lsn)
                {
                case 0b0000_0000:
                    result = new PropertyContext(position, 0, 1, PropertyType.Null, null);
                    break;

                case 0b0000_1000:
                    result = new PropertyContext(position, 0, 1, PropertyType.Bool, false);
                    break;

                case 0b0000_1001:
                    result = new PropertyContext(position, 0, 1, PropertyType.Bool, true);
                    break;

                case 0b0000_1111:
                    result = new PropertyContext(position, 0, 1, PropertyType.Fill, null);
                    break;

                default:
                    throw new InvalidDataException("Unrecognised object type " + marker.ToString("x2"));
                }
                break;

            case 0b0001_0000:
                result = ReadInteger(reader, position, lsn);
                break;

            case 0b0010_0000:
                result = ReadReal(reader, position, lsn);
                break;

            case 0b0011_0000:
                result = ReadDate(reader, position, lsn);
                break;

            case 0b0100_0000:
                result = ReadData(reader, position, lsn);
                break;

            case 0b0101_0000:
                result = ReadAsciiString(reader, position, lsn);
                break;

            case 0b0110_0000:
                result = ReadUnicodeString(reader, position, lsn);
                break;

            case 0b1000_0000:
                result = ReadUid(reader, position, lsn);
                break;

            case 0b1010_0000:
                result = ReadArray(reader, ctx, position, lsn);
                break;

            case 0b1100_0000:
                result = ReadSet(reader, ctx, position, lsn);
                break;

            case 0b1101_0000:
                result = ReadDictionary(reader, ctx, position, lsn);
                break;

            default:
                throw new InvalidDataException("Unrecognised object type " + marker.ToString("x2"));
            }

            return(result);
        }