|
// 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
{
public enum XamlNodeType:byte
{
None, // need something to return when un-inited. (and past Eof)
StartObject,
GetObject,
EndObject,
StartMember,
EndMember,
Value,
NamespaceDeclaration,
};
internal delegate void XamlNodeAddDelegate(XamlNodeType nodeType, object data);
internal delegate void XamlLineInfoAddDelegate(int lineNumber, int linePosition);
internal delegate XamlNode XamlNodeNextDelegate();
internal delegate XamlNode XamlNodeIndexDelegate(int idx);
[DebuggerDisplay("{ToString()}")]
internal struct XamlNode
{
internal enum InternalNodeType:byte { None, StartOfStream, EndOfStream, EndOfAttributes, LineInfo }
XamlNodeType _nodeType;
InternalNodeType _internalNodeType;
private object _data;
public XamlNodeType NodeType
{
get { return _nodeType; }
}
public XamlNode(XamlNodeType nodeType)
{
#if DEBUG
switch (nodeType)
{
case XamlNodeType.EndObject:
case XamlNodeType.EndMember:
case XamlNodeType.GetObject:
break;
default:
Debug.Assert(false, "XamlNode Ctor missing data argument");
break;
}
#endif
_nodeType = nodeType;
_internalNodeType = InternalNodeType.None;
_data = null;
}
public XamlNode(XamlNodeType nodeType, object data)
{
#if DEBUG
switch(nodeType)
{
case XamlNodeType.StartObject:
Debug.Assert(data is XamlType, "XamlNode ctor, StartObject data is not a XamlType");
break;
case XamlNodeType.StartMember:
Debug.Assert(data is XamlMember, "XamlNode ctor, StartMember data is not a XamlMember");
break;
case XamlNodeType.NamespaceDeclaration:
Debug.Assert(data is NamespaceDeclaration, "XamlNode ctor, NamespaceDeclaration data is not a NamespaceDeclaration");
break;
case XamlNodeType.Value:
// can be anything;
break;
case XamlNodeType.EndObject:
case XamlNodeType.EndMember:
case XamlNodeType.GetObject:
Debug.Assert(data is null, "XamlNode ctor, Internal XamlNode data must be null for this Node type");
break;
default:
Debug.Assert(false, "XamlNode ctor, incorrect ctor called.");
break;
}
#endif
_nodeType = nodeType;
_internalNodeType = InternalNodeType.None;
_data = data;
}
public XamlNode(InternalNodeType internalNodeType)
{
Debug.Assert(internalNodeType == InternalNodeType.EndOfAttributes ||
internalNodeType == InternalNodeType.StartOfStream ||
internalNodeType == InternalNodeType.EndOfStream, "XamlNode ctor: Illegal Internal node type");
_nodeType = XamlNodeType.None;
_internalNodeType = internalNodeType;
_data = null;
}
public XamlNode(LineInfo lineInfo)
{
_nodeType = XamlNodeType.None;
_internalNodeType = InternalNodeType.LineInfo;
_data = lineInfo;
}
public override string ToString()
{
string str = string.Create(TypeConverterHelper.InvariantEnglishUS, $"{NodeType}: ");
switch(NodeType)
{
case XamlNodeType.StartObject:
str += XamlType.Name;
break;
case XamlNodeType.StartMember:
str += Member.Name;
break;
case XamlNodeType.Value:
str += Value.ToString();
break;
case XamlNodeType.NamespaceDeclaration:
str += NamespaceDeclaration.ToString();
break;
case XamlNodeType.None:
switch(_internalNodeType)
{
case InternalNodeType.EndOfAttributes:
str += "End Of Attributes";
break;
case InternalNodeType.StartOfStream:
str += "Start Of Stream";
break;
case InternalNodeType.EndOfStream:
str += "End Of Stream";
break;
case InternalNodeType.LineInfo:
str += $"LineInfo: {LineInfo}";
break;
}
break;
}
return str;
}
public NamespaceDeclaration NamespaceDeclaration
{
get
{
if (NodeType == XamlNodeType.NamespaceDeclaration)
{
return (NamespaceDeclaration)_data;
}
return null;
}
}
public XamlType XamlType
{
get
{
if (NodeType == XamlNodeType.StartObject)
{
return (XamlType)_data;
}
return null;
}
}
public object Value
{
get
{
if (NodeType == XamlNodeType.Value)
{
return _data;
}
return null;
}
}
public XamlMember Member
{
get
{
if (NodeType == XamlNodeType.StartMember)
{
return (XamlMember)_data;
}
return null;
}
}
public LineInfo LineInfo
{
get
{
if (NodeType == XamlNodeType.None)
{
return _data as LineInfo; // might be null for EOF and EOA.
}
return null;
}
}
internal bool IsEof
{
get
{
if (NodeType == XamlNodeType.None && _internalNodeType == InternalNodeType.EndOfStream)
{
return true;
}
return false;
}
}
internal bool IsEndOfAttributes
{
get
{
if (NodeType == XamlNodeType.None && _internalNodeType == InternalNodeType.EndOfAttributes)
{
return true;
}
return false;
}
}
internal bool IsLineInfo
{
get
{
if (NodeType == XamlNodeType.None && _internalNodeType == InternalNodeType.LineInfo)
{
return true;
}
return false;
}
}
internal static bool IsEof_Helper(XamlNodeType nodeType, object data)
{
if (nodeType != XamlNodeType.None)
{
return false;
}
if (data is InternalNodeType)
{
InternalNodeType internalNodeType = (InternalNodeType)data;
if (internalNodeType == InternalNodeType.EndOfStream)
{
return true;
}
}
return false;
}
}
}
|