PageRenderTime 99ms CodeModel.GetById 3ms app.highlight 78ms RepoModel.GetById 1ms app.codeStats 1ms

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

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