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