NetObjectSerializer.cs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #if !NO_RUNTIME
  2. using System;
  3. using System.Reflection;
  4. using ProtoBuf.Meta;
  5. namespace ProtoBuf.Serializers
  6. {
  7. sealed class NetObjectSerializer : IProtoSerializer
  8. {
  9. private readonly int key;
  10. private readonly Type type;
  11. private readonly BclHelpers.NetObjectOptions options;
  12. public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options)
  13. {
  14. bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0;
  15. this.key = dynamicType ? -1 : key;
  16. this.type = dynamicType ? model.MapType(typeof(object)) : type;
  17. this.options = options;
  18. }
  19. public Type ExpectedType => type;
  20. public bool ReturnsValue => true;
  21. public bool RequiresOldValue => true;
  22. public object Read(object value, ProtoReader source)
  23. {
  24. return BclHelpers.ReadNetObject(value, source, key, type == typeof(object) ? null : type, options);
  25. }
  26. public void Write(object value, ProtoWriter dest)
  27. {
  28. BclHelpers.WriteNetObject(value, dest, key, options);
  29. }
  30. #if FEAT_COMPILER
  31. public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
  32. {
  33. ctx.LoadValue(valueFrom);
  34. ctx.CastToObject(type);
  35. ctx.LoadReaderWriter();
  36. ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key));
  37. if (type == ctx.MapType(typeof(object))) ctx.LoadNullRef();
  38. else ctx.LoadValue(type);
  39. ctx.LoadValue((int)options);
  40. ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("ReadNetObject"));
  41. ctx.CastFromObject(type);
  42. }
  43. public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
  44. {
  45. ctx.LoadValue(valueFrom);
  46. ctx.CastToObject(type);
  47. ctx.LoadReaderWriter();
  48. ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key));
  49. ctx.LoadValue((int)options);
  50. ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("WriteNetObject"));
  51. }
  52. #endif
  53. }
  54. }
  55. #endif