public object ReadDictionary(Ice.Dictionary dict) { Ice.DictionaryInfo dinfo = dict.IceDictInfo; int count = ReadSize(); for (int i = 0; i < count; i++) { object k, v; bool haveKey, haveValue; if (IceChannelUtils.IceByValue(dinfo.keyType)) { k = ReadObject(dinfo.keyType); haveKey = true; } else { k = ReadClassInstanceRef(); if ((int)k == 0) { throw new InvalidOperationException("Got NULL dictionary key, expected class ref for type " + dinfo.keyType); } else { haveKey = false; } } if (IceChannelUtils.IceByValue(dinfo.valueType)) { v = ReadObject(dinfo.valueType); haveValue = true; } else { v = ReadClassInstanceRef(); if ((int)v == 0) { v = null; haveValue = true; } else { haveValue = false; } } // if we have both the key and value, we put them in. // otherwise, we have to create a patch based on what // bits we have. if (haveKey && haveValue) { dict.Add(k, v); } else { if (haveKey) { _instancePatchList.Add(new DictionaryValuePatchInfo((int)v, dict, k)); } else if (haveValue) { _instancePatchList.Add(new DictionaryKeyPatchInfo((int)k, dict, v)); } else { _instancePatchList.Add(new DictionaryEntryPatchInfo((int)k, dict, (int)v)); } } } return(dict); }
// read an object of type t from the stream // does NOT handle reading classes, since these // have to be read by ref and patched public object ReadObject(Type t) { if (t.IsPrimitive) { if (t == typeof(bool)) { return(ReadBoolean()); } if (t == typeof(byte)) { return(ReadByte()); } if (t == typeof(short)) { return(ReadInt16()); } if (t == typeof(int)) { return(ReadInt32()); } if (t == typeof(long)) { return(ReadInt64()); } if (t == typeof(float)) { return(ReadSingle()); } if (t == typeof(double)) { return(ReadDouble()); } throw new NotImplementedException("ReadObject can't read primitive type " + t); } if (t == typeof(string)) { return(ReadString()); } if (t.IsEnum) { Type ue = Enum.GetUnderlyingType(t); if (ue == typeof(byte)) { byte i = ReadByte(); return(Enum.ToObject(t, i)); } if (ue == typeof(short)) { short i = ReadInt16(); return(Enum.ToObject(t, i)); } if (ue == typeof(int)) { int i = ReadInt32(); return(Enum.ToObject(t, i)); } throw new NotSupportedException("ReadObject can't read enum with underlying type " + ue); } if (t.IsSubclassOf(typeof(Ice.Dictionary))) { object o = Activator.CreateInstance(t); Ice.Dictionary dict = o as Ice.Dictionary; return(ReadDictionary(dict)); } if (t.IsArray) { int sz = ReadSize(); Type eltype = t.GetElementType(); // System.Console.WriteLine ("Reading Array: {0} {1}", sz, eltype); Array ao = Array.CreateInstance(eltype, sz); if (IceChannelUtils.IceByValue(eltype)) { for (int i = 0; i < sz; i++) { object elem = ReadObject(eltype); ao.SetValue(elem, i); // System.Console.WriteLine (" {0}: {1}", i, elem); } } else { // this is a class type (and isn't a string or dictionary) for (int i = 0; i < sz; i++) { int r = ReadClassInstanceRef(); if (r == 0) { ao.SetValue(null, i); } else { _instancePatchList.Add(new ArrayPatchInfo(r, ao, i)); } } } return(ao); } if (t.IsValueType) { object o = Activator.CreateInstance(t); MethodInfo unmarshal = t.GetMethod("ice_unmarshal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); if (unmarshal != null) { object[] args = new object[1]; args[0] = this; try { unmarshal.Invoke(o, args); } catch (TargetInvocationException te) { throw te.InnerException; } } else { foreach (FieldInfo field in t.GetFields()) { if (IceChannelUtils.IceByValue(field.FieldType)) { object elem = ReadObject(field.FieldType); field.SetValue(o, elem); } else { // this is a class type int r = ReadClassInstanceRef(); if (r == 0) { field.SetValue(o, null); } else { _instancePatchList.Add(new FieldPatchInfo(r, o, field)); } } } } return(o); } Console.WriteLine("ReadObject: can't read type " + t); throw new NotSupportedException("ReadObject: can't read type " + t); }
public object ReadSlice(object inst) { string sliceName = ReadSliceName(); int sliceDataSize = ReadInt32(); sliceDataSize -= 4; // size includes the 4 bytes of the size itself Type sliceType = IceUtil.IceNameToType(sliceName); if (sliceType == null) { // this means we have no local definition of this slice; // we keep going. Eventually we will hit an Ice.Object, // which is the terminating condition of this recursion, // since we know we have Ice.Object defined. ReadBytes(sliceDataSize); return(ReadSlice(inst)); } if (inst == null) { // if it's null, it has yet to be created, and this is // the first (i.e. most derived) slice that we // understand. inst = Activator.CreateInstance(sliceType); } MethodInfo unmarshal = sliceType.GetMethod("ice_unmarshal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); if (unmarshal != null) { object[] args = new object[1]; args[0] = this; try { unmarshal.Invoke(inst, args); } catch (TargetInvocationException te) { throw te.InnerException; } } else { FieldInfo[] fields = sliceType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (FieldInfo field in fields) { if (IceChannelUtils.IceByValue(field.FieldType)) { object elem = ReadObject(field.FieldType); field.SetValue(inst, elem); } else { // this is a class type int r = ReadClassInstanceRef(); if (r == 0) { field.SetValue(inst, null); } else { _instancePatchList.Add(new FieldPatchInfo(r, inst, field)); } } } } if (sliceType == typeof(Ice.Object)) { return(inst); } else { return(ReadSlice(inst)); } }