System.Runtime.Serialization.Plists.BinaryPlistDictionary.ToDictionary C# (CSharp) Method

ToDictionary() public method

Converts this instance into a Dictionary{Object, Object}.
public ToDictionary ( ) : object>.Dictionary
return object>.Dictionary
        public Dictionary<object, object> ToDictionary()
        {
            Dictionary<object, object> dictionary = new Dictionary<object, object>();
            int keyRef, objectRef;
            object keyValue, objectValue;
            BinaryPlistArray innerArray;
            BinaryPlistDictionary innerDict;

            for (int i = 0; i < this.KeyReference.Count; i++)
            {
                keyRef = this.KeyReference[i];
                objectRef = this.ObjectReference[i];

                if (keyRef >= 0 && keyRef < this.ObjectTable.Count && (this.ObjectTable[keyRef] == null || this.ObjectTable[keyRef].Value != this) &&
                    objectRef >= 0 && objectRef < this.ObjectTable.Count && (this.ObjectTable[objectRef] == null || this.ObjectTable[objectRef].Value != this))
                {
                    keyValue = this.ObjectTable[keyRef] == null ? null : this.ObjectTable[keyRef].Value;
                    objectValue = this.ObjectTable[objectRef] == null ? null : this.ObjectTable[objectRef].Value;
                    innerDict = objectValue as BinaryPlistDictionary;

                    if (innerDict != null)
                    {
                        objectValue = innerDict.ToDictionary();
                    }
                    else
                    {
                        innerArray = objectValue as BinaryPlistArray;

                        if (innerArray != null)
                        {
                            objectValue = innerArray.ToArray();
                        }
                    }

                    dictionary[keyValue] = objectValue;
                }
            }

            return dictionary;
        }

Usage Example

コード例 #1
0
        /// <summary>
        /// Reads a binary plist from the given stream into an <see cref="IDictionary"/>.
        /// </summary>
        /// <param name="stream">The <see cref="Stream"/> to read.</param>
        /// <returns>The result plist <see cref="IDictionary"/>.</returns>
        public IDictionary ReadObject(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream", "stream cannot be null.");
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("The stream must be readable.", "stream");
            }

            Stream concreteStream        = stream;
            bool   disposeConcreteStream = false;

            if (!stream.CanSeek)
            {
                concreteStream = new MemoryStream();
                byte[] buffer = new byte[4096];
                int    count  = 0;

                while (0 < (count = stream.Read(buffer, 0, buffer.Length)))
                {
                    concreteStream.Write(buffer, 0, count);
                }

                concreteStream.Position = 0;
                disposeConcreteStream   = true;
            }

            try
            {
                Dictionary <object, object> dictionary = null;
                this.Reset();

                // Header + trailer = 40.
                if (stream.Length > 40)
                {
                    using (BinaryReader reader = new BinaryReader(concreteStream))
                    {
                        // Read the header.
                        stream.Position = 0;
                        int bpli    = reader.ReadInt32().ToBigEndianConditional();
                        int version = reader.ReadInt32().ToBigEndianConditional();

                        if (bpli != BinaryPlistWriter.HeaderMagicNumber || version != BinaryPlistWriter.HeaderVersionNumber)
                        {
                            throw new ArgumentException("The stream data does not start with required 'bplist00' header.", "stream");
                        }

                        // Read the trailer.
                        // The first six bytes of the first eight-byte block are unused, so offset by 26 instead of 32.
                        stream.Position           = stream.Length - 26;
                        this.offsetIntSize        = (int)reader.ReadByte();
                        this.objectRefSize        = (int)reader.ReadByte();
                        this.objectCount          = (int)reader.ReadInt64().ToBigEndianConditional();
                        this.topLevelObjectOffset = (int)reader.ReadInt64().ToBigEndianConditional();
                        this.offsetTableOffset    = (int)reader.ReadInt64().ToBigEndianConditional();
                        int offsetTableSize = this.offsetIntSize * this.objectCount;

                        // Ensure our sanity.
                        if (this.offsetIntSize < 1 ||
                            this.offsetIntSize > 8 ||
                            this.objectRefSize < 1 ||
                            this.objectRefSize > 8 ||
                            this.offsetTableOffset < 8 ||
                            this.topLevelObjectOffset >= this.objectCount ||
                            offsetTableSize + this.offsetTableOffset + 32 > stream.Length)
                        {
                            throw new ArgumentException("The stream data contains an invalid trailer.", "stream");
                        }

                        // Read the offset table and then the object table.
                        this.ReadOffsetTable(reader);
                        this.ReadObjectTable(reader);
                    }
                }
                else
                {
                    throw new ArgumentException("The stream is too short to be a valid binary plist.", "stream");
                }

                BinaryPlistDictionary root = this.objectTable[this.topLevelObjectOffset].Value as BinaryPlistDictionary;

                if (root != null)
                {
                    dictionary = root.ToDictionary();
                }
                else
                {
                    throw new InvalidOperationException("Unsupported root plist object: " + this.objectTable[this.topLevelObjectOffset].GetType() + ". A dictionary must be the root plist object.");
                }

                return(dictionary ?? new Dictionary <object, object>());
            }
            finally
            {
                if (disposeConcreteStream && concreteStream != null)
                {
                    concreteStream.Dispose();
                }
            }
        }