PageRenderTime 75ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ServiceStack.Text/PclExport.Net40.cs

https://github.com/ioninteractive/ServiceStack.Text
C# | 1683 lines | 1298 code | 250 blank | 135 comment | 166 complexity | bb6a737d60ccab1b4c80346fecd5b106 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #if !(XBOX || SL5 || NETFX_CORE || WP || PCL)
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.Collections.Specialized;
  7. using System.Diagnostics;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Linq.Expressions;
  12. using System.Net;
  13. using System.Reflection;
  14. using System.Runtime.CompilerServices;
  15. using System.Runtime.Serialization;
  16. using System.Security.Cryptography;
  17. using System.Text;
  18. using System.Text.RegularExpressions;
  19. using System.Threading;
  20. using System.Xml;
  21. using ServiceStack.Text;
  22. using ServiceStack.Text.Common;
  23. using ServiceStack.Text.Json;
  24. #if !__IOS__
  25. using System.Reflection.Emit;
  26. using FastMember = ServiceStack.Text.FastMember;
  27. #endif
  28. namespace ServiceStack
  29. {
  30. public class Net40PclExport : PclExport
  31. {
  32. public static Net40PclExport Provider = new Net40PclExport();
  33. public Net40PclExport()
  34. {
  35. this.SupportsEmit = SupportsExpression = true;
  36. this.DirSep = Path.DirectorySeparatorChar;
  37. this.AltDirSep = Path.DirectorySeparatorChar == '/' ? '\\' : '/';
  38. this.RegexOptions = RegexOptions.Compiled;
  39. this.InvariantComparison = StringComparison.InvariantCulture;
  40. this.InvariantComparisonIgnoreCase = StringComparison.InvariantCultureIgnoreCase;
  41. this.InvariantComparer = StringComparer.InvariantCulture;
  42. this.InvariantComparerIgnoreCase = StringComparer.InvariantCultureIgnoreCase;
  43. this.PlatformName = Environment.OSVersion.Platform.ToString();
  44. }
  45. public static PclExport Configure()
  46. {
  47. Configure(Provider);
  48. return Provider;
  49. }
  50. public override string ReadAllText(string filePath)
  51. {
  52. return File.ReadAllText(filePath);
  53. }
  54. public override string ToTitleCase(string value)
  55. {
  56. return TextInfo.ToTitleCase(value).Replace("_", String.Empty);
  57. }
  58. public override string ToInvariantUpper(char value)
  59. {
  60. return value.ToString(CultureInfo.InvariantCulture).ToUpper();
  61. }
  62. public override bool IsAnonymousType(Type type)
  63. {
  64. return type.HasAttribute<CompilerGeneratedAttribute>()
  65. && type.IsGeneric() && type.Name.Contains("AnonymousType")
  66. && (type.Name.StartsWith("<>", StringComparison.Ordinal) || type.Name.StartsWith("VB$", StringComparison.Ordinal))
  67. && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
  68. }
  69. public override bool FileExists(string filePath)
  70. {
  71. return File.Exists(filePath);
  72. }
  73. public override bool DirectoryExists(string dirPath)
  74. {
  75. return Directory.Exists(dirPath);
  76. }
  77. public override void CreateDirectory(string dirPath)
  78. {
  79. Directory.CreateDirectory(dirPath);
  80. }
  81. public const string AppSettingsKey = "servicestack:license";
  82. public override void RegisterLicenseFromConfig()
  83. {
  84. #if ANDROID
  85. #elif __IOS__
  86. #else
  87. //Automatically register license key stored in <appSettings/>
  88. var licenceKeyText = System.Configuration.ConfigurationManager.AppSettings[AppSettingsKey];
  89. if (!string.IsNullOrEmpty(licenceKeyText))
  90. {
  91. LicenseUtils.RegisterLicense(licenceKeyText);
  92. }
  93. #endif
  94. }
  95. public override string GetEnvironmentVariable(string name)
  96. {
  97. return Environment.GetEnvironmentVariable(name);
  98. }
  99. public override void WriteLine(string line)
  100. {
  101. Console.WriteLine(line);
  102. }
  103. public override void WriteLine(string format, params object[] args)
  104. {
  105. Console.WriteLine(format, args);
  106. }
  107. public override void AddCompression(WebRequest webReq)
  108. {
  109. var httpReq = (HttpWebRequest)webReq;
  110. httpReq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
  111. httpReq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
  112. }
  113. public override Stream GetRequestStream(WebRequest webRequest)
  114. {
  115. return webRequest.GetRequestStream();
  116. }
  117. public override WebResponse GetResponse(WebRequest webRequest)
  118. {
  119. return webRequest.GetResponse();
  120. }
  121. public override bool IsDebugBuild(Assembly assembly)
  122. {
  123. return assembly.AllAttributes()
  124. .OfType<DebuggableAttribute>()
  125. .Select(attr => attr.IsJITTrackingEnabled)
  126. .FirstOrDefault();
  127. }
  128. public override string MapAbsolutePath(string relativePath, string appendPartialPathModifier)
  129. {
  130. if (relativePath.StartsWith("~"))
  131. {
  132. var assemblyDirectoryPath = Path.GetDirectoryName(new Uri(typeof(PathUtils).Assembly.EscapedCodeBase).LocalPath);
  133. // Escape the assembly bin directory to the hostname directory
  134. var hostDirectoryPath = appendPartialPathModifier != null
  135. ? assemblyDirectoryPath + appendPartialPathModifier
  136. : assemblyDirectoryPath;
  137. return Path.GetFullPath(relativePath.Replace("~", hostDirectoryPath));
  138. }
  139. return relativePath;
  140. }
  141. public override Assembly LoadAssembly(string assemblyPath)
  142. {
  143. return Assembly.LoadFrom(assemblyPath);
  144. }
  145. public virtual void AddHeader(WebRequest webReq, string name, string value)
  146. {
  147. webReq.Headers.Add(name, value);
  148. }
  149. public override Assembly[] GetAllAssemblies()
  150. {
  151. return AppDomain.CurrentDomain.GetAssemblies();
  152. }
  153. public override Type FindType(string typeName, string assemblyName)
  154. {
  155. var binPath = AssemblyUtils.GetAssemblyBinPath(Assembly.GetExecutingAssembly());
  156. Assembly assembly = null;
  157. var assemblyDllPath = binPath + String.Format("{0}.{1}", assemblyName, "dll");
  158. if (File.Exists(assemblyDllPath))
  159. {
  160. assembly = AssemblyUtils.LoadAssembly(assemblyDllPath);
  161. }
  162. var assemblyExePath = binPath + String.Format("{0}.{1}", assemblyName, "exe");
  163. if (File.Exists(assemblyExePath))
  164. {
  165. assembly = AssemblyUtils.LoadAssembly(assemblyExePath);
  166. }
  167. return assembly != null ? assembly.GetType(typeName) : null;
  168. }
  169. public override string GetAssemblyCodeBase(Assembly assembly)
  170. {
  171. return assembly.CodeBase;
  172. }
  173. public virtual string GetAssemblyPath(Type source)
  174. {
  175. var assemblyUri = new Uri(source.Assembly.EscapedCodeBase);
  176. return assemblyUri.LocalPath;
  177. }
  178. public virtual string GetAsciiString(byte[] bytes, int index, int count)
  179. {
  180. return Encoding.ASCII.GetString(bytes, index, count);
  181. }
  182. public override byte[] GetAsciiBytes(string str)
  183. {
  184. return Encoding.ASCII.GetBytes(str);
  185. }
  186. public override bool InSameAssembly(Type t1, Type t2)
  187. {
  188. return t1.GetAssembly() == t2.GetAssembly();
  189. }
  190. public override Type GetGenericCollectionType(Type type)
  191. {
  192. return type.FindInterfaces((t, critera) =>
  193. t.IsGenericType
  194. && t.GetGenericTypeDefinition() == typeof(ICollection<>), null).FirstOrDefault();
  195. }
  196. public override PropertySetterDelegate GetPropertySetterFn(PropertyInfo propertyInfo)
  197. {
  198. var propertySetMethod = propertyInfo.SetMethod();
  199. if (propertySetMethod == null) return null;
  200. if (!SupportsExpression)
  201. {
  202. return (o, convertedValue) =>
  203. propertySetMethod.Invoke(o, new[] { convertedValue });
  204. }
  205. var instance = Expression.Parameter(typeof(object), "i");
  206. var argument = Expression.Parameter(typeof(object), "a");
  207. var instanceParam = Expression.Convert(instance, propertyInfo.ReflectedType());
  208. var valueParam = Expression.Convert(argument, propertyInfo.PropertyType);
  209. var setterCall = Expression.Call(instanceParam, propertyInfo.SetMethod(), valueParam);
  210. return Expression.Lambda<PropertySetterDelegate>(setterCall, instance, argument).Compile();
  211. }
  212. public override PropertyGetterDelegate GetPropertyGetterFn(PropertyInfo propertyInfo)
  213. {
  214. if (!SupportsExpression)
  215. return base.GetPropertyGetterFn(propertyInfo);
  216. var getMethodInfo = propertyInfo.GetMethodInfo();
  217. if (getMethodInfo == null) return null;
  218. try
  219. {
  220. var oInstanceParam = Expression.Parameter(typeof(object), "oInstanceParam");
  221. var instanceParam = Expression.Convert(oInstanceParam, propertyInfo.ReflectedType); //propertyInfo.DeclaringType doesn't work on Proxy types
  222. var exprCallPropertyGetFn = Expression.Call(instanceParam, getMethodInfo);
  223. var oExprCallPropertyGetFn = Expression.Convert(exprCallPropertyGetFn, typeof(object));
  224. var propertyGetFn = Expression.Lambda<PropertyGetterDelegate>
  225. (
  226. oExprCallPropertyGetFn,
  227. oInstanceParam
  228. ).Compile();
  229. return propertyGetFn;
  230. }
  231. catch (Exception ex)
  232. {
  233. Tracer.Instance.WriteError(ex);
  234. throw;
  235. }
  236. }
  237. private static readonly MethodInfo setFieldMethod =
  238. typeof(Net40PclExport).GetStaticMethod("SetField");
  239. internal static void SetField<TValue>(ref TValue field, TValue newValue)
  240. {
  241. field = newValue;
  242. }
  243. public override PropertySetterDelegate GetFieldSetterFn(FieldInfo fieldInfo)
  244. {
  245. if (!SupportsExpression)
  246. return base.GetFieldSetterFn(fieldInfo);
  247. var fieldDeclaringType = fieldInfo.DeclaringType;
  248. var sourceParameter = Expression.Parameter(typeof(object), "source");
  249. var valueParameter = Expression.Parameter(typeof(object), "value");
  250. var sourceExpression = this.GetCastOrConvertExpression(sourceParameter, fieldDeclaringType);
  251. var fieldExpression = Expression.Field(sourceExpression, fieldInfo);
  252. var valueExpression = this.GetCastOrConvertExpression(valueParameter, fieldExpression.Type);
  253. var genericSetFieldMethodInfo = setFieldMethod.MakeGenericMethod(fieldExpression.Type);
  254. var setFieldMethodCallExpression = Expression.Call(
  255. null, genericSetFieldMethodInfo, fieldExpression, valueExpression);
  256. var setterFn = Expression.Lambda<PropertySetterDelegate>(
  257. setFieldMethodCallExpression, sourceParameter, valueParameter).Compile();
  258. return setterFn;
  259. }
  260. public override PropertyGetterDelegate GetFieldGetterFn(FieldInfo fieldInfo)
  261. {
  262. if (!SupportsExpression)
  263. return base.GetFieldGetterFn(fieldInfo);
  264. try
  265. {
  266. var fieldDeclaringType = fieldInfo.DeclaringType;
  267. var oInstanceParam = Expression.Parameter(typeof(object), "source");
  268. var instanceParam = this.GetCastOrConvertExpression(oInstanceParam, fieldDeclaringType);
  269. var exprCallFieldGetFn = Expression.Field(instanceParam, fieldInfo);
  270. //var oExprCallFieldGetFn = this.GetCastOrConvertExpression(exprCallFieldGetFn, typeof(object));
  271. var oExprCallFieldGetFn = Expression.Convert(exprCallFieldGetFn, typeof(object));
  272. var fieldGetterFn = Expression.Lambda<PropertyGetterDelegate>
  273. (
  274. oExprCallFieldGetFn,
  275. oInstanceParam
  276. )
  277. .Compile();
  278. return fieldGetterFn;
  279. }
  280. catch (Exception ex)
  281. {
  282. Tracer.Instance.WriteError(ex);
  283. throw;
  284. }
  285. }
  286. private Expression GetCastOrConvertExpression(Expression expression, Type targetType)
  287. {
  288. Expression result;
  289. var expressionType = expression.Type;
  290. if (targetType.IsAssignableFrom(expressionType))
  291. {
  292. result = expression;
  293. }
  294. else
  295. {
  296. // Check if we can use the as operator for casting or if we must use the convert method
  297. if (targetType.IsValueType && !targetType.IsNullableType())
  298. {
  299. result = Expression.Convert(expression, targetType);
  300. }
  301. else
  302. {
  303. result = Expression.TypeAs(expression, targetType);
  304. }
  305. }
  306. return result;
  307. }
  308. public override string ToXsdDateTimeString(DateTime dateTime)
  309. {
  310. return XmlConvert.ToString(dateTime.ToStableUniversalTime(), XmlDateTimeSerializationMode.Utc);
  311. }
  312. public override string ToLocalXsdDateTimeString(DateTime dateTime)
  313. {
  314. return XmlConvert.ToString(dateTime, XmlDateTimeSerializationMode.Local);
  315. }
  316. public override DateTime ParseXsdDateTime(string dateTimeStr)
  317. {
  318. return XmlConvert.ToDateTime(dateTimeStr, XmlDateTimeSerializationMode.Utc);
  319. }
  320. public override DateTime ParseXsdDateTimeAsUtc(string dateTimeStr)
  321. {
  322. return XmlConvert.ToDateTime(dateTimeStr, XmlDateTimeSerializationMode.Utc).Prepare(parsedAsUtc: true);
  323. }
  324. public override DateTime ToStableUniversalTime(DateTime dateTime)
  325. {
  326. // .Net 2.0 - 3.5 has an issue with DateTime.ToUniversalTime, but works ok with TimeZoneInfo.ConvertTimeToUtc.
  327. // .Net 4.0+ does this under the hood anyway.
  328. return TimeZoneInfo.ConvertTimeToUtc(dateTime);
  329. }
  330. public override ParseStringDelegate GetDictionaryParseMethod<TSerializer>(Type type)
  331. {
  332. if (type == typeof(Hashtable))
  333. {
  334. return SerializerUtils<TSerializer>.ParseHashtable;
  335. }
  336. return null;
  337. }
  338. public override ParseStringDelegate GetSpecializedCollectionParseMethod<TSerializer>(Type type)
  339. {
  340. if (type == typeof(StringCollection))
  341. {
  342. return SerializerUtils<TSerializer>.ParseStringCollection<TSerializer>;
  343. }
  344. return null;
  345. }
  346. public override ParseStringDelegate GetJsReaderParseMethod<TSerializer>(Type type)
  347. {
  348. #if !__IOS__
  349. if (type.AssignableFrom(typeof(System.Dynamic.IDynamicMetaObjectProvider)) ||
  350. type.HasInterface(typeof(System.Dynamic.IDynamicMetaObjectProvider)))
  351. {
  352. return DeserializeDynamic<TSerializer>.Parse;
  353. }
  354. #endif
  355. return null;
  356. }
  357. public override XmlSerializer NewXmlSerializer()
  358. {
  359. return new XmlSerializer();
  360. }
  361. public virtual void InitHttpWebRequest(HttpWebRequest httpReq,
  362. long? contentLength = null, bool allowAutoRedirect = true, bool keepAlive = true)
  363. {
  364. httpReq.UserAgent = Env.ServerUserAgent;
  365. httpReq.AllowAutoRedirect = allowAutoRedirect;
  366. httpReq.KeepAlive = keepAlive;
  367. if (contentLength != null)
  368. {
  369. httpReq.ContentLength = contentLength.Value;
  370. }
  371. }
  372. public override void CloseStream(Stream stream)
  373. {
  374. stream.Close();
  375. }
  376. public override LicenseKey VerifyLicenseKeyText(string licenseKeyText)
  377. {
  378. LicenseKey key;
  379. if (!licenseKeyText.VerifyLicenseKeyText(out key))
  380. throw new ArgumentException("licenseKeyText");
  381. return key;
  382. }
  383. public override void VerifyInAssembly(Type accessType, ICollection<string> assemblyNames)
  384. {
  385. if (!assemblyNames.Contains(accessType.Assembly.ManifestModule.Name)) //might get merged/mangled on alt platforms
  386. throw new LicenseException(LicenseUtils.ErrorMessages.UnauthorizedAccessRequest);
  387. }
  388. public override void BeginThreadAffinity()
  389. {
  390. Thread.BeginThreadAffinity();
  391. }
  392. public virtual void EndThreadAffinity()
  393. {
  394. Thread.EndThreadAffinity();
  395. }
  396. public override void Config(HttpWebRequest req,
  397. bool? allowAutoRedirect = null,
  398. TimeSpan? timeout = null,
  399. TimeSpan? readWriteTimeout = null,
  400. string userAgent = null,
  401. bool? preAuthenticate = null)
  402. {
  403. req.MaximumResponseHeadersLength = int.MaxValue; //throws "The message length limit was exceeded" exception
  404. if (allowAutoRedirect.HasValue) req.AllowAutoRedirect = allowAutoRedirect.Value;
  405. if (readWriteTimeout.HasValue) req.ReadWriteTimeout = (int)readWriteTimeout.Value.TotalMilliseconds;
  406. if (timeout.HasValue) req.Timeout = (int)timeout.Value.TotalMilliseconds;
  407. if (userAgent != null) req.UserAgent = userAgent;
  408. if (preAuthenticate.HasValue) req.PreAuthenticate = preAuthenticate.Value;
  409. }
  410. #if !__IOS__
  411. public virtual SetPropertyDelegate GetSetPropertyMethod(PropertyInfo propertyInfo)
  412. {
  413. return CreateIlPropertySetter(propertyInfo);
  414. }
  415. public virtual SetPropertyDelegate GetSetFieldMethod(FieldInfo fieldInfo)
  416. {
  417. return CreateIlFieldSetter(fieldInfo);
  418. }
  419. public override SetPropertyDelegate GetSetMethod(PropertyInfo propertyInfo, FieldInfo fieldInfo)
  420. {
  421. return propertyInfo.CanWrite
  422. ? CreateIlPropertySetter(propertyInfo)
  423. : CreateIlFieldSetter(fieldInfo);
  424. }
  425. public override Type UseType(Type type)
  426. {
  427. if (type.IsInterface || type.IsAbstract)
  428. {
  429. return DynamicProxy.GetInstanceFor(type).GetType();
  430. }
  431. return type;
  432. }
  433. public DataContractAttribute GetWeakDataContract(Type type)
  434. {
  435. return type.GetWeakDataContract();
  436. }
  437. public DataMemberAttribute GetWeakDataMember(PropertyInfo pi)
  438. {
  439. return pi.GetWeakDataMember();
  440. }
  441. public DataMemberAttribute GetWeakDataMember(FieldInfo pi)
  442. {
  443. return pi.GetWeakDataMember();
  444. }
  445. public static SetPropertyDelegate CreateIlPropertySetter(PropertyInfo propertyInfo)
  446. {
  447. var propSetMethod = propertyInfo.GetSetMethod(true);
  448. if (propSetMethod == null)
  449. return null;
  450. var setter = CreateDynamicSetMethod(propertyInfo);
  451. var generator = setter.GetILGenerator();
  452. generator.Emit(OpCodes.Ldarg_0);
  453. generator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
  454. generator.Emit(OpCodes.Ldarg_1);
  455. generator.Emit(propertyInfo.PropertyType.IsClass
  456. ? OpCodes.Castclass
  457. : OpCodes.Unbox_Any,
  458. propertyInfo.PropertyType);
  459. generator.EmitCall(OpCodes.Callvirt, propSetMethod, (Type[])null);
  460. generator.Emit(OpCodes.Ret);
  461. return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
  462. }
  463. public static SetPropertyDelegate CreateIlFieldSetter(FieldInfo fieldInfo)
  464. {
  465. var setter = CreateDynamicSetMethod(fieldInfo);
  466. var generator = setter.GetILGenerator();
  467. generator.Emit(OpCodes.Ldarg_0);
  468. generator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType);
  469. generator.Emit(OpCodes.Ldarg_1);
  470. generator.Emit(fieldInfo.FieldType.IsClass
  471. ? OpCodes.Castclass
  472. : OpCodes.Unbox_Any,
  473. fieldInfo.FieldType);
  474. generator.Emit(OpCodes.Stfld, fieldInfo);
  475. generator.Emit(OpCodes.Ret);
  476. return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
  477. }
  478. private static DynamicMethod CreateDynamicSetMethod(MemberInfo memberInfo)
  479. {
  480. var args = new[] { typeof(object), typeof(object) };
  481. var name = string.Format("_{0}{1}_", "Set", memberInfo.Name);
  482. var returnType = typeof(void);
  483. return !memberInfo.DeclaringType.IsInterface
  484. ? new DynamicMethod(name, returnType, args, memberInfo.DeclaringType, true)
  485. : new DynamicMethod(name, returnType, args, memberInfo.Module, true);
  486. }
  487. #endif
  488. }
  489. #if __IOS__
  490. [MonoTouch.Foundation.Preserve(AllMembers = true)]
  491. internal class Poco
  492. {
  493. public string Dummy { get; set; }
  494. }
  495. public class IosPclExport : Net40PclExport
  496. {
  497. public static new IosPclExport Provider = new IosPclExport();
  498. public IosPclExport()
  499. {
  500. PlatformName = "IOS";
  501. SupportsEmit = SupportsExpression = false;
  502. }
  503. public override void VerifyInAssembly(Type accessType, ICollection<string> assemblyNames)
  504. {
  505. }
  506. public new static void Configure()
  507. {
  508. Configure(Provider);
  509. }
  510. public override void ResetStream(Stream stream)
  511. {
  512. // MonoTouch throws NotSupportedException when setting System.Net.WebConnectionStream.Position
  513. // Not sure if the stream is used later though, so may have to copy to MemoryStream and
  514. // pass that around instead after this point?
  515. }
  516. /// <summary>
  517. /// Provide hint to IOS AOT compiler to pre-compile generic classes for all your DTOs.
  518. /// Just needs to be called once in a static constructor.
  519. /// </summary>
  520. [MonoTouch.Foundation.Preserve]
  521. public static void InitForAot()
  522. {
  523. }
  524. [MonoTouch.Foundation.Preserve]
  525. public override void RegisterForAot()
  526. {
  527. RegisterTypeForAot<Poco>();
  528. RegisterElement<Poco, string>();
  529. RegisterElement<Poco, bool>();
  530. RegisterElement<Poco, char>();
  531. RegisterElement<Poco, byte>();
  532. RegisterElement<Poco, sbyte>();
  533. RegisterElement<Poco, short>();
  534. RegisterElement<Poco, ushort>();
  535. RegisterElement<Poco, int>();
  536. RegisterElement<Poco, uint>();
  537. RegisterElement<Poco, long>();
  538. RegisterElement<Poco, ulong>();
  539. RegisterElement<Poco, float>();
  540. RegisterElement<Poco, double>();
  541. RegisterElement<Poco, decimal>();
  542. RegisterElement<Poco, bool?>();
  543. RegisterElement<Poco, char?>();
  544. RegisterElement<Poco, byte?>();
  545. RegisterElement<Poco, sbyte?>();
  546. RegisterElement<Poco, short?>();
  547. RegisterElement<Poco, ushort?>();
  548. RegisterElement<Poco, int?>();
  549. RegisterElement<Poco, uint?>();
  550. RegisterElement<Poco, long?>();
  551. RegisterElement<Poco, ulong?>();
  552. RegisterElement<Poco, float?>();
  553. RegisterElement<Poco, double?>();
  554. RegisterElement<Poco, decimal?>();
  555. //RegisterElement<Poco, JsonValue>();
  556. RegisterTypeForAot<DayOfWeek>(); // used by DateTime
  557. // register built in structs
  558. RegisterTypeForAot<Guid>();
  559. RegisterTypeForAot<TimeSpan>();
  560. RegisterTypeForAot<DateTime>();
  561. RegisterTypeForAot<DateTime?>();
  562. RegisterTypeForAot<TimeSpan?>();
  563. RegisterTypeForAot<Guid?>();
  564. }
  565. [MonoTouch.Foundation.Preserve]
  566. public static void RegisterTypeForAot<T>()
  567. {
  568. AotConfig.RegisterSerializers<T>();
  569. }
  570. [MonoTouch.Foundation.Preserve]
  571. public static void RegisterQueryStringWriter()
  572. {
  573. var i = 0;
  574. if (QueryStringWriter<Poco>.WriteFn() != null) i++;
  575. }
  576. [MonoTouch.Foundation.Preserve]
  577. public static int RegisterElement<T, TElement>()
  578. {
  579. var i = 0;
  580. i += AotConfig.RegisterSerializers<TElement>();
  581. AotConfig.RegisterElement<T, TElement, JsonTypeSerializer>();
  582. AotConfig.RegisterElement<T, TElement, Text.Jsv.JsvTypeSerializer>();
  583. return i;
  584. }
  585. ///<summary>
  586. /// Class contains Ahead-of-Time (AOT) explicit class declarations which is used only to workaround "-aot-only" exceptions occured on device only.
  587. /// </summary>
  588. [MonoTouch.Foundation.Preserve(AllMembers = true)]
  589. internal class AotConfig
  590. {
  591. internal static JsReader<JsonTypeSerializer> jsonReader;
  592. internal static JsWriter<JsonTypeSerializer> jsonWriter;
  593. internal static JsReader<Text.Jsv.JsvTypeSerializer> jsvReader;
  594. internal static JsWriter<Text.Jsv.JsvTypeSerializer> jsvWriter;
  595. internal static JsonTypeSerializer jsonSerializer;
  596. internal static Text.Jsv.JsvTypeSerializer jsvSerializer;
  597. static AotConfig()
  598. {
  599. jsonSerializer = new JsonTypeSerializer();
  600. jsvSerializer = new Text.Jsv.JsvTypeSerializer();
  601. jsonReader = new JsReader<JsonTypeSerializer>();
  602. jsonWriter = new JsWriter<JsonTypeSerializer>();
  603. jsvReader = new JsReader<Text.Jsv.JsvTypeSerializer>();
  604. jsvWriter = new JsWriter<Text.Jsv.JsvTypeSerializer>();
  605. }
  606. internal static int RegisterSerializers<T>()
  607. {
  608. var i = 0;
  609. i += Register<T, JsonTypeSerializer>();
  610. if (jsonSerializer.GetParseFn<T>() != null) i++;
  611. if (jsonSerializer.GetWriteFn<T>() != null) i++;
  612. if (jsonReader.GetParseFn<T>() != null) i++;
  613. if (jsonWriter.GetWriteFn<T>() != null) i++;
  614. i += Register<T, Text.Jsv.JsvTypeSerializer>();
  615. if (jsvSerializer.GetParseFn<T>() != null) i++;
  616. if (jsvSerializer.GetWriteFn<T>() != null) i++;
  617. if (jsvReader.GetParseFn<T>() != null) i++;
  618. if (jsvWriter.GetWriteFn<T>() != null) i++;
  619. //RegisterCsvSerializer<T>();
  620. RegisterQueryStringWriter();
  621. return i;
  622. }
  623. internal static void RegisterCsvSerializer<T>()
  624. {
  625. CsvSerializer<T>.WriteFn();
  626. CsvSerializer<T>.WriteObject(null, null);
  627. CsvWriter<T>.Write(null, default(IEnumerable<T>));
  628. CsvWriter<T>.WriteRow(null, default(T));
  629. }
  630. public static ParseStringDelegate GetParseFn(Type type)
  631. {
  632. var parseFn = JsonTypeSerializer.Instance.GetParseFn(type);
  633. return parseFn;
  634. }
  635. internal static int Register<T, TSerializer>() where TSerializer : ITypeSerializer
  636. {
  637. var i = 0;
  638. if (JsonWriter<T>.WriteFn() != null) i++;
  639. if (JsonWriter.Instance.GetWriteFn<T>() != null) i++;
  640. if (JsonReader.Instance.GetParseFn<T>() != null) i++;
  641. if (JsonReader<T>.Parse(null) != null) i++;
  642. if (JsonReader<T>.GetParseFn() != null) i++;
  643. //if (JsWriter.GetTypeSerializer<JsonTypeSerializer>().GetWriteFn<T>() != null) i++;
  644. if (new List<T>() != null) i++;
  645. if (new T[0] != null) i++;
  646. JsConfig<T>.ExcludeTypeInfo = false;
  647. if (JsConfig<T>.OnDeserializedFn != null) i++;
  648. if (JsConfig<T>.HasDeserializeFn) i++;
  649. if (JsConfig<T>.SerializeFn != null) i++;
  650. if (JsConfig<T>.DeSerializeFn != null) i++;
  651. //JsConfig<T>.SerializeFn = arg => "";
  652. //JsConfig<T>.DeSerializeFn = arg => default(T);
  653. if (TypeConfig<T>.Properties != null) i++;
  654. /*
  655. if (WriteType<T, TSerializer>.Write != null) i++;
  656. if (WriteType<object, TSerializer>.Write != null) i++;
  657. if (DeserializeBuiltin<T>.Parse != null) i++;
  658. if (DeserializeArray<T[], TSerializer>.Parse != null) i++;
  659. DeserializeType<TSerializer>.ExtractType(null);
  660. DeserializeArrayWithElements<T, TSerializer>.ParseGenericArray(null, null);
  661. DeserializeCollection<TSerializer>.ParseCollection<T>(null, null, null);
  662. DeserializeListWithElements<T, TSerializer>.ParseGenericList(null, null, null);
  663. SpecializedQueueElements<T>.ConvertToQueue(null);
  664. SpecializedQueueElements<T>.ConvertToStack(null);
  665. */
  666. WriteListsOfElements<T, TSerializer>.WriteList(null, null);
  667. WriteListsOfElements<T, TSerializer>.WriteIList(null, null);
  668. WriteListsOfElements<T, TSerializer>.WriteEnumerable(null, null);
  669. WriteListsOfElements<T, TSerializer>.WriteListValueType(null, null);
  670. WriteListsOfElements<T, TSerializer>.WriteIListValueType(null, null);
  671. WriteListsOfElements<T, TSerializer>.WriteGenericArrayValueType(null, null);
  672. WriteListsOfElements<T, TSerializer>.WriteArray(null, null);
  673. TranslateListWithElements<T>.LateBoundTranslateToGenericICollection(null, null);
  674. TranslateListWithConvertibleElements<T, T>.LateBoundTranslateToGenericICollection(null, null);
  675. QueryStringWriter<T>.WriteObject(null, null);
  676. return i;
  677. }
  678. internal static void RegisterElement<T, TElement, TSerializer>() where TSerializer : ITypeSerializer
  679. {
  680. DeserializeDictionary<TSerializer>.ParseDictionary<T, TElement>(null, null, null, null);
  681. DeserializeDictionary<TSerializer>.ParseDictionary<TElement, T>(null, null, null, null);
  682. ToStringDictionaryMethods<T, TElement, TSerializer>.WriteIDictionary(null, null, null, null);
  683. ToStringDictionaryMethods<TElement, T, TSerializer>.WriteIDictionary(null, null, null, null);
  684. // Include List deserialisations from the Register<> method above. This solves issue where List<Guid> properties on responses deserialise to null.
  685. // No idea why this is happening because there is no visible exception raised. Suspect IOS is swallowing an AOT exception somewhere.
  686. DeserializeArrayWithElements<TElement, TSerializer>.ParseGenericArray(null, null);
  687. DeserializeListWithElements<TElement, TSerializer>.ParseGenericList(null, null, null);
  688. // Cannot use the line below for some unknown reason - when trying to compile to run on device, mtouch bombs during native code compile.
  689. // Something about this line or its inner workings is offensive to mtouch. Luckily this was not needed for my List<Guide> issue.
  690. // DeserializeCollection<JsonTypeSerializer>.ParseCollection<TElement>(null, null, null);
  691. TranslateListWithElements<TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
  692. TranslateListWithConvertibleElements<TElement, TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
  693. }
  694. }
  695. }
  696. #endif
  697. #if ANDROID
  698. public class AndroidPclExport : Net40PclExport
  699. {
  700. public static new AndroidPclExport Provider = new AndroidPclExport();
  701. public AndroidPclExport()
  702. {
  703. PlatformName = "Android";
  704. }
  705. public override void VerifyInAssembly(Type accessType, ICollection<string> assemblyNames)
  706. {
  707. }
  708. public new static void Configure()
  709. {
  710. Configure(Provider);
  711. }
  712. }
  713. #endif
  714. #if !__IOS__
  715. public static class DynamicProxy
  716. {
  717. public static T GetInstanceFor<T>()
  718. {
  719. return (T)GetInstanceFor(typeof(T));
  720. }
  721. static readonly ModuleBuilder ModuleBuilder;
  722. static readonly AssemblyBuilder DynamicAssembly;
  723. public static object GetInstanceFor(Type targetType)
  724. {
  725. lock (DynamicAssembly)
  726. {
  727. var constructedType = DynamicAssembly.GetType(ProxyName(targetType)) ?? GetConstructedType(targetType);
  728. var instance = Activator.CreateInstance(constructedType);
  729. return instance;
  730. }
  731. }
  732. static string ProxyName(Type targetType)
  733. {
  734. return targetType.Name + "Proxy";
  735. }
  736. static DynamicProxy()
  737. {
  738. var assemblyName = new AssemblyName("DynImpl");
  739. DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
  740. ModuleBuilder = DynamicAssembly.DefineDynamicModule("DynImplModule");
  741. }
  742. static Type GetConstructedType(Type targetType)
  743. {
  744. var typeBuilder = ModuleBuilder.DefineType(targetType.Name + "Proxy", TypeAttributes.Public);
  745. var ctorBuilder = typeBuilder.DefineConstructor(
  746. MethodAttributes.Public,
  747. CallingConventions.Standard,
  748. new Type[] { });
  749. var ilGenerator = ctorBuilder.GetILGenerator();
  750. ilGenerator.Emit(OpCodes.Ret);
  751. IncludeType(targetType, typeBuilder);
  752. foreach (var face in targetType.GetInterfaces())
  753. IncludeType(face, typeBuilder);
  754. return typeBuilder.CreateType();
  755. }
  756. static void IncludeType(Type typeOfT, TypeBuilder typeBuilder)
  757. {
  758. var methodInfos = typeOfT.GetMethods();
  759. foreach (var methodInfo in methodInfos)
  760. {
  761. if (methodInfo.Name.StartsWith("set_", StringComparison.Ordinal)) continue; // we always add a set for a get.
  762. if (methodInfo.Name.StartsWith("get_", StringComparison.Ordinal))
  763. {
  764. BindProperty(typeBuilder, methodInfo);
  765. }
  766. else
  767. {
  768. BindMethod(typeBuilder, methodInfo);
  769. }
  770. }
  771. typeBuilder.AddInterfaceImplementation(typeOfT);
  772. }
  773. static void BindMethod(TypeBuilder typeBuilder, MethodInfo methodInfo)
  774. {
  775. var methodBuilder = typeBuilder.DefineMethod(
  776. methodInfo.Name,
  777. MethodAttributes.Public | MethodAttributes.Virtual,
  778. methodInfo.ReturnType,
  779. methodInfo.GetParameters().Select(p => p.GetType()).ToArray()
  780. );
  781. var methodILGen = methodBuilder.GetILGenerator();
  782. if (methodInfo.ReturnType == typeof(void))
  783. {
  784. methodILGen.Emit(OpCodes.Ret);
  785. }
  786. else
  787. {
  788. if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum)
  789. {
  790. MethodInfo getMethod = typeof(Activator).GetMethod("CreateInstance",
  791. new[] { typeof(Type) });
  792. LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType);
  793. methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType);
  794. methodILGen.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
  795. methodILGen.Emit(OpCodes.Callvirt, getMethod);
  796. methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType);
  797. }
  798. else
  799. {
  800. methodILGen.Emit(OpCodes.Ldnull);
  801. }
  802. methodILGen.Emit(OpCodes.Ret);
  803. }
  804. typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
  805. }
  806. public static void BindProperty(TypeBuilder typeBuilder, MethodInfo methodInfo)
  807. {
  808. // Backing Field
  809. string propertyName = methodInfo.Name.Replace("get_", "");
  810. Type propertyType = methodInfo.ReturnType;
  811. FieldBuilder backingField = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
  812. //Getter
  813. MethodBuilder backingGet = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public |
  814. MethodAttributes.SpecialName | MethodAttributes.Virtual |
  815. MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
  816. ILGenerator getIl = backingGet.GetILGenerator();
  817. getIl.Emit(OpCodes.Ldarg_0);
  818. getIl.Emit(OpCodes.Ldfld, backingField);
  819. getIl.Emit(OpCodes.Ret);
  820. //Setter
  821. MethodBuilder backingSet = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public |
  822. MethodAttributes.SpecialName | MethodAttributes.Virtual |
  823. MethodAttributes.HideBySig, null, new[] { propertyType });
  824. ILGenerator setIl = backingSet.GetILGenerator();
  825. setIl.Emit(OpCodes.Ldarg_0);
  826. setIl.Emit(OpCodes.Ldarg_1);
  827. setIl.Emit(OpCodes.Stfld, backingField);
  828. setIl.Emit(OpCodes.Ret);
  829. // Property
  830. PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
  831. propertyBuilder.SetGetMethod(backingGet);
  832. propertyBuilder.SetSetMethod(backingSet);
  833. }
  834. }
  835. #endif
  836. internal class SerializerUtils<TSerializer>
  837. where TSerializer : ITypeSerializer
  838. {
  839. private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
  840. private static int VerifyAndGetStartIndex(string value, Type createMapType)
  841. {
  842. var index = 0;
  843. if (!Serializer.EatMapStartChar(value, ref index))
  844. {
  845. //Don't throw ex because some KeyValueDataContractDeserializer don't have '{}'
  846. Tracer.Instance.WriteDebug("WARN: Map definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}",
  847. JsWriter.MapStartChar, createMapType != null ? createMapType.Name : "Dictionary<,>", value.Substring(0, value.Length < 50 ? value.Length : 50));
  848. }
  849. return index;
  850. }
  851. public static Hashtable ParseHashtable(string value)
  852. {
  853. var index = VerifyAndGetStartIndex(value, typeof(Hashtable));
  854. var result = new Hashtable();
  855. if (JsonTypeSerializer.IsEmptyMap(value, index)) return result;
  856. var valueLength = value.Length;
  857. while (index < valueLength)
  858. {
  859. var keyValue = Serializer.EatMapKey(value, ref index);
  860. Serializer.EatMapKeySeperator(value, ref index);
  861. var elementValue = Serializer.EatValue(value, ref index);
  862. if (keyValue == null) continue;
  863. var mapKey = keyValue;
  864. var mapValue = elementValue;
  865. result[mapKey] = mapValue;
  866. Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
  867. }
  868. return result;
  869. }
  870. public static StringCollection ParseStringCollection<TS>(string value) where TS : ITypeSerializer
  871. {
  872. if ((value = DeserializeListWithElements<TS>.StripList(value)) == null) return null;
  873. return value == String.Empty
  874. ? new StringCollection()
  875. : ToStringCollection(DeserializeListWithElements<TSerializer>.ParseStringList(value));
  876. }
  877. public static StringCollection ToStringCollection(List<string> items)
  878. {
  879. var to = new StringCollection();
  880. foreach (var item in items)
  881. {
  882. to.Add(item);
  883. }
  884. return to;
  885. }
  886. }
  887. public static class PclExportExt
  888. {
  889. public static string ToFormUrlEncoded(this NameValueCollection queryParams)
  890. {
  891. var sb = new System.Text.StringBuilder();
  892. foreach (string key in queryParams)
  893. {
  894. var values = queryParams.GetValues(key);
  895. if (values == null) continue;
  896. foreach (var value in values)
  897. {
  898. if (sb.Length > 0)
  899. sb.Append('&');
  900. sb.AppendFormat("{0}={1}", key.UrlEncode(), value.UrlEncode());
  901. }
  902. }
  903. return sb.ToString();
  904. }
  905. //HttpUtils
  906. public static WebResponse PostFileToUrl(this string url,
  907. FileInfo uploadFileInfo, string uploadFileMimeType,
  908. string accept = null,
  909. Action<HttpWebRequest> requestFilter = null)
  910. {
  911. var webReq = (HttpWebRequest)WebRequest.Create(url);
  912. using (var fileStream = uploadFileInfo.OpenRead())
  913. {
  914. var fileName = uploadFileInfo.Name;
  915. webReq.UploadFile(fileStream, fileName, uploadFileMimeType, accept: accept, requestFilter: requestFilter, method: "POST");
  916. }
  917. if (HttpUtils.ResultsFilter != null)
  918. return null;
  919. return webReq.GetResponse();
  920. }
  921. public static WebResponse PutFileToUrl(this string url,
  922. FileInfo uploadFileInfo, string uploadFileMimeType,
  923. string accept = null,
  924. Action<HttpWebRequest> requestFilter = null)
  925. {
  926. var webReq = (HttpWebRequest)WebRequest.Create(url);
  927. using (var fileStream = uploadFileInfo.OpenRead())
  928. {
  929. var fileName = uploadFileInfo.Name;
  930. webReq.UploadFile(fileStream, fileName, uploadFileMimeType, accept: accept, requestFilter: requestFilter, method: "PUT");
  931. }
  932. if (HttpUtils.ResultsFilter != null)
  933. return null;
  934. return webReq.GetResponse();
  935. }
  936. public static WebResponse UploadFile(this WebRequest webRequest,
  937. FileInfo uploadFileInfo, string uploadFileMimeType)
  938. {
  939. using (var fileStream = uploadFileInfo.OpenRead())
  940. {
  941. var fileName = uploadFileInfo.Name;
  942. webRequest.UploadFile(fileStream, fileName, uploadFileMimeType);
  943. }
  944. if (HttpUtils.ResultsFilter != null)
  945. return null;
  946. return webRequest.GetResponse();
  947. }
  948. //XmlSerializer
  949. public static void CompressToStream<TXmlDto>(TXmlDto from, Stream stream)
  950. {
  951. #if __IOS__ || ANDROID
  952. throw new NotImplementedException("Compression is not supported on this platform");
  953. #else
  954. using (var deflateStream = new System.IO.Compression.DeflateStream(stream, System.IO.Compression.CompressionMode.Compress))
  955. using (var xw = new XmlTextWriter(deflateStream, Encoding.UTF8))
  956. {
  957. var serializer = new DataContractSerializer(from.GetType());
  958. serializer.WriteObject(xw, from);
  959. xw.Flush();
  960. }
  961. #endif
  962. }
  963. public static byte[] Compress<TXmlDto>(TXmlDto from)
  964. {
  965. using (var ms = new MemoryStream())
  966. {
  967. CompressToStream(from, ms);
  968. return ms.ToArray();
  969. }
  970. }
  971. //License Utils
  972. public static bool VerifySignedHash(byte[] DataToVerify, byte[] SignedData, RSAParameters Key)
  973. {
  974. try
  975. {
  976. var RSAalg = new RSACryptoServiceProvider();
  977. RSAalg.ImportParameters(Key);
  978. return RSAalg.VerifySha1Data(DataToVerify, SignedData);
  979. }
  980. catch (CryptographicException e)
  981. {
  982. Console.WriteLine(e.Message);
  983. return false;
  984. }
  985. }
  986. public static bool VerifyLicenseKeyText(this string licenseKeyText, out LicenseKey key)
  987. {
  988. var publicRsaProvider = new RSACryptoServiceProvider();
  989. publicRsaProvider.FromXmlString(LicenseUtils.LicensePublicKey);
  990. var publicKeyParams = publicRsaProvider.ExportParameters(false);
  991. key = licenseKeyText.ToLicenseKey();
  992. var originalData = key.GetHashKeyToSign().ToUtf8Bytes();
  993. var signedData = Convert.FromBase64String(key.Hash);
  994. return VerifySignedHash(originalData, signedData, publicKeyParams);
  995. }
  996. public static bool VerifySha1Data(this RSACryptoServiceProvider RSAalg, byte[] unsignedData, byte[] encryptedData)
  997. {
  998. return RSAalg.VerifyData(unsignedData, new SHA1CryptoServiceProvider(), encryptedData);
  999. //SL5 || WP
  1000. //return RSAalg.VerifyData(unsignedData, encryptedData, new EMSAPKCS1v1_5_SHA1());
  1001. }
  1002. #if !__IOS__
  1003. //ReflectionExtensions
  1004. const string DataContract = "DataContractAttribute";
  1005. static readonly ConcurrentDictionary<Type, FastMember.TypeAccessor> typeAccessorMap
  1006. = new ConcurrentDictionary<Type, FastMember.TypeAccessor>();
  1007. public static DataContractAttribute GetWeakDataContract(this Type type)
  1008. {
  1009. var attr = type.AllAttributes().FirstOrDefault(x => x.GetType().Name == DataContract);
  1010. if (attr != null)
  1011. {
  1012. var attrType = attr.GetType();
  1013. FastMember.TypeAccessor accessor;
  1014. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1015. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1016. return new DataContractAttribute
  1017. {
  1018. Name = (string)accessor[attr, "Name"],
  1019. Namespace = (string)accessor[attr, "Namespace"],
  1020. };
  1021. }
  1022. return null;
  1023. }
  1024. public static DataMemberAttribute GetWeakDataMember(this PropertyInfo pi)
  1025. {
  1026. var attr = pi.AllAttributes().FirstOrDefault(x => x.GetType().Name == ReflectionExtensions.DataMember);
  1027. if (attr != null)
  1028. {
  1029. var attrType = attr.GetType();
  1030. FastMember.TypeAccessor accessor;
  1031. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1032. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1033. var newAttr = new DataMemberAttribute
  1034. {
  1035. Name = (string)accessor[attr, "Name"],
  1036. EmitDefaultValue = (bool)accessor[attr, "EmitDefaultValue"],
  1037. IsRequired = (bool)accessor[attr, "IsRequired"],
  1038. };
  1039. var order = (int)accessor[attr, "Order"];
  1040. if (order >= 0)
  1041. newAttr.Order = order; //Throws Exception if set to -1
  1042. return newAttr;
  1043. }
  1044. return null;
  1045. }
  1046. public static DataMemberAttribute GetWeakDataMember(this FieldInfo pi)
  1047. {
  1048. var attr = pi.AllAttributes().FirstOrDefault(x => x.GetType().Name == ReflectionExtensions.DataMember);
  1049. if (attr != null)
  1050. {
  1051. var attrType = attr.GetType();
  1052. FastMember.TypeAccessor accessor;
  1053. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1054. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1055. var newAttr = new DataMemberAttribute
  1056. {
  1057. Name = (string)acc

Large files files are truncated, but you can click here to view the full file