void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readByOrder)
{
XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
bool first = false;
// Read attributes
GenerateReadAttributeMembers (xmlMap, map, ob, isValueList, ref first);
if (!isValueList)
{
WriteLine ("Reader.MoveToElement();");
WriteLineInd ("if (Reader.IsEmptyElement) {");
WriteLine ("Reader.Skip ();");
GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
WriteLine ("return " + ob + ";");
WriteLineUni ("}");
WriteLine ("");
WriteLine ("Reader.ReadStartElement();");
}
// Reads elements
WriteLine("Reader.MoveToContent();");
WriteLine ("");
if (!GenerateReadHook (HookType.elements, xmlMapType))
{
string[] readFlag = null;
if (map.ElementMembers != null && !readByOrder)
{
string readFlagsVars = string.Empty;
readFlag = new string[map.ElementMembers.Count];
int n=0;
foreach (XmlTypeMapMember mem in map.ElementMembers) {
// The text collector doesn't need a flag
if (!((mem is XmlTypeMapMemberElement) && ((XmlTypeMapMemberElement)mem).IsXmlTextCollector)) {
readFlag[n] = GetBoolTempVar ();
if (readFlagsVars.Length > 0) readFlagsVars += ", ";
readFlagsVars += readFlag[n] + "=false";
}
n++;
}
if (readFlagsVars.Length > 0) {
readFlagsVars = "bool " + readFlagsVars;
WriteLine (readFlagsVars + ";");
}
WriteLine ("");
}
string[] indexes = null;
string[] flatLists = null;
string[] flatListsChoices = null;
if (map.FlatLists != null)
{
indexes = new string[map.FlatLists.Count];
flatLists = new string[map.FlatLists.Count];
string code = "int ";
for (int n=0; n<map.FlatLists.Count; n++)
{
XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement)map.FlatLists[n];
indexes[n] = GetNumTempVar ();
if (n > 0) code += ", ";
code += indexes[n] + "=0";
if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
flatLists[n] = GetObTempVar ();
string rval;
WriteLine (mem.TypeData.CSharpFullName + " " + flatLists[n] + ";");
if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList)) {
rval = GenerateGetMemberValue (mem, ob, isValueList);
WriteLine (flatLists[n] + " = " + rval + ";");
} else if (mem.TypeData.Type.IsArray) {
rval = GenerateInitializeList (mem.TypeData);
WriteLine (flatLists[n] + " = " + rval + ";");
} else {
WriteLine (flatLists[n] + " = " + GenerateGetMemberValue (mem, ob, isValueList) + ";");
WriteLineInd ("if (((object)" + flatLists[n] + ") == null) {");
WriteLine (flatLists[n] + " = " + GenerateInitializeList (mem.TypeData) + ";");
GenerateSetMemberValue (mem, ob, flatLists[n], isValueList);
WriteLineUni ("}");
}
}
if (mem.ChoiceMember != null) {
if (flatListsChoices == null)
flatListsChoices = new string [map.FlatLists.Count];
flatListsChoices[n] = GetObTempVar ();
string rval = GenerateInitializeList (mem.ChoiceTypeData);
WriteLine (mem.ChoiceTypeData.CSharpFullName + " " + flatListsChoices[n] + " = " + rval + ";");
}
}
WriteLine (code + ";");
WriteLine ("");
}
if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
{
_fixupCallbacks.Add (xmlMap);
WriteLine ("Fixup fixup = new Fixup(" + ob + ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap) + "), " + map.ElementMembers.Count + ");");
WriteLine ("AddFixup (fixup);");
WriteLine ("");
}
ArrayList infos = null;
int maxInd;
if (readByOrder) {
if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
else maxInd = 0;
}
else
{
infos = new ArrayList ();
infos.AddRange (map.AllElementInfos);
maxInd = infos.Count;
WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
WriteLineInd ("{");
WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
WriteLineInd ("{");
}
first = true;
for (int ind = 0; ind < maxInd; ind++)
{
XmlTypeMapElementInfo info = readByOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
if (!readByOrder)
{
if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
string elemCond = first ? "" : "else ";
elemCond += "if (";
if (!(info.Member.IsReturnValue && _format == SerializationFormat.Encoded)) {
elemCond += "Reader.LocalName == " + GetLiteral (info.ElementName);
if (!map.IgnoreMemberNamespace) elemCond += " && Reader.NamespaceURI == " + GetLiteral (info.Namespace);
elemCond += " && ";
}
if (readFlag[info.Member.Index] != null)
elemCond += "!" + readFlag[info.Member.Index] + ") {";
else
elemCond += "true) {";
WriteLineInd (elemCond);
}
if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
{
if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
{
string list = GetObTempVar ();
WriteLine ("object " + list + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
RegisterReferencingMap (info.MappedType);
WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {"); // Already read
if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList))
WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.CSharpFullName) + ");");
else
GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
WriteLineUni ("}");
if (!info.MappedType.TypeData.Type.IsArray)
{
WriteLineInd ("else {");
if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList))
WriteLine (list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
else {
WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
}
WriteLine ("AddFixup (new CollectionFixup (" + list + ", new XmlSerializationCollectionFixupCallback (" + GetFillListName(info.Member.TypeData) + "), fixup.Ids[" + info.Member.Index + "]));");
WriteLine ("fixup.Ids[" + info.Member.Index + "] = null;"); // The member already has the value, no further fix needed.
WriteLineUni ("}");
}
}
else
{
if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList)) {
GenerateReadListElement (info.MappedType, GenerateGetMemberValue (info.Member, ob, isValueList), GetLiteral(info.IsNullable), false);
} else if (info.MappedType.TypeData.Type.IsArray) {
if (info.IsNullable)
GenerateSetMemberValue (info.Member, ob, GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true), isValueList);
else {
string list = GetObTempVar ();
WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true) + ";");
WriteLineInd ("if (((object)" + list + ") != null) {");
GenerateSetMemberValue (info.Member, ob, list, isValueList);
WriteLineUni ("}");
}
} else {
string list = GetObTempVar ();
WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
WriteLineInd ("if (((object)" + list + ") == null) {");
WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
GenerateSetMemberValue (info.Member, ob, list, isValueList);
WriteLineUni ("}");
GenerateReadListElement (info.MappedType, list, GetLiteral(info.IsNullable), true);
}
GenerateEndHook ();
}
}
if (!readByOrder)
WriteLine (readFlag[info.Member.Index] + " = true;");
}
else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
{
XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GenerateReadObjectElement (info), !IsReadOnly (typeMap, info.Member, info.TypeData, isValueList));
if (mem.ChoiceMember != null) {
GenerateAddListValue (mem.ChoiceTypeData, flatListsChoices[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetLiteral (info.ChoiceValue), true);
}
GenerateEndHook ();
}
WriteLine (indexes[mem.FlatArrayIndex] + "++;");
}
else if (info.Member.GetType() == typeof (XmlTypeMapMemberAnyElement))
{
XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
if (mem.TypeData.IsListType) {
if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode (mem.TypeData.ListItemTypeData, false), true);
GenerateEndHook ();
}
WriteLine (indexes[mem.FlatArrayIndex] + "++;");
}
else {
if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
GenerateEndHook ();
}
}
}
else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
{
if (!readByOrder)
WriteLine (readFlag[info.Member.Index] + " = true;");
if (_format == SerializationFormat.Encoded)
{
string val = GetObTempVar ();
RegisterReferencingMap (info.MappedType);
if (info.Member.TypeData.SchemaType != SchemaTypes.Primitive)
WriteLine ("object " + val + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
else
WriteLine ("object " + val + " = ReadReferencingElement (" + GetLiteral(info.Member.TypeData.XmlType) + ", " + GetLiteral(System.Xml.Schema.XmlSchema.Namespace) + ", out fixup.Ids[" + info.Member.Index + "]);");
if (info.MultiReferenceType)
WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {"); // already read
else
WriteLineInd ("if (" + val + " != null) {"); // null value
GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,val), isValueList);
WriteLineUni ("}");
}
else if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
if (info.ChoiceValue != null) {
XmlTypeMapMemberElement imem = (XmlTypeMapMemberElement) info.Member;
WriteLine (ob + ".@" + imem.ChoiceMember + " = " + GetLiteral(info.ChoiceValue) + ";");
}
GenerateSetMemberValue (info.Member, ob, GenerateReadObjectElement (info), isValueList);
GenerateEndHook ();
}
}
else
throw new InvalidOperationException ("Unknown member type");
if (!readByOrder)
WriteLineUni ("}");
else
WriteLine ("Reader.MoveToContent();");
first = false;
}
if (!readByOrder)
{
if (!first) WriteLineInd ("else {");
if (map.DefaultAnyElementMember != null)
{
XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
if (mem.TypeData.IsListType) {
if (!GenerateReadArrayMemberHook (xmlMapType, mem, indexes[mem.FlatArrayIndex])) {
GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode(mem.TypeData.ListItemTypeData, false), true);
GenerateEndHook ();
}
WriteLine (indexes[mem.FlatArrayIndex] + "++;");
}
else if (! GenerateReadMemberHook (xmlMapType, mem)) {
GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
GenerateEndHook ();
}
}
else {
if (!GenerateReadHook (HookType.unknownElement, xmlMapType)) {
WriteLine ("UnknownNode (" + ob + ");");
GenerateEndHook ();
}
}
if (!first) WriteLineUni ("}");
WriteLineUni ("}");
if (map.XmlTextCollector != null)
{
WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA)");
WriteLineInd ("{");
if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
{
XmlTypeMapMemberExpandable mem = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
XmlTypeMapMemberFlatList flatl = mem as XmlTypeMapMemberFlatList;
TypeData itype = (flatl == null) ? mem.TypeData.ListItemTypeData : flatl.ListMap.FindTextElement().TypeData;
if (!GenerateReadArrayMemberHook (xmlMapType, map.XmlTextCollector, indexes[mem.FlatArrayIndex])) {
string val = (itype.Type == typeof (string)) ? "Reader.ReadString()" : GetReadXmlNode (itype, false);
GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], val, true);
GenerateEndHook ();
}
WriteLine (indexes[mem.FlatArrayIndex] + "++;");
}
else if (!GenerateReadMemberHook (xmlMapType, map.XmlTextCollector))
{
XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector;
XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
if (info.TypeData.Type == typeof (string))
GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
else {
WriteLineInd ("{");
string str = GetStrTempVar ();
WriteLine ("string " + str + " = Reader.ReadString();");
GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString (str, info.TypeData, info.MappedType, info.IsNullable), isValueList);
WriteLineUni ("}");
}
GenerateEndHook ();
}
WriteLineUni ("}");
}
WriteLine ("else");
WriteLine ("\tUnknownNode(" + ob + ");");
WriteLine ("");
WriteLine ("Reader.MoveToContent();");
WriteLineUni ("}");
}
else
WriteLine ("Reader.MoveToContent();");
if (flatLists != null)
{
WriteLine ("");
foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
{
if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
string list = flatLists[mem.FlatArrayIndex];
if (mem.TypeData.Type.IsArray)
WriteLine (list + " = (" + mem.TypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.TypeData.Type.GetElementType()) + ", true);");
if (!IsReadOnly (typeMap, mem, mem.TypeData, isValueList) && mem.TypeData.Type.IsArray)
GenerateSetMemberValue (mem, ob, list, isValueList);
}
}
if (flatListsChoices != null)
{
WriteLine ("");
foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
{
if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
if (mem.ChoiceMember == null) continue;
string list = flatListsChoices[mem.FlatArrayIndex];
WriteLine (list + " = (" + mem.ChoiceTypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.ChoiceTypeData.Type.GetElementType()) + ", true);");
WriteLine (ob + ".@" + mem.ChoiceMember + " = " + list + ";");
}
}
GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
GenerateEndHook ();
}
if (!isValueList)
{
WriteLine ("");
WriteLine ("ReadEndElement();");
}
}