示例#1
0
        public static int UnescapeChar(string s, ref int i)
        {
            UString s2     = new UString(s, i);
            EscapeC _      = 0;
            int     result = UnescapeChar(ref s2, ref _);

            i = s2.InternalStart;
            return(result);
        }
示例#2
0
		/// <summary>Escapes characters in a string using C style.</summary>
		/// <param name="flags">Specifies which characters should be escaped.</param>
		/// <param name="quoteType">Specifies a character that should always be 
		/// escaped (typically one of <c>' " `</c>)</param>
		public static string EscapeCStyle(UString s, EscapeC flags, char quoteType)
		{
			StringBuilder s2 = new StringBuilder(s.Length+1);
			bool usedEscapes = false, fail;
			for (;;) {
				int c = s.PopFirst(out fail);
				if (fail) break;
				usedEscapes |= EscapeCStyle(c, s2, flags, quoteType);
			}
			if (!usedEscapes && s.InternalString.Length == s.Length)
				return s.InternalString;
			return s2.ToString();
		}
示例#3
0
 static void EscapeU(char c, StringBuilder @out, EscapeC flags)
 {
     if (c <= 255 && (flags & EscapeC.BackslashX) != 0)
     {
         @out.Append(@"\x");
     }
     else
     {
         @out.Append(@"\u");
         @out.Append(HexDigitChar((c >> 12) & 0xF));
         @out.Append(HexDigitChar((c >> 8) & 0xF));
     }
     @out.Append(HexDigitChar((c >> 4) & 0xF));
     @out.Append(HexDigitChar(c & 0xF));
 }
示例#4
0
文件: G.cs 项目: murven/Loyc
        public static string EscapeCStyle(UString s, EscapeC flags, char quoteType)
        {
            StringBuilder s2  = new StringBuilder(s.Length + 1);
            bool          any = false;

            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                any |= EscapeCStyle(c, s2, flags, quoteType);
            }
            if (!any && s.InternalString.Length == s.Length)
            {
                return(s.InternalString);
            }
            return(s2.ToString());
        }
示例#5
0
		/// <summary>Unescapes a string that uses C-style escape sequences, e.g. 
		/// "\\\n\\\r" becomes "\n\r".</summary>
		/// <param name="encountered">Returns information about whether escape 
		/// sequences were encountered, and which categories.</param>
		/// <param name="removeUnnecessaryBackslashes">Causes the backslash before 
		/// an unrecognized escape sequence to be removed, e.g. "\z" => "z".</param>
		/// <remarks>See <see cref="UnescapeChar(ref UString, ref EscapeC)"/> for details.</remarks>
		public static StringBuilder UnescapeCStyle(UString s, out EscapeC encountered, bool removeUnnecessaryBackslashes = false)
		{
			encountered = 0;
			StringBuilder @out = new StringBuilder(s.Length);
			while (s.Length > 0) {
				EscapeC encounteredHere = 0;
				int c = UnescapeChar(ref s, ref encounteredHere);
				encountered |= encounteredHere;
				if (removeUnnecessaryBackslashes && (encounteredHere & EscapeC.Unrecognized) != 0) {
					Debug.Assert(c == '\\');
					continue;
				}
				@out.AppendCodePoint(c);
			}
			return @out;
		}
示例#6
0
        /// <summary>Unescapes a string that uses C-style escape sequences, e.g. "\n\r" becomes @"\n\r".</summary>
        /// <param name="encountered">Returns information about whether escape
        /// sequences were encountered, and which categories.</param>
        /// <param name="removeUnnecessaryBackslashes">Causes the backslash before
        /// an unrecognized escape sequence to be removed, e.g. "\z" => "z".</param>
        public static string UnescapeCStyle(string s, int index, int length, out EscapeC encountered, bool removeUnnecessaryBackslashes = false)
        {
            encountered = 0;
            StringBuilder s2 = new StringBuilder(length);

            for (int i = index; i < index + length;)
            {
                int  oldi = i;
                char c    = UnescapeChar(s, ref i, ref encountered);
                if (removeUnnecessaryBackslashes && c == '\\' && i == oldi + 1)
                {
                    continue;
                }
                s2.Append(c);
            }
            return(s2.ToString());
        }
示例#7
0
		static void EscapeU(int c, StringBuilder @out, EscapeC flags)
		{
			if (c <= 255 && (flags & EscapeC.BackslashX) != 0)
				@out.Append(@"\x");
			else {
				@out.Append(@"\u");
				if (c > 0xFFFF || (flags & EscapeC.HasLongEscape) != 0) {
					Debug.Assert(c <= 0x10FFFF);
					@out.Append(HexDigitChar((c >> 20) & 0xF));
					@out.Append(HexDigitChar((c >> 16) & 0xF));
				}
				@out.Append(HexDigitChar((c >> 12) & 0xF));
				@out.Append(HexDigitChar((c >> 8) & 0xF));
			}
			@out.Append(HexDigitChar((c >> 4) & 0xF));
			@out.Append(HexDigitChar(c & 0xF));
		}
示例#8
0
        /// <summary>Unescapes a string that uses C-style escape sequences, e.g.
        /// "\\\n\\\r" becomes "\n\r".</summary>
        /// <param name="encountered">Returns information about whether escape
        /// sequences were encountered, and which categories.</param>
        /// <param name="removeUnnecessaryBackslashes">Causes the backslash before
        /// an unrecognized escape sequence to be removed, e.g. "\z" => "z".</param>
        /// <remarks>See <see cref="UnescapeChar(ref UString, ref EscapeC)"/> for details.</remarks>
        public static StringBuilder UnescapeCStyle(UString s, out EscapeC encountered, bool removeUnnecessaryBackslashes = false)
        {
            encountered = 0;
            StringBuilder @out = new StringBuilder(s.Length);

            while (s.Length > 0)
            {
                EscapeC encounteredHere = 0;
                int     c = UnescapeChar(ref s, ref encounteredHere);
                encountered |= encounteredHere;
                if (removeUnnecessaryBackslashes && (encounteredHere & EscapeC.Unrecognized) != 0)
                {
                    Debug.Assert(c == '\\');
                    continue;
                }
                @out.AppendCodePoint(c);
            }
            return(@out);
        }
示例#9
0
        /// <summary>Escapes characters in a string using C style.</summary>
        /// <param name="flags">Specifies which characters should be escaped.</param>
        /// <param name="quoteType">Specifies a character that should always be
        /// escaped (typically one of <c>' " `</c>)</param>
        public static string EscapeCStyle(UString s, EscapeC flags, char quoteType)
        {
            StringBuilder s2 = new StringBuilder(s.Length + 1);
            bool          usedEscapes = false, fail;

            for (;;)
            {
                int c = s.PopFirst(out fail);
                if (fail)
                {
                    break;
                }
                usedEscapes |= EscapeCStyle(c, s2, flags, quoteType);
            }
            if (!usedEscapes && s.InternalString.Length == s.Length)
            {
                return(s.InternalString);
            }
            return(s2.ToString());
        }
示例#10
0
 static void EscapeU(int c, StringBuilder @out, EscapeC flags)
 {
     if (c <= 255 && (flags & EscapeC.BackslashX) != 0)
     {
         @out.Append(@"\x");
     }
     else
     {
         @out.Append(@"\u");
         if (c > 0xFFFF || (flags & EscapeC.HasLongEscape) != 0)
         {
             Debug.Assert(c <= 0x10FFFF);
             @out.Append(HexDigitChar((c >> 20) & 0xF));
             @out.Append(HexDigitChar((c >> 16) & 0xF));
         }
         @out.Append(HexDigitChar((c >> 12) & 0xF));
         @out.Append(HexDigitChar((c >> 8) & 0xF));
     }
     @out.Append(HexDigitChar((c >> 4) & 0xF));
     @out.Append(HexDigitChar(c & 0xF));
 }
示例#11
0
        /// <summary>Writes a character <c>c</c> to a StringBuilder, either as a normal
        /// character or as a C-style escape sequence.</summary>
        /// <param name="flags">Specifies which characters should be escaped.</param>
        /// <param name="quoteType">Specifies a character that should always be
        /// escaped (typically one of <c>' " `</c>)</param>
        /// <returns>true if an escape sequence was emitted, false if not.</returns>
        /// <remarks><see cref="EscapeC.HasLongEscape"/> can be used to force a 6-digit
        /// unicode escape; this may be needed if the next character after this one
        /// is a digit.</remarks>
        public static bool EscapeCStyle(int c, StringBuilder @out, EscapeC flags = EscapeC.Default, char quoteType = '\0')
        {
            for (;;)
            {
                if (c >= 128)
                {
                    if ((flags & EscapeC.NonAscii) != 0)
                    {
                        EscapeU(c, @out, flags);
                    }
                    else if (c >= 0xDC00)
                    {
                        if ((flags & EscapeC.UnicodeNonCharacters) != 0 && (
                                c >= 0xFDD0 && c <= 0xFDEF ||                     // 0xFDD0...0xFDEF
                                (c & 0xFFFE) == 0xFFFE) ||                        // 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, etc.
                            (c & 0xFC00) == 0xDC00)                               // 0xDC00...0xDCFF
                        {
                            EscapeU(c, @out, flags);
                        }
                        else if ((flags & EscapeC.UnicodePrivateUse) != 0 && (
                                     c >= 0xE000 && c <= 0xF8FF ||
                                     c >= 0xF0000 && c <= 0xFFFFD ||
                                     c >= 0x100000 && c <= 0x10FFFD))
                        {
                            EscapeU(c, @out, flags);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else if (c < 32)
                {
                    if (c == '\n')
                    {
                        @out.Append(@"\n");
                    }
                    else if (c == '\r')
                    {
                        @out.Append(@"\r");
                    }
                    else if (c == '\0')
                    {
                        @out.Append(@"\0");
                    }
                    else
                    {
                        if ((flags & EscapeC.ABFV) != 0)
                        {
                            if (c == '\a')                               // 7 (alert)
                            {
                                @out.Append(@"\a");
                                return(true);
                            }
                            if (c == '\b')                               // 8 (backspace)
                            {
                                @out.Append(@"\b");
                                return(true);
                            }
                            if (c == '\f')                               // 12 (form feed)
                            {
                                @out.Append(@"\f");
                                return(true);
                            }
                            if (c == '\v')                               // 11 (vertical tab)
                            {
                                @out.Append(@"\v");
                                return(true);
                            }
                        }
                        if ((flags & EscapeC.Control) != 0)
                        {
                            if (c == '\t')
                            {
                                @out.Append(@"\t");
                            }
                            else
                            {
                                EscapeU(c, @out, flags);
                            }
                        }
                        else
                        {
                            @out.Append(c);
                        }
                    }
                }
                else if (c == '\"' && (flags & EscapeC.DoubleQuotes) != 0)
                {
                    @out.Append("\\\"");
                }
                else if (c == '\'' && (flags & EscapeC.SingleQuotes) != 0)
                {
                    @out.Append("\\'");
                }
                else if (c == '\\')
                {
                    @out.Append(@"\\");
                }
                else
                {
                    break;
                }
                return(true);
            }

            if (c == quoteType)
            {
                @out.Append('\\');
                @out.Append((char)c);
                return(true);
            }
            else
            {
                @out.AppendCodePoint(c);
            }
            return(false);
        }
示例#12
0
 /// <summary>Escapes characters in a string using C style, e.g. the string
 /// <c>"Foo\"\n"</c> maps to <c>"Foo\\\"\\\n"</c> by default.</summary>
 public static string EscapeCStyle(UString s, EscapeC flags = EscapeC.Default)
 {
     return(EscapeCStyle(s, flags, '\0'));
 }
示例#13
0
文件: Les3.cs 项目: dadhi/ecsharp
        /// <summary>Parses a normal or triple-quoted string whose starting quotes
        /// have been stripped out. If triple-quote parsing was requested, stops
        /// parsing at three quote marks; otherwise, stops parsing at a single
        /// end-quote or newline.</summary>
        /// <returns>true if parsing stopped at one or three quote marks, or false
        /// if parsing stopped at the end of the input string or at a newline (in
        /// a string that is not triple-quoted).</returns>
        /// <remarks>This method recognizes LES and EC#-style string syntax.</remarks>
        public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool allowExtraIndent = false)
        {
            Debug.Assert(quoteType == '"' || quoteType == '\'' || quoteType == '`');
            bool fail;

            for (; ;)
            {
                if (sourceText.IsEmpty)
                {
                    return(false);
                }
                int i0 = sourceText.InternalStart;
                if (!isTripleQuoted)
                {
                    EscapeC category = 0;
                    int     c        = ParseHelpers.UnescapeChar(ref sourceText, ref category);
                    if ((c == quoteType || c == '\n') && sourceText.InternalStart == i0 + 1)
                    {
                        return(c == quoteType);                        // end of string
                    }
                    if ((category & EscapeC.Unrecognized) != 0)
                    {
                        // This backslash was ignored by UnescapeChar
                        onError(i0, @"Unrecognized escape sequence '\{0}' in string".Localized(PrintHelpers.EscapeCStyle(sourceText[0, ' '].ToString(), EscapeC.Control)));
                    }
                    else if ((category & EscapeC.HasInvalid6DigitEscape) != 0)
                    {
                        onError(i0, @"Invalid 6-digit \u code treated as 5 digits".Localized());
                    }
                    sb.AppendCodePoint(c);
                    if ((category & EscapeC.BackslashX) != 0 && c >= 0x80)
                    {
                        DetectUtf8(sb);
                    }
                    else if (c.IsInRange(0xDC00, 0xDFFF))
                    {
                        RecodeSurrogate(sb);
                    }
                }
                else
                {
                    // Inside triple-quoted string
                    int c;
                    if (sourceText[2, '\0'] == '/')
                    {
                        // Detect escape sequence
                        c = ParseHelpers.UnescapeChar(ref sourceText);
                        if (sourceText.InternalStart > i0 + 1)
                        {
                            G.Verify(sourceText.PopFirst(out fail) == '/');
                        }
                    }
                    else
                    {
                        c = sourceText.PopFirst(out fail);
                        if (fail)
                        {
                            return(false);
                        }
                        if (c == quoteType)
                        {
                            if (sourceText[0, '\0'] == quoteType &&
                                sourceText[1, '\0'] == quoteType)
                            {
                                sourceText = sourceText.Substring(2);
                                // end of string
                                return(true);
                            }
                        }
                        if (c == '\r' || c == '\n')
                        {
                            // To ensure platform independency of source code, CR and
                            // CR-LF become LF.
                            if (c == '\r')
                            {
                                c = '\n';
                                var copy = sourceText.Clone();
                                if (sourceText.PopFirst(out fail) != '\n')
                                {
                                    sourceText = copy;
                                }
                            }
                            // Inside a triple-quoted string, the indentation following a newline
                            // is ignored, as long as it matches the indentation of the first line.
                            UString src = sourceText, ind = indentation;
                            int     sp;
                            while ((sp = src.PopFirst(out fail)) == ind.PopFirst(out fail) && !fail)
                            {
                                sourceText = src;
                            }
                            if (allowExtraIndent && fail)
                            {
                                // Allow an additional one tab or three spaces when initial indent matches
                                if (sp == '\t')
                                {
                                    sourceText = src;
                                }
                                else if (sp == ' ')
                                {
                                    sourceText = src;
                                    if (src.PopFirst(out fail) == ' ')
                                    {
                                        sourceText = src;
                                    }
                                    if (src.PopFirst(out fail) == ' ')
                                    {
                                        sourceText = src;
                                    }
                                }
                            }
                        }
                    }

                    sb.AppendCodePoint(c);
                }
            }
        }
示例#14
0
        public static char UnescapeChar(string s, ref int i)
        {
            EscapeC _ = 0;

            return(UnescapeChar(s, ref i, ref _));
        }
示例#15
0
		/// <summary>Unescapes a single character of a string. Returns the 
		/// first character if it is not a backslash, or <c>\</c> if it is a 
		/// backslash but no escape sequence could be discerned.</summary>
		/// <param name="s">Slice of a string to be unescaped. When using a
		/// <c>ref UString</c> overload of this method, <c>s</c> will be shorter upon
		/// returning from this method, as the parsed character(s) are clipped 
		/// from the beginning (<c>s.InternalStart</c> is incremented by one 
		/// normally and more than one in case of an escape sequence.)</param>
		/// <param name="encountered">Bits of this parameter are set according
		/// to which escape sequence is encountered, if any.</param>
		/// <remarks>
		/// This function also decodes (non-escaped) surrogate pairs.
		/// <para/>
		/// Code points with 5 or 6 digits such as \u1F4A9 are supported.
		/// \x escapes must be two digits and set the EscapeC.BackslashX flag.
		/// \u escapes must be 4 to 6 digits. If a \u escape has more than 4 
		/// digits, the EscapeC.HasLongEscapes flag is set. Invalid 6-digit 
		/// escapes like \u123456 are "made valid" by being treated as 5 digits
		/// (the largest valid escape is <c>\u10FFFF</c>.)
		/// <para/>
		/// Supported escapes: <c>\u \x \\ \n \r \0 \' \" \` \t \a \b \f \v</c>
		/// </remarks>
		/// <example>
		/// EscapeC e = 0; 
		/// UString str = @"\nfoo";
		/// char c = UnescapeChar(ref str, ref e);
		/// Contract.Assert(str == "foo");
		/// Contract.Assert(e == EscapeC.HasEscapes);
		/// </example>
		public static int UnescapeChar(ref UString s, ref EscapeC encountered)
		{
			bool fail;
			int c = s.PopFirst(out fail);
			if (c != '\\' || s.Length <= 0)
				return c;

			encountered |= EscapeC.HasEscapes;
			int code; // hex code after \u or \x
			UString slice, original = s;
			switch (s.PopFirst(out fail)) {
				case 'u':
					slice = s.Left(6);
					if (TryParseHex(ref slice, out code) >= 4) {
						if (code <= 0x10FFFF) {
							s = s.Substring(slice.InternalStart - s.InternalStart);
						} else {
							Debug.Assert(slice.Length == 0);
							// It appears to be 6 digits but only the first 5 can 
							// be treated as part of the escape sequence.
							s = s.Substring(5);
							code >>= 4;
							encountered |= EscapeC.HasInvalid6DigitEscape;
						}
						if (slice.InternalStart > s.InternalStart + 4)
							encountered |= EscapeC.HasLongEscape;
						if (code < 32)
							encountered |= EscapeC.Control;
						else if (code > 127)
							encountered |= EscapeC.NonAscii;
						return code;
					} else
						break;
				case 'x':
					slice = s.Left(2);
					if (TryParseHex(slice, out code)) {
						encountered |= EscapeC.BackslashX;
						if (code < 32)
							encountered |= EscapeC.Control;
						else if (code > 127)
							encountered |= EscapeC.NonAscii;
						s = s.Substring(2);
						return code;
					} else
						break;
				case '\\':
					return '\\';
				case 'n':
					return '\n';
				case 'r':
					return '\r';
				case '0':
					return '\0';
				case '\"':
					encountered |= EscapeC.DoubleQuotes;
					return '\"';
				case '\'':
					encountered |= EscapeC.SingleQuotes;
					return '\'';
				case '`':
					encountered |= EscapeC.Quotes;
					return '`';
				case 't':
					encountered |= EscapeC.Control;
					return '\t';
				case 'a':
					encountered |= EscapeC.ABFV;
					return '\a';
				case 'b':
					encountered |= EscapeC.ABFV;
					return '\b';
				case 'f':
					encountered |= EscapeC.ABFV;
					return '\f';
				case 'v':
					encountered |= EscapeC.ABFV;
					return '\v';
			}
			encountered |= EscapeC.Unrecognized;
			s = original;
			return c;
		}
示例#16
0
        public static int UnescapeChar(ref UString s)
        {
            EscapeC _ = 0;

            return(UnescapeChar(ref s, ref _));
        }
示例#17
0
        /// <summary>Unescapes a single character of a string. Returns the
        /// first character if it is not a backslash, or <c>\</c> if it is a
        /// backslash but no escape sequence could be discerned.</summary>
        /// <param name="s">Slice of a string to be unescaped. When using a
        /// <c>ref UString</c> overload of this method, <c>s</c> will be shorter upon
        /// returning from this method, as the parsed character(s) are clipped
        /// from the beginning (<c>s.InternalStart</c> is incremented by one
        /// normally and more than one in case of an escape sequence.)</param>
        /// <param name="encountered">Bits of this parameter are set according
        /// to which escape sequence is encountered, if any.</param>
        /// <remarks>
        /// This function also decodes (non-escaped) surrogate pairs.
        /// <para/>
        /// Code points with 5 or 6 digits such as \u1F4A9 are supported.
        /// \x escapes must be two digits and set the EscapeC.BackslashX flag.
        /// \u escapes must be 4 to 6 digits. If a \u escape has more than 4
        /// digits, the EscapeC.HasLongEscapes flag is set. Invalid 6-digit
        /// escapes like \u123456 are "made valid" by being treated as 5 digits
        /// (the largest valid escape is <c>\u10FFFF</c>.)
        /// <para/>
        /// Supported escapes: <c>\u \x \\ \n \r \0 \' \" \` \t \a \b \f \v</c>
        /// </remarks>
        /// <example>
        /// EscapeC e = 0;
        /// UString str = @"\nfoo";
        /// char c = UnescapeChar(ref str, ref e);
        /// Contract.Assert(str == "foo");
        /// Contract.Assert(e == EscapeC.HasEscapes);
        /// </example>
        public static int UnescapeChar(ref UString s, ref EscapeC encountered)
        {
            bool fail;
            int  c = s.PopFirst(out fail);

            if (c != '\\' || s.Length <= 0)
            {
                return(c);
            }

            encountered |= EscapeC.HasEscapes;
            int     code;        // hex code after \u or \x or \U
            int     len;         // length of hex code after \u or \x or \U
            UString slice, original = s;
            int     type = s.PopFirst(out fail);

            switch (type)
            {
            case 'x':
                encountered |= EscapeC.BackslashX;
                goto case 'u';

            case 'u':
                len   = type == 'u' ? 4 : 2;
                slice = s.Left(len);
                if (TryParseHex(ref slice, out code) == len)
                {
                    s = s.Substring(slice.InternalStart - s.InternalStart);

                    if (code < 32)
                    {
                        encountered |= EscapeC.Control;
                    }
                    else if (code > 127)
                    {
                        encountered |= EscapeC.NonAscii;
                    }
                    return(code);
                }
                else
                {
                    break;
                }

            case 'U':
                encountered |= EscapeC.HasLongEscape;
                slice        = s.Left(6);
                len          = TryParseHex(ref slice, out code);
                if (len > 0)
                {
                    if (code <= 0x10FFFF)
                    {
                        s = s.Substring(len);
                    }
                    else
                    {
                        Debug.Assert(slice.Length == 0);
                        // It appears to be 6 digits but only the first 5 can
                        // be treated as part of the escape sequence.
                        encountered |= EscapeC.HasInvalid6DigitEscape;
                        s            = s.Substring(5);
                        code       >>= 4;
                    }
                    if (code < 32)
                    {
                        encountered |= EscapeC.Control;
                    }
                    else if (code > 127)
                    {
                        encountered |= EscapeC.NonAscii;
                    }
                    return(code);
                }
                else
                {
                    break;
                }

            case '\\':
                return('\\');

            case 'n':
                return('\n');

            case 'r':
                return('\r');

            case '0':
                return('\0');

            case '\"':
                encountered |= EscapeC.DoubleQuotes;
                return('\"');

            case '\'':
                encountered |= EscapeC.SingleQuotes;
                return('\'');

            case '`':
                encountered |= EscapeC.Quotes;
                return('`');

            case 't':
                encountered |= EscapeC.Control;
                return('\t');

            case 'a':
                encountered |= EscapeC.ABFV;
                return('\a');

            case 'b':
                encountered |= EscapeC.ABFV;
                return('\b');

            case 'f':
                encountered |= EscapeC.ABFV;
                return('\f');

            case 'v':
                encountered |= EscapeC.ABFV;
                return('\v');
            }
            encountered |= EscapeC.Unrecognized;
            s            = original;
            return(c);
        }
示例#18
0
        /// <summary>Unescapes a single character of a string. Returns the
        /// character at 'index' if it is not a backslash, or if it is a
        /// backslash but no escape sequence could be discerned.</summary>
        /// <param name="i">Current index within the string, incremented
        /// by one normally and more than one in case of an escape sequence.</param>
        /// <param name="encountered">Bits of this parameter are set according
        /// to which escape sequence is encountered, if any.</param>
        /// <exception cref="IndexOutOfRangeException">The index was invalid.</exception>
        /// <example>
        /// int i = 3;
        /// EscapeC e = 0;
        /// char c = UnescapeChar(@"foo\n", ref i, ref e);
        /// Contract.Assert(c == '\n' && e == EscapeC.HasEscapes);
        /// </example>
        public static char UnescapeChar(string s, ref int i, ref EscapeC encountered)
        {
            char c = s[i++];

            if (c != '\\')
            {
                return(c);
            }

            encountered |= EscapeC.HasEscapes;
            if (i < s.Length)
            {
                int     code;
                UString slice;
                switch (s[i++])
                {
                case 'u':
                    slice = s.Slice(i, 4);
                    if (TryParseHex(slice, out code))
                    {
                        encountered |= code < 32 ? EscapeC.Control
                                                                         : EscapeC.NonAscii;
                        i += slice.Length;
                        return((char)code);
                    }
                    else
                    {
                        break;
                    }

                case 'x':
                    slice = s.Slice(i, 2);
                    if (TryParseHex(slice, out code))
                    {
                        encountered |= code < 32 ? EscapeC.BackslashX | EscapeC.Control
                                                                         : EscapeC.BackslashX | EscapeC.NonAscii;
                        i += slice.Length;
                        return((char)code);
                    }
                    else
                    {
                        break;
                    }

                case '\\':
                    return('\\');

                case 'n':
                    return('\n');

                case 'r':
                    return('\r');

                case '0':
                    return('\0');

                case '\"':
                    encountered |= EscapeC.DoubleQuotes;
                    return('\"');

                case '\'':
                    encountered |= EscapeC.SingleQuotes;
                    return('\'');

                case '`':
                    encountered |= EscapeC.Quotes;
                    return('`');

                case 't':
                    encountered |= EscapeC.Control;
                    return('\t');

                case 'a':
                    encountered |= EscapeC.ABFV;
                    return('\a');

                case 'b':
                    encountered |= EscapeC.ABFV;
                    return('\b');

                case 'f':
                    encountered |= EscapeC.ABFV;
                    return('\f');

                case 'v':
                    encountered |= EscapeC.ABFV;
                    return('\v');

                default:
                    encountered |= EscapeC.Unrecognized;
                    i--;
                    break;
                }
            }
            return(c);
        }
示例#19
0
        public static bool EscapeCStyle(char c, StringBuilder @out, EscapeC flags = EscapeC.Default, char quoteType = '\0')
        {
            do
            {
                if (c >= 128)
                {
                    if ((flags & EscapeC.NonAscii) != 0)
                    {
                        EscapeU(c, @out, flags);
                    }
                    else
                    {
                        break;
                    }
                }
                else if (c < 32)
                {
                    if (c == '\n')
                    {
                        @out.Append(@"\n");
                    }
                    else if (c == '\r')
                    {
                        @out.Append(@"\r");
                    }
                    else if (c == '\0')
                    {
                        @out.Append(@"\0");
                    }
                    else
                    {
                        if ((flags & EscapeC.ABFV) != 0)
                        {
                            if (c == '\a')                               // 7 (alert)
                            {
                                @out.Append(@"\a");
                                return(true);
                            }
                            if (c == '\b')                               // 8 (backspace)
                            {
                                @out.Append(@"\b");
                                return(true);
                            }
                            if (c == '\f')                               // 12 (form feed)
                            {
                                @out.Append(@"\f");
                                return(true);
                            }
                            if (c == '\v')                               // 11 (vertical tab)
                            {
                                @out.Append(@"\v");
                                return(true);
                            }
                        }
                        if ((flags & EscapeC.Control) != 0)
                        {
                            if (c == '\t')
                            {
                                @out.Append(@"\t");
                            }
                            else
                            {
                                EscapeU(c, @out, flags);
                            }
                        }
                        else
                        {
                            @out.Append(c);
                        }
                    }
                }
                else if (c == '\"' && (flags & EscapeC.DoubleQuotes) != 0)
                {
                    @out.Append("\\\"");
                }
                else if (c == '\'' && (flags & EscapeC.SingleQuotes) != 0)
                {
                    @out.Append("\\'");
                }
                else if (c == '\\')
                {
                    @out.Append(@"\\");
                }
                else
                {
                    break;
                }
                return(true);
            } while (false);

            if (c == quoteType)
            {
                @out.Append('\\');
                @out.Append(c);
                return(true);
            }
            else
            {
                @out.Append(c);
                return(false);
            }
        }
示例#20
0
文件: G.cs 项目: murven/Loyc
 public static bool EscapeCStyle(char c, StringBuilder @out, EscapeC flags = EscapeC.Default, char quoteType = '\0')
 {
     if (c > 255 && (flags & (EscapeC.Unicode | EscapeC.NonAscii)) != 0)
     {
         @out.AppendFormat((IFormatProvider)null, @"\u{0:x0000}", (int)c);
     }
     else if (c == '\"' && (flags & EscapeC.DoubleQuotes) != 0)
     {
         @out.Append("\\\"");
     }
     else if (c == '\'' && (flags & EscapeC.SingleQuotes) != 0)
     {
         @out.Append("\\'");
     }
     else if (c == quoteType)
     {
         @out.Append('\\');
         @out.Append(c);
     }
     else if (c < 32)
     {
         if (c == '\n')
         {
             @out.Append(@"\n");
         }
         else if (c == '\r')
         {
             @out.Append(@"\r");
         }
         else if (c == '\0')
         {
             @out.Append(@"\0");
         }
         else
         {
             if ((flags & EscapeC.ABFV) != 0)
             {
                 if (c == '\a')                           // 7 (alert)
                 {
                     @out.Append(@"\a");
                     return(true);
                 }
                 if (c == '\b')                           // 8 (backspace)
                 {
                     @out.Append(@"\b");
                     return(true);
                 }
                 if (c == '\f')                           // 12 (form feed)
                 {
                     @out.Append(@"\f");
                     return(true);
                 }
                 if (c == '\v')                           // 11 (vertical tab)
                 {
                     @out.Append(@"\v");
                     return(true);
                 }
             }
             if ((flags & EscapeC.Control) != 0)
             {
                 if (c == '\t')
                 {
                     @out.Append(@"\t");
                 }
                 else
                 {
                     @out.AppendFormat(null, @"\x{0:X2}", (int)c);
                 }
             }
             else
             {
                 @out.Append(c);
             }
         }
     }
     else if (c == '\\')
     {
         @out.Append(@"\\");
     }
     else if (c > 127 && (flags & EscapeC.NonAscii) != 0)
     {
         @out.AppendFormat(null, @"\x{0:X2}", (int)c);
     }
     else
     {
         @out.Append(c);
         return(false);
     }
     return(true);
 }
示例#21
0
		/// <summary>Escapes characters in a string using C style, e.g. the string 
		/// <c>"Foo\"\n"</c> maps to <c>"Foo\\\"\\\n"</c> by default.</summary>
		public static string EscapeCStyle(UString s, EscapeC flags = EscapeC.Default)
		{
			return EscapeCStyle(s, flags, '\0');
		}
示例#22
0
		/// <summary>Writes a character <c>c</c> to a StringBuilder, either as a normal 
		/// character or as a C-style escape sequence.</summary>
		/// <param name="flags">Specifies which characters should be escaped.</param>
		/// <param name="quoteType">Specifies a character that should always be 
		/// escaped (typically one of <c>' " `</c>)</param>
		/// <returns>true if an escape sequence was emitted, false if not.</returns>
		/// <remarks><see cref="EscapeC.HasLongEscape"/> can be used to force a 6-digit 
		/// unicode escape; this may be needed if the next character after this one 
		/// is a digit.</remarks>
		public static bool EscapeCStyle(int c, StringBuilder @out, EscapeC flags = EscapeC.Default, char quoteType = '\0')
		{
			for(;;) {
				if (c >= 128) {
					if ((flags & EscapeC.NonAscii) != 0) {
						EscapeU(c, @out, flags);
					} else if (c >= 0xDC00) {
						if ((flags & EscapeC.UnicodeNonCharacters) != 0 && (
							c >= 0xFDD0 && c <= 0xFDEF || // 0xFDD0...0xFDEF 
							(c & 0xFFFE) == 0xFFFE) || // 0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, etc.
							(c & 0xFC00) == 0xDC00) { // 0xDC00...0xDCFF 
							EscapeU(c, @out, flags);
						} else if ((flags & EscapeC.UnicodePrivateUse) != 0 && (
							c >= 0xE000 && c <= 0xF8FF ||
							c >= 0xF0000 && c <= 0xFFFFD ||
							c >= 0x100000 && c <= 0x10FFFD)) {
							EscapeU(c, @out, flags);
						} else
							break;
					} else
						break;
				} else if (c < 32) {
					if (c == '\n')
						@out.Append(@"\n");
					else if (c == '\r')
						@out.Append(@"\r");
					else if (c == '\0')
						@out.Append(@"\0");
					else {
						if ((flags & EscapeC.ABFV) != 0) {
							if (c == '\a') { // 7 (alert)
								@out.Append(@"\a");
								return true;
							}
							if (c == '\b') { // 8 (backspace)
								@out.Append(@"\b");
								return true;
							}
							if (c == '\f') { // 12 (form feed)
								@out.Append(@"\f");
								return true;
							}
							if (c == '\v') { // 11 (vertical tab)
								@out.Append(@"\v");
								return true;
							}
						}
						if ((flags & EscapeC.Control) != 0) {
							if (c == '\t')
								@out.Append(@"\t");
							else
								EscapeU(c, @out, flags);
						} else
							@out.Append(c);
					}
				} else if (c == '\"' && (flags & EscapeC.DoubleQuotes) != 0) {
					@out.Append("\\\"");
				} else if (c == '\'' && (flags & EscapeC.SingleQuotes) != 0) {
					@out.Append("\\'");
				} else if (c == '\\')
					@out.Append(@"\\");
				else
					break;
				return true;
			}

			if (c == quoteType) {
				@out.Append('\\');
				@out.Append((char)c);
				return true;
			} else 
				@out.AppendCodePoint(c);
			return false;
		}