A class that stores a numeric range.
A class that stores a numeric range.
Ejemplo n.º 1
0
        /// <summary>
        /// Validates the operand (sets the ParsedBrowsePath and ParsedIndexRange properties).
        /// </summary>
        public override ServiceResult Validate(FilterContext context, int index)
        {
            m_validated = false;

            // verify attribute id.
            if (!Attributes.IsValid(m_attributeId))
            {
                return(ServiceResult.Create(
                           StatusCodes.BadAttributeIdInvalid,
                           "SimpleAttributeOperand does not specify a valid AttributeId ({0}).",
                           m_attributeId));
            }

            // initialize as empty.
            m_parsedIndexRange = NumericRange.Empty;

            // parse the index range.
            if (!String.IsNullOrEmpty(m_indexRange))
            {
                try {
                    m_parsedIndexRange = NumericRange.Parse(m_indexRange);
                } catch (Exception e) {
                    return(ServiceResult.Create(
                               e,
                               StatusCodes.BadIndexRangeInvalid,
                               "SimpleAttributeOperand does not specify a valid BrowsePath ({0}).",
                               m_indexRange));
                }

                if (m_attributeId != Attributes.Value)
                {
                    return(ServiceResult.Create(
                               StatusCodes.BadIndexRangeInvalid,
                               "SimpleAttributeOperand specifies an IndexRange for an Attribute other than Value ({0}).",
                               m_attributeId));
                }
            }

            m_validated = true;

            return(ServiceResult.Good);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Validates a read value id parameter.
        /// </summary>
        public static ServiceResult Validate(HistoryReadValueId valueId)
        {
            // check for null structure.
            if (valueId == null)
            {
                return(StatusCodes.BadStructureMissing);
            }

            // null node ids are always invalid.
            if (NodeId.IsNull(valueId.NodeId))
            {
                return(StatusCodes.BadNodeIdInvalid);
            }

            // initialize as empty.
            valueId.ParsedIndexRange = NumericRange.Empty;

            // parse the index range if specified.
            if (!String.IsNullOrEmpty(valueId.IndexRange))
            {
                try
                {
                    valueId.ParsedIndexRange = NumericRange.Parse(valueId.IndexRange);
                }
                catch (Exception e)
                {
                    return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty));
                }
            }
            else
            {
                valueId.ParsedIndexRange = NumericRange.Empty;
            }

            // passed basic validation.
            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles a write operation for an individual tag.
        /// </summary>
        public ServiceResult WriteTagValue(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MemoryTagState tag = node as MemoryTagState;

            if (tag == null)
            {
                return StatusCodes.BadNodeIdUnknown;
            }

            if (NumericRange.Empty != indexRange)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            if (!QualifiedName.IsNull(dataEncoding))
            {
                return StatusCodes.BadDataEncodingInvalid;
            }

            if (statusCode != StatusCodes.Good)
            {
                return StatusCodes.BadWriteNotSupported;
            }

            if (timestamp != DateTime.MinValue)
            {
                return StatusCodes.BadWriteNotSupported;
            }

            bool changed = false;
            int offset = (int)tag.Offset;

            lock (m_dataLock)
            {
                if (offset < 0 || offset >= m_buffer.Length)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                if (m_buffer == null)
                {
                    return StatusCodes.BadOutOfService;
                }

                byte[] bytes = null;

                switch (m_elementType)
                {
                    case BuiltInType.UInt32:
                    {
                        uint? valueToWrite = value as uint?;

                        if (valueToWrite == null)
                        {
                            return StatusCodes.BadTypeMismatch;
                        }

                        bytes = BitConverter.GetBytes(valueToWrite.Value);
                        break;
                    }

                    case BuiltInType.Double:
                    {
                        double? valueToWrite = value as double?;

                        if (valueToWrite == null)
                        {
                            return StatusCodes.BadTypeMismatch;
                        }

                        bytes = BitConverter.GetBytes(valueToWrite.Value);
                        break;
                    }

                    default:
                    {
                        return StatusCodes.BadNodeIdUnknown;
                    }
                }

                for (int ii = 0; ii < bytes.Length; ii++)
                {
                    if (!changed)
                    {
                        if (m_buffer[offset + ii] != bytes[ii])
                        {
                            changed = true;
                        }
                    }

                    m_buffer[offset + ii] = bytes[ii];
                }
            }

            if (changed)
            {
                OnBufferChanged(offset);
            }

            return ServiceResult.Good;
        }
Ejemplo n.º 4
0
        public ServiceResult OnChangeLockByWrite(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            DsatsDemo.LockConditionState condition = null;

            BaseInstanceState instance = node as BaseInstanceState;

            if (instance.Parent != null)
            {
                condition = instance.Parent as DsatsDemo.LockConditionState;
            }

            if (condition == null)
            {
                return StatusCodes.BadNotWritable;
            }

            string lockState = value as string;

            if (lockState == null)
            {
                return StatusCodes.BadTypeMismatch;
            }

            if (lockState == "Locked")
            {
                ServiceResult result = OnRequestLock(context, condition.Request, condition.NodeId, new object[0], new object[0]);
                value = condition.LockStateAsString.Value;
                return result;
            }

            else if (lockState == "Unlocked")
            {
                ServiceResult result = OnReleaseLock(context, condition.Request, condition.NodeId, new object[0], new object[0]);
                value = condition.LockStateAsString.Value;
                return result;
            }

            return StatusCodes.BadTypeMismatch;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handles the read operation for an invidual tag.
        /// </summary>
        public ServiceResult ReadTagValue(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MemoryTagState tag = node as MemoryTagState;

            if (tag == null)
            {
                return StatusCodes.BadNodeIdUnknown;
            }

            if (NumericRange.Empty != indexRange)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            if (!QualifiedName.IsNull(dataEncoding))
            {
                return StatusCodes.BadDataEncodingInvalid;
            }

            int offset = (int)tag.Offset;

            lock (m_dataLock)
            {
                if (offset < 0 || offset >= m_buffer.Length)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                if (m_buffer == null)
                {
                    return StatusCodes.BadOutOfService;
                }

                value = GetValueAtOffset(offset).Value;
            }

            statusCode = StatusCodes.Good;
            timestamp = m_lastScanTime;

            return ServiceResult.Good;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Generates a new value each time the value is read.
        /// </summary>
        private ServiceResult DoDeviceRead(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            BaseVariableState variable = node as BaseVariableState;

            if (variable == null)
            {
                return ServiceResult.Good;
            }

            if (!SimulationActive.Value)
            {
                return ServiceResult.Good;
            }

            TestDataSystem system = context.SystemHandle as TestDataSystem;

            if (system == null)
            {
                return StatusCodes.BadOutOfService;
            }

            try
            {
                value = system.ReadValue(variable);

                statusCode = StatusCodes.Good;
                timestamp = DateTime.UtcNow;

                ServiceResult error = BaseVariableState.ApplyIndexRangeAndDataEncoding(
                    context,
                    indexRange,
                    dataEncoding,
                    ref value);

                if (ServiceResult.IsBad(error))
                {
                    statusCode = error.StatusCode;
                }
                
                return ServiceResult.Good;
            }
            catch (Exception e)
            {
                return new ServiceResult(e);
            }
        }       
Ejemplo n.º 7
0
        private ServiceResult OnChangePhaseByWrite(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            string phase = value as string;

            if (phase == null)
            {
                return StatusCodes.BadTypeMismatch;
            }

            List<IReference> references = new List<IReference>();
            m_rig.Phases.GetReferences(context, references, Opc.Ua.ReferenceTypeIds.Organizes, false);

            foreach (IReference reference in references)
            {
                if (reference.TargetId.ToString().Contains(phase))
                {
                    return OnChangePhase(context, m_rig.ChangePhase, m_rig.NodeId, (NodeId)reference.TargetId);
                }
            }

            return StatusCodes.BadTypeMismatch;
        }
Ejemplo n.º 8
0
        private ServiceResult OnWriteAnalog(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            AnalogItemState variable = node as AnalogItemState;

            // verify data type.
            Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType(
                value,
                variable.DataType,
                variable.ValueRank,
                context.NamespaceUris,
                context.TypeTable);

            if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown)
            {
                return StatusCodes.BadTypeMismatch;
            }

            // check index range.
            if (variable.ValueRank >= 0)
            {
                if (indexRange != NumericRange.Empty)
                {
                    object target = variable.Value;
                    ServiceResult result = indexRange.UpdateRange(ref target, value);

                    if (ServiceResult.IsBad(result))
                    {
                        return result;
                    }

                    value = target;
                }
            }

            // check instrument range.
            else
            {
                if (indexRange != NumericRange.Empty)
                {
                    return StatusCodes.BadIndexRangeInvalid;
                }

                double number = Convert.ToDouble(value);

                if (variable.InstrumentRange != null && (number < variable.InstrumentRange.Value.Low || number > variable.InstrumentRange.Value.High))
                {
                    return StatusCodes.BadOutOfRange;
                }
            }

            return ServiceResult.Good;
        }
        /// <summary>
        /// Write the value for the value attribute.
        /// </summary>
        protected override ServiceResult WriteValueAttribute(
            ISystemContext context,
            NumericRange indexRange,
            object value,
            StatusCode statusCode,
            DateTime sourceTimestamp)
        {
            ServiceResult result = null;

            if ((WriteMask & AttributeWriteMask.ValueForVariableType) == 0)
            {
                return StatusCodes.BadNotWritable;
            }

            // ensure the source timestamp has a valid value.
            if (sourceTimestamp == DateTime.MinValue)
            {
                sourceTimestamp = DateTime.UtcNow;
            }

            // index range writes not supported.
            if (indexRange != NumericRange.Empty)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            // verify data type.
            TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType(
                value,
                m_dataType,
                m_valueRank,
                context.NamespaceUris,
                context.TypeTable);

            if (typeInfo == null || typeInfo == TypeInfo.Unknown)
            {
                return StatusCodes.BadTypeMismatch;
            }

            // check for simple write value handler.
            if (OnSimpleWriteValue != null)
            {
                result = OnSimpleWriteValue(
                    context,
                    this,
                    ref value);

                if (ServiceResult.IsBad(result))
                {
                    return result;
                }
            }

            // update cached values.
            Value = value;

            return ServiceResult.Good;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Parses a string representing a numeric range.
        /// </summary>
        /// <param name="textToParse">The text to parse, prior to checking it is within the allowed range</param>
        /// <param name="range">The parsed range.</param>
        /// <returns>The reason for any error.</returns>
        public static ServiceResult Validate(string textToParse, out NumericRange range)
        {
            range = NumericRange.Empty;

            if (String.IsNullOrEmpty(textToParse))
            {
                return(ServiceResult.Good);
            }

            // check for multidimensional ranges.
            int index = textToParse.IndexOf(',');

            if (index >= 0)
            {
                int start = 0;
                List <NumericRange> subranges = new List <NumericRange>();

                for (int ii = 0; ii < textToParse.Length; ii++)
                {
                    char ch = textToParse[ii];

                    if (ch == ',' || ii == textToParse.Length - 1)
                    {
                        NumericRange  subrange = new NumericRange();
                        string        subtext  = (ch == ',') ? textToParse.Substring(start, ii - start) : textToParse.Substring(start);
                        ServiceResult result   = Validate(subtext, out subrange);

                        if (ServiceResult.IsBad(result))
                        {
                            return(result);
                        }

                        subranges.Add(subrange);
                        start = ii + 1;
                    }
                }

                // must have at least two entries.
                if (subranges.Count < 2)
                {
                    return(StatusCodes.BadIndexRangeInvalid);
                }

                range.m_begin     = subranges[0].Begin;
                range.m_end       = subranges[0].End;
                range.m_subranges = subranges.ToArray();

                return(ServiceResult.Good);
            }

            try
            {
                index = textToParse.IndexOf(':');

                if (index != -1)
                {
                    range.Begin = Convert.ToInt32(textToParse.Substring(0, index), CultureInfo.InvariantCulture);
                    range.End   = Convert.ToInt32(textToParse.Substring(index + 1), CultureInfo.InvariantCulture);

                    if (range.End < 0)
                    {
                        return(ServiceResult.Create(
                                   StatusCodes.BadIndexRangeInvalid,
                                   "NumericRange does not have a valid end index ({0}).",
                                   range.End));
                    }

                    if (range.Begin >= range.End)
                    {
                        return(ServiceResult.Create(
                                   StatusCodes.BadIndexRangeInvalid,
                                   "NumericRange does not have a start index that is less than the end index ({0}).",
                                   range));
                    }
                }
                else
                {
                    range.Begin = Convert.ToInt32(textToParse, CultureInfo.InvariantCulture);
                    range.End   = -1;
                }

                if (range.Begin < 0)
                {
                    return(ServiceResult.Create(
                               StatusCodes.BadIndexRangeInvalid,
                               "NumericRange does not have a valid start index ({0}).",
                               range.Begin));
                }
            }
            catch (Exception e)
            {
                return(ServiceResult.Create(
                           e,
                           StatusCodes.BadIndexRangeInvalid,
                           "NumericRange cannot be parsed ({0}).",
                           textToParse));
            }

            return(ServiceResult.Good);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Validates a write value parameter.
        /// </summary>
        public static ServiceResult Validate(WriteValue value)
        {
            // check for null structure.
            if (value == null)
            {
                return(StatusCodes.BadStructureMissing);
            }

            // null node ids are always invalid.
            if (value.NodeId == null)
            {
                return(StatusCodes.BadNodeIdInvalid);
            }

            // must be a legimate attribute value.
            if (!Attributes.IsValid(value.AttributeId))
            {
                return(StatusCodes.BadAttributeIdInvalid);
            }

            // initialize as empty.
            value.ParsedIndexRange = NumericRange.Empty;

            // parse the index range if specified.
            if (!String.IsNullOrEmpty(value.IndexRange))
            {
                try
                {
                    value.ParsedIndexRange = NumericRange.Parse(value.IndexRange);
                }
                catch (Exception e)
                {
                    return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty));
                }

                if (value.ParsedIndexRange.SubRanges != null)
                {
                    Matrix matrix = value.Value.Value as Matrix;

                    if (matrix == null)
                    {
                        // Check for String or ByteString arrays. Those DataTypes have special handling
                        // when using sub ranges.
                        bool isArrayWithValidDataType = value.Value.Value is Array &&
                                                        value.Value.WrappedValue.TypeInfo.BuiltInType == BuiltInType.String ||
                                                        value.Value.WrappedValue.TypeInfo.BuiltInType == BuiltInType.ByteString;

                        if (!isArrayWithValidDataType)
                        {
                            return(StatusCodes.BadTypeMismatch);
                        }
                    }
                }
                else
                {
                    // check that value provided is actually an array.
                    Array  array = value.Value.Value as Array;
                    string str   = value.Value.Value as string;

                    if (array != null)
                    {
                        NumericRange range = value.ParsedIndexRange;

                        // check that the number of elements to write matches the index range.
                        if (range.End >= 0 && (range.End - range.Begin != array.Length - 1))
                        {
                            return(StatusCodes.BadIndexRangeNoData);
                        }

                        // check for single element.
                        if (range.End < 0 && array.Length != 1)
                        {
                            return(StatusCodes.BadIndexRangeInvalid);
                        }
                    }
                    else if (str != null)
                    {
                        NumericRange range = value.ParsedIndexRange;

                        // check that the number of elements to write matches the index range.
                        if (range.End >= 0 && (range.End - range.Begin != str.Length - 1))
                        {
                            return(StatusCodes.BadIndexRangeNoData);
                        }

                        // check for single element.
                        if (range.End < 0 && str.Length != 1)
                        {
                            return(StatusCodes.BadIndexRangeInvalid);
                        }
                    }
                    else
                    {
                        return(StatusCodes.BadTypeMismatch);
                    }
                }
            }
            else
            {
                value.ParsedIndexRange = NumericRange.Empty;
            }

            // passed basic validation.
            return(null);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Continues a read raw operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        /// <returns>False if the operation halted because the maximum number of values was discovered.</returns>
        public bool NextReadRaw(
            ServerSystemContext context,
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            DataValue value = null;
            
            do
            {
                // check for limit.
                if (m_request.NumValuesPerNode > 0 && values.Count >= m_request.NumValuesPerNode)
                {
                    return false;
                }

                value = m_source.NextRaw(m_lastTime, m_isForward, m_request.IsReadModified, ref m_position);
               
                // no more data.
                if (value == null)
                {
                    return true;
                }

                // check for bound.
                if ((m_isForward && value.ServerTimestamp >= m_endTime) || (!m_isForward && value.ServerTimestamp <= m_endTime))
                {                    
                    if (m_request.ReturnBounds)
                    {
                        AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                        return true;
                    }
                }
                
                // add value.
                AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
            }
            while (value != null);
                    
            return true;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Adds a DataValue to a list of values to return.
        /// </summary>
        private void AddValue(
            TimestampsToReturn timestampsToReturn, 
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values, 
            DataValue value)
        {
            // ignore invalid case.
            if (value == null)
            {
                return;
            }

            // save the last timestamp returned.
            m_lastTime = value.ServerTimestamp;
            
            // check if the index range or data encoding can be applied.
            if (StatusCode.IsGood(value.StatusCode))
            {
                object valueToReturn = value.Value;
                
                // apply the index range.
                if (indexRange != NumericRange.Empty)
                {
                    StatusCode error = indexRange.ApplyRange(ref valueToReturn);

                    if (StatusCode.IsBad(error))
                    {
                        value.Value = null;
                        value.StatusCode = error;
                    }
                    else
                    {
                        value.Value = valueToReturn;
                    }
                }

                // apply the data encoding.
                if (!QualifiedName.IsNull(dataEncoding))
                {
                    value.Value = null;
                    value.StatusCode = StatusCodes.BadDataEncodingUnsupported;
                }
            }

            // apply the timestamps filter.
            if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Server)
            {
                value.SourceTimestamp = DateTime.MinValue;
            }

            if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Source)
            {
                value.ServerTimestamp = DateTime.MinValue;
            }

            // add result.
            values.Add(value);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Starts reading raw values.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="request">The request parameters.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        public void BeginReadRaw(
            ServerSystemContext context,
            ReadRawModifiedDetails request, 
            TimestampsToReturn timestampsToReturn, 
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            m_request = request;

            // initialize start and end.
            m_startTime = m_request.StartTime;
            m_endTime = m_request.EndTime;

            if (m_endTime == DateTime.MinValue)
            {
                m_endTime = DateTime.MaxValue;
            }

            // check the direction.
            m_isForward = m_startTime < m_endTime;
            m_position = -1;
                        
            DataValue value = null;
            
            // get first bound.
            if (m_request.ReturnBounds)
            {
                value = m_source.FirstRaw(m_startTime, !m_isForward, m_request.IsReadModified, out m_position);
               
                if (value != null)
                {
                    AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                }
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Parses a string representing a numeric range.
        /// </summary>
        /// <param name="textToParse">The text to parse, prior to checking it is within the allowed range</param>
        /// <param name="range">The parsed range.</param>
        /// <returns>The reason for any error.</returns>
        public static ServiceResult Validate(string textToParse, out NumericRange range)
        {
            range = NumericRange.Empty;

            if (String.IsNullOrEmpty(textToParse))
            {
                return ServiceResult.Good;
            }

            // check for multidimensional ranges.
            int index = textToParse.IndexOf(',');

            if (index >= 0)
            {
                int start = 0;
                List<NumericRange> subranges = new List<NumericRange>();

                for (int ii = 0; ii < textToParse.Length; ii++)
                {
                    char ch = textToParse[ii];

                    if (ch == ',' || ii == textToParse.Length-1)
                    {
                        NumericRange subrange = new NumericRange();
                        string subtext = (ch == ',') ? textToParse.Substring(start, ii - start) : textToParse.Substring(start);
                        ServiceResult result = Validate(subtext, out subrange);

                        if (ServiceResult.IsBad(result))
                        {
                            return result;
                        }

                        subranges.Add(subrange);
                        start = ii+1;
                    }
                }

                // must have at least two entries.
                if (subranges.Count < 2)
                {
                    return StatusCodes.BadIndexRangeInvalid;
                }

                range.m_begin = subranges[0].Begin;
                range.m_end = subranges[0].End;
                range.m_subranges = subranges.ToArray();

                return ServiceResult.Good;
            }

            try
            {
                index = textToParse.IndexOf(':');

                if (index != -1)
                {
                    range.Begin = Convert.ToInt32(textToParse.Substring(0, index), CultureInfo.InvariantCulture);
                    range.End = Convert.ToInt32(textToParse.Substring(index + 1), CultureInfo.InvariantCulture);

                    if (range.End < 0)
                    {
                        return ServiceResult.Create(
                            StatusCodes.BadIndexRangeInvalid,
                            "NumericRange does not have a valid end index ({0}).",
                            range.End);
                    }

                    if (range.Begin >= range.End)
                    {
                        return ServiceResult.Create(
                            StatusCodes.BadIndexRangeInvalid,
                            "NumericRange does not have a start index that is less than the end index ({0}).",
                            range);
                    }
                }
                else
                {
                    range.Begin = Convert.ToInt32(textToParse, CultureInfo.InvariantCulture);
                    range.End   = -1;
                }                 

                if (range.Begin < 0)
                {
                    return ServiceResult.Create(
                        StatusCodes.BadIndexRangeInvalid,
                        "NumericRange does not have a valid start index ({0}).",
                        range.Begin);
                }
            }
            catch (Exception e)
            {
                return ServiceResult.Create(
                    e,
                    StatusCodes.BadIndexRangeInvalid,
                    "NumericRange cannot be parsed ({0}).", 
                    textToParse);
            }

           return ServiceResult.Good;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Returns the value of the attribute for the specified child.
        /// </summary>
        /// <param name="context">The context to use when evaluating the operand.</param>
        /// <param name="typeDefinitionId">The type of the instance.</param>
        /// <param name="relativePath">The path from the instance to the node which defines the attribute.</param>
        /// <param name="attributeId">The attribute to return.</param>
        /// <param name="indexRange">The sub-set of an array value to return.</param>
        /// <returns>
        /// The attribute value. Returns null if the attribute does not exist.
        /// </returns>
        public object GetAttributeValue(
            FilterContext context, 
            NodeId typeDefinitionId, 
            IList<QualifiedName> relativePath, 
            uint attributeId, 
            NumericRange indexRange)
        {
            if (!NodeId.IsNull(typeDefinitionId))
            {
                if (!context.TypeTree.IsTypeOf(m_typeDefinitionId, typeDefinitionId))
                {
                    return null;
                }
            }

            object value = GetAttributeValue(
                m_snapshot,
                relativePath,
                0,
                attributeId);

            if (indexRange != NumericRange.Empty)
            {
                StatusCode error = indexRange.ApplyRange(ref value);

                if (StatusCode.IsBad(error))
                {
                    value = null;
                }
            }

            return value;
        }
Ejemplo n.º 17
0
        /// <summary cref="IFilterTarget.GetAttributeValue" />
        public virtual object GetAttributeValue(
            FilterContext context, 
            NodeId typeDefinitionId, 
            IList<QualifiedName> relativePath, 
            uint attributeId, 
            NumericRange indexRange)
        {
            // check the type definition.
            if (!NodeId.IsNull(typeDefinitionId) && typeDefinitionId != ObjectTypes.BaseEventType)
            {
                if (!context.TypeTree.IsTypeOf(TypeDefinitionId, typeDefinitionId))
                {
                    return null;
                }
            }

            // read the child attribute.
            DataValue dataValue = new DataValue();   

            ServiceResult result = ReadChildAttribute(
                null,
                relativePath,
                0,
                attributeId,
                dataValue);
            
            if (ServiceResult.IsBad(result))
            {
                return null;
            }

            // apply any index range.
            object value = dataValue.Value;

            if (value != null)
            {
                result = indexRange.ApplyRange(ref value);
                
                if (ServiceResult.IsBad(result))
                {
                    return null;
                }
            }

            // return the result.
            return value;
        }
Ejemplo n.º 18
0
        private ServiceResult OnWriteDataItem(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            DataItemState variable = node as DataItemState;

            // verify data type.
            Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType(
                value,
                variable.DataType,
                variable.ValueRank,
                context.NamespaceUris,
                context.TypeTable);

            if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown)
            {
                return StatusCodes.BadTypeMismatch;
            }

            if (typeInfo.BuiltInType != BuiltInType.DateTime)
            {
                double number = Convert.ToDouble(value);
                number = Math.Round(number, (int)variable.ValuePrecision.Value);
                value = Opc.Ua.TypeInfo.Cast(number, typeInfo.BuiltInType);
            }

            return ServiceResult.Good;
        }
        /// <summary>
        /// Reads the value for the value attribute.
        /// </summary>
        protected override ServiceResult ReadValueAttribute(
            ISystemContext context,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref DateTime sourceTimestamp)
        {  
            value = m_value;

            ServiceResult result = ServiceResult.Good;

            VariableCopyPolicy copyPolicy = VariableCopyPolicy.CopyOnRead;

            // use default behavoir.
            if (OnSimpleReadValue != null)
            {
                result = OnSimpleReadValue(
                    context,
                    this,
                    ref value);

                if (ServiceResult.IsBad(result))
                {
                    return result;
                }

                copyPolicy = VariableCopyPolicy.Never;
            }
            else
            {
                // check if a valid value exists.
                if (value == null)
                {
                    return StatusCodes.BadAttributeIdInvalid;
                }
            }
            
            // apply the index range and encoding.
            result = BaseVariableState.ApplyIndexRangeAndDataEncoding(context, indexRange, dataEncoding, ref value);

            if (ServiceResult.IsBad(result))
            {
                return result;
            }

            // copy returned value.
            if (copyPolicy == VariableCopyPolicy.CopyOnRead)
            {
                value = Utils.Clone(value);
            }

            return result;
        }
Ejemplo n.º 20
0
        private ServiceResult OnWriteDiscrete(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MultiStateDiscreteState variable = node as MultiStateDiscreteState;

            // verify data type.
            Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType(
                value,
                variable.DataType,
                variable.ValueRank,
                context.NamespaceUris,
                context.TypeTable);

            if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown)
            {
                return StatusCodes.BadTypeMismatch;
            }

            if (indexRange != NumericRange.Empty)
            {
                return StatusCodes.BadIndexRangeInvalid;
            }

            double number = Convert.ToDouble(value);

            if (number >= variable.EnumStrings.Value.Length | number < 0)
            {
                return StatusCodes.BadOutOfRange;
            }

            return ServiceResult.Good;
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Validates a write value parameter.
        /// </summary>
        public static ServiceResult Validate(WriteValue value)
        {
            // check for null structure.
            if (value == null)
            {
                return(StatusCodes.BadStructureMissing);
            }

            // null node ids are always invalid.
            if (value.NodeId == null)
            {
                return(StatusCodes.BadNodeIdInvalid);
            }

            // must be a legimate attribute value.
            if (!Attributes.IsValid(value.AttributeId))
            {
                return(StatusCodes.BadAttributeIdInvalid);
            }

            // initialize as empty.
            value.ParsedIndexRange = NumericRange.Empty;

            // parse the index range if specified.
            if (!String.IsNullOrEmpty(value.IndexRange))
            {
                try
                {
                    value.ParsedIndexRange = NumericRange.Parse(value.IndexRange);
                }
                catch (Exception e)
                {
                    return(ServiceResult.Create(e, StatusCodes.BadIndexRangeInvalid, String.Empty));
                }

                // check that value provided is actually an array.
                Array array = value.Value.Value as Array;

                if (array == null)
                {
                    return(StatusCodes.BadTypeMismatch);
                }

                NumericRange range = value.ParsedIndexRange;

                // check that the number of elements to write matches the index range.
                if (range.End >= 0 && (range.End - range.Begin != array.Length - 1))
                {
                    return(StatusCodes.BadIndexRangeNoData);
                }

                // check for single element.
                if (range.End < 0 && array.Length != 1)
                {
                    return(StatusCodes.BadIndexRangeInvalid);
                }
            }
            else
            {
                value.ParsedIndexRange = NumericRange.Empty;
            }

            // passed basic validation.
            return(null);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Extracts and queues any processed values.
        /// </summary>
        private void QueueProcessedValues(
            ServerSystemContext context, 
            IAggregateCalculator calculator, 
            NumericRange indexRange,
            QualifiedName dataEncoding,
            bool applyIndexRangeOrEncoding,
            bool returnPartial,
            LinkedList<DataValue> values)
        {
            DataValue proccessedValue = calculator.GetProcessedValue(returnPartial);

            while (proccessedValue != null)
            {
                // apply any index range or encoding.
                if (applyIndexRangeOrEncoding)
                {
                    object rawValue = proccessedValue.Value;
                    ServiceResult result = BaseVariableState.ApplyIndexRangeAndDataEncoding(context, indexRange, dataEncoding, ref rawValue);

                    if (ServiceResult.IsBad(result))
                    {
                        proccessedValue.Value = rawValue;
                    }
                    else
                    {
                        proccessedValue.Value = null;
                        proccessedValue.StatusCode = result.StatusCode;
                    }
                }

                // queue the result.
                values.AddLast(proccessedValue);
                proccessedValue = calculator.GetProcessedValue(returnPartial);
            }
        }