|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
namespace System.Xaml
{
internal class XamlSubreader : XamlReader, IXamlLineInfo
{
XamlReader _reader;
IXamlLineInfo _lineInfoReader;
bool _done;
bool _firstRead;
bool _rootIsStartMember;
int _depth;
public XamlSubreader(XamlReader reader)
{
_reader = reader;
_lineInfoReader = reader as IXamlLineInfo;
_done = false;
_depth = 0;
_firstRead = true;
_rootIsStartMember = (reader.NodeType == XamlNodeType.StartMember);
}
public override bool Read()
{
ObjectDisposedException.ThrowIf(IsDisposed, typeof(XamlReader)); // Can't say XamlSubreader because its internal.
if (!_firstRead)
{
return LimitedRead();
}
_firstRead = false;
return true;
}
private bool IsEmpty { get { return _done || _firstRead; } }
public override XamlNodeType NodeType
{
get { return IsEmpty ? XamlNodeType.None : _reader.NodeType; }
}
public override bool IsEof
{
get { return IsEmpty ? true : _reader.IsEof; }
}
public override NamespaceDeclaration Namespace
{
get { return IsEmpty ? null : _reader.Namespace; }
}
public override XamlType Type
{
get { return IsEmpty ? null : _reader.Type; }
}
public override object Value
{
get { return IsEmpty ? null : _reader.Value; }
}
public override XamlMember Member
{
get { return IsEmpty ? null : _reader.Member; }
}
public override XamlSchemaContext SchemaContext
{
get { return _reader.SchemaContext; }
}
#region IXamlLineInfo Members
public bool HasLineInfo
{
get
{
if (_lineInfoReader is null)
{
return false;
}
return _lineInfoReader.HasLineInfo;
}
}
public int LineNumber
{
get
{
if (_lineInfoReader is null)
{
return 0;
}
return _lineInfoReader.LineNumber;
}
}
public int LinePosition
{
get
{
if (_lineInfoReader is null)
{
return 0;
}
return _lineInfoReader.LinePosition;
}
}
#endregion
// ---------- Private methods --------------
private bool LimitedRead()
{
if (IsEof)
{
return false;
}
XamlNodeType nodeType = _reader.NodeType;
if (_rootIsStartMember)
{
if (nodeType == XamlNodeType.StartMember)
{
_depth += 1;
}
else if (nodeType == XamlNodeType.EndMember)
{
_depth -= 1;
}
}
else
{
if (nodeType == XamlNodeType.StartObject
|| nodeType == XamlNodeType.GetObject)
{
_depth += 1;
}
else if (nodeType == XamlNodeType.EndObject)
{
_depth -= 1;
}
}
if (_depth == 0)
{
_done = true;
}
_reader.Read();
return !IsEof;
}
}
}
|