UriDecorator.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #if !NO_RUNTIME
  2. using System;
  3. #if FEAT_IKVM
  4. using Type = IKVM.Reflection.Type;
  5. using IKVM.Reflection;
  6. #else
  7. using System.Reflection;
  8. #endif
  9. namespace ProtoBuf.Serializers
  10. {
  11. sealed class UriDecorator : ProtoDecoratorBase
  12. {
  13. #if FEAT_IKVM
  14. readonly Type expectedType;
  15. #else
  16. static readonly Type expectedType = typeof(Uri);
  17. #endif
  18. public UriDecorator(ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail)
  19. {
  20. #if FEAT_IKVM
  21. expectedType = model.MapType(typeof(Uri));
  22. #endif
  23. }
  24. public override Type ExpectedType { get { return expectedType; } }
  25. public override bool RequiresOldValue { get { return false; } }
  26. public override bool ReturnsValue { get { return true; } }
  27. #if !FEAT_IKVM
  28. public override void Write(object value, ProtoWriter dest)
  29. {
  30. Tail.Write(((Uri)value).AbsoluteUri, dest);
  31. }
  32. public override object Read(object value, ProtoReader source)
  33. {
  34. Helpers.DebugAssert(value == null); // not expecting incoming
  35. string s = (string)Tail.Read(null, source);
  36. return s.Length == 0 ? null : new Uri(s);
  37. }
  38. #endif
  39. #if FEAT_COMPILER
  40. protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
  41. {
  42. ctx.LoadValue(valueFrom);
  43. ctx.LoadValue(typeof(Uri).GetProperty("AbsoluteUri"));
  44. Tail.EmitWrite(ctx, null);
  45. }
  46. protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
  47. {
  48. Tail.EmitRead(ctx, valueFrom);
  49. ctx.CopyValue();
  50. Compiler.CodeLabel @nonEmpty = ctx.DefineLabel(), @end = ctx.DefineLabel();
  51. ctx.LoadValue(typeof(string).GetProperty("Length"));
  52. ctx.BranchIfTrue(@nonEmpty, true);
  53. ctx.DiscardValue();
  54. ctx.LoadNullRef();
  55. ctx.Branch(@end, true);
  56. ctx.MarkLabel(@nonEmpty);
  57. ctx.EmitCtor(ctx.MapType(typeof(Uri)), ctx.MapType(typeof(string)));
  58. ctx.MarkLabel(@end);
  59. }
  60. #endif
  61. }
  62. }
  63. #endif