示例#1
0
        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();
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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++;
        }