/// <summary> /// ストリームからAtomを読み取ります /// </summary> /// <returns>読み取ったAtomのインスタンス</returns> /// <exception cref="EndOfStreamException">ストリームの末尾に達しました</exception> public Atom Read() { var header = new byte[8]; int pos = 0; while (pos < 8) { var r = stream.Read(header, pos, 8 - pos); if (r <= 0) { throw new EndOfStreamException(); } pos += r; } var name = new ID4(header, 0); if (!BitConverter.IsLittleEndian) { Array.Reverse(header, 4, 4); } uint len = BitConverter.ToUInt32(header, 4); if ((len & 0x80000000U) != 0) { var children = new AtomCollection(); for (var i = 0; i < (len & 0x7FFFFFFF); i++) { children.Add(Read()); } return(new Atom(name, children)); } else { var value = new byte[len]; pos = 0; while (pos < len) { var r = stream.Read(value, pos, (int)len - pos); if (r <= 0) { throw new EndOfStreamException(); } pos += r; } return(new Atom(name, value)); } }
/// <summary> /// HostBuilderを初期化します /// </summary> public HostBuilder() { SessionID = Guid.Empty; BroadcastID = Guid.Empty; LocalEndPoint = null; GlobalEndPoint = null; RelayCount = 0; DirectCount = 0; IsFirewalled = false; IsTracker = false; IsRelayFull = false; IsDirectFull = false; IsReceiving = false; IsControlFull = false; Extensions = new List <string>(); Extra = new AtomCollection(); }
/// <summary> /// 指定されたHostBuilderの値でHostBuilderを初期化します /// </summary> /// <param name="host">初期化元のHostBuilder</param> public HostBuilder(HostBuilder host) { if (host != null) { SessionID = host.SessionID; BroadcastID = host.BroadcastID; LocalEndPoint = host.LocalEndPoint; GlobalEndPoint = host.GlobalEndPoint; RelayCount = host.RelayCount; DirectCount = host.DirectCount; IsFirewalled = host.IsFirewalled; IsTracker = host.IsTracker; IsRelayFull = host.IsRelayFull; IsDirectFull = host.IsDirectFull; IsReceiving = host.IsReceiving; IsControlFull = host.IsControlFull; Extensions = new List <string>(host.Extensions); Extra = new AtomCollection(host.Extra); } else { SessionID = Guid.Empty; BroadcastID = Guid.Empty; LocalEndPoint = null; GlobalEndPoint = null; RelayCount = 0; DirectCount = 0; IsFirewalled = false; IsTracker = false; IsRelayFull = false; IsDirectFull = false; IsReceiving = false; IsControlFull = false; Extensions = new List <string>(); Extra = new AtomCollection(); } }
static public async Task <Atom> ReadAtomAsync(this Stream stream, CancellationToken cancel_token) { var header = await stream.ReadBytesAsync(8, cancel_token).ConfigureAwait(false); var name = new ID4(header, 0); if (!BitConverter.IsLittleEndian) { Array.Reverse(header, 4, 4); } uint len = BitConverter.ToUInt32(header, 4); if ((len & 0x80000000U) != 0) { if ((len & 0x7FFFFFFF) > 1024) { throw new InvalidDataException("Atom has too many children"); } var children = new AtomCollection(); for (var i = 0; i < (len & 0x7FFFFFFF); i++) { children.Add(await stream.ReadAtomAsync(cancel_token).ConfigureAwait(false)); } return(new Atom(name, children)); } else { if (len > 1024 * 1024) { throw new InvalidDataException("Atom length too long"); } var value = await stream.ReadBytesAsync((int)len, cancel_token).ConfigureAwait(false); return(new Atom(name, value)); } }
/// <summary> /// 指定された元のコレクションから読み取り専用のラッパオブジェクトを初期化します /// </summary> /// <param name="base_collection">元になるコレクション</param> public ReadOnlyAtomCollection(AtomCollection base_collection) : base(base_collection) { baseCollection = base_collection; }