/// <summary> /// Adds a date to the internal object table. /// </summary> /// <param name="value">The value to add.</param> /// <returns>The index of the added value.</returns> private int AddDate(DateTime value) { if (!_uniques.Contains(value)) { var index = _objectTable.Count; var buffer = BitConverter.GetBytes(value.ToUniversalTime().Subtract(ReferenceDate).TotalSeconds); if (BitConverter.IsLittleEndian) { Array.Reverse(buffer); } var item = new BinaryPlistItem(value); item.Marker.Add(0x33); item.SetByteValue(buffer); _objectTable.Add(item); _objectTableSize += item.Size; _uniques.SetIndex(value, index); return(index); } return(_uniques.GetIndex(value)); }
/// <summary> /// Adds a float to the internal object table. /// </summary> /// <param name="value">The value to add.</param> /// <returns>The index of the added value.</returns> private int AddFloat(float value) { if (!_uniques.Contains(value)) { var index = _objectTable.Count; var buffer = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) { Array.Reverse(buffer); } var item = new BinaryPlistItem(value); item.Marker.Add((byte)(0x20 | (byte)Math.Log(buffer.Length, 2))); item.SetByteValue(buffer); _objectTable.Add(item); _objectTableSize += item.Size; _uniques.SetIndex(value, index); return(index); } return(_uniques.GetIndex(value)); }
/// <summary> /// Adds a string to the internal object table. /// </summary> /// <param name="value">The value to add.</param> /// <returns>The index of the added value.</returns> private int AddString(string value) { if (!_uniques.Contains(value)) { var index = _objectTable.Count; var ascii = value.IsAscii(); byte[] buffer; var item = new BinaryPlistItem(value); if (value.Length < 15) { item.Marker.Add((byte)((byte)(ascii ? 0x50 : 0x60) | (byte)value.Length)); } else { item.Marker.Add((byte)(ascii ? 0x5F : 0x6F)); AddIntegerCount(item.Marker, value.Length); } if (ascii) { buffer = Encoding.ASCII.GetBytes(value); } else { buffer = Encoding.Unicode.GetBytes(value); if (BitConverter.IsLittleEndian) { for (var i = 0; i < buffer.Length; i++) { var l = buffer[i]; buffer[i] = buffer[++i]; buffer[i] = l; } } } item.SetByteValue(buffer); _objectTable.Add(item); _objectTableSize += item.Size; _uniques.SetIndex(value, index); return(index); } return(_uniques.GetIndex(value)); }
/// <summary> /// Adds an integer to the internal object table. /// </summary> /// <param name="value">The value to add.</param> /// <returns>The index of the added value.</returns> private int AddInteger(long value) { if (!_uniques.Contains(value)) { var index = _objectTable.Count; var item = new BinaryPlistItem(value); item.SetByteValue(GetIntegerBytes(value)); item.Marker.Add((byte)(0x10 | (byte)Math.Log(item.ByteValue.Count, 2))); _objectTable.Add(item); _objectTableSize += item.Size; _uniques.SetIndex(value, index); return(index); } return(_uniques.GetIndex(value)); }
/// <summary> /// Adds arbitrary data to the internal object table. /// </summary> /// <param name="value">The value to add.</param> /// <returns>The index of the added value.</returns> private int AddData(object value) { var index = _objectTable.Count; var bufferIndex = 0; if (!(value is byte[] buffer)) { using (var stream = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(stream, value); stream.Position = 0; buffer = new byte[stream.Length]; int count; while (0 < (count = stream.Read(buffer, 0, buffer.Length - bufferIndex))) { bufferIndex += count; } } } var item = new BinaryPlistItem(value); item.SetByteValue(buffer); if (buffer.Length < 15) { item.Marker.Add((byte)(0x40 | (byte)buffer.Length)); } else { item.Marker.Add(0x4F); AddIntegerCount(item.Marker, buffer.Length); } _objectTable.Add(item); _objectTableSize += item.Size; return(index); }