/// <summary> /// 指定ストリームの現在位置から受信する再帰ループ /// </summary> /// <param name="reader">ストリーム</param> /// <returns>インスタンス化されたオブジェクト</returns> private static object receiveLoop(Stream reader) { object ret = null; Type subClassType = null; for (var isLoop = true; isLoop;) { var tag = (Tag)reader.ReadByte(); Type currentType; switch (tag) { case Tag.ClassStart: { // クラスを特定する = currentType = subClassType ReceiveDirect(reader, out int classid); // クラスを特定する = currentType = subClassType var keystr = NamedId.FromIDNoName(classid).Name; var keys = keystr.Split(new char[] { '/' }); System.Diagnostics.Debug.Assert(keys.Length == 4, "シリアライズClass IDが不正でした"); // クラスのインスタンスを生成する = ret currentType = Type.GetType(keys[2]); if (currentType == null) { var hInst = Activator.CreateInstance(keys[3], keys[2]); ret = hInst.Unwrap(); currentType = ret.GetType(); } else { ret = Activator.CreateInstance(currentType, true); } subClassType = currentType; break; } case Tag.SubClass: { // サブクラスを特定する = subClassType ReceiveDirect(reader, out // サブクラスを特定する = subClassType int classid); var keystr = NamedId.FromIDNoName(classid).Name; var keys = keystr.Split(new char[] { '/' }); System.Diagnostics.Debug.Assert(keys.Length == 4, "シリアライズClass IDが不正でした"); subClassType = Type.GetType(keys[2] + ", " + keys[3]); break; } case Tag.Field: { // フィールドを特定する = fi ReceiveDirect(reader, out // フィールドを特定する = fi int fieldid); var keystr = NamedId.FromIDNoName(fieldid).Name; var keys = keystr.Split(new char[] { '/' }); System.Diagnostics.Debug.Assert(keys.Length == 4, "シリアライズField IDが不正でした"); var fi = subClassType.GetField(keys[2 /*field名*/], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); // フィールドの値を取得する(再帰コール) var fieldValue = receiveLoop(reader); // フィールドの値をインスタンスに設定する fi.SetValue(ret, fieldValue); break; } case Tag.Null: { return(null); } case Tag.List: { ReceiveDirect(reader, out int classid); var keystr = NamedId.FromIDNoName(classid).Name; var keys = keystr.Split(new char[] { '/' }); System.Diagnostics.Debug.Assert(keys.Length == 4, "シリアライズClass IDが不正でした"); // クラスのインスタンスを生成する = ret currentType = Type.GetType(keys[2]); if (currentType == null) { var hInst = Activator.CreateInstance(keys[3], keys[2]); ret = hInst.Unwrap(); currentType = ret.GetType(); } else { ret = Activator.CreateInstance(currentType, true); } // 配列数を取得す ReceiveDirect(reader, out // 配列数を取得す int n); for (var i = 0; i < n; i++) { // 各要素の値を取得する(再帰コール) var val = receiveLoop(reader); ((IList)ret).Add(val); } // サブクラスのために準備する subClassType = currentType; break; } case Tag.Dictionary: { ReceiveDirect(reader, out int classid); var keystr = NamedId.FromIDNoName(classid).Name; var keys = keystr.Split(new char[] { '/' }); System.Diagnostics.Debug.Assert(keys.Length == 4, "シリアライズClass IDが不正でした"); // クラスのインスタンスを生成する = ret currentType = Type.GetType(keys[2]); if (currentType == null) { var hInst = Activator.CreateInstance(keys[3], keys[2]); ret = hInst.Unwrap(); currentType = ret.GetType(); } else { ret = Activator.CreateInstance(currentType, true); } // 配列数を取得す ReceiveDirect(reader, out // 配列数を取得す int n); for (var i = 0; i < n; i++) { // 各要素の値を取得する(再帰コール) var key = receiveLoop(reader); var val = receiveLoop(reader); ((IDictionary)ret).Add(key, val); } // サブクラスのために準備する subClassType = currentType; break; } case Tag.ClassEnd: { receiveFinalize(ret); return(ret); } case Tag.vString: { ReceiveDirect(reader, out string s); return(s); } default: { var valType = (Type)_tagToType[tag]; var valTypeR = valType.Assembly.GetType(valType.ToString() + "&"); ret = Activator.CreateInstance(valType); var types = new Type[] { typeof(Stream), valTypeR }; var mi = typeof(SerializerEx).GetMethod("ReceiveDirect", types); ret = mi.Invoke(null, new object[] { reader, ret }); receiveFinalize(ret); return(ret); } } } receiveFinalize(ret); return(ret); }