.NET CIL Browser - Back to table of contents

Source file: AssemblyServer.cs

Files in CilBrowser.Core directory:

AssemblyServer.cs

CilBrowser.Core.csproj

CilBrowserOptions.cs

FileUtils.cs

HtmlAttribute.cs

HtmlBuilder.cs

HtmlGenerator.cs

ServerBase.cs

SourceServer.cs

Utils.cs

WebsiteGenerator.cs

/* CIL Browser (https://github.com/MSDN-WhiteKnight/CilBrowser)
 * Copyright (c) 2023,  MSDN.WhiteKnight 
 * License: BSD 3-Clause */
using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using CilTools.Reflection;

namespace CilBrowser.Core
{
    /// <summary>
    /// Provides a server that dynamically generates HTML for a disassembled IL and returns it via HTTP
    /// </summary>
    public sealed class AssemblyServer : ServerBase
    {
        Assembly _ass;        
        HtmlGenerator _gen;        
        Dictionary<string, List<Type>> _typeMap;
        
        public AssemblyServer(Assembly ass, string urlHost, string urlPrefix) : base(urlHost, urlPrefix)
        {
            this._ass = ass;
            this._gen = new HtmlGenerator(ass);

            Type[] types = ass.GetTypes();
            this._typeMap = Utils.GroupByNamespace(types);
        }
        
        int ResolveTokenFromUrl(string url)
        {
            string urlPart = StripURL(url);

            //Parse hexadecimal metadata token from URL
            int ret;

            if (int.TryParse(urlPart, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ret))
            {
                return ret;
            }
            else
            {
                return 0;
            }
        }

        static Type ResolveType(Assembly ass, int metadataToken)
        {
            if (ass is ITokenResolver)
            {
                ITokenResolver resolver = (ITokenResolver)ass;
                return resolver.ResolveType(metadataToken);
            }
            else
            {
                return ass.ManifestModule.ResolveType(metadataToken);
            }
        }
        
        protected override void OnStart()
        {
            Console.WriteLine("Assembly: " + this._ass.GetName().Name);
        }

        protected override void RenderFrontPage(HttpListenerResponse response)
        {
            // Table of contents
            response.ContentType = "text/html; charset=utf-8";
            string[] namespaces = this._typeMap.Keys.ToArray();
            Array.Sort(namespaces);

            // Write the response to output stream.
            StreamWriter wr = new StreamWriter(response.OutputStream);
            HtmlBuilder toc = new HtmlBuilder(wr);

            using (wr)
            {
                HtmlGenerator.WriteTocStart(toc, this._ass);

                for (int i = 0; i < namespaces.Length; i++)
                {
                    string nsText = namespaces[i];
                    List<Type> nsTypes = this._typeMap[namespaces[i]];

                    if (nsTypes.Count == 0) continue;

                    if (string.IsNullOrEmpty(nsText)) nsText = "(No namespace)";
                    else nsText = nsText + " namespace";

                    toc.WriteTag("h2", nsText);

                    for (int j = 0; j < nsTypes.Count; j++)
                    {
                        string fname = HtmlGenerator.GenerateTypeFileName(nsTypes[j]);

                        //TOC entry
                        toc.StartParagraph();
                        toc.WriteHyperlink(fname, nsTypes[j].FullName);
                        toc.EndParagraph();
                    }
                }//end for

                this._gen.WriteFooter(toc);
                toc.EndDocument();
            }//end using
        }

        protected override void RenderPage(string url, HttpListenerResponse response)
        {
            string content;

            if (Utils.StrEquals(url, this._urlPrefix + "assembly.html"))
            {
                // Assembly manifest
                content = this._gen.VisualizeAssemblyManifest(this._ass);
                SendHtmlResponse(response, content);
                this.AddToCache(url, content);
                return;
            }

            // Type
            int metadataToken = ResolveTokenFromUrl(url);

            if (metadataToken == 0)
            {
                //вернуть ошибку при неверном URL
                SendErrorResponse(response, 404, "Not found");
                return;
            }

            Type t = ResolveType(this._ass, metadataToken);

            if (t == null)
            {
                //вернуть ошибку при неверном URL
                SendErrorResponse(response, 404, "Not found");
                return;
            }

            content = this._gen.VisualizeType(t, this._typeMap);
            SendHtmlResponse(response, content);
            this.AddToCache(url, content);
        }
    }
}
View in source control

Back to table of contents


Generated by CIL Browser