File: System\Xml\Xsl\XPath\XPathCompileException.cs
Web Access
Project: src\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text;
 
namespace System.Xml.Xsl.XPath
{
    [Serializable]
    internal sealed class XPathCompileException : XslLoadException
    {
        public string? queryString;
        public int startChar;
        public int endChar;
 
        internal XPathCompileException(string queryString, int startChar, int endChar, string resId, params string?[]? args)
            : base(resId, args)
        {
            this.queryString = queryString;
            this.startChar = startChar;
            this.endChar = endChar;
        }
 
        internal XPathCompileException(string resId, params string[] args)
            : base(resId, args)
        { } // queryString will be set later
 
        [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
        internal XPathCompileException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            queryString = (string)info.GetValue("QueryString", typeof(string))!;
            startChar = (int)info.GetValue("StartChar", typeof(int))!;
            endChar = (int)info.GetValue("EndChar", typeof(int))!;
        }
 
        [Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("QueryString", queryString);
            info.AddValue("StartChar", startChar);
            info.AddValue("EndChar", endChar);
        }
 
        private enum TrimType
        {
            Left,
            Right,
            Middle,
        }
 
        // This function is used to prevent long quotations in error messages, SQLBUDT 222626
        private static void AppendTrimmed(StringBuilder sb, string value, int startIndex, int count, TrimType trimType)
        {
            const int TrimSize = 32;
            const string TrimMarker = "...";
 
            if (count <= TrimSize)
            {
                sb.Append(value, startIndex, count);
            }
            else
            {
                switch (trimType)
                {
                    case TrimType.Left:
                        sb.Append(TrimMarker);
                        sb.Append(value, startIndex + count - TrimSize, TrimSize);
                        break;
                    case TrimType.Right:
                        sb.Append(value, startIndex, TrimSize);
                        sb.Append(TrimMarker);
                        break;
                    case TrimType.Middle:
                        sb.Append(value, startIndex, TrimSize / 2);
                        sb.Append(TrimMarker);
                        sb.Append(value, startIndex + count - TrimSize / 2, TrimSize / 2);
                        break;
                }
            }
        }
 
        internal string? MarkOutError()
        {
            if (queryString == null || queryString.AsSpan().Trim(' ').IsEmpty)
            {
                return null;
            }
 
            int len = endChar - startChar;
            StringBuilder sb = new StringBuilder();
 
            AppendTrimmed(sb, queryString, 0, startChar, TrimType.Left);
            if (len > 0)
            {
                sb.Append(" -->");
                AppendTrimmed(sb, queryString, startChar, len, TrimType.Middle);
            }
 
            sb.Append("<-- ");
            AppendTrimmed(sb, queryString, endChar, queryString.Length - endChar, TrimType.Right);
 
            return sb.ToString();
        }
 
        internal override string FormatDetailedMessage()
        {
            string message = Message;
            string? error = MarkOutError();
 
            if (error != null && error.Length > 0)
            {
                if (message.Length > 0)
                {
                    message += Environment.NewLine;
                }
                message += error;
            }
            return message;
        }
    }
}