/// <summary> /// 指定したストリームからAtomを読み取ります /// </summary> /// <param name="stream">読み取り元のストリーム</param> /// <returns>読み取ったAtomのインスタンス</returns> /// <exception cref="EndOfStreamException">ストリームの末尾に達しました</exception> static public Atom Read(Stream stream) { var header = stream.ReadBytes(8); 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(Read(stream)); } return(new Atom(name, children)); } else { if (len > 1024 * 1024) { throw new InvalidDataException("Atom length too long"); } var value = stream.ReadBytes((int)len); return(new Atom(name, value)); } }
/// <summary> /// ストリームからAtomを読み取ります /// </summary> /// <returns>読み取ったAtomのインスタンス</returns> /// <exception cref="EndOfStreamException">ストリームの末尾に達しました</exception> public Atom Read() { var header = stream.ReadBytes(8); 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 = stream.ReadBytes((int)len); return(new Atom(name, value)); } }
/// <summary> /// 名前と値を指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="value">UInt32値</param> public Atom(ID4 name, uint value) { Name = name; this.value = BitConverter.GetBytes(value); if (!BitConverter.IsLittleEndian) { Array.Reverse(this.value); } }
/// <summary> /// 名前と値を指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="value">文字列</param> public Atom(ID4 name, string value) { Name = name; var str = System.Text.Encoding.UTF8.GetBytes(value); this.value = new byte[str.Length + 1]; str.CopyTo(this.value, 0); this.value[str.Length] = 0; }
/// <summary> /// 名前と値を指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="value">IPアドレス</param> public Atom(ID4 name, IPAddress value) { Name = name; var ip = value.GetAddressBytes(); Array.Reverse(ip); this.value = new byte[ip.Length]; ip.CopyTo(this.value, 0); }
/// <summary> /// コレクションから指定した名前を持つAtomを一つ取り除きます /// </summary> /// <param name="name">取り除くAtomの名前</param> /// <returns>取り除いたAtom、無ければnull</returns> public Atom RemoveByName(ID4 name) { var atom = this.FirstOrDefault((x) => { return(x.Name == name); }); if (atom != null) { this.Remove(atom); } return(atom); }
/// <summary> /// 指定したストリームからAtomを読み取ります /// </summary> /// <param name="stream">読み取り元のストリーム</param> /// <returns>読み取ったAtomのインスタンス</returns> /// <exception cref="EndOfStreamException">ストリームの末尾に達しました</exception> static public Atom Read(Stream stream) { 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) { 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(Read(stream)); } return(new Atom(name, children)); } else { if (len > 1024 * 1024) { throw new InvalidDataException("Atom length too long"); } 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)); } }
public static IAtomCollection GetCollectionFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); if (atom != null && atom.HasChildren) { return(atom.Children); } else { return(null); } }
public static Guid?GetIDFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); byte[] value = null; if (atom != null && atom.TryGetBytes(out value) && value.Length == 16) { return(ByteArrayToID(value)); } else { return(null); } }
public static byte?GetByteFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); byte value = 0; if (atom != null && atom.TryGetByte(out value)) { return(value); } else { return(null); } }
public static ushort?GetUShortFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); ushort value = 0; if (atom != null && atom.TryGetUInt16(out value)) { return(value); } else { return(null); } }
public static int?GetIntFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); int value = 0; if (atom != null && atom.TryGetInt32(out value)) { return(value); } else { return(null); } }
public static string GetStringFrom(IAtomCollection collection, ID4 name) { string res = null; var atom = collection.FindByName(name); if (atom != null && atom.TryGetString(out res)) { return(res); } else { return(null); } }
public static IPAddress GetIPAddressFrom(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); IPAddress value = null; if (atom != null && atom.TryGetIPAddress(out value)) { return(value); } else { return(null); } }
public static ID4?GetID4From(IAtomCollection collection, ID4 name) { var atom = collection.FindByName(name); byte[] value = null; if (atom != null && atom.TryGetBytes(out value) && value.Length == 4) { return(new ID4(value)); } else { return(null); } }
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)); } }
public static Atom GetAtomFrom(IAtomCollection collection, ID4 name) { return(collection.FindByName(name)); }
/// <summary> /// 名前と子のコレクションを指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="children">保持する子のコレクション</param> public Atom(ID4 name, IList <Atom> children) { Name = name; this.children = new ReadOnlyAtomCollection(new AtomCollection(children)); }
public static void SetChanPktType(this IAtomCollection collection, ID4 value) { SetAtomTo(collection, new Atom(Atom.PCP_CHAN_PKT_TYPE, value.GetBytes())); }
/// <summary> /// 名前と値を指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="value">byte配列</param> public Atom(ID4 name, byte[] value) { Name = name; this.value = value; }
/// <summary> /// コレクションから指定した名前を持つAtomを探して取得します /// </summary> /// <param name="name">検索する名前</param> /// <returns>指定した名前を持つ最初のAtom、無かった場合はnull</returns> public Atom FindByName(ID4 name) { return(this.FirstOrDefault((x) => { return x.Name == name; })); }
/// <summary> /// 名前と値を指定してAtomを初期化します。 /// </summary> /// <param name="name">4文字以下の名前</param> /// <param name="value">byte値</param> public Atom(ID4 name, byte value) { Name = name; this.value = new byte[] { value }; }
/// <summary> /// 元のコレクションから指定した名前を持つAtomを探して取得します /// </summary> /// <param name="name">検索する名前</param> /// <returns>指定した名前を持つ最初のAtom、無かった場合はnull</returns> public Atom FindByName(ID4 name) { return(baseCollection.FindByName(name)); }