Statistics
| Branch: | Revision:

root / trunk / Libraries / Json40r2 / Source / Src / Newtonsoft.Json / JsonTextReader.cs @ ed0be341

History | View | Annotate | Download (29.7 kB)

1 d78cbf09 Panagiotis Kanavos
#region License
2 d78cbf09 Panagiotis Kanavos
// Copyright (c) 2007 James Newton-King
3 d78cbf09 Panagiotis Kanavos
//
4 d78cbf09 Panagiotis Kanavos
// Permission is hereby granted, free of charge, to any person
5 d78cbf09 Panagiotis Kanavos
// obtaining a copy of this software and associated documentation
6 d78cbf09 Panagiotis Kanavos
// files (the "Software"), to deal in the Software without
7 d78cbf09 Panagiotis Kanavos
// restriction, including without limitation the rights to use,
8 d78cbf09 Panagiotis Kanavos
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9 d78cbf09 Panagiotis Kanavos
// copies of the Software, and to permit persons to whom the
10 d78cbf09 Panagiotis Kanavos
// Software is furnished to do so, subject to the following
11 d78cbf09 Panagiotis Kanavos
// conditions:
12 d78cbf09 Panagiotis Kanavos
//
13 d78cbf09 Panagiotis Kanavos
// The above copyright notice and this permission notice shall be
14 d78cbf09 Panagiotis Kanavos
// included in all copies or substantial portions of the Software.
15 d78cbf09 Panagiotis Kanavos
//
16 d78cbf09 Panagiotis Kanavos
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 d78cbf09 Panagiotis Kanavos
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 d78cbf09 Panagiotis Kanavos
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 d78cbf09 Panagiotis Kanavos
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 d78cbf09 Panagiotis Kanavos
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 d78cbf09 Panagiotis Kanavos
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 d78cbf09 Panagiotis Kanavos
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 d78cbf09 Panagiotis Kanavos
// OTHER DEALINGS IN THE SOFTWARE.
24 d78cbf09 Panagiotis Kanavos
#endregion
25 d78cbf09 Panagiotis Kanavos
26 d78cbf09 Panagiotis Kanavos
using System;
27 d78cbf09 Panagiotis Kanavos
using System.Collections.Generic;
28 d78cbf09 Panagiotis Kanavos
using System.Text;
29 d78cbf09 Panagiotis Kanavos
using System.IO;
30 d78cbf09 Panagiotis Kanavos
using System.Xml;
31 d78cbf09 Panagiotis Kanavos
using System.Globalization;
32 d78cbf09 Panagiotis Kanavos
using Newtonsoft.Json.Utilities;
33 d78cbf09 Panagiotis Kanavos
34 d78cbf09 Panagiotis Kanavos
namespace Newtonsoft.Json
35 d78cbf09 Panagiotis Kanavos
{
36 d78cbf09 Panagiotis Kanavos
  /// <summary>
37 d78cbf09 Panagiotis Kanavos
  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
38 d78cbf09 Panagiotis Kanavos
  /// </summary>
39 d78cbf09 Panagiotis Kanavos
  public class JsonTextReader : JsonReader, IJsonLineInfo
40 d78cbf09 Panagiotis Kanavos
  {
41 d78cbf09 Panagiotis Kanavos
    private enum ReadType
42 d78cbf09 Panagiotis Kanavos
    {
43 d78cbf09 Panagiotis Kanavos
      Read,
44 d78cbf09 Panagiotis Kanavos
      ReadAsBytes,
45 d78cbf09 Panagiotis Kanavos
      ReadAsDecimal,
46 d78cbf09 Panagiotis Kanavos
#if !NET20
47 d78cbf09 Panagiotis Kanavos
      ReadAsDateTimeOffset
48 d78cbf09 Panagiotis Kanavos
#endif
49 d78cbf09 Panagiotis Kanavos
    }
50 d78cbf09 Panagiotis Kanavos
51 d78cbf09 Panagiotis Kanavos
    private readonly TextReader _reader;
52 d78cbf09 Panagiotis Kanavos
    private readonly StringBuffer _buffer;
53 d78cbf09 Panagiotis Kanavos
    private char? _lastChar;
54 d78cbf09 Panagiotis Kanavos
    private int _currentLinePosition;
55 d78cbf09 Panagiotis Kanavos
    private int _currentLineNumber;
56 d78cbf09 Panagiotis Kanavos
    private bool _end;
57 d78cbf09 Panagiotis Kanavos
    private ReadType _readType;
58 d78cbf09 Panagiotis Kanavos
59 d78cbf09 Panagiotis Kanavos
    /// <summary>
60 d78cbf09 Panagiotis Kanavos
    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
61 d78cbf09 Panagiotis Kanavos
    /// </summary>
62 d78cbf09 Panagiotis Kanavos
    /// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
63 d78cbf09 Panagiotis Kanavos
    public JsonTextReader(TextReader reader)
64 d78cbf09 Panagiotis Kanavos
    {
65 d78cbf09 Panagiotis Kanavos
      if (reader == null)
66 d78cbf09 Panagiotis Kanavos
        throw new ArgumentNullException("reader");
67 d78cbf09 Panagiotis Kanavos
68 d78cbf09 Panagiotis Kanavos
      _reader = reader;
69 d78cbf09 Panagiotis Kanavos
      _buffer = new StringBuffer(4096);
70 d78cbf09 Panagiotis Kanavos
      _currentLineNumber = 1;
71 d78cbf09 Panagiotis Kanavos
    }
72 d78cbf09 Panagiotis Kanavos
73 d78cbf09 Panagiotis Kanavos
    private void ParseString(char quote)
74 d78cbf09 Panagiotis Kanavos
    {
75 d78cbf09 Panagiotis Kanavos
      ReadStringIntoBuffer(quote);
76 d78cbf09 Panagiotis Kanavos
77 d78cbf09 Panagiotis Kanavos
      if (_readType == ReadType.ReadAsBytes)
78 d78cbf09 Panagiotis Kanavos
      {
79 d78cbf09 Panagiotis Kanavos
        byte[] data;
80 d78cbf09 Panagiotis Kanavos
        if (_buffer.Position == 0)
81 d78cbf09 Panagiotis Kanavos
        {
82 d78cbf09 Panagiotis Kanavos
          data = new byte[0];
83 d78cbf09 Panagiotis Kanavos
        }
84 d78cbf09 Panagiotis Kanavos
        else
85 d78cbf09 Panagiotis Kanavos
        {
86 d78cbf09 Panagiotis Kanavos
          data = Convert.FromBase64CharArray(_buffer.GetInternalBuffer(), 0, _buffer.Position);
87 d78cbf09 Panagiotis Kanavos
          _buffer.Position = 0;
88 d78cbf09 Panagiotis Kanavos
        }
89 d78cbf09 Panagiotis Kanavos
90 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Bytes, data);
91 d78cbf09 Panagiotis Kanavos
      }
92 d78cbf09 Panagiotis Kanavos
      else
93 d78cbf09 Panagiotis Kanavos
      {
94 d78cbf09 Panagiotis Kanavos
        string text = _buffer.ToString();
95 d78cbf09 Panagiotis Kanavos
        _buffer.Position = 0;
96 d78cbf09 Panagiotis Kanavos
97 d78cbf09 Panagiotis Kanavos
        if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
98 d78cbf09 Panagiotis Kanavos
        {
99 d78cbf09 Panagiotis Kanavos
          ParseDate(text);
100 d78cbf09 Panagiotis Kanavos
        }
101 d78cbf09 Panagiotis Kanavos
        else
102 d78cbf09 Panagiotis Kanavos
        {
103 d78cbf09 Panagiotis Kanavos
          SetToken(JsonToken.String, text);
104 d78cbf09 Panagiotis Kanavos
          QuoteChar = quote;
105 d78cbf09 Panagiotis Kanavos
        } 
106 d78cbf09 Panagiotis Kanavos
      }
107 d78cbf09 Panagiotis Kanavos
    }
108 d78cbf09 Panagiotis Kanavos
109 d78cbf09 Panagiotis Kanavos
    private void ReadStringIntoBuffer(char quote)
110 d78cbf09 Panagiotis Kanavos
    {
111 d78cbf09 Panagiotis Kanavos
      while (true)
112 d78cbf09 Panagiotis Kanavos
      {
113 d78cbf09 Panagiotis Kanavos
        char currentChar = MoveNext();
114 d78cbf09 Panagiotis Kanavos
115 d78cbf09 Panagiotis Kanavos
        switch (currentChar)
116 d78cbf09 Panagiotis Kanavos
        {
117 d78cbf09 Panagiotis Kanavos
          case '\0':
118 d78cbf09 Panagiotis Kanavos
            if (_end)
119 d78cbf09 Panagiotis Kanavos
              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
120 d78cbf09 Panagiotis Kanavos
121 d78cbf09 Panagiotis Kanavos
            _buffer.Append('\0');
122 d78cbf09 Panagiotis Kanavos
            break;
123 d78cbf09 Panagiotis Kanavos
          case '\\':
124 d78cbf09 Panagiotis Kanavos
            if ((currentChar = MoveNext()) != '\0' || !_end)
125 d78cbf09 Panagiotis Kanavos
            {
126 d78cbf09 Panagiotis Kanavos
              switch (currentChar)
127 d78cbf09 Panagiotis Kanavos
              {
128 d78cbf09 Panagiotis Kanavos
                case 'b':
129 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\b');
130 d78cbf09 Panagiotis Kanavos
                  break;
131 d78cbf09 Panagiotis Kanavos
                case 't':
132 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\t');
133 d78cbf09 Panagiotis Kanavos
                  break;
134 d78cbf09 Panagiotis Kanavos
                case 'n':
135 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\n');
136 d78cbf09 Panagiotis Kanavos
                  break;
137 d78cbf09 Panagiotis Kanavos
                case 'f':
138 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\f');
139 d78cbf09 Panagiotis Kanavos
                  break;
140 d78cbf09 Panagiotis Kanavos
                case 'r':
141 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\r');
142 d78cbf09 Panagiotis Kanavos
                  break;
143 d78cbf09 Panagiotis Kanavos
                case '\\':
144 d78cbf09 Panagiotis Kanavos
                  _buffer.Append('\\');
145 d78cbf09 Panagiotis Kanavos
                  break;
146 d78cbf09 Panagiotis Kanavos
                case '"':
147 d78cbf09 Panagiotis Kanavos
                case '\'':
148 d78cbf09 Panagiotis Kanavos
                case '/':
149 d78cbf09 Panagiotis Kanavos
                  _buffer.Append(currentChar);
150 d78cbf09 Panagiotis Kanavos
                  break;
151 d78cbf09 Panagiotis Kanavos
                case 'u':
152 d78cbf09 Panagiotis Kanavos
                  char[] hexValues = new char[4];
153 d78cbf09 Panagiotis Kanavos
                  for (int i = 0; i < hexValues.Length; i++)
154 d78cbf09 Panagiotis Kanavos
                  {
155 d78cbf09 Panagiotis Kanavos
                    if ((currentChar = MoveNext()) != '\0' || !_end)
156 d78cbf09 Panagiotis Kanavos
                      hexValues[i] = currentChar;
157 d78cbf09 Panagiotis Kanavos
                    else
158 d78cbf09 Panagiotis Kanavos
                      throw CreateJsonReaderException("Unexpected end while parsing unicode character. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
159 d78cbf09 Panagiotis Kanavos
                  }
160 d78cbf09 Panagiotis Kanavos
161 d78cbf09 Panagiotis Kanavos
                  char hexChar = Convert.ToChar(int.Parse(new string(hexValues), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
162 d78cbf09 Panagiotis Kanavos
                  _buffer.Append(hexChar);
163 d78cbf09 Panagiotis Kanavos
                  break;
164 d78cbf09 Panagiotis Kanavos
                default:
165 d78cbf09 Panagiotis Kanavos
                  throw CreateJsonReaderException("Bad JSON escape sequence: {0}. Line {1}, position {2}.", @"\" + currentChar, _currentLineNumber, _currentLinePosition);
166 d78cbf09 Panagiotis Kanavos
              }
167 d78cbf09 Panagiotis Kanavos
            }
168 d78cbf09 Panagiotis Kanavos
            else
169 d78cbf09 Panagiotis Kanavos
            {
170 d78cbf09 Panagiotis Kanavos
              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
171 d78cbf09 Panagiotis Kanavos
            }
172 d78cbf09 Panagiotis Kanavos
            break;
173 d78cbf09 Panagiotis Kanavos
          case '"':
174 d78cbf09 Panagiotis Kanavos
          case '\'':
175 d78cbf09 Panagiotis Kanavos
            if (currentChar == quote)
176 d78cbf09 Panagiotis Kanavos
            {
177 d78cbf09 Panagiotis Kanavos
              return;
178 d78cbf09 Panagiotis Kanavos
            }
179 d78cbf09 Panagiotis Kanavos
            else
180 d78cbf09 Panagiotis Kanavos
            {
181 d78cbf09 Panagiotis Kanavos
              _buffer.Append(currentChar);
182 d78cbf09 Panagiotis Kanavos
            }
183 d78cbf09 Panagiotis Kanavos
            break;
184 d78cbf09 Panagiotis Kanavos
          default:
185 d78cbf09 Panagiotis Kanavos
            _buffer.Append(currentChar);
186 d78cbf09 Panagiotis Kanavos
            break;
187 d78cbf09 Panagiotis Kanavos
        }
188 d78cbf09 Panagiotis Kanavos
      }
189 d78cbf09 Panagiotis Kanavos
    }
190 d78cbf09 Panagiotis Kanavos
191 d78cbf09 Panagiotis Kanavos
    private JsonReaderException CreateJsonReaderException(string format, params object[] args)
192 d78cbf09 Panagiotis Kanavos
    {
193 d78cbf09 Panagiotis Kanavos
      string message = format.FormatWith(CultureInfo.InvariantCulture, args);
194 d78cbf09 Panagiotis Kanavos
      return new JsonReaderException(message, null, _currentLineNumber, _currentLinePosition);
195 d78cbf09 Panagiotis Kanavos
    }
196 d78cbf09 Panagiotis Kanavos
197 d78cbf09 Panagiotis Kanavos
    private TimeSpan ReadOffset(string offsetText)
198 d78cbf09 Panagiotis Kanavos
    {
199 d78cbf09 Panagiotis Kanavos
      bool negative = (offsetText[0] == '-');
200 d78cbf09 Panagiotis Kanavos
201 d78cbf09 Panagiotis Kanavos
      int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
202 d78cbf09 Panagiotis Kanavos
      int minutes = 0;
203 d78cbf09 Panagiotis Kanavos
      if (offsetText.Length >= 5)
204 d78cbf09 Panagiotis Kanavos
        minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
205 d78cbf09 Panagiotis Kanavos
206 d78cbf09 Panagiotis Kanavos
      TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
207 d78cbf09 Panagiotis Kanavos
      if (negative)
208 d78cbf09 Panagiotis Kanavos
        offset = offset.Negate();
209 d78cbf09 Panagiotis Kanavos
      
210 d78cbf09 Panagiotis Kanavos
      return offset;
211 d78cbf09 Panagiotis Kanavos
    }
212 d78cbf09 Panagiotis Kanavos
213 d78cbf09 Panagiotis Kanavos
    private void ParseDate(string text)
214 d78cbf09 Panagiotis Kanavos
    {
215 d78cbf09 Panagiotis Kanavos
      string value = text.Substring(6, text.Length - 8);
216 d78cbf09 Panagiotis Kanavos
      DateTimeKind kind = DateTimeKind.Utc;
217 d78cbf09 Panagiotis Kanavos
218 d78cbf09 Panagiotis Kanavos
      int index = value.IndexOf('+', 1);
219 d78cbf09 Panagiotis Kanavos
220 d78cbf09 Panagiotis Kanavos
      if (index == -1)
221 d78cbf09 Panagiotis Kanavos
        index = value.IndexOf('-', 1);
222 d78cbf09 Panagiotis Kanavos
223 d78cbf09 Panagiotis Kanavos
      TimeSpan offset = TimeSpan.Zero;
224 d78cbf09 Panagiotis Kanavos
225 d78cbf09 Panagiotis Kanavos
      if (index != -1)
226 d78cbf09 Panagiotis Kanavos
      {
227 d78cbf09 Panagiotis Kanavos
        kind = DateTimeKind.Local;
228 d78cbf09 Panagiotis Kanavos
        offset = ReadOffset(value.Substring(index));
229 d78cbf09 Panagiotis Kanavos
        value = value.Substring(0, index);
230 d78cbf09 Panagiotis Kanavos
      }
231 d78cbf09 Panagiotis Kanavos
232 d78cbf09 Panagiotis Kanavos
      long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
233 d78cbf09 Panagiotis Kanavos
234 d78cbf09 Panagiotis Kanavos
      DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
235 d78cbf09 Panagiotis Kanavos
236 d78cbf09 Panagiotis Kanavos
#if !NET20
237 d78cbf09 Panagiotis Kanavos
      if (_readType == ReadType.ReadAsDateTimeOffset)
238 d78cbf09 Panagiotis Kanavos
      {
239 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Date, new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset));
240 d78cbf09 Panagiotis Kanavos
      }
241 d78cbf09 Panagiotis Kanavos
      else
242 d78cbf09 Panagiotis Kanavos
#endif
243 d78cbf09 Panagiotis Kanavos
      {
244 d78cbf09 Panagiotis Kanavos
        DateTime dateTime;
245 d78cbf09 Panagiotis Kanavos
246 d78cbf09 Panagiotis Kanavos
        switch (kind)
247 d78cbf09 Panagiotis Kanavos
        {
248 d78cbf09 Panagiotis Kanavos
          case DateTimeKind.Unspecified:
249 d78cbf09 Panagiotis Kanavos
            dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
250 d78cbf09 Panagiotis Kanavos
            break;
251 d78cbf09 Panagiotis Kanavos
          case DateTimeKind.Local:
252 d78cbf09 Panagiotis Kanavos
            dateTime = utcDateTime.ToLocalTime();
253 d78cbf09 Panagiotis Kanavos
            break;
254 d78cbf09 Panagiotis Kanavos
          default:
255 d78cbf09 Panagiotis Kanavos
            dateTime = utcDateTime;
256 d78cbf09 Panagiotis Kanavos
            break;
257 d78cbf09 Panagiotis Kanavos
        }
258 d78cbf09 Panagiotis Kanavos
259 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Date, dateTime);
260 d78cbf09 Panagiotis Kanavos
      }
261 d78cbf09 Panagiotis Kanavos
    }
262 d78cbf09 Panagiotis Kanavos
263 d78cbf09 Panagiotis Kanavos
    private const int LineFeedValue = StringUtils.LineFeed;
264 d78cbf09 Panagiotis Kanavos
    private const int CarriageReturnValue = StringUtils.CarriageReturn;
265 d78cbf09 Panagiotis Kanavos
266 d78cbf09 Panagiotis Kanavos
    private char MoveNext()
267 d78cbf09 Panagiotis Kanavos
    {
268 d78cbf09 Panagiotis Kanavos
      int value = _reader.Read();
269 d78cbf09 Panagiotis Kanavos
270 d78cbf09 Panagiotis Kanavos
      switch (value)
271 d78cbf09 Panagiotis Kanavos
      {
272 d78cbf09 Panagiotis Kanavos
        case -1:
273 d78cbf09 Panagiotis Kanavos
          _end = true;
274 d78cbf09 Panagiotis Kanavos
          return '\0';
275 d78cbf09 Panagiotis Kanavos
        case CarriageReturnValue:
276 d78cbf09 Panagiotis Kanavos
          if (_reader.Peek() == LineFeedValue)
277 d78cbf09 Panagiotis Kanavos
            _reader.Read();
278 d78cbf09 Panagiotis Kanavos
279 d78cbf09 Panagiotis Kanavos
          _currentLineNumber++;
280 d78cbf09 Panagiotis Kanavos
          _currentLinePosition = 0;
281 d78cbf09 Panagiotis Kanavos
          break;
282 d78cbf09 Panagiotis Kanavos
        case LineFeedValue:
283 d78cbf09 Panagiotis Kanavos
          _currentLineNumber++;
284 d78cbf09 Panagiotis Kanavos
          _currentLinePosition = 0;
285 d78cbf09 Panagiotis Kanavos
          break;
286 d78cbf09 Panagiotis Kanavos
        default:
287 d78cbf09 Panagiotis Kanavos
          _currentLinePosition++;
288 d78cbf09 Panagiotis Kanavos
          break;
289 d78cbf09 Panagiotis Kanavos
      }
290 d78cbf09 Panagiotis Kanavos
291 d78cbf09 Panagiotis Kanavos
      return (char)value;
292 d78cbf09 Panagiotis Kanavos
    }
293 d78cbf09 Panagiotis Kanavos
294 d78cbf09 Panagiotis Kanavos
    private bool HasNext()
295 d78cbf09 Panagiotis Kanavos
    {
296 d78cbf09 Panagiotis Kanavos
      return (_reader.Peek() != -1);
297 d78cbf09 Panagiotis Kanavos
    }
298 d78cbf09 Panagiotis Kanavos
299 d78cbf09 Panagiotis Kanavos
    private int PeekNext()
300 d78cbf09 Panagiotis Kanavos
    {
301 d78cbf09 Panagiotis Kanavos
      return _reader.Peek();
302 d78cbf09 Panagiotis Kanavos
    }
303 d78cbf09 Panagiotis Kanavos
304 d78cbf09 Panagiotis Kanavos
    /// <summary>
305 d78cbf09 Panagiotis Kanavos
    /// Reads the next JSON token from the stream.
306 d78cbf09 Panagiotis Kanavos
    /// </summary>
307 d78cbf09 Panagiotis Kanavos
    /// <returns>
308 d78cbf09 Panagiotis Kanavos
    /// true if the next token was read successfully; false if there are no more tokens to read.
309 d78cbf09 Panagiotis Kanavos
    /// </returns>
310 d78cbf09 Panagiotis Kanavos
    public override bool Read()
311 d78cbf09 Panagiotis Kanavos
    {
312 d78cbf09 Panagiotis Kanavos
      _readType = ReadType.Read;
313 d78cbf09 Panagiotis Kanavos
      return ReadInternal();
314 d78cbf09 Panagiotis Kanavos
    }
315 d78cbf09 Panagiotis Kanavos
316 d78cbf09 Panagiotis Kanavos
    /// <summary>
317 d78cbf09 Panagiotis Kanavos
    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
318 d78cbf09 Panagiotis Kanavos
    /// </summary>
319 d78cbf09 Panagiotis Kanavos
    /// <returns>
320 d78cbf09 Panagiotis Kanavos
    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
321 d78cbf09 Panagiotis Kanavos
    /// </returns>
322 d78cbf09 Panagiotis Kanavos
    public override byte[] ReadAsBytes()
323 d78cbf09 Panagiotis Kanavos
    {
324 d78cbf09 Panagiotis Kanavos
      _readType = ReadType.ReadAsBytes;
325 d78cbf09 Panagiotis Kanavos
326 d78cbf09 Panagiotis Kanavos
      do
327 d78cbf09 Panagiotis Kanavos
      {
328 d78cbf09 Panagiotis Kanavos
        if (!ReadInternal())
329 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
330 d78cbf09 Panagiotis Kanavos
      } while (TokenType == JsonToken.Comment);
331 d78cbf09 Panagiotis Kanavos
332 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Null)
333 d78cbf09 Panagiotis Kanavos
        return null;
334 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Bytes)
335 d78cbf09 Panagiotis Kanavos
        return (byte[]) Value;
336 d78cbf09 Panagiotis Kanavos
337 d78cbf09 Panagiotis Kanavos
      throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
338 d78cbf09 Panagiotis Kanavos
    }
339 d78cbf09 Panagiotis Kanavos
340 d78cbf09 Panagiotis Kanavos
    /// <summary>
341 d78cbf09 Panagiotis Kanavos
    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
342 d78cbf09 Panagiotis Kanavos
    /// </summary>
343 d78cbf09 Panagiotis Kanavos
    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
344 d78cbf09 Panagiotis Kanavos
    public override decimal? ReadAsDecimal()
345 d78cbf09 Panagiotis Kanavos
    {
346 d78cbf09 Panagiotis Kanavos
      _readType = ReadType.ReadAsDecimal;
347 d78cbf09 Panagiotis Kanavos
      
348 d78cbf09 Panagiotis Kanavos
      do
349 d78cbf09 Panagiotis Kanavos
      {
350 d78cbf09 Panagiotis Kanavos
        if (!ReadInternal())
351 d78cbf09 Panagiotis Kanavos
          throw CreateJsonReaderException("Unexpected end when reading decimal: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
352 d78cbf09 Panagiotis Kanavos
      } while (TokenType == JsonToken.Comment);
353 d78cbf09 Panagiotis Kanavos
 
354 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Null)
355 d78cbf09 Panagiotis Kanavos
        return null;
356 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Float)
357 d78cbf09 Panagiotis Kanavos
        return (decimal?)Value;
358 d78cbf09 Panagiotis Kanavos
359 d78cbf09 Panagiotis Kanavos
      decimal d;
360 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.String && decimal.TryParse((string)Value, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
361 d78cbf09 Panagiotis Kanavos
      {
362 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Float, d);
363 d78cbf09 Panagiotis Kanavos
        return d;
364 d78cbf09 Panagiotis Kanavos
      }
365 d78cbf09 Panagiotis Kanavos
366 d78cbf09 Panagiotis Kanavos
      throw CreateJsonReaderException("Unexpected token when reading decimal: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
367 d78cbf09 Panagiotis Kanavos
    }
368 d78cbf09 Panagiotis Kanavos
369 d78cbf09 Panagiotis Kanavos
#if !NET20
370 d78cbf09 Panagiotis Kanavos
    /// <summary>
371 d78cbf09 Panagiotis Kanavos
    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
372 d78cbf09 Panagiotis Kanavos
    /// </summary>
373 d78cbf09 Panagiotis Kanavos
    /// <returns>A <see cref="DateTimeOffset"/>.</returns>
374 d78cbf09 Panagiotis Kanavos
    public override DateTimeOffset? ReadAsDateTimeOffset()
375 d78cbf09 Panagiotis Kanavos
    {
376 d78cbf09 Panagiotis Kanavos
      _readType = ReadType.ReadAsDateTimeOffset;
377 d78cbf09 Panagiotis Kanavos
378 d78cbf09 Panagiotis Kanavos
      do
379 d78cbf09 Panagiotis Kanavos
      {
380 d78cbf09 Panagiotis Kanavos
        if (!ReadInternal())
381 d78cbf09 Panagiotis Kanavos
          throw CreateJsonReaderException("Unexpected end when reading date: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
382 d78cbf09 Panagiotis Kanavos
      } while (TokenType == JsonToken.Comment);
383 d78cbf09 Panagiotis Kanavos
384 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Null)
385 d78cbf09 Panagiotis Kanavos
        return null;
386 d78cbf09 Panagiotis Kanavos
      if (TokenType == JsonToken.Date)
387 d78cbf09 Panagiotis Kanavos
        return (DateTimeOffset)Value;
388 d78cbf09 Panagiotis Kanavos
389 d78cbf09 Panagiotis Kanavos
      throw CreateJsonReaderException("Unexpected token when reading date: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
390 d78cbf09 Panagiotis Kanavos
    }
391 d78cbf09 Panagiotis Kanavos
#endif
392 d78cbf09 Panagiotis Kanavos
393 d78cbf09 Panagiotis Kanavos
    private bool ReadInternal()
394 d78cbf09 Panagiotis Kanavos
    {
395 d78cbf09 Panagiotis Kanavos
      while (true)
396 d78cbf09 Panagiotis Kanavos
      {
397 d78cbf09 Panagiotis Kanavos
        char currentChar;
398 d78cbf09 Panagiotis Kanavos
        if (_lastChar != null)
399 d78cbf09 Panagiotis Kanavos
        {
400 d78cbf09 Panagiotis Kanavos
          currentChar = _lastChar.Value;
401 d78cbf09 Panagiotis Kanavos
          _lastChar = null;
402 d78cbf09 Panagiotis Kanavos
        }
403 d78cbf09 Panagiotis Kanavos
        else
404 d78cbf09 Panagiotis Kanavos
        {
405 d78cbf09 Panagiotis Kanavos
          currentChar = MoveNext();
406 d78cbf09 Panagiotis Kanavos
        }
407 d78cbf09 Panagiotis Kanavos
408 d78cbf09 Panagiotis Kanavos
        if (currentChar == '\0' && _end)
409 d78cbf09 Panagiotis Kanavos
          return false;
410 d78cbf09 Panagiotis Kanavos
411 d78cbf09 Panagiotis Kanavos
        switch (CurrentState)
412 d78cbf09 Panagiotis Kanavos
        {
413 d78cbf09 Panagiotis Kanavos
          case State.Start:
414 d78cbf09 Panagiotis Kanavos
          case State.Property:
415 d78cbf09 Panagiotis Kanavos
          case State.Array:
416 d78cbf09 Panagiotis Kanavos
          case State.ArrayStart:
417 d78cbf09 Panagiotis Kanavos
          case State.Constructor:
418 d78cbf09 Panagiotis Kanavos
          case State.ConstructorStart:
419 d78cbf09 Panagiotis Kanavos
            return ParseValue(currentChar);
420 d78cbf09 Panagiotis Kanavos
          case State.Complete:
421 d78cbf09 Panagiotis Kanavos
            break;
422 d78cbf09 Panagiotis Kanavos
          case State.Object:
423 d78cbf09 Panagiotis Kanavos
          case State.ObjectStart:
424 d78cbf09 Panagiotis Kanavos
            return ParseObject(currentChar);
425 d78cbf09 Panagiotis Kanavos
          case State.PostValue:
426 d78cbf09 Panagiotis Kanavos
            // returns true if it hits
427 d78cbf09 Panagiotis Kanavos
            // end of object or array
428 d78cbf09 Panagiotis Kanavos
            if (ParsePostValue(currentChar))
429 d78cbf09 Panagiotis Kanavos
              return true;
430 d78cbf09 Panagiotis Kanavos
            break;
431 d78cbf09 Panagiotis Kanavos
          case State.Closed:
432 d78cbf09 Panagiotis Kanavos
            break;
433 d78cbf09 Panagiotis Kanavos
          case State.Error:
434 d78cbf09 Panagiotis Kanavos
            break;
435 d78cbf09 Panagiotis Kanavos
          default:
436 d78cbf09 Panagiotis Kanavos
            throw CreateJsonReaderException("Unexpected state: {0}. Line {1}, position {2}.", CurrentState, _currentLineNumber, _currentLinePosition);
437 d78cbf09 Panagiotis Kanavos
        }
438 d78cbf09 Panagiotis Kanavos
      }
439 d78cbf09 Panagiotis Kanavos
    }
440 d78cbf09 Panagiotis Kanavos
441 d78cbf09 Panagiotis Kanavos
    private bool ParsePostValue(char currentChar)
442 d78cbf09 Panagiotis Kanavos
    {
443 d78cbf09 Panagiotis Kanavos
      do
444 d78cbf09 Panagiotis Kanavos
      {
445 d78cbf09 Panagiotis Kanavos
        switch (currentChar)
446 d78cbf09 Panagiotis Kanavos
        {
447 d78cbf09 Panagiotis Kanavos
          case '}':
448 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndObject);
449 d78cbf09 Panagiotis Kanavos
            return true;
450 d78cbf09 Panagiotis Kanavos
          case ']':
451 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndArray);
452 d78cbf09 Panagiotis Kanavos
            return true;
453 d78cbf09 Panagiotis Kanavos
          case ')':
454 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndConstructor);
455 d78cbf09 Panagiotis Kanavos
            return true;
456 d78cbf09 Panagiotis Kanavos
          case '/':
457 d78cbf09 Panagiotis Kanavos
            ParseComment();
458 d78cbf09 Panagiotis Kanavos
            return true;
459 d78cbf09 Panagiotis Kanavos
          case ',':
460 d78cbf09 Panagiotis Kanavos
            // finished parsing
461 d78cbf09 Panagiotis Kanavos
            SetStateBasedOnCurrent();
462 d78cbf09 Panagiotis Kanavos
            return false;
463 d78cbf09 Panagiotis Kanavos
          case ' ':
464 d78cbf09 Panagiotis Kanavos
          case StringUtils.Tab:
465 d78cbf09 Panagiotis Kanavos
          case StringUtils.LineFeed:
466 d78cbf09 Panagiotis Kanavos
          case StringUtils.CarriageReturn:
467 d78cbf09 Panagiotis Kanavos
            // eat
468 d78cbf09 Panagiotis Kanavos
            break;
469 d78cbf09 Panagiotis Kanavos
          default:
470 d78cbf09 Panagiotis Kanavos
            if (char.IsWhiteSpace(currentChar))
471 d78cbf09 Panagiotis Kanavos
            {
472 d78cbf09 Panagiotis Kanavos
              // eat
473 d78cbf09 Panagiotis Kanavos
            }
474 d78cbf09 Panagiotis Kanavos
            else
475 d78cbf09 Panagiotis Kanavos
            {
476 d78cbf09 Panagiotis Kanavos
              throw CreateJsonReaderException("After parsing a value an unexpected character was encountered: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
477 d78cbf09 Panagiotis Kanavos
            }
478 d78cbf09 Panagiotis Kanavos
            break;
479 d78cbf09 Panagiotis Kanavos
        }
480 d78cbf09 Panagiotis Kanavos
      } while ((currentChar = MoveNext()) != '\0' || !_end);
481 d78cbf09 Panagiotis Kanavos
482 d78cbf09 Panagiotis Kanavos
      return false;
483 d78cbf09 Panagiotis Kanavos
    }
484 d78cbf09 Panagiotis Kanavos
485 d78cbf09 Panagiotis Kanavos
    private bool ParseObject(char currentChar)
486 d78cbf09 Panagiotis Kanavos
    {
487 d78cbf09 Panagiotis Kanavos
      do
488 d78cbf09 Panagiotis Kanavos
      {
489 d78cbf09 Panagiotis Kanavos
        switch (currentChar)
490 d78cbf09 Panagiotis Kanavos
        {
491 d78cbf09 Panagiotis Kanavos
          case '}':
492 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndObject);
493 d78cbf09 Panagiotis Kanavos
            return true;
494 d78cbf09 Panagiotis Kanavos
          case '/':
495 d78cbf09 Panagiotis Kanavos
            ParseComment();
496 d78cbf09 Panagiotis Kanavos
            return true;
497 d78cbf09 Panagiotis Kanavos
          case ' ':
498 d78cbf09 Panagiotis Kanavos
          case StringUtils.Tab:
499 d78cbf09 Panagiotis Kanavos
          case StringUtils.LineFeed:
500 d78cbf09 Panagiotis Kanavos
          case StringUtils.CarriageReturn:
501 d78cbf09 Panagiotis Kanavos
            // eat
502 d78cbf09 Panagiotis Kanavos
            break;
503 d78cbf09 Panagiotis Kanavos
          default:
504 d78cbf09 Panagiotis Kanavos
            if (char.IsWhiteSpace(currentChar))
505 d78cbf09 Panagiotis Kanavos
            {
506 d78cbf09 Panagiotis Kanavos
              // eat
507 d78cbf09 Panagiotis Kanavos
            }
508 d78cbf09 Panagiotis Kanavos
            else
509 d78cbf09 Panagiotis Kanavos
            {
510 d78cbf09 Panagiotis Kanavos
              return ParseProperty(currentChar);
511 d78cbf09 Panagiotis Kanavos
            }
512 d78cbf09 Panagiotis Kanavos
            break;
513 d78cbf09 Panagiotis Kanavos
        }
514 d78cbf09 Panagiotis Kanavos
      } while ((currentChar = MoveNext()) != '\0' || !_end);
515 d78cbf09 Panagiotis Kanavos
516 d78cbf09 Panagiotis Kanavos
      return false;
517 d78cbf09 Panagiotis Kanavos
    }
518 d78cbf09 Panagiotis Kanavos
519 d78cbf09 Panagiotis Kanavos
    private bool ParseProperty(char firstChar)
520 d78cbf09 Panagiotis Kanavos
    {
521 d78cbf09 Panagiotis Kanavos
      char currentChar = firstChar;
522 d78cbf09 Panagiotis Kanavos
      char quoteChar;
523 d78cbf09 Panagiotis Kanavos
524 d78cbf09 Panagiotis Kanavos
      if (ValidIdentifierChar(currentChar))
525 d78cbf09 Panagiotis Kanavos
      {
526 d78cbf09 Panagiotis Kanavos
        quoteChar = '\0';
527 d78cbf09 Panagiotis Kanavos
        currentChar = ParseUnquotedProperty(currentChar);
528 d78cbf09 Panagiotis Kanavos
      }
529 d78cbf09 Panagiotis Kanavos
      else if (currentChar == '"' || currentChar == '\'')
530 d78cbf09 Panagiotis Kanavos
      {
531 d78cbf09 Panagiotis Kanavos
        quoteChar = currentChar;
532 d78cbf09 Panagiotis Kanavos
        ReadStringIntoBuffer(quoteChar);
533 d78cbf09 Panagiotis Kanavos
        currentChar = MoveNext();
534 d78cbf09 Panagiotis Kanavos
      }
535 d78cbf09 Panagiotis Kanavos
      else
536 d78cbf09 Panagiotis Kanavos
      {
537 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Invalid property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
538 d78cbf09 Panagiotis Kanavos
      }
539 d78cbf09 Panagiotis Kanavos
540 d78cbf09 Panagiotis Kanavos
      if (currentChar != ':')
541 d78cbf09 Panagiotis Kanavos
      {
542 d78cbf09 Panagiotis Kanavos
        currentChar = MoveNext();
543 d78cbf09 Panagiotis Kanavos
544 d78cbf09 Panagiotis Kanavos
        // finished property. skip any whitespace and move to colon
545 d78cbf09 Panagiotis Kanavos
        EatWhitespace(currentChar, false, out currentChar);
546 d78cbf09 Panagiotis Kanavos
547 d78cbf09 Panagiotis Kanavos
        if (currentChar != ':')
548 d78cbf09 Panagiotis Kanavos
          throw CreateJsonReaderException("Invalid character after parsing property name. Expected ':' but got: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
549 d78cbf09 Panagiotis Kanavos
      }
550 d78cbf09 Panagiotis Kanavos
551 d78cbf09 Panagiotis Kanavos
      SetToken(JsonToken.PropertyName, _buffer.ToString());
552 d78cbf09 Panagiotis Kanavos
      QuoteChar = quoteChar;
553 d78cbf09 Panagiotis Kanavos
      _buffer.Position = 0;
554 d78cbf09 Panagiotis Kanavos
555 d78cbf09 Panagiotis Kanavos
      return true;
556 d78cbf09 Panagiotis Kanavos
    }
557 d78cbf09 Panagiotis Kanavos
558 d78cbf09 Panagiotis Kanavos
    private bool ValidIdentifierChar(char value)
559 d78cbf09 Panagiotis Kanavos
    {
560 d78cbf09 Panagiotis Kanavos
      return (char.IsLetterOrDigit(value) || value == '_' || value == '$');
561 d78cbf09 Panagiotis Kanavos
    }
562 d78cbf09 Panagiotis Kanavos
563 d78cbf09 Panagiotis Kanavos
    private char ParseUnquotedProperty(char firstChar)
564 d78cbf09 Panagiotis Kanavos
    {
565 d78cbf09 Panagiotis Kanavos
      // parse unquoted property name until whitespace or colon
566 d78cbf09 Panagiotis Kanavos
      _buffer.Append(firstChar);
567 d78cbf09 Panagiotis Kanavos
568 d78cbf09 Panagiotis Kanavos
      char currentChar;
569 d78cbf09 Panagiotis Kanavos
570 d78cbf09 Panagiotis Kanavos
      while ((currentChar = MoveNext()) != '\0' || !_end)
571 d78cbf09 Panagiotis Kanavos
      {
572 d78cbf09 Panagiotis Kanavos
        if (char.IsWhiteSpace(currentChar) || currentChar == ':')
573 d78cbf09 Panagiotis Kanavos
        {
574 d78cbf09 Panagiotis Kanavos
          return currentChar;
575 d78cbf09 Panagiotis Kanavos
        }
576 d78cbf09 Panagiotis Kanavos
        else if (ValidIdentifierChar(currentChar))
577 d78cbf09 Panagiotis Kanavos
        {
578 d78cbf09 Panagiotis Kanavos
          _buffer.Append(currentChar);
579 d78cbf09 Panagiotis Kanavos
        }
580 d78cbf09 Panagiotis Kanavos
        else
581 d78cbf09 Panagiotis Kanavos
        {
582 d78cbf09 Panagiotis Kanavos
          throw CreateJsonReaderException("Invalid JavaScript property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
583 d78cbf09 Panagiotis Kanavos
        }
584 d78cbf09 Panagiotis Kanavos
      }
585 d78cbf09 Panagiotis Kanavos
586 d78cbf09 Panagiotis Kanavos
      throw CreateJsonReaderException("Unexpected end when parsing unquoted property name. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
587 d78cbf09 Panagiotis Kanavos
    }
588 d78cbf09 Panagiotis Kanavos
589 d78cbf09 Panagiotis Kanavos
    private bool ParseValue(char currentChar)
590 d78cbf09 Panagiotis Kanavos
    {
591 d78cbf09 Panagiotis Kanavos
      do
592 d78cbf09 Panagiotis Kanavos
      {
593 d78cbf09 Panagiotis Kanavos
        switch (currentChar)
594 d78cbf09 Panagiotis Kanavos
        {
595 d78cbf09 Panagiotis Kanavos
          case '"':
596 d78cbf09 Panagiotis Kanavos
          case '\'':
597 d78cbf09 Panagiotis Kanavos
            ParseString(currentChar);
598 d78cbf09 Panagiotis Kanavos
            return true;
599 d78cbf09 Panagiotis Kanavos
          case 't':
600 d78cbf09 Panagiotis Kanavos
            ParseTrue();
601 d78cbf09 Panagiotis Kanavos
            return true;
602 d78cbf09 Panagiotis Kanavos
          case 'f':
603 d78cbf09 Panagiotis Kanavos
            ParseFalse();
604 d78cbf09 Panagiotis Kanavos
            return true;
605 d78cbf09 Panagiotis Kanavos
          case 'n':
606 d78cbf09 Panagiotis Kanavos
            if (HasNext())
607 d78cbf09 Panagiotis Kanavos
            {
608 d78cbf09 Panagiotis Kanavos
              char next = (char)PeekNext();
609 d78cbf09 Panagiotis Kanavos
610 d78cbf09 Panagiotis Kanavos
              if (next == 'u')
611 d78cbf09 Panagiotis Kanavos
                ParseNull();
612 d78cbf09 Panagiotis Kanavos
              else if (next == 'e')
613 d78cbf09 Panagiotis Kanavos
                ParseConstructor();
614 d78cbf09 Panagiotis Kanavos
              else
615 d78cbf09 Panagiotis Kanavos
                throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
616 d78cbf09 Panagiotis Kanavos
            }
617 d78cbf09 Panagiotis Kanavos
            else
618 d78cbf09 Panagiotis Kanavos
            {
619 d78cbf09 Panagiotis Kanavos
              throw CreateJsonReaderException("Unexpected end. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
620 d78cbf09 Panagiotis Kanavos
            }
621 d78cbf09 Panagiotis Kanavos
            return true;
622 d78cbf09 Panagiotis Kanavos
          case 'N':
623 d78cbf09 Panagiotis Kanavos
            ParseNumberNaN();
624 d78cbf09 Panagiotis Kanavos
            return true;
625 d78cbf09 Panagiotis Kanavos
          case 'I':
626 d78cbf09 Panagiotis Kanavos
            ParseNumberPositiveInfinity();
627 d78cbf09 Panagiotis Kanavos
            return true;
628 d78cbf09 Panagiotis Kanavos
          case '-':
629 d78cbf09 Panagiotis Kanavos
            if (PeekNext() == 'I')
630 d78cbf09 Panagiotis Kanavos
              ParseNumberNegativeInfinity();
631 d78cbf09 Panagiotis Kanavos
            else
632 d78cbf09 Panagiotis Kanavos
              ParseNumber(currentChar);
633 d78cbf09 Panagiotis Kanavos
            return true;
634 d78cbf09 Panagiotis Kanavos
          case '/':
635 d78cbf09 Panagiotis Kanavos
            ParseComment();
636 d78cbf09 Panagiotis Kanavos
            return true;
637 d78cbf09 Panagiotis Kanavos
          case 'u':
638 d78cbf09 Panagiotis Kanavos
            ParseUndefined();
639 d78cbf09 Panagiotis Kanavos
            return true;
640 d78cbf09 Panagiotis Kanavos
          case '{':
641 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.StartObject);
642 d78cbf09 Panagiotis Kanavos
            return true;
643 d78cbf09 Panagiotis Kanavos
          case '[':
644 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.StartArray);
645 d78cbf09 Panagiotis Kanavos
            return true;
646 d78cbf09 Panagiotis Kanavos
          case '}':
647 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndObject);
648 d78cbf09 Panagiotis Kanavos
            return true;
649 d78cbf09 Panagiotis Kanavos
          case ']':
650 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndArray);
651 d78cbf09 Panagiotis Kanavos
            return true;
652 d78cbf09 Panagiotis Kanavos
          case ',':
653 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.Undefined);
654 d78cbf09 Panagiotis Kanavos
            return true;
655 d78cbf09 Panagiotis Kanavos
          case ')':
656 d78cbf09 Panagiotis Kanavos
            SetToken(JsonToken.EndConstructor);
657 d78cbf09 Panagiotis Kanavos
            return true;
658 d78cbf09 Panagiotis Kanavos
          case ' ':
659 d78cbf09 Panagiotis Kanavos
          case StringUtils.Tab:
660 d78cbf09 Panagiotis Kanavos
          case StringUtils.LineFeed:
661 d78cbf09 Panagiotis Kanavos
          case StringUtils.CarriageReturn:
662 d78cbf09 Panagiotis Kanavos
            // eat
663 d78cbf09 Panagiotis Kanavos
            break;
664 d78cbf09 Panagiotis Kanavos
          default:
665 d78cbf09 Panagiotis Kanavos
            if (char.IsWhiteSpace(currentChar))
666 d78cbf09 Panagiotis Kanavos
            {
667 d78cbf09 Panagiotis Kanavos
              // eat
668 d78cbf09 Panagiotis Kanavos
            }
669 d78cbf09 Panagiotis Kanavos
            else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.')
670 d78cbf09 Panagiotis Kanavos
            {
671 d78cbf09 Panagiotis Kanavos
              ParseNumber(currentChar);
672 d78cbf09 Panagiotis Kanavos
              return true;
673 d78cbf09 Panagiotis Kanavos
            }
674 d78cbf09 Panagiotis Kanavos
            else
675 d78cbf09 Panagiotis Kanavos
            {
676 d78cbf09 Panagiotis Kanavos
              throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
677 d78cbf09 Panagiotis Kanavos
            }
678 d78cbf09 Panagiotis Kanavos
            break;
679 d78cbf09 Panagiotis Kanavos
        }
680 d78cbf09 Panagiotis Kanavos
      } while ((currentChar = MoveNext()) != '\0' || !_end);
681 d78cbf09 Panagiotis Kanavos
682 d78cbf09 Panagiotis Kanavos
      return false;
683 d78cbf09 Panagiotis Kanavos
    }
684 d78cbf09 Panagiotis Kanavos
685 d78cbf09 Panagiotis Kanavos
    private bool EatWhitespace(char initialChar, bool oneOrMore, out char finalChar)
686 d78cbf09 Panagiotis Kanavos
    {
687 d78cbf09 Panagiotis Kanavos
      bool whitespace = false;
688 d78cbf09 Panagiotis Kanavos
      char currentChar = initialChar;
689 d78cbf09 Panagiotis Kanavos
      while (currentChar == ' ' || char.IsWhiteSpace(currentChar))
690 d78cbf09 Panagiotis Kanavos
      {
691 d78cbf09 Panagiotis Kanavos
        whitespace = true;
692 d78cbf09 Panagiotis Kanavos
        currentChar = MoveNext();
693 d78cbf09 Panagiotis Kanavos
      }
694 d78cbf09 Panagiotis Kanavos
695 d78cbf09 Panagiotis Kanavos
      finalChar = currentChar;
696 d78cbf09 Panagiotis Kanavos
697 d78cbf09 Panagiotis Kanavos
      return (!oneOrMore || whitespace);
698 d78cbf09 Panagiotis Kanavos
    }
699 d78cbf09 Panagiotis Kanavos
700 d78cbf09 Panagiotis Kanavos
    private void ParseConstructor()
701 d78cbf09 Panagiotis Kanavos
    {
702 d78cbf09 Panagiotis Kanavos
      if (MatchValue('n', "new", true))
703 d78cbf09 Panagiotis Kanavos
      {
704 d78cbf09 Panagiotis Kanavos
        char currentChar = MoveNext();
705 d78cbf09 Panagiotis Kanavos
706 d78cbf09 Panagiotis Kanavos
        if (EatWhitespace(currentChar, true, out currentChar))
707 d78cbf09 Panagiotis Kanavos
        {
708 d78cbf09 Panagiotis Kanavos
          while (char.IsLetter(currentChar))
709 d78cbf09 Panagiotis Kanavos
          {
710 d78cbf09 Panagiotis Kanavos
            _buffer.Append(currentChar);
711 d78cbf09 Panagiotis Kanavos
            currentChar = MoveNext();
712 d78cbf09 Panagiotis Kanavos
          }
713 d78cbf09 Panagiotis Kanavos
714 d78cbf09 Panagiotis Kanavos
          EatWhitespace(currentChar, false, out currentChar);
715 d78cbf09 Panagiotis Kanavos
716 d78cbf09 Panagiotis Kanavos
          if (currentChar != '(')
717 d78cbf09 Panagiotis Kanavos
            throw CreateJsonReaderException("Unexpected character while parsing constructor: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
718 d78cbf09 Panagiotis Kanavos
719 d78cbf09 Panagiotis Kanavos
          string constructorName = _buffer.ToString();
720 d78cbf09 Panagiotis Kanavos
          _buffer.Position = 0;
721 d78cbf09 Panagiotis Kanavos
722 d78cbf09 Panagiotis Kanavos
          SetToken(JsonToken.StartConstructor, constructorName);
723 d78cbf09 Panagiotis Kanavos
        }
724 d78cbf09 Panagiotis Kanavos
      }
725 d78cbf09 Panagiotis Kanavos
    }
726 d78cbf09 Panagiotis Kanavos
727 d78cbf09 Panagiotis Kanavos
    private void ParseNumber(char firstChar)
728 d78cbf09 Panagiotis Kanavos
    {
729 d78cbf09 Panagiotis Kanavos
      char currentChar = firstChar;
730 d78cbf09 Panagiotis Kanavos
731 d78cbf09 Panagiotis Kanavos
      // parse until seperator character or end
732 d78cbf09 Panagiotis Kanavos
      bool end = false;
733 d78cbf09 Panagiotis Kanavos
      do
734 d78cbf09 Panagiotis Kanavos
      {
735 d78cbf09 Panagiotis Kanavos
        if (IsSeperator(currentChar))
736 d78cbf09 Panagiotis Kanavos
        {
737 d78cbf09 Panagiotis Kanavos
          end = true;
738 d78cbf09 Panagiotis Kanavos
          _lastChar = currentChar;
739 d78cbf09 Panagiotis Kanavos
        }
740 d78cbf09 Panagiotis Kanavos
        else
741 d78cbf09 Panagiotis Kanavos
        {
742 d78cbf09 Panagiotis Kanavos
          _buffer.Append(currentChar);
743 d78cbf09 Panagiotis Kanavos
        }
744 d78cbf09 Panagiotis Kanavos
745 d78cbf09 Panagiotis Kanavos
      } while (!end && ((currentChar = MoveNext()) != '\0' || !_end));
746 d78cbf09 Panagiotis Kanavos
747 d78cbf09 Panagiotis Kanavos
      string number = _buffer.ToString();
748 d78cbf09 Panagiotis Kanavos
      object numberValue;
749 d78cbf09 Panagiotis Kanavos
      JsonToken numberType;
750 d78cbf09 Panagiotis Kanavos
751 d78cbf09 Panagiotis Kanavos
      bool nonBase10 = (firstChar == '0' && !number.StartsWith("0.", StringComparison.OrdinalIgnoreCase));
752 d78cbf09 Panagiotis Kanavos
753 d78cbf09 Panagiotis Kanavos
      if (_readType == ReadType.ReadAsDecimal)
754 d78cbf09 Panagiotis Kanavos
      {
755 d78cbf09 Panagiotis Kanavos
        if (nonBase10)
756 d78cbf09 Panagiotis Kanavos
        {
757 d78cbf09 Panagiotis Kanavos
          // decimal.Parse doesn't support parsing hexadecimal values
758 d78cbf09 Panagiotis Kanavos
          long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
759 d78cbf09 Panagiotis Kanavos
            ? Convert.ToInt64(number, 16)
760 d78cbf09 Panagiotis Kanavos
            : Convert.ToInt64(number, 8);
761 d78cbf09 Panagiotis Kanavos
762 d78cbf09 Panagiotis Kanavos
          numberValue = Convert.ToDecimal(integer);
763 d78cbf09 Panagiotis Kanavos
        }
764 d78cbf09 Panagiotis Kanavos
        else
765 d78cbf09 Panagiotis Kanavos
        {
766 d78cbf09 Panagiotis Kanavos
          numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
767 d78cbf09 Panagiotis Kanavos
        }
768 d78cbf09 Panagiotis Kanavos
769 d78cbf09 Panagiotis Kanavos
        numberType = JsonToken.Float;
770 d78cbf09 Panagiotis Kanavos
      }
771 d78cbf09 Panagiotis Kanavos
      else
772 d78cbf09 Panagiotis Kanavos
      {
773 d78cbf09 Panagiotis Kanavos
        if (nonBase10)
774 d78cbf09 Panagiotis Kanavos
        {
775 d78cbf09 Panagiotis Kanavos
          numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
776 d78cbf09 Panagiotis Kanavos
            ? Convert.ToInt64(number, 16)
777 d78cbf09 Panagiotis Kanavos
            : Convert.ToInt64(number, 8);
778 d78cbf09 Panagiotis Kanavos
          numberType = JsonToken.Integer;
779 d78cbf09 Panagiotis Kanavos
        }
780 d78cbf09 Panagiotis Kanavos
        else if (number.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || number.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1)
781 d78cbf09 Panagiotis Kanavos
        {
782 d78cbf09 Panagiotis Kanavos
          numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
783 d78cbf09 Panagiotis Kanavos
          numberType = JsonToken.Float;
784 d78cbf09 Panagiotis Kanavos
        }
785 d78cbf09 Panagiotis Kanavos
        else
786 d78cbf09 Panagiotis Kanavos
        {
787 d78cbf09 Panagiotis Kanavos
          try
788 d78cbf09 Panagiotis Kanavos
          {
789 d78cbf09 Panagiotis Kanavos
            numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
790 d78cbf09 Panagiotis Kanavos
          }
791 d78cbf09 Panagiotis Kanavos
          catch (OverflowException ex)
792 d78cbf09 Panagiotis Kanavos
          {
793 d78cbf09 Panagiotis Kanavos
            throw new JsonReaderException("JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
794 d78cbf09 Panagiotis Kanavos
          }
795 d78cbf09 Panagiotis Kanavos
796 d78cbf09 Panagiotis Kanavos
          numberType = JsonToken.Integer;
797 d78cbf09 Panagiotis Kanavos
        }
798 d78cbf09 Panagiotis Kanavos
      }
799 d78cbf09 Panagiotis Kanavos
800 d78cbf09 Panagiotis Kanavos
      _buffer.Position = 0;
801 d78cbf09 Panagiotis Kanavos
802 d78cbf09 Panagiotis Kanavos
      SetToken(numberType, numberValue);
803 d78cbf09 Panagiotis Kanavos
    }
804 d78cbf09 Panagiotis Kanavos
805 d78cbf09 Panagiotis Kanavos
    private void ParseComment()
806 d78cbf09 Panagiotis Kanavos
    {
807 d78cbf09 Panagiotis Kanavos
      // should have already parsed / character before reaching this method
808 d78cbf09 Panagiotis Kanavos
809 d78cbf09 Panagiotis Kanavos
      char currentChar = MoveNext();
810 d78cbf09 Panagiotis Kanavos
811 d78cbf09 Panagiotis Kanavos
      if (currentChar == '*')
812 d78cbf09 Panagiotis Kanavos
      {
813 d78cbf09 Panagiotis Kanavos
        while ((currentChar = MoveNext()) != '\0' || !_end)
814 d78cbf09 Panagiotis Kanavos
        {
815 d78cbf09 Panagiotis Kanavos
          if (currentChar == '*')
816 d78cbf09 Panagiotis Kanavos
          {
817 d78cbf09 Panagiotis Kanavos
            if ((currentChar = MoveNext()) != '\0' || !_end)
818 d78cbf09 Panagiotis Kanavos
            {
819 d78cbf09 Panagiotis Kanavos
              if (currentChar == '/')
820 d78cbf09 Panagiotis Kanavos
              {
821 d78cbf09 Panagiotis Kanavos
                break;
822 d78cbf09 Panagiotis Kanavos
              }
823 d78cbf09 Panagiotis Kanavos
              else
824 d78cbf09 Panagiotis Kanavos
              {
825 d78cbf09 Panagiotis Kanavos
                _buffer.Append('*');
826 d78cbf09 Panagiotis Kanavos
                _buffer.Append(currentChar);
827 d78cbf09 Panagiotis Kanavos
              }
828 d78cbf09 Panagiotis Kanavos
            }
829 d78cbf09 Panagiotis Kanavos
          }
830 d78cbf09 Panagiotis Kanavos
          else
831 d78cbf09 Panagiotis Kanavos
          {
832 d78cbf09 Panagiotis Kanavos
            _buffer.Append(currentChar);
833 d78cbf09 Panagiotis Kanavos
          }
834 d78cbf09 Panagiotis Kanavos
        }
835 d78cbf09 Panagiotis Kanavos
      }
836 d78cbf09 Panagiotis Kanavos
      else
837 d78cbf09 Panagiotis Kanavos
      {
838 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing comment. Expected: *. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
839 d78cbf09 Panagiotis Kanavos
      }
840 d78cbf09 Panagiotis Kanavos
841 d78cbf09 Panagiotis Kanavos
      SetToken(JsonToken.Comment, _buffer.ToString());
842 d78cbf09 Panagiotis Kanavos
843 d78cbf09 Panagiotis Kanavos
      _buffer.Position = 0;
844 d78cbf09 Panagiotis Kanavos
    }
845 d78cbf09 Panagiotis Kanavos
846 d78cbf09 Panagiotis Kanavos
    private bool MatchValue(char firstChar, string value)
847 d78cbf09 Panagiotis Kanavos
    {
848 d78cbf09 Panagiotis Kanavos
      char currentChar = firstChar;
849 d78cbf09 Panagiotis Kanavos
850 d78cbf09 Panagiotis Kanavos
      int i = 0;
851 d78cbf09 Panagiotis Kanavos
      do
852 d78cbf09 Panagiotis Kanavos
      {
853 d78cbf09 Panagiotis Kanavos
        if (currentChar != value[i])
854 d78cbf09 Panagiotis Kanavos
        {
855 d78cbf09 Panagiotis Kanavos
          break;
856 d78cbf09 Panagiotis Kanavos
        }
857 d78cbf09 Panagiotis Kanavos
        i++;
858 d78cbf09 Panagiotis Kanavos
      }
859 d78cbf09 Panagiotis Kanavos
      while (i < value.Length && ((currentChar = MoveNext()) != '\0' || !_end));
860 d78cbf09 Panagiotis Kanavos
861 d78cbf09 Panagiotis Kanavos
      return (i == value.Length);
862 d78cbf09 Panagiotis Kanavos
    }
863 d78cbf09 Panagiotis Kanavos
864 d78cbf09 Panagiotis Kanavos
    private bool MatchValue(char firstChar, string value, bool noTrailingNonSeperatorCharacters)
865 d78cbf09 Panagiotis Kanavos
    {
866 d78cbf09 Panagiotis Kanavos
      // will match value and then move to the next character, checking that it is a seperator character
867 d78cbf09 Panagiotis Kanavos
      bool match = MatchValue(firstChar, value);
868 d78cbf09 Panagiotis Kanavos
869 d78cbf09 Panagiotis Kanavos
      if (!noTrailingNonSeperatorCharacters)
870 d78cbf09 Panagiotis Kanavos
      {
871 d78cbf09 Panagiotis Kanavos
        return match;
872 d78cbf09 Panagiotis Kanavos
      }
873 d78cbf09 Panagiotis Kanavos
      else
874 d78cbf09 Panagiotis Kanavos
      {
875 d78cbf09 Panagiotis Kanavos
        int c = PeekNext();
876 d78cbf09 Panagiotis Kanavos
        char next = (c != -1) ? (char) c : '\0';
877 d78cbf09 Panagiotis Kanavos
        bool matchAndNoTrainingNonSeperatorCharacters = (match && (next == '\0' || IsSeperator(next)));
878 d78cbf09 Panagiotis Kanavos
879 d78cbf09 Panagiotis Kanavos
        return matchAndNoTrainingNonSeperatorCharacters;
880 d78cbf09 Panagiotis Kanavos
      }
881 d78cbf09 Panagiotis Kanavos
    }
882 d78cbf09 Panagiotis Kanavos
883 d78cbf09 Panagiotis Kanavos
    private bool IsSeperator(char c)
884 d78cbf09 Panagiotis Kanavos
    {
885 d78cbf09 Panagiotis Kanavos
      switch (c)
886 d78cbf09 Panagiotis Kanavos
      {
887 d78cbf09 Panagiotis Kanavos
        case '}':
888 d78cbf09 Panagiotis Kanavos
        case ']':
889 d78cbf09 Panagiotis Kanavos
        case ',':
890 d78cbf09 Panagiotis Kanavos
          return true;
891 d78cbf09 Panagiotis Kanavos
        case '/':
892 d78cbf09 Panagiotis Kanavos
          // check next character to see if start of a comment
893 d78cbf09 Panagiotis Kanavos
          return (HasNext() && PeekNext() == '*');
894 d78cbf09 Panagiotis Kanavos
        case ')':
895 d78cbf09 Panagiotis Kanavos
          if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
896 d78cbf09 Panagiotis Kanavos
            return true;
897 d78cbf09 Panagiotis Kanavos
          break;
898 d78cbf09 Panagiotis Kanavos
        case ' ':
899 d78cbf09 Panagiotis Kanavos
        case StringUtils.Tab:
900 d78cbf09 Panagiotis Kanavos
        case StringUtils.LineFeed:
901 d78cbf09 Panagiotis Kanavos
        case StringUtils.CarriageReturn:
902 d78cbf09 Panagiotis Kanavos
          return true;
903 d78cbf09 Panagiotis Kanavos
        default:
904 d78cbf09 Panagiotis Kanavos
          if (char.IsWhiteSpace(c))
905 d78cbf09 Panagiotis Kanavos
            return true;
906 d78cbf09 Panagiotis Kanavos
          break;
907 d78cbf09 Panagiotis Kanavos
      }
908 d78cbf09 Panagiotis Kanavos
909 d78cbf09 Panagiotis Kanavos
      return false;
910 d78cbf09 Panagiotis Kanavos
    }
911 d78cbf09 Panagiotis Kanavos
912 d78cbf09 Panagiotis Kanavos
    private void ParseTrue()
913 d78cbf09 Panagiotis Kanavos
    {
914 d78cbf09 Panagiotis Kanavos
      // check characters equal 'true'
915 d78cbf09 Panagiotis Kanavos
      // and that it is followed by either a seperator character
916 d78cbf09 Panagiotis Kanavos
      // or the text ends
917 d78cbf09 Panagiotis Kanavos
      if (MatchValue('t', JsonConvert.True, true))
918 d78cbf09 Panagiotis Kanavos
      {
919 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Boolean, true);
920 d78cbf09 Panagiotis Kanavos
      }
921 d78cbf09 Panagiotis Kanavos
      else
922 d78cbf09 Panagiotis Kanavos
      {
923 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
924 d78cbf09 Panagiotis Kanavos
      }
925 d78cbf09 Panagiotis Kanavos
    }
926 d78cbf09 Panagiotis Kanavos
927 d78cbf09 Panagiotis Kanavos
    private void ParseNull()
928 d78cbf09 Panagiotis Kanavos
    {
929 d78cbf09 Panagiotis Kanavos
      if (MatchValue('n', JsonConvert.Null, true))
930 d78cbf09 Panagiotis Kanavos
      {
931 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Null);
932 d78cbf09 Panagiotis Kanavos
      }
933 d78cbf09 Panagiotis Kanavos
      else
934 d78cbf09 Panagiotis Kanavos
      {
935 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing null value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
936 d78cbf09 Panagiotis Kanavos
      }
937 d78cbf09 Panagiotis Kanavos
    }
938 d78cbf09 Panagiotis Kanavos
939 d78cbf09 Panagiotis Kanavos
    private void ParseUndefined()
940 d78cbf09 Panagiotis Kanavos
    {
941 d78cbf09 Panagiotis Kanavos
      if (MatchValue('u', JsonConvert.Undefined, true))
942 d78cbf09 Panagiotis Kanavos
      {
943 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Undefined);
944 d78cbf09 Panagiotis Kanavos
      }
945 d78cbf09 Panagiotis Kanavos
      else
946 d78cbf09 Panagiotis Kanavos
      {
947 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing undefined value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
948 d78cbf09 Panagiotis Kanavos
      }
949 d78cbf09 Panagiotis Kanavos
    }
950 d78cbf09 Panagiotis Kanavos
951 d78cbf09 Panagiotis Kanavos
    private void ParseFalse()
952 d78cbf09 Panagiotis Kanavos
    {
953 d78cbf09 Panagiotis Kanavos
      if (MatchValue('f', JsonConvert.False, true))
954 d78cbf09 Panagiotis Kanavos
      {
955 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Boolean, false);
956 d78cbf09 Panagiotis Kanavos
      }
957 d78cbf09 Panagiotis Kanavos
      else
958 d78cbf09 Panagiotis Kanavos
      {
959 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
960 d78cbf09 Panagiotis Kanavos
      }
961 d78cbf09 Panagiotis Kanavos
    }
962 d78cbf09 Panagiotis Kanavos
963 d78cbf09 Panagiotis Kanavos
    private void ParseNumberNegativeInfinity()
964 d78cbf09 Panagiotis Kanavos
    {
965 d78cbf09 Panagiotis Kanavos
      if (MatchValue('-', JsonConvert.NegativeInfinity, true))
966 d78cbf09 Panagiotis Kanavos
      {
967 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Float, double.NegativeInfinity);
968 d78cbf09 Panagiotis Kanavos
      }
969 d78cbf09 Panagiotis Kanavos
      else
970 d78cbf09 Panagiotis Kanavos
      {
971 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing negative infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
972 d78cbf09 Panagiotis Kanavos
      }
973 d78cbf09 Panagiotis Kanavos
    }
974 d78cbf09 Panagiotis Kanavos
975 d78cbf09 Panagiotis Kanavos
    private void ParseNumberPositiveInfinity()
976 d78cbf09 Panagiotis Kanavos
    {
977 d78cbf09 Panagiotis Kanavos
      if (MatchValue('I', JsonConvert.PositiveInfinity, true))
978 d78cbf09 Panagiotis Kanavos
      {
979 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Float, double.PositiveInfinity);
980 d78cbf09 Panagiotis Kanavos
      }
981 d78cbf09 Panagiotis Kanavos
      else
982 d78cbf09 Panagiotis Kanavos
      {
983 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing positive infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
984 d78cbf09 Panagiotis Kanavos
      }
985 d78cbf09 Panagiotis Kanavos
    }
986 d78cbf09 Panagiotis Kanavos
987 d78cbf09 Panagiotis Kanavos
    private void ParseNumberNaN()
988 d78cbf09 Panagiotis Kanavos
    {
989 d78cbf09 Panagiotis Kanavos
      if (MatchValue('N', JsonConvert.NaN, true))
990 d78cbf09 Panagiotis Kanavos
      {
991 d78cbf09 Panagiotis Kanavos
        SetToken(JsonToken.Float, double.NaN);
992 d78cbf09 Panagiotis Kanavos
      }
993 d78cbf09 Panagiotis Kanavos
      else
994 d78cbf09 Panagiotis Kanavos
      {
995 d78cbf09 Panagiotis Kanavos
        throw CreateJsonReaderException("Error parsing NaN value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
996 d78cbf09 Panagiotis Kanavos
      }
997 d78cbf09 Panagiotis Kanavos
    }
998 d78cbf09 Panagiotis Kanavos
999 d78cbf09 Panagiotis Kanavos
    /// <summary>
1000 d78cbf09 Panagiotis Kanavos
    /// Changes the state to closed. 
1001 d78cbf09 Panagiotis Kanavos
    /// </summary>
1002 d78cbf09 Panagiotis Kanavos
    public override void Close()
1003 d78cbf09 Panagiotis Kanavos
    {
1004 d78cbf09 Panagiotis Kanavos
      base.Close();
1005 d78cbf09 Panagiotis Kanavos
1006 d78cbf09 Panagiotis Kanavos
      if (CloseInput && _reader != null)
1007 d78cbf09 Panagiotis Kanavos
        _reader.Close();
1008 d78cbf09 Panagiotis Kanavos
1009 d78cbf09 Panagiotis Kanavos
      if (_buffer != null)
1010 d78cbf09 Panagiotis Kanavos
        _buffer.Clear();
1011 d78cbf09 Panagiotis Kanavos
    }
1012 d78cbf09 Panagiotis Kanavos
1013 d78cbf09 Panagiotis Kanavos
    /// <summary>
1014 d78cbf09 Panagiotis Kanavos
    /// Gets a value indicating whether the class can return line information.
1015 d78cbf09 Panagiotis Kanavos
    /// </summary>
1016 d78cbf09 Panagiotis Kanavos
    /// <returns>
1017 d78cbf09 Panagiotis Kanavos
    /// 	<c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
1018 d78cbf09 Panagiotis Kanavos
    /// </returns>
1019 d78cbf09 Panagiotis Kanavos
    public bool HasLineInfo()
1020 d78cbf09 Panagiotis Kanavos
    {
1021 d78cbf09 Panagiotis Kanavos
      return true;
1022 d78cbf09 Panagiotis Kanavos
    }
1023 d78cbf09 Panagiotis Kanavos
1024 d78cbf09 Panagiotis Kanavos
    /// <summary>
1025 d78cbf09 Panagiotis Kanavos
    /// Gets the current line number.
1026 d78cbf09 Panagiotis Kanavos
    /// </summary>
1027 d78cbf09 Panagiotis Kanavos
    /// <value>
1028 d78cbf09 Panagiotis Kanavos
    /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
1029 d78cbf09 Panagiotis Kanavos
    /// </value>
1030 d78cbf09 Panagiotis Kanavos
    public int LineNumber
1031 d78cbf09 Panagiotis Kanavos
    {
1032 d78cbf09 Panagiotis Kanavos
      get
1033 d78cbf09 Panagiotis Kanavos
      {
1034 d78cbf09 Panagiotis Kanavos
        if (CurrentState == State.Start)
1035 d78cbf09 Panagiotis Kanavos
          return 0;
1036 d78cbf09 Panagiotis Kanavos
1037 d78cbf09 Panagiotis Kanavos
        return _currentLineNumber;
1038 d78cbf09 Panagiotis Kanavos
      }
1039 d78cbf09 Panagiotis Kanavos
    }
1040 d78cbf09 Panagiotis Kanavos
1041 d78cbf09 Panagiotis Kanavos
    /// <summary>
1042 d78cbf09 Panagiotis Kanavos
    /// Gets the current line position.
1043 d78cbf09 Panagiotis Kanavos
    /// </summary>
1044 d78cbf09 Panagiotis Kanavos
    /// <value>
1045 d78cbf09 Panagiotis Kanavos
    /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
1046 d78cbf09 Panagiotis Kanavos
    /// </value>
1047 d78cbf09 Panagiotis Kanavos
    public int LinePosition
1048 d78cbf09 Panagiotis Kanavos
    {
1049 d78cbf09 Panagiotis Kanavos
      get { return _currentLinePosition; }
1050 d78cbf09 Panagiotis Kanavos
    }
1051 d78cbf09 Panagiotis Kanavos
  }
1052 d78cbf09 Panagiotis Kanavos
}