PageRenderTime 33ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ServiceStack.Pcl.Mac20/PclExport.Net40.cs

http://github.com/ServiceStack/ServiceStack
C# | 1783 lines | 1385 code | 262 blank | 136 comment | 179 complexity | 4fd8d9ddff734c85b7f2ebb023933527 MD5 | raw file
Possible License(s): BSD-3-Clause
  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.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Linq.Expressions;
  11. using System.Net;
  12. using System.Reflection;
  13. using System.Runtime.CompilerServices;
  14. using System.Runtime.Serialization;
  15. using System.Security.Cryptography;
  16. using System.Text;
  17. using System.Text.RegularExpressions;
  18. using System.Threading;
  19. using ServiceStack.Text;
  20. using ServiceStack.Text.Common;
  21. using ServiceStack.Text.Json;
  22. #if !__IOS__
  23. using System.Reflection.Emit;
  24. using FastMember = ServiceStack.Text.FastMember;
  25. #endif
  26. #if __UNIFIED__
  27. using Preserve = Foundation.PreserveAttribute;
  28. #elif __IOS__
  29. using Preserve = MonoTouch.Foundation.PreserveAttribute;
  30. #endif
  31. namespace ServiceStack
  32. {
  33. public class Net40PclExport : PclExport
  34. {
  35. public static Net40PclExport Provider = new Net40PclExport();
  36. public Net40PclExport()
  37. {
  38. this.SupportsEmit = SupportsExpression = true;
  39. this.DirSep = Path.DirectorySeparatorChar;
  40. this.AltDirSep = Path.DirectorySeparatorChar == '/' ? '\\' : '/';
  41. this.RegexOptions = RegexOptions.Compiled;
  42. #if DNXCORE50
  43. this.InvariantComparison = CultureInfo.InvariantCulture.CompareInfo.GetStringComparer();
  44. this.InvariantComparisonIgnoreCase = CultureInfo.InvariantCultureIgnoreCase.CompareInfo.GetStringComparer();
  45. #else
  46. this.InvariantComparison = StringComparison.InvariantCulture;
  47. this.InvariantComparisonIgnoreCase = StringComparison.InvariantCultureIgnoreCase;
  48. #endif
  49. this.InvariantComparer = StringComparer.InvariantCulture;
  50. this.InvariantComparerIgnoreCase = StringComparer.InvariantCultureIgnoreCase;
  51. this.PlatformName = Environment.OSVersion.Platform.ToString();
  52. }
  53. public static PclExport Configure()
  54. {
  55. Configure(Provider);
  56. return Provider;
  57. }
  58. public override string ReadAllText(string filePath)
  59. {
  60. return File.ReadAllText(filePath);
  61. }
  62. public override string ToTitleCase(string value)
  63. {
  64. return TextInfo.ToTitleCase(value).Replace("_", String.Empty);
  65. }
  66. public override string ToInvariantUpper(char value)
  67. {
  68. return value.ToString(CultureInfo.InvariantCulture).ToUpper();
  69. }
  70. public override bool IsAnonymousType(Type type)
  71. {
  72. return type.HasAttribute<CompilerGeneratedAttribute>()
  73. && type.IsGeneric() && type.Name.Contains("AnonymousType")
  74. && (type.Name.StartsWith("<>", StringComparison.Ordinal) || type.Name.StartsWith("VB$", StringComparison.Ordinal))
  75. && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
  76. }
  77. public override bool FileExists(string filePath)
  78. {
  79. return File.Exists(filePath);
  80. }
  81. public override bool DirectoryExists(string dirPath)
  82. {
  83. return Directory.Exists(dirPath);
  84. }
  85. public override void CreateDirectory(string dirPath)
  86. {
  87. Directory.CreateDirectory(dirPath);
  88. }
  89. public override string[] GetFileNames(string dirPath, string searchPattern = null)
  90. {
  91. if (!Directory.Exists(dirPath))
  92. return TypeConstants.EmptyStringArray;
  93. return searchPattern != null
  94. ? Directory.GetFiles(dirPath, searchPattern)
  95. : Directory.GetFiles(dirPath);
  96. }
  97. public override string[] GetDirectoryNames(string dirPath, string searchPattern = null)
  98. {
  99. if (!Directory.Exists(dirPath))
  100. return TypeConstants.EmptyStringArray;
  101. return searchPattern != null
  102. ? Directory.GetDirectories(dirPath, searchPattern)
  103. : Directory.GetDirectories(dirPath);
  104. }
  105. public const string AppSettingsKey = "servicestack:license";
  106. public const string EnvironmentKey = "SERVICESTACK_LICENSE";
  107. public override void RegisterLicenseFromConfig()
  108. {
  109. #if ANDROID
  110. #elif __IOS__
  111. #elif __MAC__
  112. #else
  113. //Automatically register license key stored in <appSettings/>
  114. var licenceKeyText = System.Configuration.ConfigurationManager.AppSettings[AppSettingsKey];
  115. if (!string.IsNullOrEmpty(licenceKeyText))
  116. {
  117. LicenseUtils.RegisterLicense(licenceKeyText);
  118. return;
  119. }
  120. //or SERVICESTACK_LICENSE Environment variable
  121. licenceKeyText = Environment.GetEnvironmentVariable(EnvironmentKey);
  122. if (!string.IsNullOrEmpty(licenceKeyText))
  123. {
  124. LicenseUtils.RegisterLicense(licenceKeyText);
  125. }
  126. #endif
  127. }
  128. public override string GetEnvironmentVariable(string name)
  129. {
  130. return Environment.GetEnvironmentVariable(name);
  131. }
  132. public override void WriteLine(string line)
  133. {
  134. Console.WriteLine(line);
  135. }
  136. public override void WriteLine(string format, params object[] args)
  137. {
  138. Console.WriteLine(format, args);
  139. }
  140. public override void AddCompression(WebRequest webReq)
  141. {
  142. var httpReq = (HttpWebRequest)webReq;
  143. httpReq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
  144. httpReq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
  145. }
  146. public override Stream GetRequestStream(WebRequest webRequest)
  147. {
  148. return webRequest.GetRequestStream();
  149. }
  150. public override WebResponse GetResponse(WebRequest webRequest)
  151. {
  152. return webRequest.GetResponse();
  153. }
  154. #if !LITE
  155. public override bool IsDebugBuild(Assembly assembly)
  156. {
  157. return assembly.AllAttributes()
  158. .OfType<System.Diagnostics.DebuggableAttribute>()
  159. .Select(attr => attr.IsJITTrackingEnabled)
  160. .FirstOrDefault();
  161. }
  162. #endif
  163. public override string MapAbsolutePath(string relativePath, string appendPartialPathModifier)
  164. {
  165. if (relativePath.StartsWith("~"))
  166. {
  167. var assemblyDirectoryPath = Path.GetDirectoryName(new Uri(typeof(PathUtils).Assembly.EscapedCodeBase).LocalPath);
  168. // Escape the assembly bin directory to the hostname directory
  169. var hostDirectoryPath = appendPartialPathModifier != null
  170. ? assemblyDirectoryPath + appendPartialPathModifier
  171. : assemblyDirectoryPath;
  172. return Path.GetFullPath(relativePath.Replace("~", hostDirectoryPath));
  173. }
  174. return relativePath;
  175. }
  176. public override Assembly LoadAssembly(string assemblyPath)
  177. {
  178. return Assembly.LoadFrom(assemblyPath);
  179. }
  180. public override void AddHeader(WebRequest webReq, string name, string value)
  181. {
  182. webReq.Headers.Add(name, value);
  183. }
  184. public override Assembly[] GetAllAssemblies()
  185. {
  186. return AppDomain.CurrentDomain.GetAssemblies();
  187. }
  188. public override Type FindType(string typeName, string assemblyName)
  189. {
  190. var binPath = AssemblyUtils.GetAssemblyBinPath(Assembly.GetExecutingAssembly());
  191. Assembly assembly = null;
  192. var assemblyDllPath = binPath + string.Format("{0}.{1}", assemblyName, "dll");
  193. if (File.Exists(assemblyDllPath))
  194. {
  195. assembly = AssemblyUtils.LoadAssembly(assemblyDllPath);
  196. }
  197. var assemblyExePath = binPath + string.Format("{0}.{1}", assemblyName, "exe");
  198. if (File.Exists(assemblyExePath))
  199. {
  200. assembly = AssemblyUtils.LoadAssembly(assemblyExePath);
  201. }
  202. return assembly != null ? assembly.GetType(typeName) : null;
  203. }
  204. public override string GetAssemblyCodeBase(Assembly assembly)
  205. {
  206. return assembly.CodeBase;
  207. }
  208. public override string GetAssemblyPath(Type source)
  209. {
  210. var assemblyUri = new Uri(source.Assembly.EscapedCodeBase);
  211. return assemblyUri.LocalPath;
  212. }
  213. public override string GetAsciiString(byte[] bytes, int index, int count)
  214. {
  215. return Encoding.ASCII.GetString(bytes, index, count);
  216. }
  217. public override byte[] GetAsciiBytes(string str)
  218. {
  219. return Encoding.ASCII.GetBytes(str);
  220. }
  221. public override bool InSameAssembly(Type t1, Type t2)
  222. {
  223. return t1.GetAssembly() == t2.GetAssembly();
  224. }
  225. public override Type GetGenericCollectionType(Type type)
  226. {
  227. return type.FindInterfaces((t, critera) =>
  228. t.IsGenericType
  229. && t.GetGenericTypeDefinition() == typeof(ICollection<>), null).FirstOrDefault();
  230. }
  231. public override PropertySetterDelegate GetPropertySetterFn(PropertyInfo propertyInfo)
  232. {
  233. var propertySetMethod = propertyInfo.SetMethod();
  234. if (propertySetMethod == null) return null;
  235. if (!SupportsExpression)
  236. {
  237. return (o, convertedValue) =>
  238. propertySetMethod.Invoke(o, new[] { convertedValue });
  239. }
  240. try
  241. {
  242. var instance = Expression.Parameter(typeof(object), "i");
  243. var argument = Expression.Parameter(typeof(object), "a");
  244. var instanceParam = Expression.Convert(instance, propertyInfo.ReflectedType());
  245. var valueParam = Expression.Convert(argument, propertyInfo.PropertyType);
  246. var setterCall = Expression.Call(instanceParam, propertySetMethod, valueParam);
  247. return Expression.Lambda<PropertySetterDelegate>(setterCall, instance, argument).Compile();
  248. }
  249. catch //fallback for Android
  250. {
  251. return (o, convertedValue) =>
  252. propertySetMethod.Invoke(o, new[] { convertedValue });
  253. }
  254. }
  255. public override PropertyGetterDelegate GetPropertyGetterFn(PropertyInfo propertyInfo)
  256. {
  257. if (!SupportsExpression)
  258. return base.GetPropertyGetterFn(propertyInfo);
  259. var getMethodInfo = propertyInfo.GetMethodInfo();
  260. if (getMethodInfo == null) return null;
  261. try
  262. {
  263. var oInstanceParam = Expression.Parameter(typeof(object), "oInstanceParam");
  264. var instanceParam = Expression.Convert(oInstanceParam, propertyInfo.ReflectedType); //propertyInfo.DeclaringType doesn't work on Proxy types
  265. var exprCallPropertyGetFn = Expression.Call(instanceParam, getMethodInfo);
  266. var oExprCallPropertyGetFn = Expression.Convert(exprCallPropertyGetFn, typeof(object));
  267. var propertyGetFn = Expression.Lambda<PropertyGetterDelegate>
  268. (
  269. oExprCallPropertyGetFn,
  270. oInstanceParam
  271. ).Compile();
  272. return propertyGetFn;
  273. }
  274. catch (Exception ex)
  275. {
  276. Tracer.Instance.WriteError(ex);
  277. throw;
  278. }
  279. }
  280. private static readonly MethodInfo setFieldMethod =
  281. typeof(Net40PclExport).GetStaticMethod("SetField");
  282. internal static void SetField<TValue>(ref TValue field, TValue newValue)
  283. {
  284. field = newValue;
  285. }
  286. public override PropertySetterDelegate GetFieldSetterFn(FieldInfo fieldInfo)
  287. {
  288. if (!SupportsExpression)
  289. return base.GetFieldSetterFn(fieldInfo);
  290. var fieldDeclaringType = fieldInfo.DeclaringType;
  291. var sourceParameter = Expression.Parameter(typeof(object), "source");
  292. var valueParameter = Expression.Parameter(typeof(object), "value");
  293. var sourceExpression = this.GetCastOrConvertExpression(sourceParameter, fieldDeclaringType);
  294. var fieldExpression = Expression.Field(sourceExpression, fieldInfo);
  295. var valueExpression = this.GetCastOrConvertExpression(valueParameter, fieldExpression.Type);
  296. var genericSetFieldMethodInfo = setFieldMethod.MakeGenericMethod(fieldExpression.Type);
  297. var setFieldMethodCallExpression = Expression.Call(
  298. null, genericSetFieldMethodInfo, fieldExpression, valueExpression);
  299. var setterFn = Expression.Lambda<PropertySetterDelegate>(
  300. setFieldMethodCallExpression, sourceParameter, valueParameter).Compile();
  301. return setterFn;
  302. }
  303. public override PropertyGetterDelegate GetFieldGetterFn(FieldInfo fieldInfo)
  304. {
  305. if (!SupportsExpression)
  306. return base.GetFieldGetterFn(fieldInfo);
  307. try
  308. {
  309. var fieldDeclaringType = fieldInfo.DeclaringType;
  310. var oInstanceParam = Expression.Parameter(typeof(object), "source");
  311. var instanceParam = this.GetCastOrConvertExpression(oInstanceParam, fieldDeclaringType);
  312. var exprCallFieldGetFn = Expression.Field(instanceParam, fieldInfo);
  313. //var oExprCallFieldGetFn = this.GetCastOrConvertExpression(exprCallFieldGetFn, typeof(object));
  314. var oExprCallFieldGetFn = Expression.Convert(exprCallFieldGetFn, typeof(object));
  315. var fieldGetterFn = Expression.Lambda<PropertyGetterDelegate>
  316. (
  317. oExprCallFieldGetFn,
  318. oInstanceParam
  319. )
  320. .Compile();
  321. return fieldGetterFn;
  322. }
  323. catch (Exception ex)
  324. {
  325. Tracer.Instance.WriteError(ex);
  326. throw;
  327. }
  328. }
  329. private Expression GetCastOrConvertExpression(Expression expression, Type targetType)
  330. {
  331. Expression result;
  332. var expressionType = expression.Type;
  333. if (targetType.IsAssignableFrom(expressionType))
  334. {
  335. result = expression;
  336. }
  337. else
  338. {
  339. // Check if we can use the as operator for casting or if we must use the convert method
  340. if (targetType.IsValueType && !targetType.IsNullableType())
  341. {
  342. result = Expression.Convert(expression, targetType);
  343. }
  344. else
  345. {
  346. result = Expression.TypeAs(expression, targetType);
  347. }
  348. }
  349. return result;
  350. }
  351. public override string ToXsdDateTimeString(DateTime dateTime)
  352. {
  353. #if !LITE
  354. return System.Xml.XmlConvert.ToString(dateTime.ToStableUniversalTime(), System.Xml.XmlDateTimeSerializationMode.Utc);
  355. #else
  356. return dateTime.ToStableUniversalTime().ToString(DateTimeSerializer.XsdDateTimeFormat);
  357. #endif
  358. }
  359. public override string ToLocalXsdDateTimeString(DateTime dateTime)
  360. {
  361. #if !LITE
  362. return System.Xml.XmlConvert.ToString(dateTime, System.Xml.XmlDateTimeSerializationMode.Local);
  363. #else
  364. return dateTime.ToString(DateTimeSerializer.XsdDateTimeFormat);
  365. #endif
  366. }
  367. public override DateTime ParseXsdDateTime(string dateTimeStr)
  368. {
  369. #if !LITE
  370. return System.Xml.XmlConvert.ToDateTime(dateTimeStr, System.Xml.XmlDateTimeSerializationMode.Utc);
  371. #else
  372. return DateTime.ParseExact(dateTimeStr, DateTimeSerializer.XsdDateTimeFormat, CultureInfo.InvariantCulture);
  373. #endif
  374. }
  375. #if !LITE
  376. public override DateTime ParseXsdDateTimeAsUtc(string dateTimeStr)
  377. {
  378. return System.Xml.XmlConvert.ToDateTime(dateTimeStr, System.Xml.XmlDateTimeSerializationMode.Utc).Prepare(parsedAsUtc: true);
  379. }
  380. #endif
  381. public override DateTime ToStableUniversalTime(DateTime dateTime)
  382. {
  383. // .Net 2.0 - 3.5 has an issue with DateTime.ToUniversalTime, but works ok with TimeZoneInfo.ConvertTimeToUtc.
  384. // .Net 4.0+ does this under the hood anyway.
  385. return TimeZoneInfo.ConvertTimeToUtc(dateTime);
  386. }
  387. public override ParseStringDelegate GetDictionaryParseMethod<TSerializer>(Type type)
  388. {
  389. if (type == typeof(Hashtable))
  390. {
  391. return SerializerUtils<TSerializer>.ParseHashtable;
  392. }
  393. return null;
  394. }
  395. public override ParseStringDelegate GetSpecializedCollectionParseMethod<TSerializer>(Type type)
  396. {
  397. if (type == typeof(StringCollection))
  398. {
  399. return SerializerUtils<TSerializer>.ParseStringCollection<TSerializer>;
  400. }
  401. return null;
  402. }
  403. public override ParseStringDelegate GetJsReaderParseMethod<TSerializer>(Type type)
  404. {
  405. #if !(__IOS__ || LITE)
  406. if (type.AssignableFrom(typeof(System.Dynamic.IDynamicMetaObjectProvider)) ||
  407. type.HasInterface(typeof(System.Dynamic.IDynamicMetaObjectProvider)))
  408. {
  409. return DeserializeDynamic<TSerializer>.Parse;
  410. }
  411. #endif
  412. return null;
  413. }
  414. public override void InitHttpWebRequest(HttpWebRequest httpReq,
  415. long? contentLength = null, bool allowAutoRedirect = true, bool keepAlive = true)
  416. {
  417. httpReq.UserAgent = Env.ServerUserAgent;
  418. httpReq.AllowAutoRedirect = allowAutoRedirect;
  419. httpReq.KeepAlive = keepAlive;
  420. if (contentLength != null)
  421. {
  422. httpReq.ContentLength = contentLength.Value;
  423. }
  424. }
  425. public override void CloseStream(Stream stream)
  426. {
  427. stream.Close();
  428. }
  429. public override LicenseKey VerifyLicenseKeyText(string licenseKeyText)
  430. {
  431. LicenseKey key;
  432. if (!licenseKeyText.VerifyLicenseKeyText(out key))
  433. throw new ArgumentException("licenseKeyText");
  434. return key;
  435. }
  436. public override void BeginThreadAffinity()
  437. {
  438. Thread.BeginThreadAffinity();
  439. }
  440. public override void EndThreadAffinity()
  441. {
  442. Thread.EndThreadAffinity();
  443. }
  444. public override void Config(HttpWebRequest req,
  445. bool? allowAutoRedirect = null,
  446. TimeSpan? timeout = null,
  447. TimeSpan? readWriteTimeout = null,
  448. string userAgent = null,
  449. bool? preAuthenticate = null)
  450. {
  451. req.MaximumResponseHeadersLength = int.MaxValue; //throws "The message length limit was exceeded" exception
  452. if (allowAutoRedirect.HasValue) req.AllowAutoRedirect = allowAutoRedirect.Value;
  453. if (readWriteTimeout.HasValue) req.ReadWriteTimeout = (int)readWriteTimeout.Value.TotalMilliseconds;
  454. if (timeout.HasValue) req.Timeout = (int)timeout.Value.TotalMilliseconds;
  455. if (userAgent != null) req.UserAgent = userAgent;
  456. if (preAuthenticate.HasValue) req.PreAuthenticate = preAuthenticate.Value;
  457. }
  458. public override string GetStackTrace()
  459. {
  460. return Environment.StackTrace;
  461. }
  462. #if !__IOS__
  463. public override SetPropertyDelegate GetSetPropertyMethod(PropertyInfo propertyInfo)
  464. {
  465. return CreateIlPropertySetter(propertyInfo);
  466. }
  467. public override SetPropertyDelegate GetSetFieldMethod(FieldInfo fieldInfo)
  468. {
  469. return CreateIlFieldSetter(fieldInfo);
  470. }
  471. public override SetPropertyDelegate GetSetMethod(PropertyInfo propertyInfo, FieldInfo fieldInfo)
  472. {
  473. return propertyInfo.CanWrite
  474. ? CreateIlPropertySetter(propertyInfo)
  475. : CreateIlFieldSetter(fieldInfo);
  476. }
  477. public override Type UseType(Type type)
  478. {
  479. if (type.IsInterface || type.IsAbstract)
  480. {
  481. return DynamicProxy.GetInstanceFor(type).GetType();
  482. }
  483. return type;
  484. }
  485. public override DataContractAttribute GetWeakDataContract(Type type)
  486. {
  487. return type.GetWeakDataContract();
  488. }
  489. public override DataMemberAttribute GetWeakDataMember(PropertyInfo pi)
  490. {
  491. return pi.GetWeakDataMember();
  492. }
  493. public override DataMemberAttribute GetWeakDataMember(FieldInfo pi)
  494. {
  495. return pi.GetWeakDataMember();
  496. }
  497. public static SetPropertyDelegate CreateIlPropertySetter(PropertyInfo propertyInfo)
  498. {
  499. var propSetMethod = propertyInfo.GetSetMethod(true);
  500. if (propSetMethod == null)
  501. return null;
  502. var setter = CreateDynamicSetMethod(propertyInfo);
  503. var generator = setter.GetILGenerator();
  504. generator.Emit(OpCodes.Ldarg_0);
  505. generator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
  506. generator.Emit(OpCodes.Ldarg_1);
  507. generator.Emit(propertyInfo.PropertyType.IsClass
  508. ? OpCodes.Castclass
  509. : OpCodes.Unbox_Any,
  510. propertyInfo.PropertyType);
  511. generator.EmitCall(OpCodes.Callvirt, propSetMethod, (Type[])null);
  512. generator.Emit(OpCodes.Ret);
  513. return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
  514. }
  515. public static SetPropertyDelegate CreateIlFieldSetter(FieldInfo fieldInfo)
  516. {
  517. var setter = CreateDynamicSetMethod(fieldInfo);
  518. var generator = setter.GetILGenerator();
  519. generator.Emit(OpCodes.Ldarg_0);
  520. generator.Emit(OpCodes.Castclass, fieldInfo.DeclaringType);
  521. generator.Emit(OpCodes.Ldarg_1);
  522. generator.Emit(fieldInfo.FieldType.IsClass
  523. ? OpCodes.Castclass
  524. : OpCodes.Unbox_Any,
  525. fieldInfo.FieldType);
  526. generator.Emit(OpCodes.Stfld, fieldInfo);
  527. generator.Emit(OpCodes.Ret);
  528. return (SetPropertyDelegate)setter.CreateDelegate(typeof(SetPropertyDelegate));
  529. }
  530. private static DynamicMethod CreateDynamicSetMethod(MemberInfo memberInfo)
  531. {
  532. var args = new[] { typeof(object), typeof(object) };
  533. var name = string.Format("_{0}{1}_", "Set", memberInfo.Name);
  534. var returnType = typeof(void);
  535. return !memberInfo.DeclaringType.IsInterface
  536. ? new DynamicMethod(name, returnType, args, memberInfo.DeclaringType, true)
  537. : new DynamicMethod(name, returnType, args, memberInfo.Module, true);
  538. }
  539. #endif
  540. }
  541. #if __MAC__
  542. public class MacPclExport : IosPclExport
  543. {
  544. public static new MacPclExport Provider = new MacPclExport();
  545. public MacPclExport()
  546. {
  547. PlatformName = "MAC";
  548. SupportsEmit = SupportsExpression = true;
  549. }
  550. public new static void Configure()
  551. {
  552. Configure(Provider);
  553. }
  554. }
  555. #endif
  556. #if NET45 || NETFX_CORE
  557. public class Net45PclExport : Net40PclExport
  558. {
  559. public static new Net45PclExport Provider = new IosPclExport();
  560. public Net45PclExport()
  561. {
  562. PlatformName = "NET45 " + Environment.OSVersion.Platform.ToString();
  563. }
  564. public new static void Configure()
  565. {
  566. Configure(Provider);
  567. }
  568. public override Task WriteAndFlushAsync(Stream stream, byte[] bytes)
  569. {
  570. return stream.WriteAsync(bytes, 0, bytes.Length)
  571. .ContinueWith(t => stream.FlushAsync());
  572. }
  573. }
  574. #endif
  575. #if __IOS__ || __MAC__
  576. [Preserve(AllMembers = true)]
  577. internal class Poco
  578. {
  579. public string Dummy { get; set; }
  580. }
  581. public class IosPclExport : Net40PclExport
  582. {
  583. public static new IosPclExport Provider = new IosPclExport();
  584. public IosPclExport()
  585. {
  586. PlatformName = "IOS";
  587. SupportsEmit = SupportsExpression = false;
  588. }
  589. public new static void Configure()
  590. {
  591. Configure(Provider);
  592. }
  593. public override void ResetStream(Stream stream)
  594. {
  595. // MonoTouch throws NotSupportedException when setting System.Net.WebConnectionStream.Position
  596. // Not sure if the stream is used later though, so may have to copy to MemoryStream and
  597. // pass that around instead after this point?
  598. }
  599. /// <summary>
  600. /// Provide hint to IOS AOT compiler to pre-compile generic classes for all your DTOs.
  601. /// Just needs to be called once in a static constructor.
  602. /// </summary>
  603. [Preserve]
  604. public static void InitForAot()
  605. {
  606. }
  607. [Preserve]
  608. public override void RegisterForAot()
  609. {
  610. RegisterTypeForAot<Poco>();
  611. RegisterElement<Poco, string>();
  612. RegisterElement<Poco, bool>();
  613. RegisterElement<Poco, char>();
  614. RegisterElement<Poco, byte>();
  615. RegisterElement<Poco, sbyte>();
  616. RegisterElement<Poco, short>();
  617. RegisterElement<Poco, ushort>();
  618. RegisterElement<Poco, int>();
  619. RegisterElement<Poco, uint>();
  620. RegisterElement<Poco, long>();
  621. RegisterElement<Poco, ulong>();
  622. RegisterElement<Poco, float>();
  623. RegisterElement<Poco, double>();
  624. RegisterElement<Poco, decimal>();
  625. RegisterElement<Poco, bool?>();
  626. RegisterElement<Poco, char?>();
  627. RegisterElement<Poco, byte?>();
  628. RegisterElement<Poco, sbyte?>();
  629. RegisterElement<Poco, short?>();
  630. RegisterElement<Poco, ushort?>();
  631. RegisterElement<Poco, int?>();
  632. RegisterElement<Poco, uint?>();
  633. RegisterElement<Poco, long?>();
  634. RegisterElement<Poco, ulong?>();
  635. RegisterElement<Poco, float?>();
  636. RegisterElement<Poco, double?>();
  637. RegisterElement<Poco, decimal?>();
  638. //RegisterElement<Poco, JsonValue>();
  639. RegisterTypeForAot<DayOfWeek>(); // used by DateTime
  640. // register built in structs
  641. RegisterTypeForAot<Guid>();
  642. RegisterTypeForAot<TimeSpan>();
  643. RegisterTypeForAot<DateTime>();
  644. RegisterTypeForAot<DateTimeOffset>();
  645. RegisterTypeForAot<Guid?>();
  646. RegisterTypeForAot<TimeSpan?>();
  647. RegisterTypeForAot<DateTime?>();
  648. RegisterTypeForAot<DateTimeOffset?>();
  649. }
  650. [Preserve]
  651. public static void RegisterTypeForAot<T>()
  652. {
  653. AotConfig.RegisterSerializers<T>();
  654. }
  655. [Preserve]
  656. public static void RegisterQueryStringWriter()
  657. {
  658. var i = 0;
  659. if (QueryStringWriter<Poco>.WriteFn() != null) i++;
  660. }
  661. [Preserve]
  662. public static int RegisterElement<T, TElement>()
  663. {
  664. var i = 0;
  665. i += AotConfig.RegisterSerializers<TElement>();
  666. AotConfig.RegisterElement<T, TElement, JsonTypeSerializer>();
  667. AotConfig.RegisterElement<T, TElement, Text.Jsv.JsvTypeSerializer>();
  668. return i;
  669. }
  670. ///<summary>
  671. /// Class contains Ahead-of-Time (AOT) explicit class declarations which is used only to workaround "-aot-only" exceptions occured on device only.
  672. /// </summary>
  673. [Preserve(AllMembers = true)]
  674. internal class AotConfig
  675. {
  676. internal static JsReader<JsonTypeSerializer> jsonReader;
  677. internal static JsWriter<JsonTypeSerializer> jsonWriter;
  678. internal static JsReader<Text.Jsv.JsvTypeSerializer> jsvReader;
  679. internal static JsWriter<Text.Jsv.JsvTypeSerializer> jsvWriter;
  680. internal static JsonTypeSerializer jsonSerializer;
  681. internal static Text.Jsv.JsvTypeSerializer jsvSerializer;
  682. static AotConfig()
  683. {
  684. jsonSerializer = new JsonTypeSerializer();
  685. jsvSerializer = new Text.Jsv.JsvTypeSerializer();
  686. jsonReader = new JsReader<JsonTypeSerializer>();
  687. jsonWriter = new JsWriter<JsonTypeSerializer>();
  688. jsvReader = new JsReader<Text.Jsv.JsvTypeSerializer>();
  689. jsvWriter = new JsWriter<Text.Jsv.JsvTypeSerializer>();
  690. }
  691. internal static int RegisterSerializers<T>()
  692. {
  693. var i = 0;
  694. i += Register<T, JsonTypeSerializer>();
  695. if (jsonSerializer.GetParseFn<T>() != null) i++;
  696. if (jsonSerializer.GetWriteFn<T>() != null) i++;
  697. if (jsonReader.GetParseFn<T>() != null) i++;
  698. if (jsonWriter.GetWriteFn<T>() != null) i++;
  699. i += Register<T, Text.Jsv.JsvTypeSerializer>();
  700. if (jsvSerializer.GetParseFn<T>() != null) i++;
  701. if (jsvSerializer.GetWriteFn<T>() != null) i++;
  702. if (jsvReader.GetParseFn<T>() != null) i++;
  703. if (jsvWriter.GetWriteFn<T>() != null) i++;
  704. //RegisterCsvSerializer<T>();
  705. RegisterQueryStringWriter();
  706. return i;
  707. }
  708. internal static void RegisterCsvSerializer<T>()
  709. {
  710. CsvSerializer<T>.WriteFn();
  711. CsvSerializer<T>.WriteObject(null, null);
  712. CsvWriter<T>.Write(null, default(IEnumerable<T>));
  713. CsvWriter<T>.WriteRow(null, default(T));
  714. }
  715. public static ParseStringDelegate GetParseFn(Type type)
  716. {
  717. var parseFn = JsonTypeSerializer.Instance.GetParseFn(type);
  718. return parseFn;
  719. }
  720. internal static int Register<T, TSerializer>() where TSerializer : ITypeSerializer
  721. {
  722. var i = 0;
  723. if (JsonWriter<T>.WriteFn() != null) i++;
  724. if (JsonWriter.Instance.GetWriteFn<T>() != null) i++;
  725. if (JsonReader.Instance.GetParseFn<T>() != null) i++;
  726. if (JsonReader<T>.Parse(null) != null) i++;
  727. if (JsonReader<T>.GetParseFn() != null) i++;
  728. //if (JsWriter.GetTypeSerializer<JsonTypeSerializer>().GetWriteFn<T>() != null) i++;
  729. if (new List<T>() != null) i++;
  730. if (new T[0] != null) i++;
  731. JsConfig<T>.ExcludeTypeInfo = false;
  732. if (JsConfig<T>.OnDeserializedFn != null) i++;
  733. if (JsConfig<T>.HasDeserializeFn) i++;
  734. if (JsConfig<T>.SerializeFn != null) i++;
  735. if (JsConfig<T>.DeSerializeFn != null) i++;
  736. //JsConfig<T>.SerializeFn = arg => "";
  737. //JsConfig<T>.DeSerializeFn = arg => default(T);
  738. if (TypeConfig<T>.Properties != null) i++;
  739. /*
  740. if (WriteType<T, TSerializer>.Write != null) i++;
  741. if (WriteType<object, TSerializer>.Write != null) i++;
  742. if (DeserializeBuiltin<T>.Parse != null) i++;
  743. if (DeserializeArray<T[], TSerializer>.Parse != null) i++;
  744. DeserializeType<TSerializer>.ExtractType(null);
  745. DeserializeArrayWithElements<T, TSerializer>.ParseGenericArray(null, null);
  746. DeserializeCollection<TSerializer>.ParseCollection<T>(null, null, null);
  747. DeserializeListWithElements<T, TSerializer>.ParseGenericList(null, null, null);
  748. SpecializedQueueElements<T>.ConvertToQueue(null);
  749. SpecializedQueueElements<T>.ConvertToStack(null);
  750. */
  751. WriteListsOfElements<T, TSerializer>.WriteList(null, null);
  752. WriteListsOfElements<T, TSerializer>.WriteIList(null, null);
  753. WriteListsOfElements<T, TSerializer>.WriteEnumerable(null, null);
  754. WriteListsOfElements<T, TSerializer>.WriteListValueType(null, null);
  755. WriteListsOfElements<T, TSerializer>.WriteIListValueType(null, null);
  756. WriteListsOfElements<T, TSerializer>.WriteGenericArrayValueType(null, null);
  757. WriteListsOfElements<T, TSerializer>.WriteArray(null, null);
  758. TranslateListWithElements<T>.LateBoundTranslateToGenericICollection(null, null);
  759. TranslateListWithConvertibleElements<T, T>.LateBoundTranslateToGenericICollection(null, null);
  760. QueryStringWriter<T>.WriteObject(null, null);
  761. return i;
  762. }
  763. internal static void RegisterElement<T, TElement, TSerializer>() where TSerializer : ITypeSerializer
  764. {
  765. DeserializeDictionary<TSerializer>.ParseDictionary<T, TElement>(null, null, null, null);
  766. DeserializeDictionary<TSerializer>.ParseDictionary<TElement, T>(null, null, null, null);
  767. ToStringDictionaryMethods<T, TElement, TSerializer>.WriteIDictionary(null, null, null, null);
  768. ToStringDictionaryMethods<TElement, T, TSerializer>.WriteIDictionary(null, null, null, null);
  769. // Include List deserialisations from the Register<> method above. This solves issue where List<Guid> properties on responses deserialise to null.
  770. // No idea why this is happening because there is no visible exception raised. Suspect IOS is swallowing an AOT exception somewhere.
  771. DeserializeArrayWithElements<TElement, TSerializer>.ParseGenericArray(null, null);
  772. DeserializeListWithElements<TElement, TSerializer>.ParseGenericList(null, null, null);
  773. // Cannot use the line below for some unknown reason - when trying to compile to run on device, mtouch bombs during native code compile.
  774. // Something about this line or its inner workings is offensive to mtouch. Luckily this was not needed for my List<Guide> issue.
  775. // DeserializeCollection<JsonTypeSerializer>.ParseCollection<TElement>(null, null, null);
  776. TranslateListWithElements<TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
  777. TranslateListWithConvertibleElements<TElement, TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
  778. }
  779. }
  780. }
  781. #endif
  782. #if ANDROID
  783. public class AndroidPclExport : Net40PclExport
  784. {
  785. public static new AndroidPclExport Provider = new AndroidPclExport();
  786. public AndroidPclExport()
  787. {
  788. PlatformName = "Android";
  789. }
  790. public new static void Configure()
  791. {
  792. Configure(Provider);
  793. }
  794. }
  795. #endif
  796. #if !__IOS__
  797. public static class DynamicProxy
  798. {
  799. public static T GetInstanceFor<T>()
  800. {
  801. return (T)GetInstanceFor(typeof(T));
  802. }
  803. static readonly ModuleBuilder ModuleBuilder;
  804. static readonly AssemblyBuilder DynamicAssembly;
  805. public static object GetInstanceFor(Type targetType)
  806. {
  807. lock (DynamicAssembly)
  808. {
  809. var constructedType = DynamicAssembly.GetType(ProxyName(targetType)) ?? GetConstructedType(targetType);
  810. var instance = Activator.CreateInstance(constructedType);
  811. return instance;
  812. }
  813. }
  814. static string ProxyName(Type targetType)
  815. {
  816. return targetType.Name + "Proxy";
  817. }
  818. static DynamicProxy()
  819. {
  820. var assemblyName = new AssemblyName("DynImpl");
  821. DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
  822. ModuleBuilder = DynamicAssembly.DefineDynamicModule("DynImplModule");
  823. }
  824. static Type GetConstructedType(Type targetType)
  825. {
  826. var typeBuilder = ModuleBuilder.DefineType(targetType.Name + "Proxy", TypeAttributes.Public);
  827. var ctorBuilder = typeBuilder.DefineConstructor(
  828. MethodAttributes.Public,
  829. CallingConventions.Standard,
  830. new Type[] { });
  831. var ilGenerator = ctorBuilder.GetILGenerator();
  832. ilGenerator.Emit(OpCodes.Ret);
  833. IncludeType(targetType, typeBuilder);
  834. foreach (var face in targetType.GetInterfaces())
  835. IncludeType(face, typeBuilder);
  836. return typeBuilder.CreateType();
  837. }
  838. static void IncludeType(Type typeOfT, TypeBuilder typeBuilder)
  839. {
  840. var methodInfos = typeOfT.GetMethods();
  841. foreach (var methodInfo in methodInfos)
  842. {
  843. if (methodInfo.Name.StartsWith("set_", StringComparison.Ordinal)) continue; // we always add a set for a get.
  844. if (methodInfo.Name.StartsWith("get_", StringComparison.Ordinal))
  845. {
  846. BindProperty(typeBuilder, methodInfo);
  847. }
  848. else
  849. {
  850. BindMethod(typeBuilder, methodInfo);
  851. }
  852. }
  853. typeBuilder.AddInterfaceImplementation(typeOfT);
  854. }
  855. static void BindMethod(TypeBuilder typeBuilder, MethodInfo methodInfo)
  856. {
  857. var methodBuilder = typeBuilder.DefineMethod(
  858. methodInfo.Name,
  859. MethodAttributes.Public | MethodAttributes.Virtual,
  860. methodInfo.ReturnType,
  861. methodInfo.GetParameters().Select(p => p.GetType()).ToArray()
  862. );
  863. var methodILGen = methodBuilder.GetILGenerator();
  864. if (methodInfo.ReturnType == typeof(void))
  865. {
  866. methodILGen.Emit(OpCodes.Ret);
  867. }
  868. else
  869. {
  870. if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum)
  871. {
  872. MethodInfo getMethod = typeof(Activator).GetMethod("CreateInstance",
  873. new[] { typeof(Type) });
  874. LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType);
  875. methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType);
  876. methodILGen.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
  877. methodILGen.Emit(OpCodes.Callvirt, getMethod);
  878. methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType);
  879. }
  880. else
  881. {
  882. methodILGen.Emit(OpCodes.Ldnull);
  883. }
  884. methodILGen.Emit(OpCodes.Ret);
  885. }
  886. typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
  887. }
  888. public static void BindProperty(TypeBuilder typeBuilder, MethodInfo methodInfo)
  889. {
  890. // Backing Field
  891. string propertyName = methodInfo.Name.Replace("get_", "");
  892. Type propertyType = methodInfo.ReturnType;
  893. FieldBuilder backingField = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
  894. //Getter
  895. MethodBuilder backingGet = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public |
  896. MethodAttributes.SpecialName | MethodAttributes.Virtual |
  897. MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
  898. ILGenerator getIl = backingGet.GetILGenerator();
  899. getIl.Emit(OpCodes.Ldarg_0);
  900. getIl.Emit(OpCodes.Ldfld, backingField);
  901. getIl.Emit(OpCodes.Ret);
  902. //Setter
  903. MethodBuilder backingSet = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public |
  904. MethodAttributes.SpecialName | MethodAttributes.Virtual |
  905. MethodAttributes.HideBySig, null, new[] { propertyType });
  906. ILGenerator setIl = backingSet.GetILGenerator();
  907. setIl.Emit(OpCodes.Ldarg_0);
  908. setIl.Emit(OpCodes.Ldarg_1);
  909. setIl.Emit(OpCodes.Stfld, backingField);
  910. setIl.Emit(OpCodes.Ret);
  911. // Property
  912. PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null);
  913. propertyBuilder.SetGetMethod(backingGet);
  914. propertyBuilder.SetSetMethod(backingSet);
  915. }
  916. }
  917. #endif
  918. internal class SerializerUtils<TSerializer>
  919. where TSerializer : ITypeSerializer
  920. {
  921. private static readonly ITypeSerializer Serializer = JsWriter.GetTypeSerializer<TSerializer>();
  922. private static int VerifyAndGetStartIndex(string value, Type createMapType)
  923. {
  924. var index = 0;
  925. if (!Serializer.EatMapStartChar(value, ref index))
  926. {
  927. //Don't throw ex because some KeyValueDataContractDeserializer don't have '{}'
  928. Tracer.Instance.WriteDebug("WARN: Map definitions should start with a '{0}', expecting serialized type '{1}', got string starting with: {2}",
  929. JsWriter.MapStartChar, createMapType != null ? createMapType.Name : "Dictionary<,>", value.Substring(0, value.Length < 50 ? value.Length : 50));
  930. }
  931. return index;
  932. }
  933. public static Hashtable ParseHashtable(string value)
  934. {
  935. if (value == null)
  936. return null;
  937. var index = VerifyAndGetStartIndex(value, typeof(Hashtable));
  938. var result = new Hashtable();
  939. if (JsonTypeSerializer.IsEmptyMap(value, index)) return result;
  940. var valueLength = value.Length;
  941. while (index < valueLength)
  942. {
  943. var keyValue = Serializer.EatMapKey(value, ref index);
  944. Serializer.EatMapKeySeperator(value, ref index);
  945. var elementValue = Serializer.EatValue(value, ref index);
  946. if (keyValue == null) continue;
  947. var mapKey = keyValue;
  948. var mapValue = elementValue;
  949. result[mapKey] = mapValue;
  950. Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
  951. }
  952. return result;
  953. }
  954. public static StringCollection ParseStringCollection<TS>(string value) where TS : ITypeSerializer
  955. {
  956. if ((value = DeserializeListWithElements<TS>.StripList(value)) == null) return null;
  957. return value == String.Empty
  958. ? new StringCollection()
  959. : ToStringCollection(DeserializeListWithElements<TSerializer>.ParseStringList(value));
  960. }
  961. public static StringCollection ToStringCollection(List<string> items)
  962. {
  963. var to = new StringCollection();
  964. foreach (var item in items)
  965. {
  966. to.Add(item);
  967. }
  968. return to;
  969. }
  970. }
  971. public static class PclExportExt
  972. {
  973. public static string ToFormUrlEncoded(this NameValueCollection queryParams)
  974. {
  975. var sb = new System.Text.StringBuilder();
  976. foreach (string key in queryParams)
  977. {
  978. var values = queryParams.GetValues(key);
  979. if (values == null) continue;
  980. foreach (var value in values)
  981. {
  982. if (sb.Length > 0)
  983. sb.Append('&');
  984. sb.AppendFormat("{0}={1}", key.UrlEncode(), value.UrlEncode());
  985. }
  986. }
  987. return sb.ToString();
  988. }
  989. //HttpUtils
  990. public static WebResponse PostFileToUrl(this string url,
  991. FileInfo uploadFileInfo, string uploadFileMimeType,
  992. string accept = null,
  993. Action<HttpWebRequest> requestFilter = null)
  994. {
  995. var webReq = (HttpWebRequest)WebRequest.Create(url);
  996. using (var fileStream = uploadFileInfo.OpenRead())
  997. {
  998. var fileName = uploadFileInfo.Name;
  999. webReq.UploadFile(fileStream, fileName, uploadFileMimeType, accept: accept, requestFilter: requestFilter, method: "POST");
  1000. }
  1001. if (HttpUtils.ResultsFilter != null)
  1002. return null;
  1003. return webReq.GetResponse();
  1004. }
  1005. public static WebResponse PutFileToUrl(this string url,
  1006. FileInfo uploadFileInfo, string uploadFileMimeType,
  1007. string accept = null,
  1008. Action<HttpWebRequest> requestFilter = null)
  1009. {
  1010. var webReq = (HttpWebRequest)WebRequest.Create(url);
  1011. using (var fileStream = uploadFileInfo.OpenRead())
  1012. {
  1013. var fileName = uploadFileInfo.Name;
  1014. webReq.UploadFile(fileStream, fileName, uploadFileMimeType, accept: accept, requestFilter: requestFilter, method: "PUT");
  1015. }
  1016. if (HttpUtils.ResultsFilter != null)
  1017. return null;
  1018. return webReq.GetResponse();
  1019. }
  1020. public static WebResponse UploadFile(this WebRequest webRequest,
  1021. FileInfo uploadFileInfo, string uploadFileMimeType)
  1022. {
  1023. using (var fileStream = uploadFileInfo.OpenRead())
  1024. {
  1025. var fileName = uploadFileInfo.Name;
  1026. webRequest.UploadFile(fileStream, fileName, uploadFileMimeType);
  1027. }
  1028. if (HttpUtils.ResultsFilter != null)
  1029. return null;
  1030. return webRequest.GetResponse();
  1031. }
  1032. //XmlSerializer
  1033. public static void CompressToStream<TXmlDto>(TXmlDto from, Stream stream)
  1034. {
  1035. #if __IOS__ || ANDROID
  1036. throw new NotImplementedException("Compression is not supported on this platform");
  1037. #else
  1038. using (var deflateStream = new System.IO.Compression.DeflateStream(stream, System.IO.Compression.CompressionMode.Compress))
  1039. using (var xw = new System.Xml.XmlTextWriter(deflateStream, Encoding.UTF8))
  1040. {
  1041. var serializer = new DataContractSerializer(from.GetType());
  1042. serializer.WriteObject(xw, from);
  1043. xw.Flush();
  1044. }
  1045. #endif
  1046. }
  1047. public static byte[] Compress<TXmlDto>(TXmlDto from)
  1048. {
  1049. using (var ms = MemoryStreamFactory.GetStream())
  1050. {
  1051. CompressToStream(from, ms);
  1052. return ms.ToArray();
  1053. }
  1054. }
  1055. //License Utils
  1056. public static bool VerifySignedHash(byte[] DataToVerify, byte[] SignedData, RSAParameters Key)
  1057. {
  1058. try
  1059. {
  1060. var RSAalg = new RSACryptoServiceProvider();
  1061. RSAalg.ImportParameters(Key);
  1062. return RSAalg.VerifySha1Data(DataToVerify, SignedData);
  1063. }
  1064. catch (CryptographicException ex)
  1065. {
  1066. Tracer.Instance.WriteError(ex);
  1067. return false;
  1068. }
  1069. }
  1070. public static bool VerifyLicenseKeyText(this string licenseKeyText, out LicenseKey key)
  1071. {
  1072. var publicRsaProvider = new RSACryptoServiceProvider();
  1073. publicRsaProvider.FromXmlString(LicenseUtils.LicensePublicKey);
  1074. var publicKeyParams = publicRsaProvider.ExportParameters(false);
  1075. key = licenseKeyText.ToLicenseKey();
  1076. var originalData = key.GetHashKeyToSign().ToUtf8Bytes();
  1077. var signedData = Convert.FromBase64String(key.Hash);
  1078. return VerifySignedHash(originalData, signedData, publicKeyParams);
  1079. }
  1080. public static bool VerifySha1Data(this RSACryptoServiceProvider RSAalg, byte[] unsignedData, byte[] encryptedData)
  1081. {
  1082. return RSAalg.VerifyData(unsignedData, new SHA1CryptoServiceProvider(), encryptedData);
  1083. //SL5 || WP
  1084. //return RSAalg.VerifyData(unsignedData, encryptedData, new EMSAPKCS1v1_5_SHA1());
  1085. }
  1086. #if !__IOS__
  1087. //ReflectionExtensions
  1088. const string DataContract = "DataContractAttribute";
  1089. static readonly ConcurrentDictionary<Type, FastMember.TypeAccessor> typeAccessorMap
  1090. = new ConcurrentDictionary<Type, FastMember.TypeAccessor>();
  1091. public static DataContractAttribute GetWeakDataContract(this Type type)
  1092. {
  1093. var attr = type.AllAttributes().FirstOrDefault(x => x.GetType().Name == DataContract);
  1094. if (attr != null)
  1095. {
  1096. var attrType = attr.GetType();
  1097. FastMember.TypeAccessor accessor;
  1098. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1099. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1100. return new DataContractAttribute
  1101. {
  1102. Name = (string)accessor[attr, "Name"],
  1103. Namespace = (string)accessor[attr, "Namespace"],
  1104. };
  1105. }
  1106. return null;
  1107. }
  1108. public static DataMemberAttribute GetWeakDataMember(this PropertyInfo pi)
  1109. {
  1110. var attr = pi.AllAttributes().FirstOrDefault(x => x.GetType().Name == ReflectionExtensions.DataMember);
  1111. if (attr != null)
  1112. {
  1113. var attrType = attr.GetType();
  1114. FastMember.TypeAccessor accessor;
  1115. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1116. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1117. var newAttr = new DataMemberAttribute
  1118. {
  1119. Name = (string)accessor[attr, "Name"],
  1120. EmitDefaultValue = (bool)accessor[attr, "EmitDefaultValue"],
  1121. IsRequired = (bool)accessor[attr, "IsRequired"],
  1122. };
  1123. var order = (int)accessor[attr, "Order"];
  1124. if (order >= 0)
  1125. newAttr.Order = order; //Throws Exception if set to -1
  1126. return newAttr;
  1127. }
  1128. return null;
  1129. }
  1130. public static DataMemberAttribute GetWeakDataMember(this FieldInfo pi)
  1131. {
  1132. var attr = pi.AllAttributes().FirstOrDefault(x => x.GetType().Name == ReflectionExtensions.DataMember);
  1133. if (attr != null)
  1134. {
  1135. var attrType = attr.GetType();
  1136. FastMember.TypeAccessor accessor;
  1137. if (!typeAccessorMap.TryGetValue(attrType, out accessor))
  1138. typeAccessorMap[attrType] = accessor = FastMember.TypeAccessor.Create(attr.GetType());
  1139. var newAttr = new DataMemberAttribute
  1140. {
  1141. Name = (string)accessor[attr, "Name"],
  1142. EmitDefaultValue = (bool)accessor[attr, "EmitDefaultValue"],
  1143. IsRequired = (bool)accessor[attr, "IsRequired"],
  1144. };
  1145. var order = (int)accessor[attr, "Order"];
  1146. if (order >= 0)
  1147. newAttr.Order = order; //Throws Exception if set to -1
  1148. return newAttr;
  1149. }
  1150. return null;
  1151. }
  1152. #endif
  1153. }
  1154. }
  1155. #if !__IOS__
  1156. //Not using it here, but @marcgravell's stuff is too good not to include
  1157. // http://code.google.com/p/fast-member/ Apache License 2.0
  1158. namespace ServiceStack.Text.FastMember
  1159. {
  1160. /// <summary>
  1161. /// Represents an individual object, allowing access to members by-name
  1162. /// </summary>
  1163. public abstract class ObjectAccessor
  1164. {
  1165. /// <summary>
  1166. /// Get or Set the value of a named member for the underlying object
  1167. /// </summary>
  1168. public abstract object this[string name] { get; set; }
  1169. /// <summary>
  1170. /// The object represented by this instance
  1171. /// </summary>
  1172. public abstract object Target { get; }
  1173. /// <summary>
  1174. /// Use the target types definition of equality
  1175. /// </summary>
  1176. public override bool Equals(object obj)
  1177. {
  1178. return Target.Equals(obj);
  1179. }
  1180. /// <summary>
  1181. /// Obtain the hash of the target object
  1182. /// </summary>
  1183. public override int GetHashCode()
  1184. {
  1185. return Target.GetHashCode();
  1186. }
  1187. /// <summary>
  1188. /// Use the target's definition of a string representation
  1189. /// </summary>
  1190. public override string ToString()
  1191. {
  1192. return Target.ToString();
  1193. }
  1194. /// <summary>
  1195. /// Wraps an individual object, allowing by-name access to that instance
  1196. /// </summary>
  1197. public static ObjectAccessor Create(object target)
  1198. {
  1199. if (target == null) throw new ArgumentNullException("target");
  1200. //IDynamicMetaObjectProvider dlr = target as IDynamicMetaObjectProvider;
  1201. //if (dlr != null) return new DynamicWrapper(dlr); // use the DLR
  1202. return new TypeAccessorWrapper(target, TypeAccessor.Create(target.GetType()));
  1203. }
  1204. sealed class TypeAccessorWrapper : ObjectAccessor
  1205. {
  1206. private readonly object target;
  1207. private readonly TypeAccessor accessor;
  1208. public TypeAccessorWrapper(object target, TypeAccessor accessor)
  1209. {
  1210. this.target = target;
  1211. this.accessor = accessor;
  1212. }
  1213. public override object this[string name]
  1214. {
  1215. get { return accessor[target, name.ToUpperInvariant()]; }
  1216. set { accessor[target, name.ToUpperInvariant()] = value; }
  1217. }
  1218. public override object Target
  1219. {
  1220. get { return target; }
  1221. }
  1222. }
  1223. //sealed class DynamicWrapper : ObjectAccessor
  1224. //{
  1225. // private readonly IDynamicMetaObjectProvider target;
  1226. // public override object Target
  1227. // {
  1228. // get { return target; }
  1229. // }
  1230. // public DynamicWrapper(IDynamicMetaObjectProvider target)
  1231. // {
  1232. // this.target = target;
  1233. // }
  1234. // public override object this[string name]
  1235. // {
  1236. // get { return CallSiteCache.GetValue(name, target); }
  1237. // set { CallSiteCache.SetValue(name, target, value); }
  1238. // }
  1239. //}
  1240. }
  1241. /// <summary>
  1242. /// Provides by-name member-access to objects of a given type
  1243. /// </summary>
  1244. public abstract class TypeAccessor
  1245. {
  1246. // hash-table has better read-without-locking semantics than dictionary
  1247. private static readonly Hashtable typeLookyp = new Hashtable();
  1248. /// <summary>
  1249. /// Does this type support new instances via a parameterless constructor?
  1250. /// </summary>
  1251. public virtual bool CreateNewSupported { get { return false; } }
  1252. /// <summary>
  1253. /// Create a new instance of this type
  1254. /// </summary>
  1255. public virtual object CreateNew() { throw new NotSupportedException(); }
  1256. /// <summary>
  1257. /// Provides a type-specific accessor, allowing by-name access for all objects of that type
  1258. /// </summary>
  1259. /// <remarks>The accessor is cached internally; a pre-existing accessor may be returned</remarks>
  1260. public static TypeAccessor Create(Type type)
  1261. {
  1262. if (type == null) throw new ArgumentNullException("type");
  1263. TypeAccessor obj = (TypeAccessor)typeLookyp[type];
  1264. if (obj != null) return obj;
  1265. lock (typeLookyp)
  1266. {
  1267. // double-check
  1268. obj = (TypeAccessor)typeLookyp[type];
  1269. if (obj != null) return obj;
  1270. obj = CreateNew(type);
  1271. typeLookyp[type] = obj;
  1272. return obj;
  1273. }
  1274. }
  1275. //sealed class DynamicAccessor : TypeAccessor
  1276. //{
  1277. // public static readonly DynamicAccessor Singleton = new DynamicAccessor();
  1278. // private DynamicAccessor(){}
  1279. // public override object this[object target, string name]
  1280. // {
  1281. // get { return CallSiteCache.GetValue(name, target); }
  1282. // set { CallSiteCache.SetValue(name, target, value); }
  1283. // }
  1284. //}
  1285. private static AssemblyBuilder assembly;
  1286. private static ModuleBuilder module;
  1287. private static int counter;
  1288. private static void WriteGetter(ILGenerator il, Type type, PropertyInfo[] props, FieldInfo[] fields, bool isStatic)
  1289. {
  1290. LocalBuilder loc = type.IsValueType ? il.DeclareLocal(type) : null;
  1291. OpCode propName = isStatic ? OpCodes.Ldarg_1 : OpCodes.Ldarg_2, target = isStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1;
  1292. foreach (PropertyInfo prop in props)
  1293. {
  1294. if (prop.GetIndexParameters().Length != 0 || !prop.CanRead) continue;
  1295. var getFn = prop.GetGetMethod();
  1296. if (getFn == null) continue; //Mono
  1297. Label next = il.DefineLabel();
  1298. il.Emit(propName);
  1299. il.Emit(OpCodes.Ldstr, prop.Name);
  1300. il.EmitCall(OpCodes.Call, strinqEquals, null);
  1301. il.Emit(OpCodes.Brfalse_S, next);
  1302. // match:
  1303. il.Emit(target);
  1304. Cast(il, type, loc);
  1305. il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, getFn, null);
  1306. if (prop.PropertyType.IsValueType)
  1307. {
  1308. il.Emit(OpCodes.Box, prop.PropertyType);
  1309. }
  1310. il.Emit(OpCodes.Ret);
  1311. // not match:
  1312. il.MarkLabel(next);
  1313. }
  1314. foreach (FieldInfo field in fields)
  1315. {
  1316. Label next = il.DefineLabel();
  1317. il.Emit(propName);
  1318. il.Emit(OpCodes.Ldstr, field.Name);
  1319. il.EmitCall(OpCodes.Call, strinqEquals, null);
  1320. il.Emit(OpCodes.Brfalse_S, next);
  1321. // match:
  1322. il.Emit(target);
  1323. Cast(il, type, loc);
  1324. il.Emit(OpCodes.Ldfld, field);
  1325. if (field.FieldType.IsValueType)
  1326. {
  1327. il.Emit(OpCodes.Box, field.FieldType);
  1328. }
  1329. il.Emit(OpCodes.Ret);
  1330. // not match:
  1331. il.MarkLabel(next);
  1332. }
  1333. il.Emit(OpCodes.Ldstr, "name");
  1334. il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
  1335. il.Emit(OpCodes.Throw);
  1336. }
  1337. private static void WriteSetter(ILGenerator il, Type type, PropertyInfo[] props, FieldInfo[] fields, bool isStatic)
  1338. {
  1339. if (type.IsValueType)
  1340. {
  1341. il.Emit(OpCodes.Ldstr, "Write is not supported for structs");
  1342. il.Emit(OpCodes.Newobj, typeof(NotSupportedException).GetConstructor(new Type[] { typeof(string) }));
  1343. il.Emit(OpCodes.Throw);
  1344. }
  1345. else
  1346. {
  1347. OpCode propName = isStatic ? OpCodes.Ldarg_1 : OpCodes.Ldarg_2,
  1348. target = isStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1,
  1349. value = isStatic ? OpCodes.Ldarg_2 : OpCodes.Ldarg_3;
  1350. LocalBuilder loc = type.IsValueType ? il.DeclareLocal(type) : null;
  1351. foreach (PropertyInfo prop in props)
  1352. {
  1353. if (prop.GetIndexParameters().Length != 0 || !prop.CanWrite) continue;
  1354. var setFn = prop.GetSetMethod();
  1355. if (setFn == null) continue; //Mono
  1356. Label next = il.DefineLabel();
  1357. il.Emit(propName);
  1358. il.Emit(OpCodes.Ldstr, prop.Name);
  1359. il.EmitCall(OpCodes.Call, strinqEquals, null);
  1360. il.Emit(OpCodes.Brfalse_S, next);
  1361. // match:
  1362. il.Emit(target);
  1363. Cast(il, type, loc);
  1364. il.Emit(value);
  1365. Cast(il, prop.PropertyType, null);
  1366. il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, setFn, null);
  1367. il.Emit(OpCodes.Ret);
  1368. // not match:
  1369. il.MarkLabel(next);
  1370. }
  1371. foreach (FieldInfo field in fields)
  1372. {
  1373. Label next = il.DefineLabel();
  1374. il.Emit(propName);
  1375. il.Emit(OpCodes.Ldstr, field.Name);
  1376. il.EmitCall(OpCodes.Call, strinqEquals, null);
  1377. il.Emit(OpCodes.Brfalse_S, next);
  1378. // match:
  1379. il.Emit(target);
  1380. Cast(il, type, loc);
  1381. il.Emit(value);
  1382. Cast(il, field.FieldType, null);
  1383. il.Emit(OpCodes.Stfld, field);
  1384. il.Emit(OpCodes.Ret);
  1385. // not match:
  1386. il.MarkLabel(next);
  1387. }
  1388. il.Emit(OpCodes.Ldstr, "name");
  1389. il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
  1390. il.Emit(OpCodes.Throw);
  1391. }
  1392. }
  1393. private static readonly MethodInfo strinqEquals = typeof(string).GetMethod("op_Equality", new Type[] { typeof(string), typeof(string) });
  1394. sealed class DelegateAccessor : TypeAccessor
  1395. {
  1396. private readonly Func<object, string, object> getter;
  1397. private readonly Action<object, string, object> setter;
  1398. private readonly Func<object> ctor;
  1399. public DelegateAccessor(Func<object, string, object> getter, Action<object, string, object> setter, Func<object> ctor)
  1400. {
  1401. this.getter = getter;
  1402. this.setter = setter;
  1403. this.ctor = ctor;
  1404. }
  1405. public override bool CreateNewSupported { get { return ctor != null; } }
  1406. public override object CreateNew()
  1407. {
  1408. return ctor != null ? ctor() : base.CreateNew();
  1409. }
  1410. public override object this[object target, string name]
  1411. {
  1412. get { return getter(target, name); }
  1413. set { setter(target, name, value); }
  1414. }
  1415. }
  1416. private static bool IsFullyPublic(Type type)
  1417. {
  1418. while (type.IsNestedPublic) type = type.DeclaringType;
  1419. return type.IsPublic;
  1420. }
  1421. static TypeAccessor CreateNew(Type type)
  1422. {
  1423. //if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type))
  1424. //{
  1425. // return DynamicAccessor.Singleton;
  1426. //}
  1427. PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
  1428. FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
  1429. ConstructorInfo ctor = null;
  1430. if (type.IsClass && !type.IsAbstract)
  1431. {
  1432. ctor = type.GetConstructor(Type.EmptyTypes);
  1433. }
  1434. ILGenerator il;
  1435. if (!IsFullyPublic(type))
  1436. {
  1437. DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true),
  1438. dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true);
  1439. WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true);
  1440. WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true);
  1441. DynamicMethod dynCtor = null;
  1442. if (ctor != null)
  1443. {
  1444. dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true);
  1445. il = dynCtor.GetILGenerator();
  1446. il.Emit(OpCodes.Newobj, ctor);
  1447. il.Emit(OpCodes.Ret);
  1448. }
  1449. return new DelegateAccessor(
  1450. (Func<object, string, object>)dynGetter.CreateDelegate(typeof(Func<object, string, object>)),
  1451. (Action<object, string, object>)dynSetter.CreateDelegate(typeof(Action<object, string, object>)),
  1452. dynCtor == null ? null : (Func<object>)dynCtor.CreateDelegate(typeof(Func<object>)));
  1453. }
  1454. // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders
  1455. if (assembly == null)
  1456. {
  1457. AssemblyName name = new AssemblyName("FastMember_dynamic");
  1458. assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  1459. module = assembly.DefineDynamicModule(name.Name);
  1460. }
  1461. TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter),
  1462. (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed) & ~TypeAttributes.Abstract, typeof(TypeAccessor));
  1463. tb.DefineDefaultConstructor(MethodAttributes.Public);
  1464. PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item");
  1465. MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod();
  1466. MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) });
  1467. il = body.GetILGenerator();
  1468. WriteGetter(il, type, props, fields, false);
  1469. tb.DefineMethodOverride(body, baseGetter);
  1470. body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) });
  1471. il = body.GetILGenerator();
  1472. WriteSetter(il, type, props, fields, false);
  1473. tb.DefineMethodOverride(body, baseSetter);
  1474. if (ctor != null)
  1475. {
  1476. MethodInfo baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod();
  1477. body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(bool), Type.EmptyTypes);
  1478. il = body.GetILGenerator();
  1479. il.Emit(OpCodes.Ldc_I4_1);
  1480. il.Emit(OpCodes.Ret);
  1481. tb.DefineMethodOverride(body, baseMethod);
  1482. baseMethod = typeof(TypeAccessor).GetMethod("CreateNew");
  1483. body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(object), Type.EmptyTypes);
  1484. il = body.GetILGenerator();
  1485. il.Emit(OpCodes.Newobj, ctor);
  1486. il.Emit(OpCodes.Ret);
  1487. tb.DefineMethodOverride(body, baseMethod);
  1488. }
  1489. return (TypeAccessor)Activator.CreateInstance(tb.CreateType());
  1490. }
  1491. private static void Cast(ILGenerator il, Type type, LocalBuilder addr)
  1492. {
  1493. if (type == typeof(object)) { }
  1494. else if (type.IsValueType)
  1495. {
  1496. il.Emit(OpCodes.Unbox_Any, type);
  1497. if (addr != null)
  1498. {
  1499. il.Emit(OpCodes.Stloc, addr);
  1500. il.Emit(OpCodes.Ldloca_S, addr);
  1501. }
  1502. }
  1503. else
  1504. {
  1505. il.Emit(OpCodes.Castclass, type);
  1506. }
  1507. }
  1508. /// <summary>
  1509. /// Get or set the value of a named member on the target instance
  1510. /// </summary>
  1511. public abstract object this[object target, string name]
  1512. {
  1513. get;
  1514. set;
  1515. }
  1516. }
  1517. }
  1518. #endif
  1519. #endif