~ubuntu-branches/ubuntu/trusty/smuxi/trusty-proposed

« back to all changes in this revision

Viewing changes to lib/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs

  • Committer: Package Import Robot
  • Author(s): Mirco Bauer
  • Date: 2013-05-25 22:11:31 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130525221131-nd2mc0kzubuwyx20
Tags: 0.8.11-1
* [22d13d5] Imported Upstream version 0.8.11
* [6d2b95a] Refreshed patches
* [89eb66e] Added ServiceStack libraries to smuxi-engine package
* [848ab10] Enable Campfire engine
* [c6dbdc7] Always build db4o for predictable build result
* [13ec489] Exclude OS X specific libraries from dh_clideps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#if !SILVERLIGHT && !PocketPC
2
 
using System;
3
 
using System.Collections.Generic;
4
 
using System.IO;
5
 
using System.Linq;
6
 
using System.Reflection;
7
 
using System.Reflection.Emit;
8
 
using System.Resources;
9
 
using System.Text;
10
 
using System.Threading;
11
 
using System.Globalization;
12
 
 
13
 
namespace Newtonsoft.Json.Utilities
14
 
{
15
 
  internal class DynamicWrapperBase
16
 
  {
17
 
    internal protected object UnderlyingObject;
18
 
  }
19
 
 
20
 
  internal static class DynamicWrapper
21
 
  {
22
 
    private static readonly object _lock = new object();
23
 
    private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
24
 
 
25
 
    private static ModuleBuilder _moduleBuilder;
26
 
 
27
 
    private static ModuleBuilder ModuleBuilder
28
 
    {
29
 
      get
30
 
      {
31
 
        Init();
32
 
        return _moduleBuilder;
33
 
      }
34
 
    }
35
 
 
36
 
    private static void Init()
37
 
    {
38
 
      if (_moduleBuilder == null)
39
 
      {
40
 
        lock (_lock)
41
 
        {
42
 
          if (_moduleBuilder == null)
43
 
          {
44
 
            AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic");
45
 
            assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey());
46
 
 
47
 
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
48
 
            _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false);
49
 
          }
50
 
        }
51
 
      }
52
 
    }
53
 
 
54
 
    private static byte[] GetStrongKey()
55
 
    {
56
 
      using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Newtonsoft.Json.Dynamic.snk"))
57
 
      {
58
 
        if (stream == null)
59
 
          throw new MissingManifestResourceException("Should have a Newtonsoft.Json.Dynamic.snk as an embedded resource.");
60
 
 
61
 
        int length = (int)stream.Length;
62
 
        byte[] buffer = new byte[length];
63
 
        stream.Read(buffer, 0, length);
64
 
 
65
 
        return buffer;
66
 
      }
67
 
    }
68
 
 
69
 
    public static Type GetWrapper(Type interfaceType, Type realObjectType)
70
 
    {
71
 
      Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
72
 
 
73
 
      if (wrapperType == null)
74
 
      {
75
 
        wrapperType = GenerateWrapperType(interfaceType, realObjectType);
76
 
        _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
77
 
      }
78
 
 
79
 
      return wrapperType;
80
 
    }
81
 
 
82
 
    public static object GetUnderlyingObject(object wrapper)
83
 
    {
84
 
      DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase;
85
 
      if (wrapperBase == null)
86
 
        throw new ArgumentException("Object is not a wrapper.", "wrapper");
87
 
 
88
 
      return wrapperBase.UnderlyingObject;
89
 
    }
90
 
 
91
 
    private static Type GenerateWrapperType(Type interfaceType, Type underlyingType)
92
 
    {
93
 
      TypeBuilder wrapperBuilder = ModuleBuilder.DefineType(
94
 
          "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name),
95
 
          TypeAttributes.NotPublic | TypeAttributes.Sealed,
96
 
          typeof(DynamicWrapperBase),
97
 
          new[] { interfaceType });
98
 
 
99
 
      WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder);
100
 
 
101
 
      foreach (MethodInfo method in interfaceType.AllMethods())
102
 
      {
103
 
        wrapperMethod.Generate(method);
104
 
      }
105
 
 
106
 
      return wrapperBuilder.CreateType();
107
 
    }
108
 
 
109
 
    public static T CreateWrapper<T>(object realObject) where T : class
110
 
    {
111
 
      var dynamicType = GetWrapper(typeof(T), realObject.GetType());
112
 
      var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
113
 
 
114
 
      dynamicWrapper.UnderlyingObject = realObject;
115
 
 
116
 
      return dynamicWrapper as T;
117
 
    }
118
 
  }
119
 
 
120
 
  internal class WrapperMethodBuilder
121
 
  {
122
 
    private readonly Type _realObjectType;
123
 
    private readonly TypeBuilder _wrapperBuilder;
124
 
 
125
 
    public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
126
 
    {
127
 
      _realObjectType = realObjectType;
128
 
      _wrapperBuilder = proxyBuilder;
129
 
    }
130
 
 
131
 
    public void Generate(MethodInfo newMethod)
132
 
    {
133
 
      if (newMethod.IsGenericMethod)
134
 
        newMethod = newMethod.GetGenericMethodDefinition();
135
 
 
136
 
      FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic);
137
 
 
138
 
      var parameters = newMethod.GetParameters();
139
 
      var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
140
 
 
141
 
      MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(
142
 
          newMethod.Name,
143
 
          MethodAttributes.Public | MethodAttributes.Virtual,
144
 
          newMethod.ReturnType,
145
 
          parameterTypes);
146
 
 
147
 
      if (newMethod.IsGenericMethod)
148
 
      {
149
 
        methodBuilder.DefineGenericParameters(
150
 
            newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
151
 
      }
152
 
 
153
 
      ILGenerator ilGenerator = methodBuilder.GetILGenerator();
154
 
 
155
 
      LoadUnderlyingObject(ilGenerator, srcField);
156
 
      PushParameters(parameters, ilGenerator);
157
 
      ExecuteMethod(newMethod, parameterTypes, ilGenerator);
158
 
      Return(ilGenerator);
159
 
    }
160
 
 
161
 
    private static void Return(ILGenerator ilGenerator)
162
 
    {
163
 
      ilGenerator.Emit(OpCodes.Ret);
164
 
    }
165
 
 
166
 
    private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
167
 
    {
168
 
      MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
169
 
 
170
 
      if (srcMethod == null)
171
 
        throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName);
172
 
 
173
 
      ilGenerator.Emit(OpCodes.Call, srcMethod);
174
 
    }
175
 
 
176
 
    private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
177
 
    {
178
 
      if (realMethod.IsGenericMethod)
179
 
        return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
180
 
 
181
 
      return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
182
 
    }
183
 
 
184
 
    private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
185
 
    {
186
 
      for (int i = 1; i < parameters.Count + 1; i++)
187
 
        ilGenerator.Emit(OpCodes.Ldarg, i);
188
 
    }
189
 
 
190
 
    private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField)
191
 
    {
192
 
      ilGenerator.Emit(OpCodes.Ldarg_0);
193
 
      ilGenerator.Emit(OpCodes.Ldfld, srcField);
194
 
    }
195
 
  }
196
 
 
197
 
  internal class WrapperDictionary
198
 
  {
199
 
    private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
200
 
 
201
 
    private static string GenerateKey(Type interfaceType, Type realObjectType)
202
 
    {
203
 
      return interfaceType.Name + "_" + realObjectType.Name;
204
 
    }
205
 
 
206
 
    public Type GetType(Type interfaceType, Type realObjectType)
207
 
    {
208
 
      string key = GenerateKey(interfaceType, realObjectType);
209
 
 
210
 
      if (_wrapperTypes.ContainsKey(key))
211
 
        return _wrapperTypes[key];
212
 
 
213
 
      return null;
214
 
    }
215
 
 
216
 
    public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
217
 
    {
218
 
      string key = GenerateKey(interfaceType, realObjectType);
219
 
 
220
 
      if (_wrapperTypes.ContainsKey(key))
221
 
        _wrapperTypes[key] = wrapperType;
222
 
      else
223
 
        _wrapperTypes.Add(key, wrapperType);
224
 
    }
225
 
  }
226
 
 
227
 
  internal static class TypeExtensions
228
 
  {
229
 
    public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
230
 
    {
231
 
      var methods = type.GetMethods().Where(method => method.Name == name);
232
 
 
233
 
      foreach (var method in methods)
234
 
      {
235
 
        if (method.HasParameters(parameterTypes))
236
 
          return method;
237
 
      }
238
 
 
239
 
      return null;
240
 
    }
241
 
 
242
 
    public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes)
243
 
    {
244
 
      var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
245
 
 
246
 
      if (methodParameters.Length != parameterTypes.Length)
247
 
        return false;
248
 
 
249
 
      for (int i = 0; i < methodParameters.Length; i++)
250
 
        if (methodParameters[i].ToString() != parameterTypes[i].ToString())
251
 
          return false;
252
 
 
253
 
      return true;
254
 
    }
255
 
 
256
 
    public static IEnumerable<Type> AllInterfaces(this Type target)
257
 
    {
258
 
      foreach (var IF in target.GetInterfaces())
259
 
      {
260
 
        yield return IF;
261
 
        foreach (var childIF in IF.AllInterfaces())
262
 
        {
263
 
          yield return childIF;
264
 
        }
265
 
      }
266
 
    }
267
 
 
268
 
    public static IEnumerable<MethodInfo> AllMethods(this Type target)
269
 
    {
270
 
      var allTypes = target.AllInterfaces().ToList();
271
 
      allTypes.Add(target);
272
 
 
273
 
      return from type in allTypes
274
 
             from method in type.GetMethods()
275
 
             select method;
276
 
    }
277
 
  }
278
 
}
 
1
#region License
 
2
// Copyright (c) 2007 James Newton-King
 
3
//
 
4
// Permission is hereby granted, free of charge, to any person
 
5
// obtaining a copy of this software and associated documentation
 
6
// files (the "Software"), to deal in the Software without
 
7
// restriction, including without limitation the rights to use,
 
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
// copies of the Software, and to permit persons to whom the
 
10
// Software is furnished to do so, subject to the following
 
11
// conditions:
 
12
//
 
13
// The above copyright notice and this permission notice shall be
 
14
// included in all copies or substantial portions of the Software.
 
15
//
 
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
23
// OTHER DEALINGS IN THE SOFTWARE.
 
24
#endregion
 
25
 
 
26
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
 
27
using System;
 
28
using System.Collections.Generic;
 
29
using System.IO;
 
30
using System.Reflection;
 
31
using System.Reflection.Emit;
 
32
using System.Resources;
 
33
using System.Globalization;
 
34
#if NET20
 
35
using Newtonsoft.Json.Utilities.LinqBridge;
 
36
#else
 
37
using System.Linq;
 
38
#endif
 
39
 
 
40
namespace Newtonsoft.Json.Utilities
 
41
{
 
42
  internal class DynamicWrapperBase
 
43
  {
 
44
    internal protected object UnderlyingObject;
 
45
  }
 
46
 
 
47
  internal static class DynamicWrapper
 
48
  {
 
49
    private static readonly object _lock = new object();
 
50
    private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
 
51
 
 
52
    private static ModuleBuilder _moduleBuilder;
 
53
 
 
54
    private static ModuleBuilder ModuleBuilder
 
55
    {
 
56
      get
 
57
      {
 
58
        Init();
 
59
        return _moduleBuilder;
 
60
      }
 
61
    }
 
62
 
 
63
    private static void Init()
 
64
    {
 
65
      if (_moduleBuilder == null)
 
66
      {
 
67
        lock (_lock)
 
68
        {
 
69
          if (_moduleBuilder == null)
 
70
          {
 
71
            AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic");
 
72
            assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey());
 
73
 
 
74
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
 
75
            _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false);
 
76
          }
 
77
        }
 
78
      }
 
79
    }
 
80
 
 
81
    private static byte[] GetStrongKey()
 
82
    {
 
83
      const string name = "Newtonsoft.Json.Dynamic.snk";
 
84
 
 
85
      using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
 
86
      {
 
87
        if (stream == null)
 
88
          throw new MissingManifestResourceException("Should have " + name + " as an embedded resource.");
 
89
 
 
90
        int length = (int)stream.Length;
 
91
        byte[] buffer = new byte[length];
 
92
        stream.Read(buffer, 0, length);
 
93
 
 
94
        return buffer;
 
95
      }
 
96
    }
 
97
 
 
98
    public static Type GetWrapper(Type interfaceType, Type realObjectType)
 
99
    {
 
100
      Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
 
101
 
 
102
      if (wrapperType == null)
 
103
      {
 
104
        lock (_lock)
 
105
        {
 
106
          wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
 
107
 
 
108
          if (wrapperType == null)
 
109
          {
 
110
            wrapperType = GenerateWrapperType(interfaceType, realObjectType);
 
111
            _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
 
112
          }
 
113
        }
 
114
      }
 
115
 
 
116
      return wrapperType;
 
117
    }
 
118
 
 
119
    public static object GetUnderlyingObject(object wrapper)
 
120
    {
 
121
      DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase;
 
122
      if (wrapperBase == null)
 
123
        throw new ArgumentException("Object is not a wrapper.", "wrapper");
 
124
 
 
125
      return wrapperBase.UnderlyingObject;
 
126
    }
 
127
 
 
128
    private static Type GenerateWrapperType(Type interfaceType, Type underlyingType)
 
129
    {
 
130
      TypeBuilder wrapperBuilder = ModuleBuilder.DefineType(
 
131
          "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name),
 
132
          TypeAttributes.NotPublic | TypeAttributes.Sealed,
 
133
          typeof(DynamicWrapperBase),
 
134
          new[] { interfaceType });
 
135
 
 
136
      WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder);
 
137
 
 
138
      foreach (MethodInfo method in interfaceType.GetAllMethods())
 
139
      {
 
140
        wrapperMethod.Generate(method);
 
141
      }
 
142
 
 
143
      return wrapperBuilder.CreateType();
 
144
    }
 
145
 
 
146
    public static T CreateWrapper<T>(object realObject) where T : class
 
147
    {
 
148
      var dynamicType = GetWrapper(typeof(T), realObject.GetType());
 
149
      var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
 
150
 
 
151
      dynamicWrapper.UnderlyingObject = realObject;
 
152
 
 
153
      return dynamicWrapper as T;
 
154
    }
 
155
  }
 
156
 
 
157
  internal class WrapperMethodBuilder
 
158
  {
 
159
    private readonly Type _realObjectType;
 
160
    private readonly TypeBuilder _wrapperBuilder;
 
161
 
 
162
    public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
 
163
    {
 
164
      _realObjectType = realObjectType;
 
165
      _wrapperBuilder = proxyBuilder;
 
166
    }
 
167
 
 
168
    public void Generate(MethodInfo newMethod)
 
169
    {
 
170
      if (newMethod.IsGenericMethod)
 
171
        newMethod = newMethod.GetGenericMethodDefinition();
 
172
 
 
173
      FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic);
 
174
 
 
175
      var parameters = newMethod.GetParameters();
 
176
      var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
 
177
 
 
178
      MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(
 
179
          newMethod.Name,
 
180
          MethodAttributes.Public | MethodAttributes.Virtual,
 
181
          newMethod.ReturnType,
 
182
          parameterTypes);
 
183
 
 
184
      if (newMethod.IsGenericMethod)
 
185
      {
 
186
        methodBuilder.DefineGenericParameters(
 
187
            newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
 
188
      }
 
189
 
 
190
      ILGenerator ilGenerator = methodBuilder.GetILGenerator();
 
191
 
 
192
      LoadUnderlyingObject(ilGenerator, srcField);
 
193
      PushParameters(parameters, ilGenerator);
 
194
      ExecuteMethod(newMethod, parameterTypes, ilGenerator);
 
195
      Return(ilGenerator);
 
196
    }
 
197
 
 
198
    private static void Return(ILGenerator ilGenerator)
 
199
    {
 
200
      ilGenerator.Emit(OpCodes.Ret);
 
201
    }
 
202
 
 
203
    private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
 
204
    {
 
205
      MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
 
206
 
 
207
      if (srcMethod == null)
 
208
        throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName);
 
209
 
 
210
      ilGenerator.Emit(OpCodes.Call, srcMethod);
 
211
    }
 
212
 
 
213
    private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
 
214
    {
 
215
      if (realMethod.IsGenericMethod)
 
216
        return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
 
217
 
 
218
      return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
 
219
    }
 
220
 
 
221
    private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
 
222
    {
 
223
      for (int i = 1; i < parameters.Count + 1; i++)
 
224
        ilGenerator.Emit(OpCodes.Ldarg, i);
 
225
    }
 
226
 
 
227
    private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField)
 
228
    {
 
229
      ilGenerator.Emit(OpCodes.Ldarg_0);
 
230
      ilGenerator.Emit(OpCodes.Ldfld, srcField);
 
231
    }
 
232
  }
 
233
 
 
234
  internal class WrapperDictionary
 
235
  {
 
236
    private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
 
237
 
 
238
    private static string GenerateKey(Type interfaceType, Type realObjectType)
 
239
    {
 
240
      return interfaceType.Name + "_" + realObjectType.Name;
 
241
    }
 
242
 
 
243
    public Type GetType(Type interfaceType, Type realObjectType)
 
244
    {
 
245
      string key = GenerateKey(interfaceType, realObjectType);
 
246
 
 
247
      if (_wrapperTypes.ContainsKey(key))
 
248
        return _wrapperTypes[key];
 
249
 
 
250
      return null;
 
251
    }
 
252
 
 
253
    public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
 
254
    {
 
255
      string key = GenerateKey(interfaceType, realObjectType);
 
256
 
 
257
      if (_wrapperTypes.ContainsKey(key))
 
258
        _wrapperTypes[key] = wrapperType;
 
259
      else
 
260
        _wrapperTypes.Add(key, wrapperType);
 
261
    }
 
262
  }
 
263
}
279
264
#endif
 
 
b'\\ No newline at end of file'