示例#1
0
文件: Version.cs 项目: damoxc/corert
        private static Version ParseVersion(ReadOnlySpan <char> input, bool throwOnFailure)
        {
            // Find the separator between major and minor.  It must exist.
            int majorEnd = input.IndexOf('.');

            if (majorEnd < 0)
            {
                if (throwOnFailure)
                {
                    throw new ArgumentException(SR.Arg_VersionString, nameof(input));
                }
                return(null);
            }

            // Find the ends of the optional minor and build portions.
            // We musn't have any separators after build.
            int buildEnd = -1;
            int minorEnd = input.Slice(majorEnd + 1).IndexOf('.');

            if (minorEnd != -1)
            {
                minorEnd += (majorEnd + 1);
                buildEnd  = input.Slice(minorEnd + 1).IndexOf('.');
                if (buildEnd != -1)
                {
                    buildEnd += (minorEnd + 1);
                    if (input.Slice(buildEnd + 1).IndexOf('.') != -1)
                    {
                        if (throwOnFailure)
                        {
                            throw new ArgumentException(SR.Arg_VersionString, nameof(input));
                        }
                        return(null);
                    }
                }
            }

            int minor, build, revision;

            // Parse the major version
            if (!TryParseComponent(input.Slice(0, majorEnd), nameof(input), throwOnFailure, out int major))
            {
                return(null);
            }

            if (minorEnd != -1)
            {
                // If there's more than a major and minor, parse the minor, too.
                if (!TryParseComponent(input.Slice(majorEnd + 1, minorEnd - majorEnd - 1), nameof(input), throwOnFailure, out minor))
                {
                    return(null);
                }

                if (buildEnd != -1)
                {
                    // major.minor.build.revision
                    return
                        (TryParseComponent(input.Slice(minorEnd + 1, buildEnd - minorEnd - 1), nameof(build), throwOnFailure, out build) &&
                         TryParseComponent(input.Slice(buildEnd + 1), nameof(revision), throwOnFailure, out revision) ?
                         new Version(major, minor, build, revision) :
                         null);
                }
                else
                {
                    // major.minor.build
                    return(TryParseComponent(input.Slice(minorEnd + 1), nameof(build), throwOnFailure, out build) ?
                           new Version(major, minor, build) :
                           null);
                }
            }
            else
            {
                // major.minor
                return(TryParseComponent(input.Slice(majorEnd + 1), nameof(input), throwOnFailure, out minor) ?
                       new Version(major, minor) :
                       null);
            }
        }
示例#2
0
        public static unsafe IDictionary GetEnvironmentVariables()
        {
            // Format for GetEnvironmentStrings is:
            //     [=HiddenVar=value\0]* [Variable=value\0]* \0
            // See the description of Environment Blocks in MSDN's CreateProcess
            // page (null-terminated array of null-terminated strings). Note
            // the =HiddenVar's aren't always at the beginning.

            // Copy strings out, parsing into pairs and inserting into the table.
            // The first few environment variable entries start with an '='.
            // The current working directory of every drive (except for those drives
            // you haven't cd'ed into in your DOS window) are stored in the
            // environment block (as =C:=pwd) and the program's exit code is
            // as well (=ExitCode=00000000).

            char *stringPtr = Interop.Kernel32.GetEnvironmentStringsW();

            if (stringPtr == null)
            {
                throw new OutOfMemoryException();
            }

            try
            {
                var results = new Hashtable();

                char *currentPtr = stringPtr;
                while (true)
                {
                    ReadOnlySpan <char> variable = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(currentPtr);
                    if (variable.IsEmpty)
                    {
                        break;
                    }

                    // Find the = separating the key and value. We skip entries that begin with =.  We also skip entries that don't
                    // have =, which can happen on some older OSes when the environment block gets corrupted.
                    int i = variable.IndexOf('=');
                    if (i > 0)
                    {
                        // Add the key and value.
                        string key   = new string(variable.Slice(0, i));
                        string value = new string(variable.Slice(i + 1));
                        try
                        {
                            // Add may throw if the environment block was corrupted leading to duplicate entries.
                            // We allow such throws and eat them (rather than proactively checking for duplication)
                            // to provide a non-fatal notification about the corruption.
                            results.Add(key, value);
                        }
                        catch (ArgumentException) { }
                    }

                    // Move to the end of this variable, after its terminator.
                    currentPtr += variable.Length + 1;
                }

                return(results);
            }
            finally
            {
                Interop.BOOL success = Interop.Kernel32.FreeEnvironmentStringsW(stringPtr);
                Debug.Assert(success != Interop.BOOL.FALSE);
            }
        }
        /// <summary>
        /// Gets the null-terminated string length of the given span.
        /// </summary>
        internal static int GetFixedBufferStringLength(this ReadOnlySpan <char> span)
        {
            int length = span.IndexOf('\0');

            return(length < 0 ? span.Length : length);
        }