// Array object item encountered in stream private void ParseArrayMember(ParseRecord pr) { SerTrace.Log( this, "ParseArrayMember Entry"); ParseRecord objectPr = (ParseRecord)stack.Peek(); // Set up for inserting value into correct array position if (objectPr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular) { if (objectPr.PRmemberIndex > 0) NextRectangleMap(objectPr); // Rectangle array, calculate position in array if (objectPr.PRisLowerBound) { for (int i=0; i<objectPr.PRrank; i++) { if (objectPr.PRpositionA == null) objectPr.PRindexMap[i] = objectPr.PRrectangularMap[i] + objectPr.PRlowerBoundA[i]; else objectPr.PRindexMap[i] = objectPr.PRpositionA[i]; } } } else { if (!objectPr.PRisLowerBound) { if (objectPr.PRpositionA == null) objectPr.PRindexMap[0] = objectPr.PRmemberIndex; // Zero based array else objectPr.PRindexMap[0] = objectPr.PRpositionA[0]; // item position specified in SOAP stream } else objectPr.PRindexMap[0] = objectPr.PRlowerBoundA[0]+objectPr.PRmemberIndex; // Lower Bound based array } IndexTraceMessage("ParseArrayMember isLowerBound "+objectPr.PRisLowerBound+" indexMap ", objectPr.PRindexMap); // Set Array element according to type of element if (pr.PRmemberValueEnum == InternalMemberValueE.Reference) { // Object Reference // See if object has already been instantiated Object refObj = m_objectManager.GetObject(pr.PRidRef); if (refObj == null) { // Object not instantiated // Array fixup manager IndexTraceMessage("ParseArrayMember Record Fixup "+objectPr.PRnewObj.GetType(), objectPr.PRindexMap); int[] fixupIndex = new int[objectPr.PRrank]; Array.Copy(objectPr.PRindexMap, 0, fixupIndex, 0, objectPr.PRrank); SerTrace.Log( this, "ParseArrayMember RecordArrayElementFixup objectId ",objectPr.PRobjectId," idRef ",pr.PRidRef); m_objectManager.RecordArrayElementFixup(objectPr.PRobjectId, fixupIndex, pr.PRidRef); } else { IndexTraceMessage("ParseArrayMember SetValue ObjectReference "+objectPr.PRnewObj.GetType()+" "+refObj, objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = refObj; else ((Array)objectPr.PRnewObj).SetValue(refObj, objectPr.PRindexMap); // Object has been instantiated } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested) { //Set up dtType for ParseObject SerTrace.Log( this, "ParseArrayMember Nested "); if (pr.PRdtType == null) { pr.PRdtType = objectPr.PRarrayElementType; } ParseObject(pr); stack.Push(pr); if ((objectPr.PRarrayElementType.IsValueType) && (pr.PRarrayElementTypeCode == InternalPrimitiveTypeE.Invalid)) { SerTrace.Log( "ParseArrayMember ValueType ObjectPr ",objectPr.PRnewObj," index ",objectPr.PRmemberIndex); pr.PRisValueTypeFixup = true; //Valuefixup ValueFixupStack.Push(new ValueFixup((Array)objectPr.PRnewObj, objectPr.PRindexMap)); //valuefixup pr.PRisRegistered = true; // No need to register a value object, because there cant be 2 references to same instance of value type // (we know its not boxed here..array element type IsValueType, not Object) //RegisterObject(pr.PRnewObj, pr, objectPr); } else { SerTrace.Log( "ParseArrayMember SetValue Nested, memberIndex ",objectPr.PRmemberIndex); IndexTraceMessage("ParseArrayMember SetValue Nested ContainerObject "+objectPr.PRnewObj.GetType()+" "+objectPr.PRnewObj+" item Object "+pr.PRnewObj+" index ", objectPr.PRindexMap); stack.Dump(); SerTrace.Log( "ParseArrayMember SetValue Nested ContainerObject objectPr ",objectPr.Trace()); SerTrace.Log( "ParseArrayMember SetValue Nested ContainerObject pr ",pr.Trace()); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = pr.PRnewObj; else ((Array)objectPr.PRnewObj).SetValue(pr.PRnewObj, objectPr.PRindexMap); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue) { if ((objectPr.PRarrayElementType == Converter.typeofString) || (pr.PRdtType == Converter.typeofString)) { // String in either a string array, or a string element of an object array ParseString(pr, objectPr); IndexTraceMessage("ParseArrayMember SetValue String "+objectPr.PRnewObj.GetType()+" "+pr.PRvalue, objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = (Object)pr.PRvalue; else ((Array)objectPr.PRnewObj).SetValue((Object)pr.PRvalue, objectPr.PRindexMap); } else if (objectPr.PRisArrayVariant) { // Array of type object if (pr.PRkeyDt == null) throw new SerializationException(Environment.GetResourceString("Serialization_ArrayTypeObject")); Object var = null; if (pr.PRdtType == Converter.typeofString) { ParseString(pr, objectPr); var = pr.PRvalue; } else if (pr.PRdtTypeCode == InternalPrimitiveTypeE.Invalid) { // Not nested and invalid, so it is an empty object var = FormatterServices.GetUninitializedObject(pr.PRdtType); } else { if (pr.PRvarValue != null) var = pr.PRvarValue; else var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode); } IndexTraceMessage("ParseArrayMember SetValue variant or Object "+objectPr.PRnewObj.GetType()+" var "+var+" indexMap ", objectPr.PRindexMap); if (objectPr.PRobjectA != null) objectPr.PRobjectA[objectPr.PRindexMap[0]] = var; else ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type } else { // Primitive type if (objectPr.PRprimitiveArray != null) { // Fast path for Soap primitive arrays. Binary was handled in the BinaryParser objectPr.PRprimitiveArray.SetValue(pr.PRvalue, objectPr.PRindexMap[0]); } else { Object var = null; if (pr.PRvarValue != null) var = pr.PRvarValue; else var = Converter.FromString(pr.PRvalue, objectPr.PRarrayElementTypeCode); SerTrace.Log( this, "ParseArrayMember SetValue Primitive pr.PRvalue "+var," elementTypeCode ",((Enum)objectPr.PRdtTypeCode)); IndexTraceMessage("ParseArrayMember SetValue Primitive "+objectPr.PRnewObj.GetType()+" var: "+var+" varType "+var.GetType(), objectPr.PRindexMap); if (objectPr.PRobjectA != null) { SerTrace.Log( this, "ParseArrayMember SetValue Primitive predefined array "+objectPr.PRobjectA.GetType()); objectPr.PRobjectA[objectPr.PRindexMap[0]] = var; } else ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type SerTrace.Log( this, "ParseArrayMember SetValue Primitive after"); } } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Null) { SerTrace.Log( "ParseArrayMember Null item ",pr.PRmemberIndex," nullCount ",pr.PRnullCount); objectPr.PRmemberIndex += pr.PRnullCount-1; //also incremented again below } else ParseError(pr, objectPr); SerTrace.Log( "ParseArrayMember increment memberIndex ",objectPr.PRmemberIndex," ",objectPr.Trace()); objectPr.PRmemberIndex++; SerTrace.Log( "ParseArrayMember Exit"); }
// Object member encountered in stream private void ParseMember(ParseRecord pr) { SerTrace.Log( this, "ParseMember Entry "); ParseRecord objectPr = (ParseRecord)stack.Peek(); String objName = null; if (objectPr != null) objName = objectPr.PRname; SerTrace.Log( this, "ParseMember ",objectPr.PRobjectId," ",pr.PRname); SerTrace.Log( this, "ParseMember objectPr ",objectPr.Trace()); SerTrace.Log( this, "ParseMember pr ",pr.Trace()); switch (pr.PRmemberTypeEnum) { case InternalMemberTypeE.Item: ParseArrayMember(pr); return; case InternalMemberTypeE.Field: break; } //if ((pr.PRdtType == null) && !objectPr.PRobjectInfo.isSi) if ((pr.PRdtType == null) && objectPr.PRobjectInfo.isTyped) { SerTrace.Log( this, "ParseMember pr.PRdtType null and not isSi"); pr.PRdtType = objectPr.PRobjectInfo.GetType(pr.PRname); if (pr.PRdtType == null) throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_TypeResolved"), objectPr.PRnewObj+" "+pr.PRname)); pr.PRdtTypeCode = Converter.ToCode(pr.PRdtType); } if (pr.PRmemberValueEnum == InternalMemberValueE.Null) { // Value is Null SerTrace.Log( this, "ParseMember null member: ",pr.PRname); SerTrace.Log( this, "AddValue 1"); objectPr.PRobjectInfo.AddValue(pr.PRname, null, ref objectPr.PRsi, ref objectPr.PRmemberData); } else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested) { SerTrace.Log( this, "ParseMember Nested Type member: ",pr.PRname," objectPr.PRnewObj ",objectPr.PRnewObj); ParseObject(pr); stack.Push(pr); SerTrace.Log( this, "AddValue 2 ",pr.PRnewObj," is value type ",pr.PRnewObj.GetType().IsValueType); if ((pr.PRobjectInfo != null) && (pr.PRobjectInfo.objectType.IsValueType)) { SerTrace.Log( "ParseMember ValueType ObjectPr ",objectPr.PRnewObj," memberName ",pr.PRname," nested object ",pr.PRnewObj); pr.PRisValueTypeFixup = true; //Valuefixup ValueFixupStack.Push(new ValueFixup(objectPr.PRnewObj, pr.PRname, objectPr.PRobjectInfo));//valuefixup } else { SerTrace.Log( this, "AddValue 2A "); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRnewObj, ref objectPr.PRsi, ref objectPr.PRmemberData); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.Reference) { SerTrace.Log( this, "ParseMember Reference Type member: ",pr.PRname); // See if object has already been instantiated Object refObj = m_objectManager.GetObject(pr.PRidRef); if (refObj == null) { SerTrace.Log( this, "ParseMember RecordFixup: ",pr.PRname); SerTrace.Log( this, "AddValue 3"); objectPr.PRobjectInfo.AddValue(pr.PRname, null, ref objectPr.PRsi, ref objectPr.PRmemberData); objectPr.PRobjectInfo.RecordFixup(objectPr.PRobjectId, pr.PRname, pr.PRidRef); // Object not instantiated } else { SerTrace.Log( this, "ParseMember Referenced Object Known ",pr.PRname," ",refObj); SerTrace.Log( this, "AddValue 5"); objectPr.PRobjectInfo.AddValue(pr.PRname, refObj, ref objectPr.PRsi, ref objectPr.PRmemberData); } } else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue) { // Primitive type or String SerTrace.Log( this, "ParseMember primitive or String member: ",pr.PRname); if (pr.PRdtType == Converter.typeofString) { ParseString(pr, objectPr); SerTrace.Log( this, "AddValue 6"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue, ref objectPr.PRsi, ref objectPr.PRmemberData); } else if (pr.PRdtTypeCode == InternalPrimitiveTypeE.Invalid) { // The member field was an object put the value is Inline either bin.Base64 or invalid if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64) { SerTrace.Log( this, "AddValue 7"); objectPr.PRobjectInfo.AddValue(pr.PRname, Convert.FromBase64String(pr.PRvalue), ref objectPr.PRsi, ref objectPr.PRmemberData); } else if (pr.PRdtType == Converter.typeofObject) throw new SerializationException(String.Format(Environment.GetResourceString("Serialization_TypeMissing"), pr.PRname)); else { SerTrace.Log( this, "Object Class with no memberInfo data Member "+pr.PRname+" type "+pr.PRdtType); ParseString(pr, objectPr); // Register the object if it has an objectId // Object Class with no memberInfo data // only special case where AddValue is needed? if (pr.PRdtType == Converter.typeofSystemVoid) { SerTrace.Log( this, "AddValue 9"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRdtType, ref objectPr.PRsi, ref objectPr.PRmemberData); } else if (objectPr.PRobjectInfo.isSi) { // ISerializable are added as strings, the conversion to type is done by the // ISerializable object SerTrace.Log( this, "AddValue 10"); objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue, ref objectPr.PRsi, ref objectPr.PRmemberData); } } } else { Object var = null; if (pr.PRvarValue != null) var = pr.PRvarValue; else var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode); // Not a string, convert the value SerTrace.Log( this, "ParseMember Converting primitive and storing"); stack.Dump(); SerTrace.Log( this, "ParseMember pr "+pr.Trace()); SerTrace.Log( this, "ParseMember objectPr ",objectPr.Trace()); SerTrace.Log( this, "AddValue 11"); objectPr.PRobjectInfo.AddValue(pr.PRname, var, ref objectPr.PRsi, ref objectPr.PRmemberData); } } else ParseError(pr, objectPr); }
// End of object encountered in stream private void ParseObjectEnd(ParseRecord pr) { SerTrace.Log( this, "ParseObjectEnd Entry ",pr.Trace()); ParseRecord objectPr = (ParseRecord)stack.Peek(); if (objectPr == null) objectPr = pr; //BCLDebug.Assert(objectPr != null, "[System.Runtime.Serialization.Formatters.ParseObjectEnd]objectPr != null"); SerTrace.Log( this, "ParseObjectEnd objectPr ",objectPr.Trace()); if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) { SerTrace.Log( this, "ParseObjectEnd Top Object dtType ",objectPr.PRdtType); if (objectPr.PRdtType == Converter.typeofString) { SerTrace.Log( this, "ParseObjectEnd Top String"); objectPr.PRnewObj = objectPr.PRvalue; isTopObjectResolved = true; topObject = objectPr.PRnewObj; return; } } stack.Pop(); ParseRecord parentPr = (ParseRecord)stack.Peek(); if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array) { if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) { SerTrace.Log( this, "ParseObjectEnd Top Object (Array) Resolved"); isTopObjectResolved = true; topObject = objectPr.PRnewObj; } SerTrace.Log( this, "ParseArray RegisterObject ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType()); RegisterObject(objectPr.PRnewObj, objectPr, parentPr); return; } objectPr.PRobjectInfo.PopulateObjectMembers(objectPr.PRnewObj, objectPr.PRmemberData); // Registration is after object is populated if ((!objectPr.PRisRegistered) && (objectPr.PRobjectId > 0)) { SerTrace.Log( this, "ParseObject Register Object ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType()); RegisterObject(objectPr.PRnewObj, objectPr, parentPr); } if (objectPr.PRisValueTypeFixup) { SerTrace.Log( this, "ParseObjectEnd ValueTypeFixup ",objectPr.PRnewObj.GetType()); ValueFixup fixup = (ValueFixup)ValueFixupStack.Pop(); //Value fixup fixup.Fixup(objectPr, parentPr); // Value fixup } if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top) { SerTrace.Log( this, "ParseObjectEnd Top Object Resolved ",objectPr.PRnewObj.GetType()); isTopObjectResolved = true; topObject = objectPr.PRnewObj; } objectPr.PRobjectInfo.ObjectEnd(); SerTrace.Log( this, "ParseObjectEnd Exit ",objectPr.PRnewObj.GetType()," id: ",objectPr.PRobjectId); }