BililiveRecorder/BililiveRecorder.Flv/Amf/ScriptDataObject.cs

71 lines
4.7 KiB
C#
Raw Normal View History

2021-02-08 16:51:19 +08:00
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
using Newtonsoft.Json;
namespace BililiveRecorder.Flv.Amf
{
[DebuggerTypeProxy(typeof(AmfDictionaryDebugView))]
[DebuggerDisplay("AmfObject, Count = {Count}")]
public class ScriptDataObject : IScriptDataValue, IDictionary<string, IScriptDataValue>, ICollection<KeyValuePair<string, IScriptDataValue>>, IEnumerable<KeyValuePair<string, IScriptDataValue>>, IReadOnlyCollection<KeyValuePair<string, IScriptDataValue>>, IReadOnlyDictionary<string, IScriptDataValue>
{
public ScriptDataType Type => ScriptDataType.Object;
[JsonProperty]
public Dictionary<string, IScriptDataValue> Value { get; set; } = new Dictionary<string, IScriptDataValue>();
public void WriteTo(Stream stream)
{
stream.WriteByte((byte)this.Type);
foreach (var item in this.Value)
{
// key
var bytes = Encoding.UTF8.GetBytes(item.Key);
if (bytes.Length > ushort.MaxValue)
throw new AmfException($"Cannot write more than {ushort.MaxValue} into ScriptDataString");
var buffer = new byte[sizeof(ushort)];
BinaryPrimitives.WriteUInt16BigEndian(buffer, (ushort)bytes.Length);
stream.Write(buffer);
stream.Write(bytes);
// value
item.Value.WriteTo(stream);
}
stream.Write(new byte[] { 0, 0, 9 });
}
public IScriptDataValue this[string key] { get => ((IDictionary<string, IScriptDataValue>)this.Value)[key]; set => ((IDictionary<string, IScriptDataValue>)this.Value)[key] = value; }
public ICollection<string> Keys => ((IDictionary<string, IScriptDataValue>)this.Value).Keys;
public ICollection<IScriptDataValue> Values => ((IDictionary<string, IScriptDataValue>)this.Value).Values;
IEnumerable<string> IReadOnlyDictionary<string, IScriptDataValue>.Keys => ((IReadOnlyDictionary<string, IScriptDataValue>)this.Value).Keys;
IEnumerable<IScriptDataValue> IReadOnlyDictionary<string, IScriptDataValue>.Values => ((IReadOnlyDictionary<string, IScriptDataValue>)this.Value).Values;
public int Count => ((IDictionary<string, IScriptDataValue>)this.Value).Count;
public bool IsReadOnly => ((IDictionary<string, IScriptDataValue>)this.Value).IsReadOnly;
public void Add(string key, IScriptDataValue value) => ((IDictionary<string, IScriptDataValue>)this.Value).Add(key, value);
public void Add(KeyValuePair<string, IScriptDataValue> item) => ((IDictionary<string, IScriptDataValue>)this.Value).Add(item);
public void Clear() => ((IDictionary<string, IScriptDataValue>)this.Value).Clear();
public bool Contains(KeyValuePair<string, IScriptDataValue> item) => ((IDictionary<string, IScriptDataValue>)this.Value).Contains(item);
public bool ContainsKey(string key) => ((IDictionary<string, IScriptDataValue>)this.Value).ContainsKey(key);
public void CopyTo(KeyValuePair<string, IScriptDataValue>[] array, int arrayIndex) => ((IDictionary<string, IScriptDataValue>)this.Value).CopyTo(array, arrayIndex);
public IEnumerator<KeyValuePair<string, IScriptDataValue>> GetEnumerator() => ((IDictionary<string, IScriptDataValue>)this.Value).GetEnumerator();
public bool Remove(string key) => ((IDictionary<string, IScriptDataValue>)this.Value).Remove(key);
public bool Remove(KeyValuePair<string, IScriptDataValue> item) => ((IDictionary<string, IScriptDataValue>)this.Value).Remove(item);
#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
public bool TryGetValue(string key, [MaybeNullWhen(false)] out IScriptDataValue value) => ((IDictionary<string, IScriptDataValue>)this.Value).TryGetValue(key, out value!);
#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
IEnumerator IEnumerable.GetEnumerator() => ((IDictionary<string, IScriptDataValue>)this.Value).GetEnumerator();
public static implicit operator Dictionary<string, IScriptDataValue>(ScriptDataObject @object) => @object.Value;
public static implicit operator ScriptDataObject(Dictionary<string, IScriptDataValue> @object) => new ScriptDataObject { Value = @object };
public static implicit operator ScriptDataObject(ScriptDataEcmaArray ecmaArray) => new ScriptDataObject { Value = ecmaArray };
}
}