initial commit
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
|
||||
namespace ProtoBuf.ServiceModel;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public sealed class ProtoBehaviorAttribute : Attribute, IOperationBehavior
|
||||
{
|
||||
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
|
||||
{
|
||||
}
|
||||
|
||||
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
|
||||
{
|
||||
IOperationBehavior val = (IOperationBehavior)(object)new ProtoOperationBehavior(operationDescription);
|
||||
val.ApplyClientBehavior(operationDescription, clientOperation);
|
||||
}
|
||||
|
||||
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
|
||||
{
|
||||
IOperationBehavior val = (IOperationBehavior)(object)new ProtoOperationBehavior(operationDescription);
|
||||
val.ApplyDispatchBehavior(operationDescription, dispatchOperation);
|
||||
}
|
||||
|
||||
void IOperationBehavior.Validate(OperationDescription operationDescription)
|
||||
{
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.ServiceModel.Configuration;
|
||||
|
||||
namespace ProtoBuf.ServiceModel;
|
||||
|
||||
public class ProtoBehaviorExtension : BehaviorExtensionElement
|
||||
{
|
||||
public override Type BehaviorType => typeof(ProtoEndpointBehavior);
|
||||
|
||||
protected override object CreateBehavior()
|
||||
{
|
||||
return new ProtoEndpointBehavior();
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ServiceModel.Channels;
|
||||
using System.ServiceModel.Description;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
|
||||
namespace ProtoBuf.ServiceModel;
|
||||
|
||||
public class ProtoEndpointBehavior : IEndpointBehavior
|
||||
{
|
||||
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
|
||||
{
|
||||
}
|
||||
|
||||
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
|
||||
{
|
||||
ReplaceDataContractSerializerOperationBehavior(endpoint);
|
||||
}
|
||||
|
||||
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
|
||||
{
|
||||
ReplaceDataContractSerializerOperationBehavior(endpoint);
|
||||
}
|
||||
|
||||
void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
private static void ReplaceDataContractSerializerOperationBehavior(ServiceEndpoint serviceEndpoint)
|
||||
{
|
||||
foreach (OperationDescription item in (Collection<OperationDescription>)(object)serviceEndpoint.Contract.Operations)
|
||||
{
|
||||
ReplaceDataContractSerializerOperationBehavior(item);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
|
||||
{
|
||||
DataContractSerializerOperationBehavior val = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
|
||||
if (val != null)
|
||||
{
|
||||
((Collection<IOperationBehavior>)(object)description.Behaviors).Remove((IOperationBehavior)(object)val);
|
||||
ProtoOperationBehavior protoOperationBehavior = new ProtoOperationBehavior(description);
|
||||
((DataContractSerializerOperationBehavior)protoOperationBehavior).MaxItemsInObjectGraph = val.MaxItemsInObjectGraph;
|
||||
((Collection<IOperationBehavior>)(object)description.Behaviors).Add((IOperationBehavior)(object)protoOperationBehavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Xml;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
namespace ProtoBuf.ServiceModel;
|
||||
|
||||
public sealed class ProtoOperationBehavior : DataContractSerializerOperationBehavior
|
||||
{
|
||||
private TypeModel model;
|
||||
|
||||
public TypeModel Model
|
||||
{
|
||||
get
|
||||
{
|
||||
return model;
|
||||
}
|
||||
set
|
||||
{
|
||||
model = value ?? throw new ArgumentNullException("value");
|
||||
}
|
||||
}
|
||||
|
||||
public ProtoOperationBehavior(OperationDescription operation)
|
||||
: base(operation)
|
||||
{
|
||||
model = RuntimeTypeModel.Default;
|
||||
}
|
||||
|
||||
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new InvalidOperationException("No Model instance has been assigned to the ProtoOperationBehavior");
|
||||
}
|
||||
return (XmlObjectSerializer)(((object)XmlProtoSerializer.TryCreate(model, type)) ?? ((object)((DataContractSerializerOperationBehavior)this).CreateSerializer(type, name, ns, knownTypes)));
|
||||
}
|
||||
}
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
namespace ProtoBuf.ServiceModel;
|
||||
|
||||
public sealed class XmlProtoSerializer : XmlObjectSerializer
|
||||
{
|
||||
private readonly TypeModel model;
|
||||
|
||||
private readonly int key;
|
||||
|
||||
private readonly bool isList;
|
||||
|
||||
private readonly bool isEnum;
|
||||
|
||||
private readonly Type type;
|
||||
|
||||
private const string PROTO_ELEMENT = "proto";
|
||||
|
||||
internal XmlProtoSerializer(TypeModel model, int key, Type type, bool isList)
|
||||
{
|
||||
if (key < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("key");
|
||||
}
|
||||
this.model = model ?? throw new ArgumentNullException("model");
|
||||
this.key = key;
|
||||
this.isList = isList;
|
||||
this.type = type ?? throw new ArgumentOutOfRangeException("type");
|
||||
isEnum = Helpers.IsEnum(type);
|
||||
}
|
||||
|
||||
public static XmlProtoSerializer TryCreate(TypeModel model, Type type)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException("model");
|
||||
}
|
||||
if ((object)type == null)
|
||||
{
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
bool flag;
|
||||
int num = GetKey(model, ref type, out flag);
|
||||
if (num >= 0)
|
||||
{
|
||||
return new XmlProtoSerializer(model, num, type, flag);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlProtoSerializer(TypeModel model, Type type)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException("model");
|
||||
}
|
||||
if ((object)type == null)
|
||||
{
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
key = GetKey(model, ref type, out isList);
|
||||
this.model = model;
|
||||
this.type = type;
|
||||
isEnum = Helpers.IsEnum(type);
|
||||
if (key < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("type", "Type not recognised by the model: " + type.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetKey(TypeModel model, ref Type type, out bool isList)
|
||||
{
|
||||
if (model != null && (object)type != null)
|
||||
{
|
||||
int num = model.GetKey(ref type);
|
||||
if (num >= 0)
|
||||
{
|
||||
isList = false;
|
||||
return num;
|
||||
}
|
||||
Type listItemType = TypeModel.GetListItemType(model, type);
|
||||
if ((object)listItemType != null)
|
||||
{
|
||||
num = model.GetKey(ref listItemType);
|
||||
if (num >= 0)
|
||||
{
|
||||
isList = true;
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
isList = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override void WriteEndObject(XmlDictionaryWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException("writer");
|
||||
}
|
||||
((XmlWriter)writer).WriteEndElement();
|
||||
}
|
||||
|
||||
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException("writer");
|
||||
}
|
||||
((XmlWriter)writer).WriteStartElement("proto");
|
||||
}
|
||||
|
||||
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException("writer");
|
||||
}
|
||||
if (graph == null)
|
||||
{
|
||||
((XmlWriter)writer).WriteAttributeString("nil", "true");
|
||||
return;
|
||||
}
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
if (isList)
|
||||
{
|
||||
model.Serialize(memoryStream, graph, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
using ProtoWriter dest = ProtoWriter.Create(memoryStream, model);
|
||||
model.Serialize(key, graph, dest);
|
||||
}
|
||||
byte[] buffer = memoryStream.GetBuffer();
|
||||
((XmlWriter)writer).WriteBase64(buffer, 0, (int)memoryStream.Length);
|
||||
}
|
||||
|
||||
public override bool IsStartObject(XmlDictionaryReader reader)
|
||||
{
|
||||
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001f: Invalid comparison between Unknown and I4
|
||||
if (reader == null)
|
||||
{
|
||||
throw new ArgumentNullException("reader");
|
||||
}
|
||||
((XmlReader)reader).MoveToContent();
|
||||
if ((int)((XmlReader)reader).NodeType == 1)
|
||||
{
|
||||
return ((XmlReader)reader).Name == "proto";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
|
||||
{
|
||||
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (reader == null)
|
||||
{
|
||||
throw new ArgumentNullException("reader");
|
||||
}
|
||||
((XmlReader)reader).MoveToContent();
|
||||
bool isEmptyElement = ((XmlReader)reader).IsEmptyElement;
|
||||
bool flag = ((XmlReader)reader).GetAttribute("nil") == "true";
|
||||
((XmlReader)reader).ReadStartElement("proto");
|
||||
if (flag)
|
||||
{
|
||||
if (!isEmptyElement)
|
||||
{
|
||||
((XmlReader)reader).ReadEndElement();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isEmptyElement)
|
||||
{
|
||||
if (isList || isEnum)
|
||||
{
|
||||
return model.Deserialize(Stream.Null, null, type, null);
|
||||
}
|
||||
ProtoReader protoReader = null;
|
||||
try
|
||||
{
|
||||
protoReader = ProtoReader.Create(Stream.Null, model, null, -1L);
|
||||
return model.Deserialize(key, null, protoReader);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ProtoReader.Recycle(protoReader);
|
||||
}
|
||||
}
|
||||
object result;
|
||||
using (MemoryStream source = new MemoryStream(reader.ReadContentAsBase64()))
|
||||
{
|
||||
if (isList || isEnum)
|
||||
{
|
||||
result = model.Deserialize(source, null, type, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProtoReader protoReader2 = null;
|
||||
try
|
||||
{
|
||||
protoReader2 = ProtoReader.Create(source, model, null, -1L);
|
||||
result = model.Deserialize(key, null, protoReader2);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ProtoReader.Recycle(protoReader2);
|
||||
}
|
||||
}
|
||||
}
|
||||
((XmlReader)reader).ReadEndElement();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user