예제 #1
0
        private static async Task <T> ReadValue <T>(
            PushbackTextReader reader,
            CancellationToken cancellationToken)
        {
            var startChar = (Char)reader.Read();

            if (startChar < 0)
            {
                throw new InvalidDataException("Unexpected end of buffer attempting to read Troop message.");
            }
            else if (startChar != '<')
            {
                throw new InvalidDataException($"Expected a value string with '<value>' but found a starting character of: '{startChar}'");
            }

            using var jsonReader = new MessageJsonReader(reader);
            var token = await JToken.LoadAsync(jsonReader, cancellationToken);

            // Hopefully this works with value types
            var result = token.ToObject <T>();

            // Calling close pushes unused buffer back to the reader
            jsonReader.Close();

            var endChar = (Char)reader.Read();

            if (endChar != '>')
            {
                throw new InvalidDataException($"Expected a value string with '<value>' but found a ending character of: '{startChar}'");
            }

            return(result);
        }
예제 #2
0
        static List <Object> ReadDelimitedList(char delim, PushbackTextReader r, bool isRecursive, object opts)
        {
            LineNumberingTextReader lntr = r as LineNumberingTextReader;
            int firstLine = lntr != null ? lntr.LineNumber : -1;

            List <Object> a = new List <object>();

            for (;;)
            {
                int ch = r.Read();

                while (isWhitespace(ch))
                {
                    ch = r.Read();
                }

                if (ch == -1)
                {
                    if (firstLine < 0)
                    {
                        throw new EndOfStreamException("EOF while reading");
                    }
                    else
                    {
                        throw new EndOfStreamException("EOF while reading, starting at line " + firstLine);
                    }
                }

                if (ch == delim)
                {
                    break;
                }

                IFn macroFn = getMacro(ch);
                if (macroFn != null)
                {
                    Object mret = macroFn.invoke(r, (char)ch, opts);
                    //no op macros return the reader
                    if (mret != r)
                    {
                        a.Add(mret);
                    }
                }
                else
                {
                    Unread(r, ch);
                    object o = read(r, true, null, isRecursive, opts);
                    if (o != r)
                    {
                        a.Add(o);
                    }
                }
            }

            return(a);
        }
예제 #3
0
        static object readNumber(PushbackTextReader r, char initch)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(initch);

            for (;;)
            {
                int ch = r.Read();
                if (ch == -1 || isWhitespace(ch) || isMacro(ch))
                {
                    Unread(r, ch);
                    break;
                }
                sb.Append((char)ch);
            }

            string s = sb.ToString();
            object n = MatchNumber(s);

            if (n == null)
            {
                throw new FormatException("Invalid number: " + s);
            }
            return(n);
        }
예제 #4
0
        static int readUnicodeChar(PushbackTextReader r, int initch, int radix, int length, bool exact)
        {
            int uc = CharValueInRadix(initch, radix);

            if (uc == -1)
            {
                throw new ArgumentException("Invalid digit: " + (char)initch);
            }
            int i = 1;

            for (; i < length; ++i)
            {
                int ch = r.Read();
                if (ch == -1 || isWhitespace(ch) || isMacro(ch))
                {
                    Unread(r, ch);
                    break;
                }
                int d = CharValueInRadix(ch, radix);
                if (d == -1)
                {
                    throw new ArgumentException("Invalid digit: " + (char)ch);
                }
                uc = uc * radix + d;
            }
            if (i != length && exact)
            {
                throw new ArgumentException("Invalid character length: " + i + ", should be: " + length);
            }
            return(uc);
        }
예제 #5
0
            protected override object Read(PushbackTextReader r, char semicolon, object opts)
            {
                int ch;

                do
                {
                    ch = r.Read();
                } while (ch != -1 && ch != '\n' && ch != '\r');
                return(r);
            }
예제 #6
0
            protected override object Read(PushbackTextReader r, char hash, object opts)
            {
                int ch = r.Read();

                if (ch == -1)
                {
                    throw new EndOfStreamException("EOF while reading character");
                }
                IFn fn = _dispatchMacros[ch];

                if (fn == null)
                {
                    // try tagged reader
                    if (Char.IsLetter((char)ch))
                    {
                        Unread(r, ch);
                        return(_taggedReader.invoke(r, (char)ch, opts));
                    }
                    throw new InvalidOperationException(String.Format("No dispatch macro for: {0}", (char)ch));
                }
                return(fn.invoke(r, (char)ch, opts));
            }
예제 #7
0
        static string readSimpleToken(PushbackTextReader r, char initch, bool leadConstituent)
        {
            if (leadConstituent && NonConstituent(initch))
            {
                throw new InvalidOperationException("Invalid leading characters: " + (char)initch);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(initch);

            for (;;)
            {
                int ch = r.Read();
                if (ch == -1 || isWhitespace(ch) || isTerminatingMacro(ch))
                {
                    Unread(r, ch);
                    return(sb.ToString());
                }
                sb.Append((char)ch);
            }
        }
예제 #8
0
        public static object read(PushbackTextReader r,
                                  bool eofIsError,
                                  object eofValue,
                                  bool isRecursive,
                                  Object opts)
        {
            try
            {
                for (;;)
                {
                    int ch = r.Read();

                    while (isWhitespace(ch))
                    {
                        ch = r.Read();
                    }

                    if (ch == -1)
                    {
                        if (eofIsError)
                        {
                            throw new EndOfStreamException("EOF while reading");
                        }
                        return(eofValue);
                    }

                    if (Char.IsDigit((char)ch))
                    {
                        object n = readNumber(r, (char)ch);
                        return(RT.suppressRead() ? null : n);
                    }

                    IFn macroFn = getMacro(ch);
                    if (macroFn != null)
                    {
                        object ret = macroFn.invoke(r, (char)ch, opts);
                        if (RT.suppressRead())
                        {
                            return(null);
                        }
                        // no op macros return the reader
                        if (ret == r)
                        {
                            continue;
                        }
                        return(ret);
                    }

                    if (ch == '+' || ch == '-')
                    {
                        int ch2 = r.Read();
                        if (Char.IsDigit((char)ch2))
                        {
                            Unread(r, ch2);
                            object n = readNumber(r, (char)ch);
                            return(RT.suppressRead() ? null : n);
                        }
                        Unread(r, ch2);
                    }

                    //string token = readToken(r, (char)ch);
                    //return RT.suppressRead() ? null : interpretToken(token);
                    string rawToken;
                    string token;
                    string mask;
                    bool   eofSeen;
                    readToken(r, (char)ch, true, out rawToken, out token, out mask, out eofSeen);
                    if (eofSeen)
                    {
                        if (eofIsError)
                        {
                            throw new EndOfStreamException("EOF while reading symbol");
                        }
                        return(eofValue);
                    }
                    return(RT.suppressRead() ? null : InterpretToken(rawToken, token, mask));
                }
            }
            catch (Exception e)
            {
                if (isRecursive)
                {
                    throw;
                }

                LineNumberingTextReader lntr = r as LineNumberingTextReader;
                if (lntr == null)
                {
                    throw;
                }

                throw new ReaderException(lntr.LineNumber, lntr.ColumnNumber, e);
            }
        }
예제 #9
0
            protected override object Read(PushbackTextReader r, char doublequote, object opts)
            {
                StringBuilder sb = new StringBuilder();

                for (int ch = r.Read(); ch != '"'; ch = r.Read())
                {
                    if (ch == -1)
                    {
                        throw new EndOfStreamException("EOF while reading string");
                    }
                    if (ch == '\\')                     //escape
                    {
                        ch = r.Read();
                        if (ch == -1)
                        {
                            throw new EndOfStreamException("EOF while reading string");
                        }
                        switch (ch)
                        {
                        case 't':
                            ch = '\t';
                            break;

                        case 'r':
                            ch = '\r';
                            break;

                        case 'n':
                            ch = '\n';
                            break;

                        case '\\':
                            break;

                        case '"':
                            break;

                        case 'b':
                            ch = '\b';
                            break;

                        case 'f':
                            ch = '\f';
                            break;

                        case 'u':
                            ch = r.Read();
                            if (CharValueInRadix(ch, 16) == -1)
                            {
                                throw new InvalidOperationException("Invalid unicode escape: \\u" + (char)ch);
                            }
                            ch = readUnicodeChar((PushbackTextReader)r, ch, 16, 4, true);
                            break;

                        default:
                        {
                            //if (CharValueInRadix(ch, 8) != -1)  -- this is correct, but we end up with different error message for 8,9 than JVM, so do the following to match:
                            if (Char.IsDigit((char)ch))
                            {
                                ch = readUnicodeChar((PushbackTextReader)r, ch, 8, 3, false);
                                if (ch > 255)                                                 //octal377
                                {
                                    throw new InvalidOperationException("Octal escape sequence must be in range [0, 377].");
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("Unsupported escape character: \\" + (char)ch);
                            }
                        }
                        break;
                        }
                    }
                    sb.Append((char)ch);
                }
                return(sb.ToString());
            }
예제 #10
0
            protected override object Read(PushbackTextReader r, char backslash, object opts)
            {
                int ch = r.Read();

                if (ch == -1)
                {
                    throw new EndOfStreamException("EOF while reading character");
                }
                String token = readSimpleToken(r, (char)ch, false);

                if (token.Length == 1)
                {
                    return(token[0]);
                }
                else if (token.Equals("newline"))
                {
                    return('\n');
                }
                else if (token.Equals("space"))
                {
                    return(' ');
                }
                else if (token.Equals("tab"))
                {
                    return('\t');
                }
                else if (token.Equals("backspace"))
                {
                    return('\b');
                }
                else if (token.Equals("formfeed"))
                {
                    return('\f');
                }
                else if (token.Equals("return"))
                {
                    return('\r');
                }
                else if (token.StartsWith("u"))
                {
                    char c = (char)readUnicodeChar(token, 1, 4, 16);
                    if (c >= '\uD800' && c <= '\uDFFF')                     // surrogate code unit?
                    {
                        throw new InvalidOperationException("Invalid character constant: \\u" + ((int)c).ToString("x"));
                    }
                    return(c);
                }
                else if (token.StartsWith("o"))
                {
                    int len = token.Length - 1;
                    if (len > 3)
                    {
                        throw new InvalidOperationException("Invalid octal escape sequence length: " + len);
                    }
                    int uc = readUnicodeChar(token, 1, len, 8);
                    if (uc > 255)                     //octal377
                    {
                        throw new InvalidOperationException("Octal escape sequence must be in range [0, 377].");
                    }
                    return((char)uc);
                }
                throw new InvalidOperationException("Unsupported character: \\" + token);
            }
예제 #11
0
        static void readToken(PushbackTextReader r, char initch, bool leadConstituent, out String rawToken, out String token, out String mask, out bool eofSeen)
        {
            if (leadConstituent && NonConstituent(initch))
            {
                throw new InvalidOperationException("Invalid leading characters: " + (char)initch);
            }

            bool allowSymEscape = RT.booleanCast(RT.AllowSymbolEscapeVar.deref());

            bool rawMode = false;

            StringBuilder sbRaw   = new StringBuilder();
            StringBuilder sbToken = new StringBuilder();
            StringBuilder sbMask  = new StringBuilder();

            if (allowSymEscape && initch == '|')
            {
                rawMode = true;
                sbRaw.Append(initch);
            }
            else
            {
                sbRaw.Append(initch);
                sbToken.Append(initch);
                sbMask.Append(initch);
            }

            for (;;)
            {
                int ch = r.Read();
                if (rawMode)
                {
                    if (ch == -1)
                    {
                        rawToken = sbRaw.ToString();
                        token    = sbToken.ToString();
                        mask     = sbMask.ToString();
                        eofSeen  = true;
                        return;
                    }
                    if (ch == '|')
                    {
                        int ch2 = r.Read();
                        if (ch2 == '|')
                        {
                            sbRaw.Append('|');
                            sbToken.Append('|');
                            sbMask.Append('a');
                        }
                        else
                        {
                            r.Unread(ch2);
                            rawMode = false;
                            sbRaw.Append(ch);
                        }
                    }
                    else
                    {
                        sbRaw.Append((char)ch);
                        sbToken.Append((char)ch);
                        sbMask.Append('a');
                    }
                }
                else
                {
                    if (ch == -1 || isWhitespace(ch) || isTerminatingMacro(ch))
                    {
                        Unread(r, ch);
                        rawToken = sbRaw.ToString();
                        token    = sbToken.ToString();
                        mask     = sbMask.ToString();
                        eofSeen  = false;
                        return;
                    }
                    else if (NonConstituent(ch))
                    {
                        throw new InvalidOperationException("Invalid constituent character: " + (char)ch);
                    }
                    else if (ch == '|' && allowSymEscape)
                    {
                        rawMode = true;
                        sbRaw.Append((char)ch);
                    }
                    else
                    {
                        sbRaw.Append((char)ch);
                        sbToken.Append((char)ch);
                        sbMask.Append((char)ch);
                    }
                }
            }
        }