Esempio n. 1
0
        public static byte[] WriteObjectBinary(object root)
        {
            MemoryStream stream = new MemoryStream();

            stream.WriteByte((byte)'b');
            stream.WriteByte((byte)'p');
            stream.WriteByte((byte)'l');
            stream.WriteByte((byte)'i');
            stream.WriteByte((byte)'s');
            stream.WriteByte((byte)'t');
            stream.WriteByte((byte)'0');
            stream.WriteByte((byte)'0');

            // var analytics = AnalyzeObject(root);
            ObjectAnalytics analytics = ObjectAnalytics.Nil;

            AnalyzeObject(root, ref analytics);

            byte objectRefSize = MinBytesUnsignedInteger(analytics.NumberOfObject);

            byte[] encodeBuffer = new byte[analytics.MaxStringEncodingBytes];

            ulong        objectIndex = 0;
            List <ulong> offsetTable = new List <ulong>((int)analytics.NumberOfObject /* capacity */);

            WriteObjectBinary(stream, root, objectRefSize, encodeBuffer, ref objectIndex, offsetTable);

            byte offsetIntSize = MinOffsetIntSize(stream.Position, offsetTable.Count);

            Trailer trailer = new Trailer()
            {
                ShortVersion      = 0,
                OffsetIntSize     = offsetIntSize,
                ObjectRefSize     = objectRefSize,
                NumObjects        = analytics.NumberOfObject,
                TopObject         = 0,
                OffsetTableOffset = (ulong)stream.Position,
            };

            foreach (ulong offset in offsetTable)
            {
                BigEndianWriter.WriteNBytesUnsignedInteger(stream, offset, offsetIntSize);
            }

            WriteTrailerBinary(stream, trailer);

            return(stream.ToArray());
        }
Esempio n. 2
0
        public static void AnalyzeObject(object root, ref ObjectAnalytics analytics)
        {
            if (root == null)
            {
                throw new PlistException("unsupported null");
            }

            if (
                root is bool ||
                root is int ||
                root is double ||
                root is DateTime ||
                root is byte[]
                )
            {
                analytics.NumberOfObject++;
                return;
            }

            if (root is string)
            {
                analytics.MaxStringEncodingBytes = Math.Max(analytics.MaxStringEncodingBytes, (ulong)UTF16BE.GetMaxByteCount(((string)root).Length));
                analytics.NumberOfObject++;
                return;
            }
            if (root is PlistList)
            {
                foreach (var o in root as PlistList)
                {
                    AnalyzeObject(o, ref analytics);
                }
                analytics.NumberOfObject++; /* me */
                return;
            }
            if (root is PlistDictionary)
            {
                foreach (var o in root as PlistDictionary)
                {
                    AnalyzeObject(o.Key, ref analytics);
                    AnalyzeObject(o.Value, ref analytics);
                }
                analytics.NumberOfObject++; /* me */
                return;
            }
            throw new PlistException("undefined data type");
        }