예제 #1
0
        internal static int Serialize(T instance, SerializationContext context)
        {
            // check for inheritance; if the instance is a subclass, then we
            // should serialize the sub-type first, allowing for more efficient
            // deserialization; note that we don't push the instance onto the
            // stack yet - we'll do that within each instance (otherwise deep
            // items could incorrectly count as cyclic).
            Type actualType = instance.GetType();
            int  total = 0, len;

            Callback(CallbackType.BeforeSerialization, instance);

            if (actualType != typeof(T))
            {
                bool subclassFound = false;
                foreach (KeyValuePair <Type, Property <T, T> > subclass in subclasses)
                {
                    if (subclass.Key.IsAssignableFrom(actualType))
                    {
                        total        += subclass.Value.Serialize(instance, context);
                        subclassFound = true;
                        break;
                    }
                }
                if (!subclassFound)
                {
                    throw new ProtoException("Unexpected type found during serialization; types must be included with ProtoIncludeAttribute; "
                                             + "found " + actualType.Name + " passed as " + typeof(T).Name);
                }
            }

            context.Push(instance);
            for (int i = 0; i < writeProps.Length; i++)
            {
                // note that this serialization includes the headers...
                total += writeProps[i].Serialize(instance, context);
            }
            IExtensible extensible = instance as IExtensible;
            IExtension  extra      = extensible == null ? null : extensible.GetExtensionObject(false);

            if (extra != null && (len = extra.GetLength()) > 0)
            {
                Stream extraStream = extra.BeginQuery();
                try
                {
                    context.WriteFrom(extraStream, len);
                    total += len;
                }
                finally
                {
                    extra.EndQuery(extraStream);
                }
            }
            context.Pop(instance);
            Callback(CallbackType.AfterSerialization, instance);
            return(total);
        }