Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 10 commits
  • 29 files changed
  • 0 commit comments
  • 2 contributors
Commits on Feb 04, 2012
marc.gravell Fix: SO 9144967
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@484 b72047a4-3652-0410-9617-b3994939e97b
ca205a4
Commits on Feb 07, 2012
marc.gravell Support Type serialization; added incomplete SO9151111
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@485 b72047a4-3652-0410-9617-b3994939e97b
20a63ef
Commits on Feb 29, 2012
marc.gravell ADD: Strong name for Mono
FIX: SO9408133 - detect corrupt streams more aggressively
ADD: SO9398578 - more elegant handling of ProtoInclude for generic crossover scenarios
REMOVE: "beta" warning


git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@486 b72047a4-3652-0410-9617-b3994939e97b
163873b
marc.gravell FIX: Issue 266 - null assertion
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@487 b72047a4-3652-0410-9617-b3994939e97b
ebcb67c
marc.gravell FIX: SO9491933
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@488 b72047a4-3652-0410-9617-b3994939e97b
9b04112
Commits on Mar 30, 2012
marc.gravell Clarify problem when non-contract-types fail with DynamicType (Issue …
…284)

git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@491 b72047a4-3652-0410-9617-b3994939e97b
3122608
Commits on Apr 12, 2012
marc.gravell SO10115538.cs
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@492 b72047a4-3652-0410-9617-b3994939e97b
2397b64
Commits on May 07, 2012
marc.gravell Remove T : class constraint from Serializer.PrepareSerializer<T>()
git-svn-id: http://protobuf-net.googlecode.com/svn/trunk@506 b72047a4-3652-0410-9617-b3994939e97b
19e1eff
Commits on May 19, 2012
@mdavid Merge branch 'master' of github.com:mdavid/protobuf-net f1d6c0b
@mdavid ignores for git 414080a
View
1 .gitignore
@@ -0,0 +1 @@
+.svn2git
View
8 Examples/Examples.csproj
@@ -208,6 +208,7 @@
<Compile Include="Issues\Issue266.cs" />
<Compile Include="Issues\Issue27.cs" />
<Compile Include="Issues\Issue218.cs" />
+ <Compile Include="Issues\Issue284.cs" />
<Compile Include="Issues\Issue29.cs" />
<Compile Include="Issues\Issue32.cs" />
<Compile Include="Issues\Issue41.cs" />
@@ -247,6 +248,12 @@
<Compile Include="Issues\SO7727355.cs" />
<Compile Include="Issues\SO8093623.cs" />
<Compile Include="Issues\SO8466936.cs" />
+ <Compile Include="Issues\SO9144967.cs" />
+ <Compile Include="Issues\SO9151111.cs" />
+ <Compile Include="Issues\SO9151111b.cs" />
+ <Compile Include="Issues\SO9398578.cs" />
+ <Compile Include="Issues\SO9408133.cs" />
+ <Compile Include="Issues\SO9491933.cs" />
<Compile Include="ItemsWithLengthPrefix.cs" />
<Compile Include="ListAsInterfaceTests.cs" />
<Compile Include="ListsWithInheritance.cs" />
@@ -309,6 +316,7 @@
<Compile Include="TestNumbers\NumberTests.cs" />
<Compile Include="TraceError.cs" />
<Compile Include="Tuples.cs" />
+ <Compile Include="Type.cs" />
<Compile Include="TypeFactory.cs" />
<Compile Include="UnwrappedOuters.cs" />
<Compile Include="ValueWrapper.cs" />
View
13 Examples/Issues/Issue266.cs
@@ -5,6 +5,7 @@
using NUnit.Framework;
using ProtoBuf;
using System.IO;
+using ProtoBuf.Meta;
namespace Examples.Issues
{
@@ -29,6 +30,18 @@ public void TestNakedNullableEnumDeserialize()
Foo? foo = Serializer.Deserialize<Foo?>(Stream.Null);
Assert.IsNull(foo);
}
+ [Test]
+ public void TestNakedDirectFoo()
+ {
+ Foo orig = Foo.B, result;
+ using(var ms = new MemoryStream())
+ {
+ RuntimeTypeModel.Default.Serialize(ms, Foo.B);
+ ms.Position = 0;
+ result = (Foo) RuntimeTypeModel.Default.Deserialize(ms, null, typeof (Foo));
+ }
+ Assert.AreEqual(orig, result);
+ }
public enum Foo
{
View
38 Examples/Issues/Issue284.cs
@@ -0,0 +1,38 @@
+using System.IO;
+using NUnit.Framework;
+using ProtoBuf;
+using System;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class Issue284
+ {
+ [Test, ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Dynamic type is not a contract-type: Int32")]
+ public void Execute()
+ {
+ MyArgs test = new MyArgs
+ {
+ Value = 12,
+ };
+
+ byte[] buffer = new byte[256];
+ using (MemoryStream ms = new MemoryStream(buffer))
+ {
+ Serializer.Serialize(ms, test);
+ }
+
+ using (MemoryStream ms = new MemoryStream(buffer))
+ {
+ Serializer.Deserialize<MyArgs>(ms);
+ }
+ }
+
+ [ProtoContract]
+ public class MyArgs
+ {
+ [ProtoMember(1, DynamicType = true)]
+ public object Value;
+ }
+ }
+}
View
366 Examples/Issues/SO10115538.cs
@@ -0,0 +1,366 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using NUnit.Framework;
+using ProtoBuf;
+using ProtoBuf.Meta;
+using ProtoBuf.ServiceModel;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO10115538
+ {
+ public class MyService : IMyService
+ {
+ public string Test(Member member)
+ {
+ return "from svc: " + member.ToString();
+ }
+ }
+ [ServiceContract]
+ public interface IMyService
+ {
+ [OperationContract]
+ string Test(Member member);
+ }
+ ServiceHost host;
+
+ public IMyService GetService()
+ {
+ var endpoint =
+ new ServiceEndpoint(
+ ContractDescription.GetContract(typeof(IMyService)), new NetTcpBinding(SecurityMode.None),
+ new EndpointAddress("net.tcp://localhost:89/MyService/svc"));
+ endpoint.Behaviors.Add(new ProtoEndpointBehavior());
+ return new ChannelFactory<IMyService>(endpoint).CreateChannel();
+
+ //ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(new NetTcpBinding(SecurityMode.None), "net.tcp://localhost:89/MyService/svc");
+ //var client = factory.CreateChannel();
+ //return client;
+ }
+ [TestFixtureSetUp]
+ public void StartServer()
+ {
+ try
+ {
+ StopServer();
+ host = new ServiceHost(typeof(MyService),
+ new Uri("net.tcp://localhost:89/MyService"));
+ host.AddServiceEndpoint(typeof (IMyService), new NetTcpBinding(SecurityMode.None),
+ "net.tcp://localhost:89/MyService/svc").Behaviors.Add(
+ new ProtoEndpointBehavior());
+ host.Open();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.GetType().FullName);
+ Console.WriteLine(ex.Message);
+ throw;
+ }
+ }
+
+ [TestFixtureTearDown]
+ public void StopServer()
+ {
+ if (host != null)
+ {
+ host.Close();
+ host = null;
+ }
+ }
+
+
+ Member InventMember()
+ {
+ Member m = new Member();
+ m.FirstName = "Mike";
+ m.LastName = "Hanrahan";
+ m.UserId = new Guid("467c231f-f692-4432-ab1b-342c237b3ca9");
+ m.AccountStatus = MemberAccountStatus.Blocked;
+ m.EnteredBy = "qwertt";
+
+ return m;
+ }
+ [Test]
+ public void TestUsingMemoryStream()
+ {
+ Base.PrepareMetaDataForSerialization();
+ var m = InventMember();
+ Assert.AreEqual("Mike Hanrahan, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt", m.ToString());
+ using (var ms = new MemoryStream())
+ {
+ Serializer.Serialize<Member>(ms, m);
+ Console.WriteLine(ms.Length.ToString());
+ ms.Position = 0;
+ var member2 = Serializer.Deserialize<Member>(ms);
+ Assert.AreEqual("qwertt", member2.EnteredBy);
+ Assert.AreEqual("Mike", member2.FirstName);
+
+ Assert.AreEqual("Mike Hanrahan, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt",
+ member2.ToString());
+ }
+ }
+
+
+ [Test]
+ public void TestUsingWcf()
+ {
+ Base.PrepareMetaDataForSerialization();
+ var m = InventMember();
+ var client = GetService();
+ string s = client.Test(m);
+ Assert.AreEqual("from svc: Mike Hanrahan, 467c231f-f692-4432-ab1b-342c237b3ca9, Blocked, qwertt", s);
+ }
+
+ /// <summary>
+ /// This entity represents a member or user of the site.
+ /// </summary>
+ [DataContract]
+ [Serializable]
+ public class Member : User
+ {
+ public override string ToString()
+ {
+ return string.Format("{0} {1}, {2}, {3}, {4}", FirstName, LastName, UserId, AccountStatus, EnteredBy);
+ }
+ public Member()
+ : base()
+ {
+ EntityType = EntityType.Member;
+ }
+
+ [DataMember(Order = 20)]
+ public int Id { get; set; }
+
+ [DataMember(Order = 21)]
+ public string MemberName { get; set; }
+
+
+ [DataMember(Order = 23)]
+ public MemberAccountStatus AccountStatus { get; set; }
+
+ #region static
+
+ public static readonly string CacheCollectionKey = "MemberCollection";
+
+ private static readonly string CacheItemKeyPrefix = "Member:";
+
+ public static string GetCacheItemKey(int id)
+ {
+ return CacheItemKeyPrefix + id.ToString();
+ }
+
+ #endregion
+ }
+ /// <summary>
+ /// This class represents a user in the system. For example, a user could be a member or a merchant user.
+ /// </summary>
+ [DataContract]
+ [Serializable]
+ public class User: Base
+ {
+ public User()
+ :base()
+ {
+ EntityType = EntityType.User;
+ }
+
+ [DataMember(Order = 10)]
+ public Guid UserId { get; set; }
+
+ [DataMember(Order = 11, Name = "First Name")]
+ public string FirstName { get; set; }
+
+ [DataMember(Order = 12, Name = "Last Name")]
+ public string LastName { get; set; }
+
+ }
+ /// <summary>
+ /// This is the base class for all entities involved in the request/response pattern of our services
+ /// </summary>
+ /// <remarks>
+ /// The objects derived from this class are used to transfer data from our service classes to our UIs and back again and they should
+ /// not contain any logic.
+ /// </remarks>
+ [DataContract]
+ [Serializable]
+ public abstract class Base
+ {
+ public Base()
+ {
+ //Set some defaults for this
+ EnteredBy = System.Environment.UserName;
+ EnteredSource = System.Environment.MachineName;
+ }
+
+ /// <summary>
+ /// This is the record timestamp
+ /// </summary>
+ [DataMember(Order = 2)]
+ public DateTime RecordTimeStamp { get; set; }
+
+ /// <summary>
+ /// This is the name of the user who last edited the entity
+ /// </summary>
+ [DataMember(Order = 3)]
+ public string EnteredBy { get; set; }
+
+ /// <summary>
+ /// This is the source of the last edited entity
+ /// </summary>
+ [DataMember(Order = 4)]
+ public string EnteredSource { get; set; }
+
+ /// <summary>
+ /// Flag denoting if the record is a new record or not.
+ /// </summary>
+ /// <remarks>
+ /// To flag an entity as an existing record call the "FlagAsExistingReport()" method.
+ /// </remarks>
+ public bool IsNewRecord
+ {
+ get
+ {
+ return _isNewRecord;
+ }
+ }
+
+ [DataMember(Order = 6)]
+ protected bool _isNewRecord = true;
+ /// <summary>
+ /// Flags the entity as a record that already exists in the database
+ /// </summary>
+ /// <remarks>
+ /// This is a method rather than a field to demonstrait that this should be called with caution (as opposed to inadvertantly setting a flag!)
+ /// <para>
+ /// Note that this method should only need to be called on object creation if the entity has a composite key. Otherwise the flag is
+ /// set when the id is being set. It should always be called on saving an entity.
+ /// </para>
+ /// </remarks>
+ public void FlagAsExistingRecord()
+ {
+ _isNewRecord = false;
+ }
+
+
+ /// <summary>
+ /// This is the type of entity we are working with
+ /// </summary>
+ [DataMember(Order = 7)]
+ private EntityType _entityType = EntityType.Unknown;
+ public EntityType EntityType
+ {
+ get
+ {
+ return _entityType;
+ }
+ protected set
+ {
+ _entityType = value;
+ }
+ }
+
+
+ /// <summary>
+ /// Flag to say if the id generated for this class need to be int64 in size.
+ /// </summary>
+ [DataMember(Order = 9)]
+ public bool IdRequiresInt64 { get; protected set; }
+
+ /// <summary>
+ /// This method tells us if the database id has been assigned. Note that this does
+ /// not mean the entity has been saved, only if the id has been assigned (so the id could be greater than 0, but the
+ /// entity could still be a NewRecord
+ /// </summary>
+ /// <returns></returns>
+ [DataMember(Order = 8)]
+ public bool HasDbIdBeenAssigned { get; protected set; }
+
+ private Guid _validationId = Guid.NewGuid();
+ public Guid EntityValidationId
+ {
+ get
+ {
+ return _validationId;
+ }
+ }
+
+ /// <summary>
+ /// Returns all known child types
+ /// </summary>
+ public IEnumerable<Type> GetAllTypes()
+ {
+ Assembly current = Assembly.GetCallingAssembly();
+ List<Type> derivedTypes = new List<Type>();
+ var allTypes = current.GetTypes();
+ foreach (var t in allTypes)
+ {
+ if (t.IsAssignableFrom(typeof(Base)))
+ {
+ derivedTypes.Add(t);
+ }
+ }
+ return derivedTypes;
+ }
+
+ #region Static Methods
+
+
+ private static object _metaLock = new object();
+ private static bool _metaDataPrepared = false;
+ /// <summary>
+ /// Creates protobuf type models from the entities in this assembly
+ /// </summary>
+ public static void PrepareMetaDataForSerialization()
+ {
+ lock (_metaLock)
+ {
+ if (_metaDataPrepared) { return; }
+
+ Assembly current = Assembly.GetExecutingAssembly();
+ var allTypes = current.GetTypes();
+ foreach (var t in allTypes.Where(t => t.IsNested && t.DeclaringType == typeof(SO10115538)))
+ {
+ Console.WriteLine("Checking type: " + t.Name);
+ checkType(t);
+ }
+
+ _metaDataPrepared = true;
+ }
+ }
+
+ private static void checkType(Type type)
+ {
+ Assembly current = Assembly.GetExecutingAssembly();
+ var allTypes = current.GetTypes();
+ int key = 1000;
+ foreach (var t in allTypes)
+ {
+ if (t.IsSubclassOf(type) && t.BaseType == type)
+ {
+ Console.WriteLine("Adding sub-type " + t.Name + " with key " + key);
+ RuntimeTypeModel.Default[type].AddSubType(key, t);
+ key++;
+ }
+ }
+ }
+
+ #endregion
+ }
+ public enum EntityType
+ {
+ Unknown, Member, User
+ }
+ public enum MemberAccountStatus
+ {
+ Blocked
+ }
+ }
+
+}
View
49 Examples/Issues/SO9144967.cs
@@ -0,0 +1,49 @@
+using System.Linq;
+using System.Net;
+using NUnit.Framework;
+using ProtoBuf;
+using ProtoBuf.Meta;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9144967
+ {
+ [ProtoContract]
+ public class HasBlobs
+ {
+ [ProtoMember(1)]
+ public byte[] Foo { get; set; }
+ [ProtoMember(2, OverwriteList = true)]
+ public byte[] Bar{ get; set; }
+
+ public HasBlobs()
+ {
+ Foo = new byte[] { 1, 2, 3};
+ Bar = new byte[] { 4, 5, 6 };
+ }
+ }
+
+
+ [Test]
+ public void Execute()
+ {
+ var obj = new HasBlobs {Foo = new byte[] {7, 8}, Bar = new byte[] {8, 9}};
+
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+
+
+ var clone = (HasBlobs)model.DeepClone(obj);
+ Assert.IsTrue(clone.Foo.SequenceEqual(new byte[] { 1, 2, 3, 7, 8}), "Runtime Foo");
+ Assert.IsTrue(clone.Bar.SequenceEqual(new byte[] { 8, 9 }), "Runtime Bar");
+ model.CompileInPlace();
+ clone = (HasBlobs)model.DeepClone(obj);
+ Assert.IsTrue(clone.Foo.SequenceEqual(new byte[] { 1, 2, 3, 7, 8 }), "CompileInPlace Foo");
+ Assert.IsTrue(clone.Bar.SequenceEqual(new byte[] { 8, 9 }), "CompileInPlace Bar");
+ clone = (HasBlobs)model.Compile().DeepClone(obj);
+ Assert.IsTrue(clone.Foo.SequenceEqual(new byte[] { 1, 2, 3, 7, 8 }), "Compile Foo");
+ Assert.IsTrue(clone.Bar.SequenceEqual(new byte[] { 8, 9 }), "Compile Bar");
+ }
+}
+}
View
62 Examples/Issues/SO9151111.cs
@@ -0,0 +1,62 @@
+using System.Data.Entity.DynamicProxies;
+using NUnit.Framework;
+using ProtoBuf.Meta;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9151111
+ {
+
+ public class Command<TData> : BaseCommand where TData : ISomeInterface
+ {
+ public string Foo { get; set; }
+ }
+
+ public interface ISomeInterface
+ {
+ }
+
+ public class BaseCommand
+ {
+ }
+
+ public class SomeData : ISomeInterface
+ {
+ public string Bar { get; set; }
+ }
+ [Test]
+ public void TestManualConstuctionClosedType()
+ {
+ // In runtime this class is build (with specific TDATA) and Serialized. When I'm adding this type to runtime modal : (error)
+ var model = RuntimeTypeModel.Create();
+ model.Add(typeof (Command<SomeData>), false).Add(1, "Foo");
+ }
+ [Test]
+ public void TestManualConstuctionOpenType()
+ {
+ // don't actually expect this to work for serialization - I'm just doing this to try to repro the error
+ var model = RuntimeTypeModel.Create();
+ model.Add(typeof(Command<>), false).Add(1, "Foo");
+ }
+ [Test]
+ public void TestCanSerializeBehaviourWithSubTypeAndBaseType()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.Add(typeof (BaseCommand), false);
+ // base-type; is defined - should be able to serialize
+ Assert.IsTrue(model.CanSerializeContractType(typeof(BaseCommand)), "BaseCommand");
+ // derived type; not defined; should not recognise
+ Assert.IsFalse(model.CanSerializeContractType(typeof(Command<SomeData>)), "Command<SomeData>");
+ // proxy derived type; should work the same as BaseCommand
+ Assert.IsTrue(model.CanSerializeContractType(typeof(FakeProxyClassForBaseCommand)), "FakeProxyClassForBaseCommand");
+ }
+ }
+}
+namespace System.Data.Entity.DynamicProxies
+{
+ public class FakeProxyClassForBaseCommand : Examples.Issues.SO9151111.BaseCommand
+ {
+
+ }
+}
View
257 Examples/Issues/SO9151111b.cs
@@ -0,0 +1,257 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Examples.Issues;
+using NUnit.Framework;
+using Proto;
+using ProtoBuf.Meta;
+using Types;
+
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9151111_b
+ {
+ [Test]
+ public void Execute()
+ {
+ var p = new SeniorDeveloper<bool> {Id = 1, Name = "x", Boaring = true, VeryBoaring = true};
+ byte[] buf;
+ SeniorDeveloper<bool> p2;
+
+ var t = TimeSpan.Parse("01:10:00");
+
+ var s = new ProtoBufModalSerializer(); // new ProtoBufModalSerializer();// new ProtoBufSerializer();
+
+ using (var f = new FileStream("protoTest.txt", FileMode.OpenOrCreate))
+ {
+ buf = s.Serialize(p);
+
+ f.Write(buf, 0, buf.Length);
+ f.Flush();
+ }
+
+ Console.WriteLine("Serialized... Buf length={0}", buf.Length.ToString());
+
+ Console.WriteLine("Deserializing...");
+
+ using (var f = new FileStream("protoTest.txt", FileMode.OpenOrCreate))
+ {
+ f.Read(buf, 0, buf.Length);
+
+ p2 = (SeniorDeveloper<bool>) s.Deserialize(buf, typeof (SeniorDeveloper<bool>));
+
+ //p2 = (Person)s.Deserialize(buf, typeof(Person));
+ }
+
+ Console.WriteLine(p2.ToString());
+ }
+ }
+}
+
+namespace Proto
+{
+ public class ProtoBufModalSerializer
+ {
+ protected RuntimeTypeModel _modal;
+
+ public ProtoBufModalSerializer()
+ {
+ this._modal = RuntimeTypeModel.Create();
+ //this._modal.AutoAddMissingTypes = true;
+ this.init();
+ }
+
+ private void init()
+ {
+ Dictionary<Type, List<Type>> repo = new Dictionary<Type, List<Type>>();
+
+ foreach (var type in this.GetDCTypes("Types"))
+ {
+ //if (type.IsGenericTypeDefinition == false)
+ //{
+ var meta = this._modal.Add(type, false)
+ .Add(this.GetDMProperties(type).Select(p => p.Name)
+ .ToArray());
+
+ this.setCallbacks(meta);
+
+ if (type.BaseType != null && type.BaseType != typeof(Object))
+ {
+ List<Type> childs;
+
+ if (!repo.TryGetValue(type.BaseType, out childs))
+ {
+ childs = new List<Type>();
+ repo.Add(type.BaseType, childs);
+ }
+
+ childs.Add(type);
+ }
+
+
+ foreach (var parent in repo.Keys)
+ {
+ if (this._modal.IsDefined(parent))
+ {
+ int i = 500;
+
+ foreach (var child in repo[parent].OrderBy(t => t.Name))
+ {
+ this._modal[parent].AddSubType(i++, child);
+ }
+ }
+ }
+ //}
+ }
+
+ this._modal.CompileInPlace();
+ }
+
+
+
+ public virtual object Deserialize(byte[] serializedObj, Type objectType)
+ {
+ using (var memStream = new MemoryStream(serializedObj))
+ {
+ //return Serializer.NonGeneric.Deserialize(objectType, memStream);
+ return this._modal.Deserialize(memStream, null, objectType);
+ }
+ }
+
+ public virtual byte[] Serialize(object obj)
+ {
+ return this.Serialize(obj.GetType(), obj);
+ }
+
+ public virtual byte[] Serialize(Type objectType, object obj)
+ {
+ using (var memStream = new MemoryStream())
+ {
+ //Serializer.NonGeneric.Serialize(memStream, obj);
+ this._modal.Serialize(memStream, obj);
+
+ return memStream.ToArray();
+ }
+ }
+
+ public virtual TType Deserialize<TType>(byte[] serializedObj)
+ {
+ using (var memStream = new MemoryStream(serializedObj))
+ {
+ //return Serializer.Deserialize<TType>(memStream);
+ return (TType)this._modal.Deserialize(memStream, null, typeof(TType));
+
+ }
+ }
+
+
+ private IEnumerable<Type> GetDCTypes(string assemblyName)
+ {
+ foreach (var type in typeof(SO9151111_b).Assembly.GetTypes().Where(t => t.Namespace=="Types"))
+ {
+ if (type.IsDefined(typeof(DataContractAttribute), false))
+ yield return type;
+ }
+ }
+
+ private IEnumerable<PropertyInfo> GetDMProperties(Type dcType)
+ {
+ foreach (var prop in dcType.GetProperties())
+ {
+ if (prop.IsDefined(typeof(DataMemberAttribute), false))
+ yield return prop;
+ }
+ }
+
+ private void setCallbacks(MetaType meta)
+ {
+ MethodInfo beforeDeserialized = null;
+ MethodInfo afterDeserialized = null;
+ MethodInfo beforeSerialized = null;
+ MethodInfo afterSerialized = null;
+
+ foreach (var method in meta.Type.GetMethods())
+ {
+ beforeDeserialized = method.IsDefined(typeof(OnDeserializingAttribute), false) ? method : beforeDeserialized;
+ afterDeserialized = method.IsDefined(typeof(OnDeserializedAttribute), false) ? method : afterDeserialized;
+ beforeSerialized = method.IsDefined(typeof(OnSerializingAttribute), false) ? method : beforeSerialized;
+ afterSerialized = method.IsDefined(typeof(OnSerializedAttribute), false) ? method : afterSerialized;
+ }
+
+ meta.SetCallbacks(beforeSerialized, afterSerialized, beforeDeserialized, afterDeserialized);
+ }
+ }
+}
+
+namespace Types
+{
+ //[ProtoContract]
+ [DataContract]
+ //[ProtoInclude(500, typeof(Developer))]
+ public class Person
+ {
+ //[ProtoMember(1)]
+ [DataMember]
+ public int Id { get; set; }
+ //[ProtoMember(2)]
+ [DataMember]
+ public string Name { get; set; }
+
+ public override string ToString()
+ {
+ return "Id=" + Id.ToString() + " Name=" + Name;
+ }
+
+ [OnDeserialized]
+ public void OnDesr(StreamingContext c)
+ {
+ Console.WriteLine("OnDeserialized");
+ }
+ }
+
+ [DataContract]
+ //[ProtoContract]
+ public class Developer : Person
+ {
+ [DataMember]
+ //[ProtoMember(1)]
+ public bool Boaring { get; set; }
+
+ public bool XBoaring { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() + " Boaring=" + Boaring.ToString() + " XBoaring=" + XBoaring.ToString();
+ }
+ }
+
+ [DataContract]
+ public class SeniorDeveloper<T> : Developer
+ {
+ [DataMember]
+ //[ProtoMember(1)]
+ public T VeryBoaring { get; set; }
+
+ public override string ToString()
+ {
+ return base.ToString() + " VeryBoaring=" + VeryBoaring.ToString();
+ }
+
+ [OnDeserialized]
+ public void OnDesrd(StreamingContext c)
+ {
+ Console.WriteLine("OnDeserialized");
+ }
+
+ [OnSerializing]
+ public void X(StreamingContext c)
+ {
+ Console.WriteLine("OnSerializing");
+ }
+ }
+}
View
57 Examples/Issues/SO9398578.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using ProtoBuf;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9398578
+ {
+ [Test, ExpectedException(typeof(ProtoException))]
+ public void TestRandomDataWithString()
+ {
+ var input = File.ReadAllBytes("protobuf-net.dll");
+ var stream = new MemoryStream(input);
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.Greater(3, 0); // I always double-check the param order
+ Assert.Greater(stream.Length, 0);
+ Serializer.Deserialize<string>(stream);
+ }
+ [Test, ExpectedException(typeof(ProtoException))]
+ public void TestRandomDataWithContractType()
+ {
+ var input = File.ReadAllBytes("protobuf-net.dll");
+ var stream = new MemoryStream(input);
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.Greater(3, 0); // I always double-check the param order
+ Assert.Greater(stream.Length, 0);
+ Serializer.Deserialize<Foo>(stream);
+ }
+ [Test, ExpectedException(typeof(ProtoException))]
+ public void TestRandomDataWithReader()
+ {
+ var input = File.ReadAllBytes("protobuf-net.dll");
+ var stream = new MemoryStream(input);
+ stream.Seek(0, SeekOrigin.Begin);
+ Assert.Greater(3, 0); // I always double-check the param order
+ Assert.Greater(stream.Length, 0);
+
+ using (var reader = new ProtoReader(stream, null, null))
+ {
+ while (reader.ReadFieldHeader() > 0)
+ {
+ reader.SkipField();
+ }
+ }
+ }
+
+ [ProtoContract]
+ public class Foo
+ {
+ }
+ }
+}
View
110 Examples/Issues/SO9408133.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using ProtoBuf;
+using ProtoBuf.Meta;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9408133
+ {
+ [ProtoContract] public class Ship
+ {
+ [ProtoMember(1)]
+ public int Foo { get; set; }
+ }
+ [ProtoContract] public class SomeType
+ {
+ [ProtoMember(1)]
+ public string Bar { get; set; }
+ }
+
+ [ProtoContract]
+ [ProtoInclude(1, typeof(SomeNodeType)), ProtoInclude(2, typeof(SomeOtherType))]
+ [ProtoInclude(3, typeof(ResourceNode<Ship>)), ProtoInclude(4, typeof(ResourceNode<SomeType>))]
+ public class Node { }
+ [ProtoContract] public class SomeNodeType : Node { }
+ [ProtoContract] public class SomeOtherType : Node { }
+
+ [ProtoContract]
+ [ProtoInclude(1, typeof(ShipResource)), ProtoInclude(1, typeof(SomeResource))]
+ public class ResourceNode<T> : Node { }
+ [ProtoContract] public class ShipResource : ResourceNode<Ship>
+ {
+ [ProtoMember(1)]
+ public Ship Value { get; set; }
+ }
+ [ProtoContract] public class SomeResource : ResourceNode<SomeType>
+ {
+ [ProtoMember(1)]
+ public SomeType Value { get; set; }
+ }
+
+ [Test]
+ public void TestImplicitSetup()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+
+ var obj1 = new ShipResource { Value = new Ship { Foo = 123 } };
+ var obj2 = new SomeResource { Value = new SomeType { Bar = "abc" } };
+
+ Test(model, obj1, obj2, "Runtime");
+
+ model.Compile("SO9408133_TestImplicitSetup", "SO9408133_TestImplicitSetup.dll");
+ PEVerify.AssertValid("SO9408133_TestImplicitSetup.dll");
+
+ model.CompileInPlace();
+ Test(model, obj1, obj2, "CompileInPlace");
+ Test(model.Compile(), obj1, obj2, "Compile");
+ }
+ [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "SomeType is not a valid sub-type of", MatchType = MessageMatch.Contains)]
+ public void TestStupidSetup()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+ model.Add(typeof(ResourceNode<Ship>), false).AddSubType(1, typeof(ShipResource));
+ // I did this to myself... sigh
+ model.Add(typeof(ResourceNode<SomeType>), false).AddSubType(1, typeof(SomeType));
+ }
+ [Test]
+ public void TestExplicitSetup()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+ model.Add(typeof (ResourceNode<Ship>), false).AddSubType(1, typeof (ShipResource));
+ model.Add(typeof (ResourceNode<SomeType>), false).AddSubType(1, typeof (SomeResource));
+
+ var obj1 = new ShipResource { Value = new Ship { Foo = 123} };
+ var obj2 = new SomeResource { Value = new SomeType { Bar = "abc" } };
+
+ Test(model, obj1, obj2, "Runtime");
+
+ model.Compile("SO9408133_TestExplicitSetup", "SO9408133_TestExplicitSetup.dll");
+ PEVerify.AssertValid("SO9408133_TestExplicitSetup.dll");
+
+ model.CompileInPlace();
+ Test(model, obj1, obj2, "CompileInPlace");
+ Test(model.Compile(), obj1, obj2, "Compile");
+ }
+
+ private void Test(TypeModel model, ShipResource obj1, SomeResource obj2, string caption)
+ {
+ try
+ {
+ var clone1 = (ShipResource) model.DeepClone(obj1);
+ var clone2 = (SomeResource) model.DeepClone(obj2);
+
+ Assert.AreEqual(obj1.Value.Foo, clone1.Value.Foo, caption + ":Foo");
+ Assert.AreEqual(obj2.Value.Bar, clone2.Value.Bar, caption + ":Bar");
+ } catch(Exception ex)
+ {
+ throw new Exception(caption + ":" + ex.Message, ex);
+ }
+ }
+
+ }
+}
View
89 Examples/Issues/SO9491933.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using NUnit.Framework;
+using ProtoBuf;
+
+namespace Examples.Issues
+{
+ [TestFixture]
+ public class SO9491933
+ {
+ [ProtoContract]
+ [ProtoInclude(6, typeof(B))]
+ public class A
+ {
+ [ProtoMember(1)]
+ public int Property1 { get; set; }
+
+ [ProtoMember(2)]
+ public int? Property2 { get; set; }
+
+ [ProtoMember(3)]
+ public int Property3 { get; set; }
+
+ [ProtoMember(4, DynamicType = true)]
+ public object Property4 { get; set; }
+
+ [ProtoMember(5, DynamicType = true)]
+ public object Property5 { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ A a = obj as A;
+ if (a == null)
+ return false;
+
+ return a.Property1 == this.Property1
+ && a.Property2 == this.Property2
+ && a.Property3 == this.Property3
+ && Object.Equals(a.Property4, this.Property4)
+ && Object.Equals(a.Property5, this.Property5);
+ }
+ }
+
+ public class B : A
+ {
+ [ProtoMember(1)]
+ public string Property6 { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ B b = obj as B;
+ if (b == null)
+ return false;
+
+ return b.Property6 == this.Property6 && base.Equals(obj);
+ }
+ }
+
+ [Test]
+ public void TestProtoBuf2()
+ {
+ IList<A> list = new List<A>
+ {
+ new A {Property1 = 1, Property2 = 1, Property3 = 200, Property4 = "Test1", Property5 = DateTime.Now},
+ new B {Property1 = 2, Property2 = 2, Property3 = 400, Property4 = "Test2", Property5 = DateTime.Now, Property6 = "yyyy"},
+ new A {Property1 = 3, Property2 = 3, Property3 = 600, Property4 = "Test3", Property5 = new Decimal(200)},
+ };
+ using (var file = new FileStream("list.bin", FileMode.Create))
+ {
+ Serializer.Serialize(file, list);
+ }
+
+ IList<A> list2;
+ using (var file = File.OpenRead("list.bin"))
+ {
+ list2 = Serializer.Deserialize<IList<A>>(file);
+ }
+
+ Assert.AreEqual(list.Count, list2.Count);
+
+ for (int i = 0; i < list.Count; i++)
+ {
+ Assert.AreEqual(list[i], list2[i]);
+ }
+ }
+
+ }
+}
View
90 Examples/Type.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Data.SqlClient;
+using System.Text;
+using NUnit.Framework;
+using ProtoBuf;
+using ProtoBuf.Meta;
+
+namespace Examples
+{
+ [TestFixture]
+ public class TypeTests
+ {
+ [ProtoContract]
+ public class MyModel
+ {
+ [ProtoMember(1)]
+ public Type Type { get; set; }
+ }
+
+ [Test]
+ public void ShouldRoundtripTypeWithoutEvent()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+ var orig = new MyModel {Type = typeof (SqlCommand)};
+
+ var clone = (MyModel) model.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+
+ string s = typeof (SqlCommand).AssemblyQualifiedName;
+ byte[] expected = new byte[Encoding.UTF8.GetByteCount(s) + 2];
+ Encoding.UTF8.GetBytes(s, 0, s.Length, expected, 2);
+ expected[0] = 0x0A; // field-header
+ expected[1] = 0x70; // length
+ Program.CheckBytes(orig, model, expected);
+
+ model.CompileInPlace();
+ clone = (MyModel)model.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+ Program.CheckBytes(orig, model, expected);
+
+ var compiled = model.Compile();
+ clone = (MyModel)compiled.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+ Program.CheckBytes(orig, compiled, expected);
+ }
+
+ [Test]
+ public void ShouldRoundtripTypeWithEvent()
+ {
+ var model = RuntimeTypeModel.Create();
+ model.AutoCompile = false;
+ model.DynamicTypeFormatting += new TypeFormatEventHandler(model_DynamicTypeFormatting);
+ var orig = new MyModel { Type = typeof(SqlCommand) };
+
+ var clone = (MyModel)model.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+
+ string s = "abc";
+ byte[] expected = new byte[Encoding.UTF8.GetByteCount(s) + 2];
+ Encoding.UTF8.GetBytes(s, 0, s.Length, expected, 2);
+ expected[0] = 0x0A; // field-header
+ expected[1] = 0x03; // length
+ Program.CheckBytes(orig, model, expected);
+
+ model.CompileInPlace();
+ clone = (MyModel)model.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+ Program.CheckBytes(orig, model, expected);
+
+ var compiled = model.Compile();
+ compiled.DynamicTypeFormatting += new TypeFormatEventHandler(model_DynamicTypeFormatting);
+ clone = (MyModel)compiled.DeepClone(orig);
+ Assert.AreSame(typeof(SqlCommand), clone.Type);
+ Program.CheckBytes(orig, compiled, expected);
+
+ }
+
+ void model_DynamicTypeFormatting(object sender, TypeFormatEventArgs args)
+ {
+ if(args.Type == typeof(SqlCommand))
+ {
+ args.FormattedName = "abc";
+ } else if (args.FormattedName == "abc")
+ {
+ args.Type = typeof (SqlCommand);
+ }
+ }
+ }
+}
View
14 build_gmcs.bat
@@ -1,11 +1,11 @@
-cls
-@del protobuf-net.dll
-@del gmcs-test.exe
+@rem cls
+@rem @del protobuf-net.dll
+@rem del gmcs-test.exe
-gmcs -recurse:protobuf-net\*.cs -out:protobuf-net.dll -target:library -unsafe+ -define:FEAT_COMPILER -doc:protobuf-net.xml
+@gmcs -recurse:protobuf-net\*.cs -out:protobuf-net.dll -target:library -unsafe+ -define:FEAT_COMPILER -define:PLAT_BINARYFORMATTER -doc:protobuf-net.xml -define:FEAT_SERVICEMODEL -define:PLAT_XMLSERIALIZER -r:System.Runtime.Serialization.dll -r:System.ServiceModel.dll /keyfile:ProtoBuf.snk
-gmcs -recurse:protobuf-net\*.cs -out:protobuf-net-gmcs.dll -target:library -unsafe+ -define:FEAT_COMPILER
+@rem gmcs -recurse:protobuf-net\*.cs -out:protobuf-net-gmcs.dll -target:library -unsafe+ -define:FEAT_COMPILER
-gmcs -recurse:FX11\*.cs -target:exe -out:gmcs-test.exe -define:FEAT_COMPILER -r:protobuf-net-gmcs
+@rem gmcs -recurse:FX11\*.cs -target:exe -out:gmcs-test.exe -define:FEAT_COMPILER -r:protobuf-net-gmcs
-mono gmcs-test.exe
+@rem mono gmcs-test.exe
View
14 protobuf-net/BclHelpers.cs
@@ -401,6 +401,7 @@ public static object ReadNetObject(object value, ProtoReader source, int key, Ty
throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)");
}
key = source.GetTypeKey(ref type);
+ if(key < 0) throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
break;
case FieldObject:
bool isString = type == typeof(string);
@@ -437,16 +438,24 @@ public static object ReadNetObject(object value, ProtoReader source, int key, Ty
source.NetCache.SetKeyedObject(newObjectKey, value);
if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type);
}
- if (!lateSet && !ReferenceEquals(oldValue, value))
+ if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value))
{
throw new ProtoException("A reference-tracked object changed reference during deserialization");
- }
+ }
+ if (newObjectKey < 0 && newTypeKey >= 0)
+ { // have a new type, but not a new object
+ source.NetCache.SetKeyedObject(newTypeKey, type);
+ }
break;
default:
source.SkipField();
break;
}
}
+ if(newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0)
+ {
+ throw new ProtoException("Object key in input stream, but reference-tracking was not expected");
+ }
ProtoReader.EndSubItem(token, source);
return value;
@@ -481,6 +490,7 @@ public static void WriteNetObject(object value, ProtoWriter dest, int key, NetOb
bool existing;
Type type = value.GetType();
key = dest.GetTypeKey(ref type);
+ if (key < 0) throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name);
int typeKey = dest.NetCache.AddObjectKey(type, out existing);
ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest);
ProtoWriter.WriteInt32(typeKey, dest);
View
8 protobuf-net/Helpers.cs
@@ -191,14 +191,14 @@ public static bool IsInfinity(double value)
typeof(long), typeof(ulong), typeof(float), typeof(double),
typeof(decimal), typeof(string),
typeof(DateTime), typeof(TimeSpan), typeof(Guid), typeof(Uri),
- typeof(byte[])};
+ typeof(byte[]), typeof(Type)};
private static readonly ProtoTypeCode[] knownCodes = new ProtoTypeCode[] {
ProtoTypeCode.Boolean, ProtoTypeCode.Char, ProtoTypeCode.SByte, ProtoTypeCode.Byte,
ProtoTypeCode.Int16, ProtoTypeCode.UInt16, ProtoTypeCode.Int32, ProtoTypeCode.UInt32,
ProtoTypeCode.Int64, ProtoTypeCode.UInt64, ProtoTypeCode.Single, ProtoTypeCode.Double,
ProtoTypeCode.Decimal, ProtoTypeCode.String,
ProtoTypeCode.DateTime, ProtoTypeCode.TimeSpan, ProtoTypeCode.Guid, ProtoTypeCode.Uri,
- ProtoTypeCode.ByteArray
+ ProtoTypeCode.ByteArray, ProtoTypeCode.Type
};
#endif
@@ -235,6 +235,7 @@ public static ProtoTypeCode GetTypeCode(Type type)
if (type == typeof(Guid)) return ProtoTypeCode.Guid;
if (type == typeof(Uri)) return ProtoTypeCode.Uri;
if (type == typeof(byte[])) return ProtoTypeCode.ByteArray;
+ if (type == typeof(Type)) return ProtoTypeCode.Type;
return ProtoTypeCode.Unknown;
#endif
@@ -345,6 +346,7 @@ internal enum ProtoTypeCode
TimeSpan = 100,
ByteArray = 101,
Guid = 102,
- Uri = 103
+ Uri = 103,
+ Type = 104
}
}
View
15 protobuf-net/Meta/MetaType.cs
@@ -50,6 +50,10 @@ public bool AsReferenceDefault
}
private BasicList subTypes;
+ private bool IsValidSubType(Type subType)
+ {
+ return type.IsAssignableFrom(subType);
+ }
/// <summary>
/// Adds a known sub-type to the inheritance model
/// </summary>
@@ -64,7 +68,10 @@ public MetaType AddSubType(int fieldNumber, Type derivedType)
#endif
throw new InvalidOperationException("Sub-types can only be added to non-sealed classes");
}
-
+ if (!IsValidSubType(derivedType))
+ {
+ throw new ArgumentException(derivedType.Name + " is not a valid sub-type of " + type.Name, "derivedType");
+ }
MetaType derivedMeta = model[derivedType];
ThrowIfFrozen();
derivedMeta.ThrowIfFrozen();
@@ -224,7 +231,7 @@ internal MetaType(RuntimeTypeModel model, Type type)
if (model == null) throw new ArgumentNullException("model");
if (type == null) throw new ArgumentNullException("type");
WireType defaultWireType;
- IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(null, DataFormat.Default, type, out defaultWireType, false, false);
+ IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(null, DataFormat.Default, type, out defaultWireType, false, false, false);
if (coreSerializer != null)
{
throw new ArgumentException("Data of this type has inbuilt behaviour, and cannot be added to a model in this way: " + type.FullName);
@@ -424,8 +431,8 @@ internal void ApplyDefaultBehaviour()
if (knownType == null)
{
throw new InvalidOperationException("Unable to resolve sub-type: " + pia.KnownTypeName);
- }
- AddSubType(pia.Tag, knownType);
+ }
+ if(IsValidSubType(knownType)) AddSubType(pia.Tag, knownType);
}
if(item is ProtoPartialIgnoreAttribute)
{
View
3 protobuf-net/Meta/RuntimeTypeModel.cs
@@ -413,7 +413,8 @@ protected internal override object Deserialize(int key, object value, ProtoReade
//Helpers.DebugWriteLine("Deserialize", value);
IProtoSerializer ser = ((MetaType)types[key]).Serializer;
if (value == null && Helpers.IsValueType(ser.ExpectedType)) {
- return ser.Read(Activator.CreateInstance(ser.ExpectedType), source);
+ if(ser.RequiresOldValue) value = Activator.CreateInstance(ser.ExpectedType);
+ return ser.Read(value, source);
} else {
return ser.Read(value, source);
}
View
17 protobuf-net/Meta/TypeModel.cs
@@ -953,6 +953,7 @@ public static RuntimeTypeModel Create()
protected internal static Type ResolveProxies(Type type)
{
if (type == null) return null;
+ if (type.IsGenericParameter) return null;
#if !NO_GENERICS
// Nullable<T>
Type tmp = Nullable.GetUnderlyingType(type);
@@ -1139,25 +1140,25 @@ public static void ThrowCannotCreateInstance(Type type)
throw new ProtoException("No parameterless constructor found for " + type.Name);
}
- internal string SerializeType(Type type)
+ internal static string SerializeType(TypeModel model, Type type)
{
- TypeFormatEventHandler handler = DynamicTypeFormatting;
- if (handler != null)
+ TypeFormatEventHandler handler;
+ if (model != null && (handler = model.DynamicTypeFormatting) != null)
{
TypeFormatEventArgs args = new TypeFormatEventArgs(type);
- handler(this, args);
+ handler(model, args);
if (!Helpers.IsNullOrEmpty(args.FormattedName)) return args.FormattedName;
}
return type.AssemblyQualifiedName;
}
- internal Type DeserializeType(string value)
+ internal static Type DeserializeType(TypeModel model, string value)
{
- TypeFormatEventHandler handler = DynamicTypeFormatting;
- if (handler != null)
+ TypeFormatEventHandler handler;
+ if (model != null && (handler = model.DynamicTypeFormatting) != null)
{
TypeFormatEventArgs args = new TypeFormatEventArgs(value);
- handler(this, args);
+ handler(model, args);
if (args.Type != null) return args.Type;
}
return Type.GetType(value);
View
9 protobuf-net/Meta/ValueMember.cs
@@ -258,7 +258,7 @@ private IProtoSerializer BuildSerializer()
model.TakeLock(ref opaqueToken);// check nobody is still adding this type
WireType wireType;
Type finalType = itemType == null ? memberType : itemType;
- IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType);
+ IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList);
if (ser == null) throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
// apply tags
if (itemType != null && SupportNull)
@@ -345,7 +345,7 @@ private static WireType GetDateTimeWireType(DataFormat format)
}
}
- internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType)
+ internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList)
{
#if !NO_GENERICS
type = Nullable.GetUnderlyingType(type) ?? type;
@@ -427,7 +427,10 @@ internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, Da
return new StringSerializer(); // treat as string; wrapped in decorator later
case ProtoTypeCode.ByteArray:
defaultWireType = WireType.String;
- return new BlobSerializer();
+ return new BlobSerializer(overwriteList);
+ case ProtoTypeCode.Type:
+ defaultWireType = WireType.String;
+ return new SystemTypeSerializer();
}
IProtoSerializer parseable = ParseableSerializer.TryCreate(type);
if (parseable != null)
View
2 protobuf-net/Properties/AssemblyInfo.cs
@@ -3,8 +3,6 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
-#warning IMPORTANT: this is the **BETA** v2 release. For the stable version, see /branches/v1
-
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
View
10 protobuf-net/ProtoReader.cs
@@ -620,6 +620,7 @@ public int ReadFieldHeader()
{
wireType = (WireType)(tag & 7);
fieldNumber = (int)(tag >> 3);
+ if(fieldNumber < 1) throw new ProtoException("Invalid field in source data: " + fieldNumber);
}
else
{
@@ -1215,7 +1216,7 @@ internal NetObjectCache NetCache
internal Type DeserializeType(string value)
{
- return model.DeserializeType(value);
+ return TypeModel.DeserializeType(model, value);
}
internal void SetRootObject(object value)
@@ -1236,5 +1237,12 @@ public static void NoteObject(object value, ProtoReader reader)
}
}
+ /// <summary>
+ /// Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String
+ /// </summary>
+ public Type ReadType()
+ {
+ return TypeModel.DeserializeType(model, ReadString());
+ }
}
}
View
9 protobuf-net/ProtoWriter.cs
@@ -878,7 +878,7 @@ public static void SetPackedField(int fieldNumber, ProtoWriter writer)
internal string SerializeType(Type type)
{
- return model.SerializeType(type);
+ return TypeModel.SerializeType(model, type);
}
/// <summary>
/// Specifies a known root object to use during reference-tracked serialization
@@ -888,5 +888,12 @@ public void SetRootObject(object value)
NetCache.SetKeyedObject(NetObjectCache.Root, value);
}
+ /// <summary>
+ /// Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String
+ /// </summary>
+ public static void WriteType(Type value, ProtoWriter writer)
+ {
+ WriteString(writer.SerializeType(value), writer);
+ }
}
}
View
2 protobuf-net/Serializer.cs
@@ -224,7 +224,7 @@ public static void Serialize<T>(Stream destination, T instance)
/// <summary>
/// Precompiles the serializer for a given type.
/// </summary>
- public static void PrepareSerializer<T>() where T : class
+ public static void PrepareSerializer<T>()
{
#if FEAT_COMPILER
RuntimeTypeModel.Default[typeof(T)].CompileInPlace();
View
18 protobuf-net/Serializers/BlobSerializer.cs
@@ -15,11 +15,16 @@ public void Write(object value, ProtoWriter dest)
{
ProtoWriter.WriteBytes((byte[])value, dest);
}
+ public BlobSerializer(bool overwriteList)
+ {
+ this.overwriteList = overwriteList;
+ }
+ private readonly bool overwriteList;
public object Read(object value, ProtoReader source)
{
- return ProtoReader.AppendBytes((byte[])value, source);
+ return ProtoReader.AppendBytes(overwriteList ? null : (byte[])value, source);
}
- bool IProtoSerializer.RequiresOldValue { get { return true; } }
+ bool IProtoSerializer.RequiresOldValue { get { return !overwriteList; } }
bool IProtoSerializer.ReturnsValue { get { return true; } }
#if FEAT_COMPILER
void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
@@ -28,7 +33,14 @@ void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local val
}
void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
{
- ctx.LoadValue(valueFrom);
+ if (overwriteList)
+ {
+ ctx.LoadNullRef();
+ }
+ else
+ {
+ ctx.LoadValue(valueFrom);
+ }
ctx.LoadReaderWriter();
ctx.EmitCall(typeof(ProtoReader).GetMethod("AppendBytes"));
}
View
1 protobuf-net/Serializers/SubItemSerializer.cs
@@ -62,6 +62,7 @@ bool EmitDedicatedMethod(Compiler.CompilerContext ctx, Compiler.Local valueFrom,
{
System.Reflection.Emit.MethodBuilder method = ctx.GetDedicatedMethod(key, read);
if (method == null) return false;
+
using (Compiler.Local token = new ProtoBuf.Compiler.Local(ctx, typeof(SubItemToken)))
{
Type rwType = read ? typeof(ProtoReader) : typeof(ProtoWriter);
View
38 protobuf-net/Serializers/SystemTypeSerializer.cs
@@ -0,0 +1,38 @@
+using System;
+
+#if !NO_RUNTIME
+
+namespace ProtoBuf.Serializers
+{
+ class SystemTypeSerializer : IProtoSerializer
+ {
+ public Type ExpectedType { get { return typeof(Type); } }
+
+ void IProtoSerializer.Write(object value, ProtoWriter dest)
+ {
+ ProtoWriter.WriteType((Type)value, dest);
+ }
+
+ object IProtoSerializer.Read(object value, ProtoReader source)
+ {
+ Helpers.DebugAssert(value == null); // since replaces
+ return source.ReadType();
+ }
+
+ bool IProtoSerializer.RequiresOldValue { get { return false; } }
+ bool IProtoSerializer.ReturnsValue { get { return true; } }
+
+#if FEAT_COMPILER
+ void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
+ {
+ ctx.EmitBasicWrite("WriteType", valueFrom);
+ }
+ void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
+ {
+ ctx.EmitBasicRead("ReadType", ExpectedType);
+ }
+#endif
+ }
+}
+
+#endif
View
2 protobuf-net/Serializers/TupleSerializer.cs
@@ -27,7 +27,7 @@ public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[
MetaType.ResolveListTypes(finalType, ref itemType, ref defaultType);
Type tmp = itemType == null ? finalType : itemType;
- IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, false, false), serializer;
+ IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, false, false, false), serializer;
if (tail == null) throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName);
tail = new TagDecorator(i + 1, wireType, false, tail);
View
3 protobuf-net/Serializers/TypeSerializer.cs
@@ -430,8 +430,7 @@ void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Lo
for (int i = 0; i < serializers.Length; i++)
{
IProtoSerializer ser = serializers[i];
- IProtoTypeSerializer typeser;
- if (ser.ExpectedType != forType && (typeser = (IProtoTypeSerializer)ser).HasCallbacks(callbackType))
+ if (ser.ExpectedType != forType && ((IProtoTypeSerializer)ser).HasCallbacks(callbackType))
{
actuallyHasInheritance = true;
}
View
1 protobuf-net/protobuf-net.csproj
@@ -213,6 +213,7 @@
<Compile Include="Serializers\NetObjectSerializer.cs" />
<Compile Include="Serializers\SByteSerializer.cs" />
<Compile Include="Serializers\MemberSpecifiedDecorator.cs" />
+ <Compile Include="Serializers\SystemTypeSerializer.cs" />
<Compile Include="Serializers\TupleSerializer.cs" />
<Compile Include="Serializers\UriDecorator.cs" />
<Compile Include="Serializers\EnumSerializer.cs" />

No commit comments for this range

Something went wrong with that request. Please try again.