internal static Utf8FormatSegment[] Utf8Parse(string format, out byte[] utf8buffer)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            var list = new List <Utf8FormatSegment>();

            utf8buffer = new byte[Encoding.UTF8.GetMaxByteCount(format.Length)];
            var bufOffset = 0;

            int i   = 0;
            int len = format.Length;

            var copyFrom   = 0;
            var formatSpan = format.AsSpan();

            while (true)
            {
                while (i < len)
                {
                    var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i);

                    if (ParserScanResult.NormalChar == parserScanResult && i < len)
                    {
                        // skip normal char
                        continue;
                    }

                    var size = i - copyFrom;
                    if (ParserScanResult.EscapedChar == parserScanResult)
                    {
                        size--;
                    }

                    if (size != 0)
                    {
                        var utf8size = Encoding.UTF8.GetBytes(format, copyFrom, size, utf8buffer, bufOffset);
                        list.Add(new Utf8FormatSegment(bufOffset, utf8size, Utf8FormatSegment.NotFormatIndex, default, 0));
示例#2
0
        internal static FormatSegment[] Parse(string format, bool withStandardFormat)
        {
            var list = new List <FormatSegment>();

            var copyFrom = 0;

            for (int i = 0; i < format.Length; i++)
            {
                if (format[i] == '{')
                {
                    // escape.
                    if (i == format.Length - 1)
                    {
                        throw new FormatException("invalid format");
                    }

                    if (i != format.Length && format[i + 1] == '{')
                    {
                        var size = i - copyFrom;
                        if (size != 0)
                        {
                            list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat));
                        }
                        i        = i + 1; // skip escaped '{'
                        copyFrom = i;
                        continue;
                    }
                    else
                    {
                        var size = i - copyFrom;
                        if (size != 0)
                        {
                            list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat));
                        }
                    }

                    // try to find range
                    var indexParse = FormatParser.Parse(format.AsSpan(i));
                    list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString(), withStandardFormat));

                    copyFrom = i + indexParse.LastIndex + 1;
                    i        = i + indexParse.LastIndex;
                }
                else if (format[i] == '}')
                {
                    if (i != format.Length && format[i + 1] == '}')
                    {
                        var size = i - copyFrom;
                        if (size != 0)
                        {
                            list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat));
                        }
                        i        = i + 1; // skip escaped '}'
                        copyFrom = i;
                        continue;
                    }
                }
            }

            {
                // final string
                var copyLength = format.Length - copyFrom;
                if (copyLength > 0)
                {
                    list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null, withStandardFormat));
                }
            }

            return(list.ToArray());
        }
        internal static Utf16FormatSegment[] Utf16Parse(string format)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            var list = new List <Utf16FormatSegment>();

            int i   = 0;
            int len = format.Length;

            var copyFrom   = 0;
            var formatSpan = format.AsSpan();

            while (true)
            {
                while (i < len)
                {
                    var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i);

                    if (ParserScanResult.NormalChar == parserScanResult && i < len)
                    {
                        // skip normal char
                        continue;
                    }

                    var size = i - copyFrom;
                    if (ParserScanResult.EscapedChar == parserScanResult)
                    {
                        size--;
                    }

                    if (size != 0)
                    {
                        list.Add(new Utf16FormatSegment(copyFrom, size, Utf16FormatSegment.NotFormatIndex, 0));
                    }

                    copyFrom = i;

                    if (ParserScanResult.BraceOpen == parserScanResult)
                    {
                        break;
                    }
                }

                if (i >= len)
                {
                    break;
                }

                // Here it is before `{`.
                var indexParse = FormatParser.Parse(format, i);
                copyFrom = indexParse.LastIndex; // continue after '}'
                i        = indexParse.LastIndex;

                list.Add(new Utf16FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, indexParse.Alignment));
            }

            return(list.ToArray());
        }