[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pnet-developers] ISeralizable patch
From: |
Andre 'Ilu' Seidelt |
Subject: |
[Pnet-developers] ISeralizable patch |
Date: |
Sun, 16 May 2004 23:07:21 +0200 |
User-agent: |
Mozilla Thunderbird 0.6 (Windows/20040502) |
Hi,
this is a patch which fixes (beside some minor stuff) the (de)seralization
of classes implementing ISerializable.
Changes:
Hashtable:
- the hash-provider is stored as HashCodeProvider instead of
HashCodeProviderName
ObjectManager:
- the OM can now handle SerializationInfo fixups
- the .ctor() of an ISerializable object is called when all fixups
to the
SerInfo are done (thx again Gopal ;).
- the deserialization event is now really raised
- now ALL IDeserializationCallback objects get registered
BinaryValueReader:
- switched from 'ilu coding convention' to 'pnet cc' :-)
- extended TypeInfo to handle ISer objects
- added missing BinaryTypeTags for String, Object and arrays of these
- ObjectReader know knows IS11n objects
BinaryValueWriter
- added IS11nWriter
- fixed GetMemberName() which always prefixed the name with the class
I did successfull (de)s11n a Hashtable :-)
regards
Ilu
Index: runtime/System/Collections/Hashtable.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/Collections/Hashtable.cs,v
retrieving revision 1.14
diff -u -r1.14 Hashtable.cs
--- runtime/System/Collections/Hashtable.cs 9 May 2004 14:36:39 -0000
1.14
+++ runtime/System/Collections/Hashtable.cs 16 May 2004 21:02:39 -0000
@@ -868,7 +868,7 @@
info.AddValue("LoadFactor", loadFactor);
info.AddValue("Version", generation);
info.AddValue("Comparer", comparer,
typeof(IComparer));
- info.AddValue("HashCodeProviderName", hcp,
+ info.AddValue("HashCodeProvider", hcp,
typeof(IHashCodeProvider));
info.AddValue("HashSize", (table == null ? 0 :
table.Length));
Index: runtime/System/Runtime/Serialization/ObjectManager.cs
===================================================================
RCS file:
/cvsroot/dotgnu-pnet/pnetlib/runtime/System/Runtime/Serialization/ObjectManager.cs,v
retrieving revision 1.5
diff -u -r1.5 ObjectManager.cs
--- runtime/System/Runtime/Serialization/ObjectManager.cs 2 May 2004
12:06:32 -0000 1.5
+++ runtime/System/Runtime/Serialization/ObjectManager.cs 16 May 2004
21:02:41 -0000
@@ -24,27 +24,31 @@
#if CONFIG_SERIALIZATION
+using System;
using System.Collections;
using System.Reflection;
using System.Security.Permissions;
+using System.Runtime.Serialization;
public class ObjectManager
{
// Common information that is stored for a member fixup.
private abstract class ObjectFixup
{
+ public ObjectManager manager;
public ObjectInfo value;
public ObjectFixup nextFixup;
// Constructor.
- protected ObjectFixup(ObjectInfo value, ObjectFixup nextFixup)
+ protected ObjectFixup(ObjectManager manager, ObjectInfo value,
ObjectFixup nextFixup)
{
+ this.manager = manager;
this.value = value;
this.nextFixup = nextFixup;
}
// Apply this fixup to an object.
- public virtual void Apply(Object obj)
+ public virtual void Apply(ObjectInfo objI)
{
throw new SerializationException
(_("Serialize_BadFixup"));
@@ -58,19 +62,19 @@
private MemberInfo member;
// Constructor.
- public MemberInfoFixup(ObjectInfo value, MemberInfo member,
- ObjectFixup
nextFixup)
- : base(value, nextFixup)
+ public MemberInfoFixup(ObjectManager manager, ObjectInfo value,
+ MemberInfo member, ObjectFixup nextFixup)
+ : base(manager, value, nextFixup)
{
this.member = member;
}
// Apply this fixup to an object.
- public override void Apply(Object obj)
+ public override void Apply(ObjectInfo objI)
{
if(member is FieldInfo)
{
-
((FieldInfo)member).SetValue(obj, value.obj);
+
((FieldInfo)member).SetValue(objI.obj, value.obj);
}
else
{
@@ -87,32 +91,54 @@
private String memberName;
// Constructor.
- public MemberNameFixup(ObjectInfo value, String memberName,
- ObjectFixup
nextFixup)
- : base(value, nextFixup)
+ public MemberNameFixup(ObjectManager manager, ObjectInfo value,
+ String memberName, ObjectFixup nextFixup)
+ : base(manager, value, nextFixup)
{
this.memberName = memberName;
}
// Apply this fixup to an object.
- public override void Apply(Object obj)
- {
- MemberInfo[] member =
obj.GetType().GetMember
- (memberName);
- if(member == null || member.Length != 1)
- {
- throw new SerializationException
-
(_("Serialize_BadFixup"));
- }
- if(member[0] is FieldInfo)
- {
-
((FieldInfo)(member[0])).SetValue(obj, value.obj);
- }
- else
- {
- throw new SerializationException
-
(_("Serialize_BadFixup"));
- }
+ public override void Apply(ObjectInfo objI)
+ {
+ if(objI.sinfo != null)
+ {
+ objI.sinfo.AddValue(memberName,
value.obj);
+
+ if(nextFixup == null)
+ {
+ BindingFlags flags =
BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance;
+ Type[] pTypes = new Type[]
{typeof(SerializationInfo), typeof(StreamingContext)};
+ Type type = objI.obj.GetType();
+ ConstructorInfo ctor =
type.GetConstructor(flags, null , pTypes, null);
+ if(ctor == null)
+ {
+ throw new SerializationException
+
(_("Serialize_BadFixup"));
+ }
+ Object[] parms = new Object[]
{objI.sinfo, manager.context};
+ (ctor as
ClrConstructor).InvokeOnEmpty(objI.obj, parms);
+ }
+ }
+ else
+ {
+ MemberInfo[] member =
objI.obj.GetType().GetMember
+ (memberName);
+ if(member == null || member.Length != 1)
+ {
+ throw new SerializationException
+
(_("Serialize_BadFixup"));
+ }
+ if(member[0] is FieldInfo)
+ {
+
((FieldInfo)(member[0])).SetValue(objI.obj, value.obj);
+ }
+ else
+ {
+ throw new SerializationException
+
(_("Serialize_BadFixup"));
+ }
+ }
}
}; // class MemberNameFixup
@@ -123,17 +149,17 @@
private int[] indices;
// Constructor.
- public ArrayIndexFixup(ObjectInfo value, int[] indices,
- ObjectFixup
nextFixup)
- : base(value, nextFixup)
+ public ArrayIndexFixup(ObjectManager manager, ObjectInfo value,
+ int[] indices, ObjectFixup nextFixup)
+ : base(manager, value, nextFixup)
{
this.indices = indices;
}
// Apply this fixup to an object.
- public override void Apply(Object obj)
+ public override void Apply(ObjectInfo objI)
{
- ((Array)obj).SetValue(value.obj,
indices);
+ ((Array)objI.obj).SetValue(value.obj,
indices);
}
}; // class ArrayIndexFixup
@@ -144,17 +170,17 @@
private int index;
// Constructor.
- public SingleArrayIndexFixup(ObjectInfo value, int index,
-
ObjectFixup nextFixup)
- : base(value, nextFixup)
+ public SingleArrayIndexFixup(ObjectManager manager, ObjectInfo
value,
+ int index, ObjectFixup nextFixup)
+ : base(manager, value, nextFixup)
{
this.index = index;
}
// Apply this fixup to an object.
- public override void Apply(Object obj)
+ public override void Apply(ObjectInfo objI)
{
- ((Array)obj).SetValue(value.obj, index);
+ ((Array)objI.obj).SetValue(value.obj,
index);
}
}; // class SingleArrayIndexFixup
@@ -176,7 +202,7 @@
// Internal state.
private ISurrogateSelector selector;
- private StreamingContext context;
+ protected StreamingContext context;
private Hashtable objects;
private ArrayList callbackList;
@@ -251,7 +277,7 @@
throw new
SerializationException
(_("Serialize_MissingFixup"));
}
-
fixup.Apply(contain.obj);
+ fixup.Apply(contain);
fixup = fixup.nextFixup;
}
ApplyContained(oinfo, contain);
@@ -295,10 +321,11 @@
throw new
SerializationException
(_("Serialize_MissingFixup"));
}
- fixup.Apply(oinfo.obj);
+ fixup.Apply(oinfo);
fixup = fixup.nextFixup;
}
}
+ RaiseDeserializationEvent();
}
// Return an object with a specific identifier.
@@ -363,7 +390,7 @@
ObjectInfo oinfo1 =
GetObjectInfo(arrayToBeFixed);
ObjectInfo oinfo2 =
GetObjectInfo(objectRequired);
oinfo1.fixups = new SingleArrayIndexFixup
- (oinfo2, index, oinfo1.fixups);
+ (this, oinfo2, index, oinfo1.fixups);
}
public virtual void RecordArrayElementFixup
(long arrayToBeFixed, int[] indices, long
objectRequired)
@@ -375,7 +402,7 @@
throw new
ArgumentNullException("indices");
}
oinfo1.fixups = new ArrayIndexFixup
- (oinfo2, indices, oinfo1.fixups);
+ (this, oinfo2, indices, oinfo1.fixups);
}
// Record an object member fixup to be performed later.
@@ -389,7 +416,7 @@
throw new
ArgumentNullException("memberName");
}
oinfo1.fixups = new MemberNameFixup
- (oinfo2, memberName, oinfo1.fixups);
+ (this, oinfo2, memberName,
oinfo1.fixups);
}
public virtual void RecordFixup
(long objectToBeFixed, MemberInfo member, long
objectRequired)
@@ -401,7 +428,7 @@
throw new
ArgumentNullException("member");
}
oinfo1.fixups = new MemberInfoFixup
- (oinfo2, member, oinfo1.fixups);
+ (this, oinfo2, member, oinfo1.fixups);
}
// Register an object with the object manager.
@@ -447,6 +474,10 @@
{
// Update the information for an
existing reference.
oinfo.obj = obj;
+ if(obj is IDeserializationCallback)
+ {
+ callbackList.Add(obj);
+ }
if(info != null)
{
oinfo.sinfo = info;
Index:
runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueReader.cs
===================================================================
RCS file:
/cvsroot/dotgnu-pnet/pnetlib/runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueReader.cs,v
retrieving revision 1.3
diff -u -r1.3 BinaryValueReader.cs
--- runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueReader.cs
3 May 2004 13:36:04 -0000 1.3
+++ runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueReader.cs
16 May 2004 21:02:41 -0000
@@ -28,13 +28,13 @@
using System.IO;
using System.Reflection;
using System.Collections;
+using System.Runtime.Serialization;
/*
* unsupported features:
* - BinaryElementType.MethodCall: not needed by me :-)
* - BinaryElementType.MethodResponse: not needed by me :-)
* - user defined serialization headers
-* - classes implementing the ISerializable interface
*
* unsupported array types:
* - Arrays of Enums
@@ -111,12 +111,17 @@
}
}
- public ObjectManager manager
+ public ObjectManager Manager
{
get { return mObjManager; }
}
- public BinaryReader reader
+ public BinaryFormatter Formatter
+ {
+ get { return mFormatter; }
+ }
+
+ public BinaryReader Reader
{
get { return mReader; }
}
@@ -207,10 +212,13 @@
private TypeSpecification[] mTypeSpec;
private Type mObjectType;
private MemberInfo[] mMembers;
+ private bool mIsIserializable;
+ private FormatterConverter mConverter;
- public TypeInfo(String name, String[] fieldNames, BinaryTypeTag[] tt,
- TypeSpecification[] ts, Assembly
assembly)
+ public TypeInfo(DeserializationContext context, String name, String[]
fieldNames,
+ BinaryTypeTag[] tt, TypeSpecification[] ts, Assembly
assembly)
{
+ mConverter = context.Formatter.converter;
mFieldNames = fieldNames;
mTypeTag = tt;
mTypeSpec = ts;
@@ -225,100 +233,109 @@
mObjectType = assembly.GetType(name, true);
}
- // lookup all members once
- mMembers = new MemberInfo[NumMembers];
- for(int i = 0; i < NumMembers; i++)
- {
- // ms and mono have their values for
boxed primitive types called 'm_value', we need a fix for that
- if(mObjectType.IsPrimitive && (mFieldNames[i] ==
"m_value"))
- {
- mFieldNames[i] = "value_";
- }
- else if (mObjectType == typeof(DateTime) &&
- (mFieldNames[i] == "ticks"))
- {
- // this is for DateTime
- mFieldNames[i] = "value_";
- }
- else if (mObjectType == typeof(TimeSpan) &&
- (mFieldNames[i] == "_ticks"))
- {
- // this is for TimeSpan
- mFieldNames[i] = "value_";
- }
- else if (mObjectType == typeof(Decimal))
- {
- switch(mFieldNames[i])
- {
- case "hi":
- {
- mFieldNames[i] = "high";
- }
- break;
- case "lo":
- {
- mFieldNames[i] = "low";
- }
- break;
- case "mid":
- {
- mFieldNames[i] = "middle";
- }
- break;
- }
- }
-
- Type memberType;
- String memberName;
- int classSeparator = mFieldNames[i].IndexOf('+');
- if(classSeparator != -1)
- {
- /*
- * TODO: check if there are constraints in
which assembly
- * the Type may be looked up! for now just look
it up
- * generally
- */
- String baseName = mFieldNames[i].Substring(0,
classSeparator);
- memberName =
mFieldNames[i].Substring(classSeparator+1,
mFieldNames[i].Length-classSeparator-1);
- memberType = mObjectType;
-
- // MS does NOT store the FullQualifiedTypename
if there
- // is no collision but only the Typename :-(
- while(!memberType.FullName.EndsWith(baseName))
- {
- // check if we reached System.Object
- if(memberType == memberType.BaseType ||
memberType == null)
- {
- // TODO : I18n
- throw new
SerializationException("Can't find member "+mFieldNames[i]);
- }
- memberType = memberType.BaseType;
- }
- }
- else
- {
- memberType = mObjectType;
- memberName = mFieldNames[i];
- }
-
- // get member from object
- MemberInfo[] members = memberType.GetMember(memberName,
-
MemberTypes.Field |
-
MemberTypes.Property,
-
BindingFlags.Instance |
-
BindingFlags.Public |
-
BindingFlags.NonPublic);
-
- if((members == null) || (members.Length < 1))
- {
- // TODO: I18n
- throw new SerializationException("Can't find
member "+mFieldNames[i]);
- }
- else
- {
- mMembers[i] = members[0];
- }
- }
+ if(typeof(ISerializable).IsAssignableFrom(mObjectType))
+ {
+ mIsIserializable = true;
+ }
+ else
+ {
+ mIsIserializable = false;
+
+ // lookup all members once
+ mMembers = new MemberInfo[NumMembers];
+ for(int i = 0; i < NumMembers; i++)
+ {
+ // ms and mono have their values for boxed primitive
types called 'm_value', we need a fix for that
+ if(mObjectType.IsPrimitive && (mFieldNames[i] ==
"m_value"))
+ {
+ mFieldNames[i] = "value_";
+ }
+ else if (mObjectType == typeof(DateTime) &&
+ (mFieldNames[i] == "ticks"))
+ {
+ // this is for DateTime
+ mFieldNames[i] = "value_";
+ }
+ else if (mObjectType == typeof(TimeSpan) &&
+ (mFieldNames[i] == "_ticks"))
+ {
+ // this is for TimeSpan
+ mFieldNames[i] = "value_";
+ }
+ else if (mObjectType == typeof(Decimal))
+ {
+ switch(mFieldNames[i])
+ {
+ case "hi":
+ {
+ mFieldNames[i] = "high";
+ }
+ break;
+ case "lo":
+ {
+ mFieldNames[i] = "low";
+ }
+ break;
+ case "mid":
+ {
+ mFieldNames[i] = "middle";
+ }
+ break;
+ }
+ }
+
+ Type memberType;
+ String memberName;
+ int classSeparator = mFieldNames[i].IndexOf('+');
+ if(classSeparator != -1)
+ {
+ /*
+ * TODO: check if there are constraints in
which assembly
+ * the Type may be looked up! for now just
look it up
+ * generally
+ */
+ String baseName = mFieldNames[i].Substring(0,
classSeparator);
+ memberName =
mFieldNames[i].Substring(classSeparator+1,
mFieldNames[i].Length-classSeparator-1);
+ memberType = mObjectType;
+
+ // MS does NOT store the FullQualifiedTypename
if there
+ // is no collision but only the Typename :-(
+
while(!memberType.FullName.EndsWith(baseName))
+ {
+ // check if we reached System.Object
+ if(memberType == memberType.BaseType ||
memberType == null)
+ {
+ // TODO : I18n
+ throw new
SerializationException("Can't find member "+mFieldNames[i]);
+ }
+ memberType = memberType.BaseType;
+ }
+ }
+ else
+ {
+ memberType = mObjectType;
+ memberName = mFieldNames[i];
+ }
+
+ // get member from object
+ MemberInfo[] members = memberType.GetMember(memberName,
+
MemberTypes.Field |
+
MemberTypes.Property,
+
BindingFlags.Instance |
+
BindingFlags.Public |
+
BindingFlags.NonPublic);
+
+ if((members == null) || (members.Length < 1))
+ {
+ // TODO: I18n
+ throw new SerializationException("Can't find
member "+mFieldNames[i]);
+ }
+ else
+ {
+ mMembers[i] = members[0];
+ }
+ }
+ }
}
public BinaryTypeTag GetTypeTag(uint index)
@@ -336,6 +353,16 @@
return mMembers[index];
}
+ public String GetFieldName(uint index)
+ {
+ return mFieldNames[index];
+ }
+
+ public SerializationInfo GetSerializationInfo()
+ {
+ return new SerializationInfo(mObjectType, mConverter);
+ }
+
public Type ObjectType
{
get {return mObjectType; }
@@ -345,6 +372,11 @@
{
get { return mTypeTag.Length; }
}
+
+ public bool IsISerializable
+ {
+ get { return mIsIserializable; }
+ }
}
/*
@@ -454,42 +486,42 @@
}
}
- public static object ReadPrimitiveType(DeserializationContext context,
BinaryPrimitiveTypeCode typeCode)
+ public static Object ReadPrimitiveType(DeserializationContext context,
BinaryPrimitiveTypeCode typeCode)
{
switch(typeCode)
{
case BinaryPrimitiveTypeCode.Boolean:
- return context.reader.ReadBoolean();
+ return context.Reader.ReadBoolean();
case BinaryPrimitiveTypeCode.Byte:
- return context.reader.ReadByte();
+ return context.Reader.ReadByte();
case BinaryPrimitiveTypeCode.Char:
- return context.reader.ReadChar();
+ return context.Reader.ReadChar();
case BinaryPrimitiveTypeCode.Decimal:
- return
Decimal.Parse(context.reader.ReadString());
+ return
Decimal.Parse(context.Reader.ReadString());
case BinaryPrimitiveTypeCode.Double:
- return context.reader.ReadDouble();
+ return context.Reader.ReadDouble();
case BinaryPrimitiveTypeCode.Int16:
- return context.reader.ReadInt16();
+ return context.Reader.ReadInt16();
case BinaryPrimitiveTypeCode.Int32:
- return context.reader.ReadInt32();
+ return context.Reader.ReadInt32();
case BinaryPrimitiveTypeCode.Int64:
- return context.reader.ReadInt64();
+ return context.Reader.ReadInt64();
case BinaryPrimitiveTypeCode.SByte:
- return context.reader.ReadSByte();
+ return context.Reader.ReadSByte();
case BinaryPrimitiveTypeCode.Single:
- return context.reader.ReadSingle();
+ return context.Reader.ReadSingle();
case BinaryPrimitiveTypeCode.TimeSpan:
- return new TimeSpan(context.reader.ReadInt64());
+ return new TimeSpan(context.Reader.ReadInt64());
case BinaryPrimitiveTypeCode.DateTime:
- return new DateTime(context.reader.ReadInt64());
+ return new DateTime(context.Reader.ReadInt64());
case BinaryPrimitiveTypeCode.UInt16:
- return context.reader.ReadUInt16();
+ return context.Reader.ReadUInt16();
case BinaryPrimitiveTypeCode.UInt32:
- return context.reader.ReadUInt32();
+ return context.Reader.ReadUInt32();
case BinaryPrimitiveTypeCode.UInt64:
- return context.reader.ReadUInt64();
+ return context.Reader.ReadUInt64();
case BinaryPrimitiveTypeCode.String:
- return context.reader.ReadString();
+ return context.Reader.ReadString();
default:
throw new SerializationException("unknown
primitive type code:"+typeCode);
@@ -538,10 +570,10 @@
}
}
- public static object Deserialize(DeserializationContext context)
+ public static Object Deserialize(DeserializationContext context)
{
bool keepGoing = true;
- object tree = null;
+ Object tree = null;
// TODO: find better solution for finding the root of the
object tree
do
@@ -557,9 +589,9 @@
return tree;
}
- public static bool ReadValue(DeserializationContext context, out object
outVal)
+ public static bool ReadValue(DeserializationContext context, out Object
outVal)
{
- BinaryElementType element = (BinaryElementType)
context.reader.ReadByte();
+ BinaryElementType element = (BinaryElementType)
context.Reader.ReadByte();
BinaryValueReader reader = GetReader(element);
return reader.Read(context, out outVal);
}
@@ -570,27 +602,39 @@
{
case BinaryTypeTag.PrimitiveType:
case BinaryTypeTag.ArrayOfPrimitiveType:
- return new
TypeSpecification((BinaryPrimitiveTypeCode) context.reader.ReadByte());
+ return new
TypeSpecification((BinaryPrimitiveTypeCode) context.Reader.ReadByte());
case BinaryTypeTag.RuntimeType:
- return new
TypeSpecification(context.reader.ReadString());
+ return new
TypeSpecification(context.Reader.ReadString());
case BinaryTypeTag.GenericType:
- String typeName = context.reader.ReadString();
- uint assId = context.reader.ReadUInt32();
+ String typeName = context.Reader.ReadString();
+ uint assId = context.Reader.ReadUInt32();
return new TypeSpecification(typeName, assId);
+ case BinaryTypeTag.String:
+ return new TypeSpecification("System.String");
+
+ case BinaryTypeTag.ObjectType:
+ return new TypeSpecification("System.Object");
+
+ case BinaryTypeTag.ArrayOfString:
+ return new TypeSpecification("System.String[]");
+
+ case BinaryTypeTag.ArrayOfObject:
+ return new TypeSpecification("System.Object[]");
+
default:
return null;
}
}
- public abstract bool Read(DeserializationContext context, out object
outVal);
+ public abstract bool Read(DeserializationContext context, out Object
outVal);
}
class NullReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
outVal = null;
return true;
@@ -599,9 +643,9 @@
class EndReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- context.manager.DoFixups();
+ context.Manager.DoFixups();
outVal = null;
return false;
}
@@ -609,12 +653,12 @@
class HeaderReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
// check if there is a serialization header
- int hasHeader = context.reader.ReadInt32();
+ int hasHeader = context.Reader.ReadInt32();
if(hasHeader == 2)
{
context.IsHeaderPresent = true;
@@ -629,8 +673,8 @@
}
// read major/minor version
- context.MajorVersion = context.reader.ReadUInt32();
- context.MinorVersion = context.reader.ReadUInt32();
+ context.MajorVersion = context.Reader.ReadUInt32();
+ context.MinorVersion = context.Reader.ReadUInt32();
outVal = null;
return true;
@@ -639,12 +683,12 @@
class StringReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- String str = context.reader.ReadString();
+ uint id = context.Reader.ReadUInt32();
+ String str = context.Reader.ReadString();
- context.manager.RegisterObject(str, id);
+ context.Manager.RegisterObject(str, id);
outVal = str;
return true;
}
@@ -666,7 +710,7 @@
array = Array.CreateInstance(convertedType, (int)
count);
for(uint i = 0; i < count; i++)
{
- object val;
+ Object val;
val = ReadPrimitiveType(context,
(BinaryPrimitiveTypeCode) type);
array.SetValue(val, i);
}
@@ -678,14 +722,14 @@
array = Array.CreateInstance(convertedType, (int)
count);
for(int i = 0; i < count; i++)
{
- object val;
+ Object val;
ret &= ReadValue(context, out val);
if(val is DelayedReferenceHolder)
{
// record this index for fixup
DelayedReferenceHolder holder =
(DelayedReferenceHolder) val;
-
context.manager.RecordArrayElementFixup(id, i, holder.ReferenceId);
+
context.Manager.RecordArrayElementFixup(id, i, holder.ReferenceId);
}
else if(val is ArrayNullValueHolder)
{
@@ -708,7 +752,7 @@
throw new SerializationException("illegal call
with:"+type);
}
- context.manager.RegisterObject(array, id);
+ context.Manager.RegisterObject(array, id);
outVal = array;
return ret;
@@ -717,10 +761,10 @@
class StringArrayReader : ArrayReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- uint count = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
+ uint count = context.Reader.ReadUInt32();
return Read(context, id, count, typeof(String), out outVal);
}
@@ -728,10 +772,10 @@
class ObjectArrayReader : ArrayReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- uint count = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
+ uint count = context.Reader.ReadUInt32();
return Read(context, id, count, typeof(Object), out outVal);
}
@@ -739,28 +783,28 @@
class PrimitiveArrayReader : ArrayReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- uint count = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
+ uint count = context.Reader.ReadUInt32();
- BinaryPrimitiveTypeCode typeCode = (BinaryPrimitiveTypeCode)
context.reader.ReadByte();
+ BinaryPrimitiveTypeCode typeCode = (BinaryPrimitiveTypeCode)
context.Reader.ReadByte();
return Read(context, id, count, typeCode, out outVal);
}
}
class GenericArrayReader : ArrayReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- uint arrayType = context.reader.ReadByte();
- uint dimensions = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
+ uint arrayType = context.Reader.ReadByte();
+ uint dimensions = context.Reader.ReadUInt32();
uint[] dimSizes = new uint[dimensions];
for(int i = 0; i < dimensions; i++)
{
- dimSizes[i] = context.reader.ReadUInt32();
+ dimSizes[i] = context.Reader.ReadUInt32();
}
// TODO: up to now we only support single dimension arrays
@@ -769,7 +813,7 @@
throw new SerializationException("array dimmensions > 1
|| jagged arrays NYI!");
}
- BinaryTypeTag typeTag = (BinaryTypeTag)
context.reader.ReadByte();
+ BinaryTypeTag typeTag = (BinaryTypeTag)
context.Reader.ReadByte();
TypeSpecification typeSpec = ReadTypeSpec(context, typeTag);
if(typeTag == BinaryTypeTag.PrimitiveType)
@@ -785,10 +829,10 @@
class AssemblyReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- String name = context.reader.ReadString();
+ uint id = context.Reader.ReadUInt32();
+ String name = context.Reader.ReadString();
// load specified assembly
Assembly assembly = Assembly.Load(name);
@@ -809,57 +853,100 @@
abstract class ObjectReader : BinaryValueReader
{
- public bool Read(DeserializationContext context, out object outVal,
uint id, TypeInfo typeInfo)
+ public bool Read(DeserializationContext context, out Object outVal,
uint id, TypeInfo typeInfo)
{
bool ret = true;
- // create instance
- Object obj =
FormatterServices.GetUninitializedObject(typeInfo.ObjectType);
-
- // read and set values
- for(uint i = 0; i < typeInfo.NumMembers; i++)
- {
- // first get inlined data
- Object memberValue;
- if(typeInfo.GetTypeTag(i) ==
BinaryTypeTag.PrimitiveType)
- {
- memberValue = ReadPrimitiveType(context,
typeInfo.GetTypeSpecification(i).GetPrimitiveType());
- }
- else
- {
- ret &= ReadValue(context, out memberValue);
- }
-
- // set value
- MemberInfo field = typeInfo.GetMember(i);
- if(memberValue is DelayedReferenceHolder)
- {
- // this is a reference
- DelayedReferenceHolder holder =
(DelayedReferenceHolder) memberValue;
- context.manager.RecordFixup(id, field,
holder.ReferenceId);
- }
- else
- {
- // this is a real value
- if(field is FieldInfo)
- {
- FieldInfo fi = (FieldInfo) field;
- fi.SetValue(obj, memberValue);
- }
- // TODO: i'm not sure if I have to
cover that case, too!
- // I just noticed that Mono does this
- // else
if(field is PropertyInfo)
- // {
- //
PropertyInfo pi = (PropertyInfo) field;
- //
pi.SetValue();
- else
- {
- throw new
SerializationException("unknown memeber type:"+field.GetType());
- }
- }
- }
-
- context.manager.RegisterObject(obj, id);
+ // create instance
+ Object obj = null;
+ SerializationInfo info = null;
+
+ if(typeInfo.IsISerializable)
+ {
+ info = typeInfo.GetSerializationInfo();
+
+ // create instance
+ obj =
FormatterServices.GetUninitializedObject(typeInfo.ObjectType);
+
+ // read and set values
+ for(uint i = 0; i < typeInfo.NumMembers; i++)
+ {
+ // first get inlined data
+ Object memberValue;
+ if(typeInfo.GetTypeTag(i) ==
BinaryTypeTag.PrimitiveType)
+ {
+ memberValue = ReadPrimitiveType(context,
typeInfo.GetTypeSpecification(i).GetPrimitiveType());
+ }
+ else
+ {
+ ret &= ReadValue(context, out memberValue);
+ }
+
+ // set value
+ String field = typeInfo.GetFieldName(i);
+ if(memberValue is DelayedReferenceHolder)
+ {
+ // this is a reference
+ DelayedReferenceHolder holder =
(DelayedReferenceHolder) memberValue;
+ context.Manager.RecordDelayedFixup(id, field,
holder.ReferenceId);
+ }
+ else
+ {
+ // this is a real value
+ info.AddValue(field, memberValue,
typeInfo.GetTypeSpecification(i).GetObjectType(context));
+ }
+ }
+ context.Manager.RegisterObject(obj, id, info);
+ }
+ else
+ {
+ // create instance
+ obj =
FormatterServices.GetUninitializedObject(typeInfo.ObjectType);
+
+ // read and set values
+ for(uint i = 0; i < typeInfo.NumMembers; i++)
+ {
+ // first get inlined data
+ Object memberValue;
+ if(typeInfo.GetTypeTag(i) ==
BinaryTypeTag.PrimitiveType)
+ {
+ memberValue = ReadPrimitiveType(context,
typeInfo.GetTypeSpecification(i).GetPrimitiveType());
+ }
+ else
+ {
+ ret &= ReadValue(context, out memberValue);
+ }
+
+ // set value
+ MemberInfo field = typeInfo.GetMember(i);
+ if(memberValue is DelayedReferenceHolder)
+ {
+ // this is a reference
+ DelayedReferenceHolder holder =
(DelayedReferenceHolder) memberValue;
+ context.Manager.RecordFixup(id, field,
holder.ReferenceId);
+ }
+ else
+ {
+ // this is a real value
+ if(field is FieldInfo)
+ {
+ FieldInfo fi = (FieldInfo) field;
+ fi.SetValue(obj, memberValue);
+ }
+ // TODO: i'm not sure if I have to
cover that case, too!
+ // I just noticed that Mono does
this
+ // else
if(field is PropertyInfo)
+ // {
+ //
PropertyInfo pi = (PropertyInfo) field;
+ //
pi.SetValue();
+ else
+ {
+ throw new
SerializationException("unknown memeber type:"+field.GetType());
+ }
+ }
+ }
+ context.Manager.RegisterObject(obj, id);
+ }
outVal = obj;
return ret;
}
@@ -867,25 +954,25 @@
abstract class FullObjectReader : ObjectReader
{
- public bool Read(DeserializationContext context, out object outVal,
bool external)
+ public bool Read(DeserializationContext context, out Object outVal,
bool external)
{
- uint id = context.reader.ReadUInt32();
- String name = context.reader.ReadString();
+ uint id = context.Reader.ReadUInt32();
+ String name = context.Reader.ReadString();
- uint fieldCount = context.reader.ReadUInt32();
+ uint fieldCount = context.Reader.ReadUInt32();
// collect the names of the fields
String[] fieldNames = new String[fieldCount];
for(int i = 0; i < fieldCount; i++)
{
- fieldNames[i] = context.reader.ReadString();
+ fieldNames[i] = context.Reader.ReadString();
}
// collect the type-tags of the fields
BinaryTypeTag[] typeTags = new BinaryTypeTag[fieldCount];
for(int i = 0; i < fieldCount; i++)
{
- typeTags[i] = (BinaryTypeTag) context.reader.ReadByte();
+ typeTags[i] = (BinaryTypeTag) context.Reader.ReadByte();
}
// collect the type-specifications of the fields if necessary
@@ -899,11 +986,11 @@
Assembly assembly = null;
if(external)
{
- assembly =
context.GetAssembly(context.reader.ReadUInt32());
+ assembly =
context.GetAssembly(context.Reader.ReadUInt32());
}
// store type-information for later usage
- TypeInfo typeInfo = new TypeInfo(name, fieldNames, typeTags,
typeSpecs, assembly);
+ TypeInfo typeInfo = new TypeInfo(context, name, fieldNames,
typeTags, typeSpecs, assembly);
context.SetTypeInfo(id, typeInfo);
// let our parent read the inlined values
@@ -913,7 +1000,7 @@
class ExternalObjectReader : FullObjectReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
return Read(context, out outVal, true);
}
@@ -921,7 +1008,7 @@
class RuntimeObjectReader : FullObjectReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
return Read(context, out outVal, false);
}
@@ -929,10 +1016,10 @@
class RefObjectReader : ObjectReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint id = context.reader.ReadUInt32();
- uint refId = context.reader.ReadUInt32();
+ uint id = context.Reader.ReadUInt32();
+ uint refId = context.Reader.ReadUInt32();
// get type-information from context
TypeInfo typeInfo = context.GetTypeInfo(refId);
@@ -943,9 +1030,9 @@
class ObjectReferenceReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint refId = context.reader.ReadUInt32();
+ uint refId = context.Reader.ReadUInt32();
// this 'special' object indicates that we haven't read a real
object, but will read it later on
outVal = new DelayedReferenceHolder(refId);
@@ -955,9 +1042,9 @@
class ArrayFiller8bReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint numNulls = context.reader.ReadByte();
+ uint numNulls = context.Reader.ReadByte();
// this 'special' object indicates that we haven't read a real
object,
// but should insert a number of NULL values.
@@ -968,9 +1055,9 @@
class ArrayFiller32bReader : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
- uint numNulls = context.reader.ReadUInt32();
+ uint numNulls = context.Reader.ReadUInt32();
// this 'special' object indicates that we haven't read a real
object,
// but should insert a number of NULL values.
@@ -981,7 +1068,7 @@
class BoxedPrimitiveTypeValue : BinaryValueReader
{
- public override bool Read(DeserializationContext context, out object
outVal)
+ public override bool Read(DeserializationContext context, out Object
outVal)
{
TypeSpecification typeSpec = ReadTypeSpec(context,
BinaryTypeTag.PrimitiveType);
outVal = ReadPrimitiveType(context,
typeSpec.GetPrimitiveType());
Index:
runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueWriter.cs
===================================================================
RCS file:
/cvsroot/dotgnu-pnet/pnetlib/runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueWriter.cs,v
retrieving revision 1.9
diff -u -r1.9 BinaryValueWriter.cs
--- runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueWriter.cs
3 May 2004 13:36:04 -0000 1.9
+++ runtime/System/Runtime/Serialization/Formatters/Binary/BinaryValueWriter.cs
16 May 2004 21:02:41 -0000
@@ -22,11 +22,12 @@
namespace System.Runtime.Serialization.Formatters.Binary
{
-#if CONFIG_SERIALIZATION
+//#if CONFIG_SERIALIZATION
using System.IO;
using System.Reflection;
using System.Collections;
+using System.Runtime.Serialization;
internal abstract class BinaryValueWriter
{
@@ -49,6 +50,7 @@
private static BinaryValueWriter stringWriter = new StringWriter();
private static BinaryValueWriter objectWriter = new ObjectWriter();
private static BinaryValueWriter infoWriter = new SurrogateWriter(null);
+ private static BinaryValueWriter serializableWriter = new
ISerializableWriter();
private static BinaryValueWriter arrayWriter = new ArrayWriter();
// Context information for writing binary values.
@@ -243,6 +245,12 @@
return stringWriter;
}
+ // Check for types that implement ISerializable.
+ if(typeof(ISerializable).IsAssignableFrom(type))
+ {
+ return serializableWriter;
+ }
+
// Handle special types that we recognize.
if(type == typeof(Object))
{
@@ -267,15 +275,9 @@
}
}
- // Check for types that implement ISerializable.
- if(typeof(ISerializable).IsAssignableFrom(type))
- {
- return infoWriter;
- }
-
// Bail out if the type is not marked with the
// "serializable" flag.
- if(!type.IsSerializable)
+ if(!type.IsSerializable && !type.IsInterface)
{
throw new SerializationException
(String.Format
@@ -315,7 +317,7 @@
private static String GetMemberName(MemberInfo[] allMembers, MemberInfo
member) {
bool prefix = false;
foreach(MemberInfo mi in allMembers) {
- if(mi.Name == member.Name) {
+ if(mi.Name == member.Name && mi.DeclaringType !=
member.DeclaringType) {
prefix = true;
break;
}
@@ -572,6 +574,117 @@
}; // class ObjectWriter
+ private class ISerializableWriter : ObjectWriter
+ {
+ // Write the object header information for a type.
+ // IS11n objects are written like normal objects, but the
+ // members are replaced by the key->value pairs from the
+ // SerInfo.
+ public override void WriteObjectHeader(BinaryValueContext
context,
+
Object value, Type type,
+
long objectID, long prevObject)
+ {
+ if(prevObject == -1)
+ {
+ // Write the full type
information.
+ long assemblyID;
+ if(type.Assembly ==
Assembly.GetExecutingAssembly())
+ {
+ context.writer.Write
+
((byte)(BinaryElementType.RuntimeObject));
+ assemblyID = -1;
+ }
+ else
+ {
+ bool firstTime;
+ assemblyID =
context.gen.GetId
+ (type.Assembly,
out firstTime);
+ if(firstTime)
+ {
+
context.writer.Write
+
((byte)(BinaryElementType.Assembly));
+
context.writer.Write((int)assemblyID);
+
WriteAssemblyName(context, type.Assembly);
+ }
+ context.writer.Write
+
((byte)(BinaryElementType.ExternalObject));
+ }
+
context.writer.Write((int)objectID);
+
context.writer.Write(type.FullName);
+
+ // get members
+ StreamingContext streamContext
= context.formatter.Context;
+ SerializationInfo info = new
SerializationInfo(type, context.formatter.converter);
+ ((ISerializable)
value).GetObjectData(info, streamContext);
+
+ // write out number of members
+
context.writer.Write((int)info.MemberCount);
+
+ int index;
+ Type fieldType;
+
+ foreach(SerializationEntry
entry in info)
+ {
+
context.writer.Write(entry.Name);
+ }
+
+ foreach(SerializationEntry
entry in info)
+ {
+ GetWriter(context,
entry.ObjectType).WriteTypeTag
+ (context,
entry.ObjectType);
+ }
+
+ foreach(SerializationEntry
entry in info)
+ {
+ GetWriter(context,
entry.ObjectType).WriteTypeSpec
+ (context,
entry.ObjectType);
+ }
+ if(assemblyID != -1)
+ {
+
context.writer.Write((int)assemblyID);
+ }
+ }
+ else
+ {
+ // Write a short header,
referring to a previous
+ // object's type information.
+ context.writer.Write
+
((byte)(BinaryElementType.RefTypeObject));
+
context.writer.Write((int)objectID);
+
context.writer.Write((int)prevObject);
+ }
+ }
+
+ // Write the object form of values for a type.
+ public override void WriteObject(BinaryValueContext context,
+ Object value, Type type)
+ {
+ StreamingContext streamContext =
context.formatter.Context;
+ SerializationInfo info = new SerializationInfo(type,
context.formatter.converter);
+
+ ((ISerializable) value).GetObjectData(info,
streamContext);
+
+ // the entries are written using the type-spec supplied when
+ // they were put into the SerInfo, but the writer is determined
+ // by the real type!
+ foreach(SerializationEntry entry in info)
+ {
+ Object val = entry.Value;
+ if(val != null)
+ {
+ GetWriter(context,
val.GetType()).WriteInline
+ (context, val, val.GetType(),
entry.ObjectType);
+ }
+ else
+ {
+ // NULL is always written as object
+ GetWriter(context,
typeof(Object)).WriteInline
+ (context, val, typeof(Object),
entry.ObjectType);
+ }
+ }
+ }
+ }
+
// Write object values using serialization surrogates.
private class SurrogateWriter : ObjectWriter
{
@@ -1472,6 +1585,6 @@
}; // class BinaryValueWriter
-#endif // CONFIG_SERIALIZATION
+//#endif // CONFIG_SERIALIZATION
}; // namespace System.Runtime.Serialization.Formatters.Binary
- [Pnet-developers] ISeralizable patch,
Andre 'Ilu' Seidelt <=