コード例 #1
0
            internal Scope(Scope?previousScope, IEnumerable <Type> allowedTypes)
            {
                Debug.Assert(allowedTypes != null);

                m_previousScope        = previousScope;
                m_allowedTypes         = new HashSet <Type>(allowedTypes.Where(type => type != null));
                m_deserializationToken = SerializationInfo.StartDeserialization();
            }
コード例 #2
0
        internal object Deserialize(BinaryParser serParser, bool fCheck)
        {
            if (serParser == null)
            {
                throw new ArgumentNullException(nameof(serParser));
            }

            _fullDeserialization = false;
            TopObject            = null;
            _topId = 0;

            _isSimpleAssembly = (_formatterEnums._assemblyFormat == FormatterAssemblyStyle.Simple);

            using (DeserializationToken token = SerializationInfo.StartDeserialization())
            {
                if (_fullDeserialization)
                {
                    // Reinitialize
                    _objectManager     = new ObjectManager(_surrogates, _context);
                    _serObjectInfoInit = new SerObjectInfoInit();
                }

                // Will call back to ParseObject, ParseHeader for each object found
                serParser.Run();

                if (_fullDeserialization)
                {
                    _objectManager !.DoFixups();
                }

                if (TopObject == null)
                {
                    throw new SerializationException(SR.Serialization_TopObject);
                }

                //if TopObject has a surrogate then the actual object may be changed during special fixup
                //So refresh it using topID.
                if (HasSurrogate(TopObject.GetType()) && _topId != 0)//Not yet resolved
                {
                    Debug.Assert(_objectManager != null);
                    TopObject = _objectManager.GetObject(_topId);
                }

                if (TopObject is IObjectReference)
                {
                    TopObject = ((IObjectReference)TopObject).GetRealObject(_context);
                }

                if (_fullDeserialization)
                {
                    _objectManager !.RaiseDeserializationEvent(); // This will raise both IDeserialization and [OnDeserialized] events
                }

                return(TopObject !);
            }
        }
コード例 #3
0
        private object EvalFunction(FunctionId id, object[] argumentValues, DataRow row, DataRowVersion version)
        {
            StorageType storageType;

            switch (id)
            {
            case FunctionId.Abs:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());
                if (ExpressionNode.IsInteger(storageType))
                {
                    return(Math.Abs((long)argumentValues[0]));
                }
                if (ExpressionNode.IsNumeric(storageType))
                {
                    return(Math.Abs((double)argumentValues[0]));
                }

                throw ExprException.ArgumentTypeInteger(s_funcs[_info]._name, 1);

            case FunctionId.cBool:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());
                switch (storageType)
                {
                case StorageType.Boolean:
                    return((bool)argumentValues[0]);

                case StorageType.Int32:
                    return((int)argumentValues[0] != 0);

                case StorageType.Double:
                    return((double)argumentValues[0] != 0.0);

                case StorageType.String:
                    return(bool.Parse((string)argumentValues[0]));

                default:
                    throw ExprException.DatatypeConvertion(argumentValues[0].GetType(), typeof(bool));
                }

            case FunctionId.cInt:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToInt32(argumentValues[0], FormatProvider));

            case FunctionId.cDate:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToDateTime(argumentValues[0], FormatProvider));

            case FunctionId.cDbl:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToDouble(argumentValues[0], FormatProvider));

            case FunctionId.cStr:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToString(argumentValues[0], FormatProvider));

            case FunctionId.Charindex:
                Debug.Assert(_argumentCount == 2, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                Debug.Assert(argumentValues[0] is string, "Invalid argument type for " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[1] is string, "Invalid argument type for " + s_funcs[_info]._name);

                if (DataStorage.IsObjectNull(argumentValues[0]) || DataStorage.IsObjectNull(argumentValues[1]))
                {
                    return(DBNull.Value);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                if (argumentValues[1] is SqlString)
                {
                    argumentValues[1] = ((SqlString)argumentValues[1]).Value;
                }

                return(((string)argumentValues[1]).IndexOf((string)argumentValues[0], StringComparison.Ordinal));

            case FunctionId.Iif:
                Debug.Assert(_argumentCount == 3, "Invalid argument argumentCount: " + _argumentCount.ToString(FormatProvider));

                object first = _arguments[0].Eval(row, version);

                if (DataExpression.ToBoolean(first) != false)
                {
                    return(_arguments[1].Eval(row, version));
                }
                else
                {
                    return(_arguments[2].Eval(row, version));
                }

            case FunctionId.In:
                // we never evaluate IN directly: IN as a binary operator, so evaluation of this should be in
                // BinaryNode class
                throw ExprException.NYI(s_funcs[_info]._name);

            case FunctionId.IsNull:
                Debug.Assert(_argumentCount == 2, "Invalid argument argumentCount: ");

                if (DataStorage.IsObjectNull(argumentValues[0]))
                {
                    return(argumentValues[1]);
                }
                else
                {
                    return(argumentValues[0]);
                }

            case FunctionId.Len:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid argument type for " + s_funcs[_info]._name);

                if (argumentValues[0] is SqlString)
                {
                    if (((SqlString)argumentValues[0]).IsNull)
                    {
                        return(DBNull.Value);
                    }
                    else
                    {
                        argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                    }
                }

                return(((string)argumentValues[0]).Length);


            case FunctionId.Substring:
                Debug.Assert(_argumentCount == 3, "Invalid argument argumentCount: " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid first argument " + argumentValues[0].GetType().FullName + " in " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[1] is int, "Invalid second argument " + argumentValues[1].GetType().FullName + " in " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[2] is int, "Invalid third argument " + argumentValues[2].GetType().FullName + " in " + s_funcs[_info]._name);

                // work around the differences in .NET and VBA implementation of the Substring function
                // 1. The <index> Argument is 0-based in .NET, and 1-based in VBA
                // 2. If the <Length> argument is longer then the string length .NET throws an ArgumentException
                //    but our users still want to get a result.

                int start = (int)argumentValues[1] - 1;

                int length = (int)argumentValues[2];

                if (start < 0)
                {
                    throw ExprException.FunctionArgumentOutOfRange("index", "Substring");
                }

                if (length < 0)
                {
                    throw ExprException.FunctionArgumentOutOfRange("length", "Substring");
                }

                if (length == 0)
                {
                    return(string.Empty);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                int src_length = ((string)argumentValues[0]).Length;

                if (start > src_length)
                {
                    return(DBNull.Value);
                }

                if (start + length > src_length)
                {
                    length = src_length - start;
                }

                return(((string)argumentValues[0]).Substring(start, length));

            case FunctionId.Trim:
            {
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid argument type for " + s_funcs[_info]._name);

                if (DataStorage.IsObjectNull(argumentValues[0]))
                {
                    return(DBNull.Value);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                return(((string)argumentValues[0]).Trim());
            }

            case FunctionId.Convert:
                if (_argumentCount != 2)
                {
                    throw ExprException.FunctionArgumentCount(_name);
                }

                if (argumentValues[0] == DBNull.Value)
                {
                    return(DBNull.Value);
                }

                Type        type   = (Type)argumentValues[1];
                StorageType mytype = DataStorage.GetStorageType(type);
                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());

                if (mytype == StorageType.DateTimeOffset)
                {
                    if (storageType == StorageType.String)
                    {
                        return(SqlConvert.ConvertStringToDateTimeOffset((string)argumentValues[0], FormatProvider));
                    }
                }

                if (StorageType.Object != mytype)
                {
                    if ((mytype == StorageType.Guid) && (storageType == StorageType.String))
                    {
                        return(new Guid((string)argumentValues[0]));
                    }

                    if (ExpressionNode.IsFloatSql(storageType) && ExpressionNode.IsIntegerSql(mytype))
                    {
                        if (StorageType.Single == storageType)
                        {
                            return(SqlConvert.ChangeType2((float)SqlConvert.ChangeType2(argumentValues[0], StorageType.Single, typeof(float), FormatProvider), mytype, type, FormatProvider));
                        }
                        else if (StorageType.Double == storageType)
                        {
                            return(SqlConvert.ChangeType2((double)SqlConvert.ChangeType2(argumentValues[0], StorageType.Double, typeof(double), FormatProvider), mytype, type, FormatProvider));
                        }
                        else if (StorageType.Decimal == storageType)
                        {
                            return(SqlConvert.ChangeType2((decimal)SqlConvert.ChangeType2(argumentValues[0], StorageType.Decimal, typeof(decimal), FormatProvider), mytype, type, FormatProvider));
                        }
                    }

                    // The Convert function can be called lazily, outside of a previous Serialization Guard scope.
                    // If there was a type limiter scope on the stack at the time this Convert function was created,
                    // we must manually re-enter the Serialization Guard scope.

                    DeserializationToken deserializationToken = (_capturedLimiter != null) ? SerializationInfo.StartDeserialization() : default;
                    using (deserializationToken)
                    {
                        return(SqlConvert.ChangeType2(argumentValues[0], mytype, type, FormatProvider));
                    }
                }

                return(argumentValues[0]);

            case FunctionId.DateTimeOffset:
                if (argumentValues[0] == DBNull.Value || argumentValues[1] == DBNull.Value || argumentValues[2] == DBNull.Value)
                {
                    return(DBNull.Value);
                }
                switch (((DateTime)argumentValues[0]).Kind)
                {
                case DateTimeKind.Utc:
                    if ((int)argumentValues[1] != 0 && (int)argumentValues[2] != 0)
                    {
                        throw ExprException.MismatchKindandTimeSpan();
                    }
                    break;

                case DateTimeKind.Local:
                    if (DateTimeOffset.Now.Offset.Hours != (int)argumentValues[1] && DateTimeOffset.Now.Offset.Minutes != (int)argumentValues[2])
                    {
                        throw ExprException.MismatchKindandTimeSpan();
                    }
                    break;

                case DateTimeKind.Unspecified: break;
                }
                if ((int)argumentValues[1] < -14 || (int)argumentValues[1] > 14)
                {
                    throw ExprException.InvalidHoursArgument();
                }
                if ((int)argumentValues[2] < -59 || (int)argumentValues[2] > 59)
                {
                    throw ExprException.InvalidMinutesArgument();
                }
                // range should be within -14 hours and  +14 hours
                if ((int)argumentValues[1] == 14 && (int)argumentValues[2] > 0)
                {
                    throw ExprException.InvalidTimeZoneRange();
                }
                if ((int)argumentValues[1] == -14 && (int)argumentValues[2] < 0)
                {
                    throw ExprException.InvalidTimeZoneRange();
                }

                return(new DateTimeOffset((DateTime)argumentValues[0], new TimeSpan((int)argumentValues[1], (int)argumentValues[2], 0)));

            default:
                throw ExprException.UndefinedFunction(s_funcs[_info]._name);
            }
        }