protected void InternalReadXml(XmlReader r)
{
string containingElementType = "";
MemberInfo[] fields = GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
bool skipCloseElement = false;
foreach (MemberInfo f in fields)
{
var mInfo = Globs.GetAttr<MarshalAsAttribute>(f);
var elementType = Globs.GetMemberType(f);
string elementName = f.Name.TrimStart(new[] { '_' });
if (r.HasAttributes)
{
containingElementType = r.GetAttribute("type");
}
r.ReadStartElement(elementName);
string s;
Object val;
switch (mInfo.MarshType)
{
case MarshalType.UnionSelector:
s = r.ReadContentAsString();
// ReSharper disable once AssignNullToNotNullAttribute
val = Enum.Parse(elementType, s);
Globs.SetMember(f, this, val);
break;
case MarshalType.ArrayCount:
int intVal = r.ReadContentAsInt();
// ReSharper disable once AssignNullToNotNullAttribute
val = Convert.ChangeType(intVal, elementType);
Globs.SetMember(f, this, val);
break;
case MarshalType.Normal:
// ReSharper disable once PossibleNullReferenceException
if (elementType.GetTypeInfo().IsSubclassOf(typeof(TpmStructureBase)))
{
val = Activator.CreateInstance(elementType);
Globs.SetMember(f, this, val);
((TpmStructureBase)val).InternalReadXml(r);
break;
}
// ReSharper disable once RedundantIfElseBlock
else
{
if(elementType.TypeIsEnum())
{
s = r.ReadContentAsString();
val = Enum.Parse(elementType, s);
Globs.SetMember(f, this, val);
break;
}
if (elementType == typeof(uint) || elementType == typeof(ushort) || elementType == typeof(byte))
{
// TODO: This should be unsigned
long longVal = r.ReadContentAsLong();
val = Convert.ChangeType(longVal, elementType);
Globs.SetMember(f, this, val);
break;
}
throw new NotImplementedException("");
}
// ReSharper disable once CSharpWarnings::CS0162
// ReSharper disable once HeuristicUnreachableCode
throw new NotImplementedException("");
case MarshalType.FixedLengthArray:
case MarshalType.VariableLengthArray:
var supportedElementaryTypes = new[] { typeof(byte[]), typeof(ushort[]), typeof(uint[]) };
if (supportedElementaryTypes.Contains(elementType))
{
if (r.HasValue)
{
// ReSharper disable once AssignNullToNotNullAttribute
val = r.ReadContentAs(elementType, null);
Globs.SetMember(f, this, val);
}
else
{
// ReSharper disable once AssignNullToNotNullAttribute
Object nullObj = Activator.CreateInstance(elementType, 0x0);
Globs.SetMember(f, this, nullObj);
skipCloseElement = true;
}
break;
}
// ReSharper disable once RedundantIfElseBlock
else
{
throw new NotImplementedException("");
}
case MarshalType.Union:
// ReSharper disable once AssignNullToNotNullAttribute
val = Activator.CreateInstance(Type.GetType(containingElementType));
((TpmStructureBase)val).InternalReadXml(r);
Globs.SetMember(f, this, val);
break;
default:
throw new NotImplementedException("");
}
if (!skipCloseElement)
{
r.ReadEndElement();
}
skipCloseElement = false;
}
}
#endif // false