public static PropertyListContext HeaderFromBinaryReader(this PropertyListContext result, BinaryReader reader) { result.MagicNumber = reader.ReadAsciiString(6); result.FileFormatVersion = reader.ReadAsciiString(2); return(result); }
public static PropertyListContext OffsetTableFromBinaryReader(this PropertyListContext result, BinaryReader reader) { reader.BaseStream.Seek(result.OffsetTableStart, SeekOrigin.Begin); result.Offsets = reader.ReadIntArrayBigEndian(result.OffsetTableOffsetSize, (int)result.NumObjects); return(result); }
/// <remarks> /// set 1100 nnnn[int], objref* /// nnnn is count, unless '1111', then int count follows /// </remarks> private PropertyContext ReadSet(BinaryReader reader, PropertyListContext ctx, long position, int count) { count = ReadObjectSize(reader, count); var valueRefs = reader.ReadIntArrayBigEndian(ctx.ObjectRefSize, count); int totalSize = reader.GetOffsetFromCurrentPosition(position); var value = ParseArrayCore(reader, ctx, count, valueRefs); return(CreatePropertyContext(position, count, totalSize, PropertyType.Set, value)); }
private object ParseArrayCore(BinaryReader reader, PropertyListContext ctx, int count, int[] valueRefs) { var result = new object[count]; for (int i = 0; i < count; i++) { var valueRef = valueRefs[i]; var valueContext = ParseObjectByOffsetIndex(reader, ctx, valueRef); result[i] = valueContext.Value; } return(result); }
public static PropertyListContext TrailerFromBinaryReader(this PropertyListContext result, BinaryReader reader) { reader.BaseStream.Seek(-32, SeekOrigin.End); var data = reader.ReadBytes(32); result.SortVersion = data[5]; result.OffsetTableOffsetSize = data[6]; result.ObjectRefSize = data[7]; result.NumObjects = BinaryPrimitives.ReadInt64BigEndian(data.AsSpan(8, 8)); result.TopObjectOffset = BinaryPrimitives.ReadInt64BigEndian(data.AsSpan(16, 8)); result.OffsetTableStart = BinaryPrimitives.ReadInt64BigEndian(data.AsSpan(24, 8)); return(result); }
private void TraceContext(PropertyListContext context) { Trace.TraceInformation("MagicNumber:{0}", context.MagicNumber); Trace.TraceInformation("FileFormatVersion:{0}", context.FileFormatVersion); Trace.TraceInformation("SortVersion:{0}", context.SortVersion); Trace.TraceInformation("OffsetTableOffsetSize:{0}", context.OffsetTableOffsetSize); Trace.TraceInformation("ObjectRefSize:{0}", context.ObjectRefSize); Trace.TraceInformation("NumObjects:{0}", context.NumObjects); Trace.TraceInformation("TopObjectOffset:{0}", context.TopObjectOffset); Trace.TraceInformation("OffsetTableStart:{0:x8}", context.OffsetTableStart); for (int i = 0; i < context.Offsets.Length; i++) { Trace.TraceInformation("Offset[{0}]:{1:x8}", i, context.Offsets[i]); } }
private object ParseDictionaryCore(BinaryReader reader, PropertyListContext ctx, int count, int[] keyRefs, int[] valueRefs) { var result = new Dictionary <string, object>(); for (int i = 0; i < count; i++) { var keyRef = keyRefs[i]; var valueRef = valueRefs[i]; var keyContext = ParseObjectByOffsetIndex(reader, ctx, keyRef); var valueContext = ParseObjectByOffsetIndex(reader, ctx, valueRef); var key = (string)keyContext.Value; var value = valueContext.Value; result.Add(key, value); } return(result); }
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); }
internal PropertyListContext Parse(BinaryReader reader) { PropertyListContext result = default; if (reader.BaseStream.Length >= MinimumViableFileSize) { result = new PropertyListContext() .HeaderFromBinaryReader(reader); if (result.IsSupportedBinaryPropertyList()) { result = result.TrailerFromBinaryReader(reader) .OffsetTableFromBinaryReader(reader); #if TRACE_BINARYPROPERTYLISTREADER TraceContext(result); #endif result.Root = ParseObjectByOffsetIndex(reader, result, (int)result.TopObjectOffset); } } return(result); }
public static bool IsSupportedBinaryPropertyList(this PropertyListContext item) { return(string.Equals(MagicNumber, item.MagicNumber, StringComparison.OrdinalIgnoreCase) && string.Equals(VersionNumber, item.FileFormatVersion, StringComparison.Ordinal)); }
private PropertyContext ParseObjectByOffsetIndex(BinaryReader reader, PropertyListContext ctx, int index) { return(ParseObjectByPosition(reader, ctx, ctx.Offsets[index])); }
private PropertyContext ParseObject(BinaryReader reader, PropertyListContext ctx, long position) { PropertyContext result; var marker = reader.ReadByte(); var msn = marker & 0xf0; var lsn = marker & 0x0f; #if TRACE_BINARYPROPERTYLISTREADER Trace.TraceInformation("marker:{0:x2},msn:{1:x2},lsn:{2:x2}", marker, msn, lsn); #endif switch (msn) { case 0b0000_0000: switch (lsn) { case 0b0000_0000: result = CreatePropertyContext(position, 0, 1, PropertyType.Null, null); break; case 0b0000_1000: result = CreatePropertyContext(position, 0, 1, PropertyType.Bool, false); break; case 0b0000_1001: result = CreatePropertyContext(position, 0, 1, PropertyType.Bool, true); break; case 0b0000_1111: result = CreatePropertyContext(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); }
private PropertyContext ParseObjectByPosition(BinaryReader reader, PropertyListContext ctx, long position) { reader.BaseStream.Seek(position, SeekOrigin.Begin); return(ParseObject(reader, ctx, position)); }