public ITypeScope?FindType(string name)
        {
            Throw.CheckNotNullOrEmptyArgument(name);
            var m = name.AsSpan();

            m.SkipWhiteSpacesAndJSComments();
            if (!m.MatchTypeKey(out string?key))
            {
                Throw.ArgumentException(nameof(name), $"Invalid type name: {name}");
            }
            _types.TryGetValue(key, out TypeScopeImpl? result);
            return(result);
        }
        /// <summary>
        /// Attempts to load a StObjMap from an assembly name.
        /// <para>
        /// If a <see cref="SuffixSignature"/> file exists and contains a valid signature, the StObjMap is
        /// loaded from the <see cref="GetAvailableMapInfos(IActivityMonitor?)"/> if it exists.
        /// </para>
        /// </summary>
        /// <param name="assemblyName">The assembly name.</param>
        /// <param name="monitor">Optional monitor to use.</param>
        /// <returns>A <see cref="IStObjMap"/> that provides access to the objects graph.</returns>
        public static IStObjMap?Load(string assemblyName, IActivityMonitor?monitor = null)
        {
            Throw.CheckNotNullOrEmptyArgument(assemblyName);
            Throw.CheckArgument(FileUtil.IndexOfInvalidFileNameChars(assemblyName) < 0);

            if (!assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) &&
                !assemblyName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
            {
                assemblyName = assemblyName + ".dll";
            }
            string assemblyFullPath = Path.Combine(AppContext.BaseDirectory, assemblyName);
            var    signaturePath    = assemblyFullPath + SuffixSignature;

            if (File.Exists(signaturePath) &&
                SHA1Value.TryParse(File.ReadAllText(signaturePath), out var signature))
            {
                var map = Load(signature, monitor);
                if (map != null)
                {
                    return(map);
                }
            }

            lock ( _alreadyHandled )
            {
                LockedEnsureMonitor(ref monitor);
                using (monitor.OpenInfo($"Loading StObj map from '{assemblyName}'."))
                {
                    try
                    {
                        // LoadFromAssemblyPath caches the assemblies by their path.
                        // No need to do it.
                        var a    = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyFullPath);
                        var info = LockedGetMapInfo(a, ref monitor);
                        if (info == null)
                        {
                            return(null);
                        }
                        return(LockedGetStObjMapFromInfo(info, ref monitor));
                    }
                    catch (Exception ex)
                    {
                        monitor.Error(ex);
                        return(null);
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Opens a <see cref="LogReader"/> to read the content of a compressed or uncompressed file.
        /// The file will be closed when <see cref="LogReader.Dispose"/> will be called.
        /// </summary>
        /// <param name="path">Path of the log file.</param>
        /// <param name="dataOffset">
        /// An optional offset where the stream position must be initially set: this is the position of an entry in the actual (potentially uncompressed stream),
        /// not the offset in the original stream.
        /// </param>
        /// <param name="filter">An optional <see cref="MulticastFilter"/>.</param>
        /// <returns>A <see cref="LogReader"/> that will close the file when disposed.</returns>
        /// <remarks>
        /// .ckmon files exist in different file versions, depending on headers.
        /// The file can be compressed using GZipStream, in which case the header will be the magic GZIP header: 1F 8B.
        /// New header (applies to version 5), the file will start with 43 4B 4D 4F 4E (CKMON in ASCII), followed by the version number, instead of only the version number.
        /// </remarks>
        public static LogReader Open(string path, long dataOffset = 0, MulticastFilter?filter = null)
        {
            Throw.CheckNotNullOrEmptyArgument(path);
            FileStream?fs = null;

            try
            {
                fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 8192, FileOptions.SequentialScan);
                return(Open(fs, dataOffset, filter));
            }
            catch
            {
                if (fs != null)
                {
                    fs.Dispose();
                }
                throw;
            }
        }