Ejemplo n.º 1
0
        private static bool TryLoadMembers()
        {
            // .NET Core, .NET 4.6+
            s_lazyCreateFromFile = LightUpHelper.GetMethod(
                s_lazyMemoryMappedFileType,
                "CreateFromFile",
                FileStreamReadLightUp.FileStreamType.Value,
                typeof(string),
                typeof(long),
                s_lazyMemoryMappedFileAccessType,
                s_lazyHandleInheritabilityType,
                typeof(bool)
                );

            // .NET < 4.6
            if (s_lazyCreateFromFile == null)
            {
                if (s_lazyMemoryMappedFileSecurityType != null)
                {
                    s_lazyCreateFromFileClassic = LightUpHelper.GetMethod(
                        s_lazyMemoryMappedFileType,
                        "CreateFromFile",
                        FileStreamReadLightUp.FileStreamType.Value,
                        typeof(string),
                        typeof(long),
                        s_lazyMemoryMappedFileAccessType,
                        s_lazyMemoryMappedFileSecurityType,
                        s_lazyHandleInheritabilityType,
                        typeof(bool));
                }

                if (s_lazyCreateFromFileClassic == null)
                {
                    return(false);
                }
            }

            s_lazyCreateViewAccessor = LightUpHelper.GetMethod(
                s_lazyMemoryMappedFileType,
                "CreateViewAccessor",
                typeof(long),
                typeof(long),
                s_lazyMemoryMappedFileAccessType);

            if (s_lazyCreateViewAccessor == null)
            {
                return(false);
            }

            s_lazySafeMemoryMappedViewHandle = s_lazyMemoryMappedViewAccessorType.GetTypeInfo().GetDeclaredProperty("SafeMemoryMappedViewHandle");
            if (s_lazySafeMemoryMappedViewHandle == null)
            {
                return(false);
            }

            // .NET Core, .NET 4.5.1+
            s_lazyPointerOffset = s_lazyMemoryMappedViewAccessorType.GetTypeInfo().GetDeclaredProperty("PointerOffset");

            // .NET < 4.5.1
            if (s_lazyPointerOffset == null)
            {
                s_lazyInternalViewField = s_lazyMemoryMappedViewAccessorType.GetTypeInfo().GetDeclaredField("m_view");
                if (s_lazyInternalViewField == null)
                {
                    return(false);
                }

                s_lazyInternalPointerOffset = s_lazyInternalViewField.FieldType.GetTypeInfo().GetDeclaredProperty("PointerOffset");
                if (s_lazyInternalPointerOffset == null)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        private static Encoding_GetString LoadGetStringPlatform()
        {
            // .NET Framework 4.6+ and recent versions of other .NET platforms.
            //
            // Try to bind to Encoding.GetString(byte*, int);

            MethodInfo getStringInfo = LightUpHelper.GetMethod(typeof(Encoding), "GetString", typeof(byte *), typeof(int));

            if (getStringInfo != null && getStringInfo.ReturnType == typeof(String))
            {
                try
                {
                    return((Encoding_GetString)getStringInfo.CreateDelegate(typeof(Encoding_GetString), null));
                }
                catch (MemberAccessException)
                {
                }
            }

            // .NET Framework < 4.6
            //
            // Try to bind to String.CreateStringFromEncoding(byte*, int, Encoding)
            //
            // Note that this one is internal and GetRuntimeMethod only searches public methods, which accounts for the different
            // pattern from above.
            //
            // NOTE: Another seeming equivalent is new string(sbyte*, int, Encoding), but  don't be fooled. First of all, we can't get
            //       a delegate to a constructor. Worst than that, even if we could, it is actually about 4x slower than both of these
            //       and even the portable version (only ~20% slower than these) crushes it.
            //
            //       It spends an inordinate amount of time transitioning to managed code from the VM and then lands in String.CreateString
            //       (note no FromEncoding suffix), which defensively copies to a new byte array on every call -- defeating the entire purpose
            //       of this class!
            //
            //       For this reason, desktop callers should not implement an interner that falls back to the unsafe string ctor but instead
            //       return null and let us find the best decoding approach for the current platform.
            //
            //       Yet another approach is to use new string('\0', GetCharCount) and use unsafe GetChars to fill it.
            //       However, on .NET < 4.6, there isn't no-op fast path for zero-initialization case so we'd slow down.
            //       Plus, mutating a System.String is no better than the reflection here.

            IEnumerable <MethodInfo> createStringInfos = typeof(String).GetTypeInfo().GetDeclaredMethods("CreateStringFromEncoding");

            foreach (var methodInfo in createStringInfos)
            {
                var parameters = methodInfo.GetParameters();
                if (parameters.Length == 3 &&
                    parameters[0].ParameterType == typeof(byte *) &&
                    parameters[1].ParameterType == typeof(int) &&
                    parameters[2].ParameterType == typeof(Encoding) &&
                    methodInfo.ReturnType == typeof(String))
                {
                    try
                    {
                        var createStringFromEncoding = (String_CreateStringFromEncoding)methodInfo.CreateDelegate(typeof(String_CreateStringFromEncoding), null);
                        return((encoding, bytes, byteCount) => GetStringUsingCreateStringFromEncoding(createStringFromEncoding, bytes, byteCount, encoding));
                    }
                    catch (MemberAccessException)
                    {
                    }
                }
            }

            // Other platforms: Give up and fall back to GetStringPortable above.
            return(null);
        }