bool ReadContent (bool objectValue)
{
int ch = ReadChar ();
if (ch < 0) {
ReadEndOfStream ();
return false;
}
bool itemMustFollow = false;
if (!objectValue && elements.Count > 0 && elements.Peek ().HasContent) {
if (ch == ',') {
switch (elements.Peek ().Type) {
case "object":
case "array":
SkipWhitespaces ();
ch = ReadChar ();
itemMustFollow = true;
break;
}
}
else if (ch != '}' && ch != ']')
throw XmlError ("Comma is required unless an array or object is at the end");
}
if (elements.Count > 0 && elements.Peek ().Type == "array")
next_element = "item";
else if (next_object_content_name != null) {
next_element = next_object_content_name;
next_object_content_name = null;
if (ch != ':')
throw XmlError ("':' is expected after a name of an object content");
SkipWhitespaces ();
ReadContent (true);
return true;
}
switch (ch) {
case '{':
ReadStartObject ();
return true;
case '[':
ReadStartArray ();
return true;
case '}':
if (itemMustFollow)
throw XmlError ("Invalid comma before an end of object");
if (objectValue)
throw XmlError ("Invalid end of object as an object content");
ReadEndObject ();
return true;
case ']':
if (itemMustFollow)
throw XmlError ("Invalid comma before an end of array");
if (objectValue)
throw XmlError ("Invalid end of array as an object content");
ReadEndArray ();
return true;
case '"':
bool lame = LameSilverlightLiteralParser && ch != '"';
string s = ReadStringLiteral (lame);
if (!objectValue && elements.Count > 0 && elements.Peek ().Type == "object") {
next_element = s;
SkipWhitespaces ();
if (!lame)
Expect (':');
SkipWhitespaces ();
ReadContent (true);
}
else
ReadAsSimpleContent ("string", s);
return true;
case '-':
ReadNumber (ch);
return true;
case 'n':
if (TryReadString("ull")) {
ReadAsSimpleContent ("null", "null");
return true;
}
else {
// the pushback for 'n' is taken care of by the
// default case if we're in lame silverlight literal
// mode
goto default;
}
case 't':
if (TryReadString ("rue")) {
ReadAsSimpleContent ("boolean", "true");
return true;
}
else {
// the pushback for 't' is taken care of by the
// default case if we're in lame silverlight literal
// mode
goto default;
}
case 'f':
if (TryReadString ("alse")) {
ReadAsSimpleContent ("boolean", "false");
return true;
}
else {
// the pushback for 'f' is taken care of by the
// default case if we're in lame silverlight literal
// mode
goto default;
}
default:
if ('0' <= ch && ch <= '9') {
ReadNumber (ch);
return true;
}
if (LameSilverlightLiteralParser) {
PushbackChar (ch);
goto case '"';
}
throw XmlError (String.Format ("Unexpected token: '{0}' ({1:X04})", (char) ch, (int) ch));
}
}