private void ParseObjectEnd(ParseRecord pr) { Debug.Assert(_stack != null); ParseRecord objectPr = (ParseRecord?)_stack.Peek() ?? pr; if (objectPr._objectPositionEnum == InternalObjectPositionE.Top) { if (ReferenceEquals(objectPr._dtType, Converter.s_typeofString)) { objectPr._newObj = objectPr._value; TopObject = objectPr._newObj; return; } } _stack.Pop(); ParseRecord?parentPr = (ParseRecord?)_stack.Peek(); if (objectPr._newObj == null) { return; } if (objectPr._objectTypeEnum == InternalObjectTypeE.Array) { if (objectPr._objectPositionEnum == InternalObjectPositionE.Top) { TopObject = objectPr._newObj; } RegisterObject(objectPr._newObj, objectPr, parentPr); return; } Debug.Assert(objectPr._objectInfo != null); objectPr._objectInfo.PopulateObjectMembers(objectPr._newObj, objectPr._memberData); // Registration is after object is populated if ((!objectPr._isRegistered) && (objectPr._objectId > 0)) { RegisterObject(objectPr._newObj, objectPr, parentPr); } if (objectPr._isValueTypeFixup) { ValueFixup?fixup = (ValueFixup?)ValueFixupStack.Pop(); //Value fixup Debug.Assert(fixup != null && parentPr != null); fixup.Fixup(objectPr, parentPr); // Value fixup } if (objectPr._objectPositionEnum == InternalObjectPositionE.Top) { TopObject = objectPr._newObj; } objectPr._objectInfo.ObjectEnd(); }
private void ParseMember(ParseRecord pr) { Debug.Assert(_stack != null); ParseRecord?objectPr = (ParseRecord?)_stack.Peek(); switch (pr._memberTypeEnum) { case InternalMemberTypeE.Item: ParseArrayMember(pr); return; case InternalMemberTypeE.Field: break; } Debug.Assert(objectPr != null && objectPr._objectInfo != null && pr._name != null); //if ((pr.PRdtType == null) && !objectPr.PRobjectInfo.isSi) if (pr._dtType == null && objectPr._objectInfo._isTyped) { pr._dtType = objectPr._objectInfo.GetType(pr._name); if (pr._dtType != null) { pr._dtTypeCode = Converter.ToCode(pr._dtType); } } if (pr._memberValueEnum == InternalMemberValueE.Null) { // Value is Null objectPr._objectInfo.AddValue(pr._name, null, ref objectPr._si, ref objectPr._memberData); } else if (pr._memberValueEnum == InternalMemberValueE.Nested) { ParseObject(pr); _stack.Push(pr); if ((pr._objectInfo != null) && pr._objectInfo._objectType != null && (pr._objectInfo._objectType.IsValueType)) { pr._isValueTypeFixup = true; //Valuefixup ValueFixupStack.Push(new ValueFixup(objectPr._newObj, pr._name, objectPr._objectInfo)); //valuefixup } else { objectPr._objectInfo.AddValue(pr._name, pr._newObj, ref objectPr._si, ref objectPr._memberData); } } else if (pr._memberValueEnum == InternalMemberValueE.Reference) { Debug.Assert(_objectManager != null); // See if object has already been instantiated object?refObj = _objectManager.GetObject(pr._idRef); if (refObj == null) { objectPr._objectInfo.AddValue(pr._name, null, ref objectPr._si, ref objectPr._memberData); objectPr._objectInfo.RecordFixup(objectPr._objectId, pr._name, pr._idRef); // Object not instantiated } else { objectPr._objectInfo.AddValue(pr._name, refObj, ref objectPr._si, ref objectPr._memberData); } } else if (pr._memberValueEnum == InternalMemberValueE.InlineValue) { // Primitive type or String if (ReferenceEquals(pr._dtType, Converter.s_typeofString)) { ParseString(pr, objectPr); objectPr._objectInfo.AddValue(pr._name, pr._value, ref objectPr._si, ref objectPr._memberData); } else if (pr._dtTypeCode == InternalPrimitiveTypeE.Invalid) { // The member field was an object put the value is Inline either bin.Base64 or invalid if (pr._arrayTypeEnum == InternalArrayTypeE.Base64) { Debug.Assert(pr._value != null); objectPr._objectInfo.AddValue(pr._name, Convert.FromBase64String(pr._value), ref objectPr._si, ref objectPr._memberData); } else if (ReferenceEquals(pr._dtType, Converter.s_typeofObject)) { throw new SerializationException(SR.Format(SR.Serialization_TypeMissing, pr._name)); } else { 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 (ReferenceEquals(pr._dtType, Converter.s_typeofSystemVoid)) { objectPr._objectInfo.AddValue(pr._name, pr._dtType, ref objectPr._si, ref objectPr._memberData); } else if (objectPr._objectInfo._isSi) { // ISerializable are added as strings, the conversion to type is done by the // ISerializable object objectPr._objectInfo.AddValue(pr._name, pr._value, ref objectPr._si, ref objectPr._memberData); } } } else { object?var = pr._varValue ?? Converter.FromString(pr._value, pr._dtTypeCode); objectPr._objectInfo.AddValue(pr._name, var, ref objectPr._si, ref objectPr._memberData); } } else { ParseError(pr, objectPr); } }
private void ParseArrayMember(ParseRecord pr) { Debug.Assert(_stack != null); ParseRecord?objectPr = (ParseRecord?)_stack.Peek(); Debug.Assert(objectPr != null && objectPr._indexMap != null && objectPr._lowerBoundA != null); // Set up for inserting value into correct array position if (objectPr._arrayTypeEnum == InternalArrayTypeE.Rectangular) { if (objectPr._memberIndex > 0) { NextRectangleMap(objectPr); // Rectangle array, calculate position in array } if (objectPr._isLowerBound) { Debug.Assert(objectPr._rectangularMap != null); for (int i = 0; i < objectPr._rank; i++) { objectPr._indexMap[i] = objectPr._rectangularMap[i] + objectPr._lowerBoundA[i]; } } } else { objectPr._indexMap[0] = !objectPr._isLowerBound ? objectPr._memberIndex : // Zero based array objectPr._lowerBoundA[0] + objectPr._memberIndex; // Lower Bound based array } // Set Array element according to type of element if (pr._memberValueEnum == InternalMemberValueE.Reference) { // Object Reference Debug.Assert(_objectManager != null); // See if object has already been instantiated object?refObj = _objectManager.GetObject(pr._idRef); if (refObj == null) { // Object not instantiated // Array fixup manager int[] fixupIndex = new int[objectPr._rank]; Array.Copy(objectPr._indexMap, fixupIndex, objectPr._rank); _objectManager.RecordArrayElementFixup(objectPr._objectId, fixupIndex, pr._idRef); } else { if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = refObj; } else { Debug.Assert(objectPr._newObj != null); ((Array)objectPr._newObj).SetValue(refObj, objectPr._indexMap); // Object has been instantiated } } } else if (pr._memberValueEnum == InternalMemberValueE.Nested) { //Set up dtType for ParseObject if (pr._dtType == null) { pr._dtType = objectPr._arrayElementType; } ParseObject(pr); _stack.Push(pr); if (objectPr._arrayElementType != null) { Debug.Assert(objectPr._newObj != null); if ((objectPr._arrayElementType.IsValueType) && (pr._arrayElementTypeCode == InternalPrimitiveTypeE.Invalid)) { pr._isValueTypeFixup = true; //Valuefixup ValueFixupStack.Push(new ValueFixup((Array)objectPr._newObj, objectPr._indexMap)); //valuefixup } else { if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = pr._newObj; } else { ((Array)objectPr._newObj).SetValue(pr._newObj, objectPr._indexMap); } } } } else if (pr._memberValueEnum == InternalMemberValueE.InlineValue) { if ((ReferenceEquals(objectPr._arrayElementType, Converter.s_typeofString)) || (ReferenceEquals(pr._dtType, Converter.s_typeofString))) { // String in either a string array, or a string element of an object array ParseString(pr, objectPr); if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = pr._value; } else { Debug.Assert(objectPr._newObj != null); ((Array)objectPr._newObj).SetValue(pr._value, objectPr._indexMap); } } else if (objectPr._isArrayVariant) { // Array of type object if (pr._keyDt == null) { throw new SerializationException(SR.Serialization_ArrayTypeObject); } object?var; if (ReferenceEquals(pr._dtType, Converter.s_typeofString)) { ParseString(pr, objectPr); var = pr._value; } else { var = pr._varValue ?? Converter.FromString(pr._value, pr._dtTypeCode); } if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = var; } else { Debug.Assert(objectPr._newObj != null); ((Array)objectPr._newObj).SetValue(var, objectPr._indexMap); // Primitive type } } else { // Primitive type if (objectPr._primitiveArray != null) { Debug.Assert(pr._value != null); // Fast path for Soap primitive arrays. Binary was handled in the BinaryParser objectPr._primitiveArray.SetValue(pr._value, objectPr._indexMap[0]); } else { object?var = pr._varValue ?? Converter.FromString(pr._value, objectPr._arrayElementTypeCode); if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = var; } else { Debug.Assert(objectPr._newObj != null); ((Array)objectPr._newObj).SetValue(var, objectPr._indexMap); // Primitive type } } } } else if (pr._memberValueEnum == InternalMemberValueE.Null) { objectPr._memberIndex += pr._consecutiveNullArrayEntryCount - 1; //also incremented again below } else { ParseError(pr, objectPr); } objectPr._memberIndex++; }