Files
Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JsonTokenReader.cs
T
JamesNK 3209f09f0f -XML comments for everything!!!
-Some members changed to internal
2008-04-10 10:30:43 +00:00

171 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Linq
{
/// <summary>
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
/// </summary>
public class JsonTokenReader : JsonReader
{
private JToken _root;
private JToken _parent;
private JToken _current;
/// <summary>
/// Initializes a new instance of the <see cref="JsonTokenReader"/> class.
/// </summary>
/// <param name="token">The token to read from.</param>
public JsonTokenReader(JToken token)
{
ValidationUtils.ArgumentNotNull(token, "token");
_root = token;
_current = token;
}
/// <summary>
/// Reads the next Json token from the stream.
/// </summary>
/// <returns></returns>
public override bool Read()
{
if (CurrentState != State.Start)
{
JContainer container = _current as JContainer;
if (container != null && _parent != container)
return ReadInto(container);
else
return ReadOver(_current);
}
SetToken(_current);
return true;
}
private bool ReadOver(JToken t)
{
if (t == _root)
return ReadToEnd();
JToken next = t.Next;
if ((next == null || next == t) || t == t.Parent.Last)
{
if (t.Parent == null)
return ReadToEnd();
return SetEnd(t.Parent);
}
else
{
_current = next;
SetToken(_current);
return true;
}
}
private bool ReadToEnd()
{
//CurrentState = State.Finished;
return false;
}
private JsonToken? GetEndToken(JContainer c)
{
switch (c.Type)
{
case JsonTokenType.Object:
return JsonToken.EndObject;
case JsonTokenType.Array:
return JsonToken.EndArray;
case JsonTokenType.Constructor:
return JsonToken.EndConstructor;
case JsonTokenType.Property:
return null;
default:
throw new ArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type.");
}
}
private bool ReadInto(JContainer c)
{
JToken firstChild = c.First;
if (firstChild == null)
{
return SetEnd(c);
}
else
{
SetToken(firstChild);
_current = firstChild;
_parent = c;
return true;
}
}
private bool SetEnd(JContainer c)
{
JsonToken? endToken = GetEndToken(c);
if (endToken != null)
{
SetToken(endToken.Value);
_current = c;
_parent = c;
return true;
}
else
{
return ReadOver(c);
}
}
private void SetToken(JToken token)
{
switch (token.Type)
{
case JsonTokenType.Object:
SetToken(JsonToken.StartObject);
break;
case JsonTokenType.Array:
SetToken(JsonToken.StartArray);
break;
case JsonTokenType.Constructor:
SetToken(JsonToken.StartConstructor);
break;
case JsonTokenType.Property:
SetToken(JsonToken.PropertyName, ((JProperty)token).Name);
break;
case JsonTokenType.Comment:
SetToken(JsonToken.Comment, ((JValue)token).Value);
break;
case JsonTokenType.Integer:
SetToken(JsonToken.Integer, ((JValue)token).Value);
break;
case JsonTokenType.Float:
SetToken(JsonToken.Float, ((JValue)token).Value);
break;
case JsonTokenType.String:
SetToken(JsonToken.String, ((JValue)token).Value);
break;
case JsonTokenType.Boolean:
SetToken(JsonToken.Boolean, ((JValue)token).Value);
break;
case JsonTokenType.Null:
SetToken(JsonToken.Null, ((JValue)token).Value);
break;
case JsonTokenType.Undefined:
SetToken(JsonToken.Undefined, ((JValue)token).Value);
break;
case JsonTokenType.Date:
SetToken(JsonToken.Date, ((JValue)token).Value);
break;
default:
throw new ArgumentOutOfRangeException("Type", token.Type, "Unexpected JsonTokenType.");
}
}
}
}