Ejemplo n.º 1
0
        /// <summary>
        /// Generates binary image of the <see cref="CompactMeasurement"/> and copies it into the given buffer, for <see cref="ISupportBinaryImage.BinaryLength"/> bytes.
        /// </summary>
        /// <param name="buffer">Buffer used to hold generated binary image of the source object.</param>
        /// <param name="startIndex">0-based starting index in the <paramref name="buffer"/> to start writing.</param>
        /// <returns>The number of bytes written to the <paramref name="buffer"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> or <see cref="ISupportBinaryImage.BinaryLength"/> is less than 0 -or-
        /// <paramref name="startIndex"/> and <see cref="ISupportBinaryImage.BinaryLength"/> will exceed <paramref name="buffer"/> length.
        /// </exception>
        /// <remarks>
        /// <para>
        /// Field:     Bytes: <br/>
        /// --------   -------<br/>
        ///  Flags        1   <br/>
        ///   ID          2   <br/>
        ///  Value        4   <br/>
        ///  [Time]       2?  <br/>
        /// </para>
        /// <para>
        /// Constant Length = 7<br/>
        /// Variable Length = 0, 2, 4 or 8 (i.e., total size is 7, 9, 11 or 15)
        /// </para>
        /// </remarks>
        public int GenerateBinaryImage(byte[] buffer, int startIndex)
        {
            // Call to binary length property caches result of m_usingBaseTimeOffset
            int length = BinaryLength;

            buffer.ValidateParameters(startIndex, length);

            // Encode compact state flags
            CompactMeasurementStateFlags flags = StateFlags.MapToCompactFlags();

            if (m_timeIndex != 0)
            {
                flags |= CompactMeasurementStateFlags.TimeIndex;
            }

            if (m_usingBaseTimeOffset)
            {
                flags |= CompactMeasurementStateFlags.BaseTimeOffset;
            }

            // Added flags to beginning of buffer
            buffer[startIndex++] = (byte)flags;

            // Encode runtime ID
            EndianOrder.BigEndian.CopyBytes(m_signalIndexCache.GetSignalIndex(ID), buffer, startIndex);

            startIndex += 2;

            // Encode adjusted value (accounts for adder and multipler)
            EndianOrder.BigEndian.CopyBytes((float)AdjustedValue, buffer, startIndex);
            startIndex += 4;

            if (m_includeTime)
            {
                if (m_usingBaseTimeOffset)
                {
                    if (m_useMillisecondResolution)
                    {
                        // Encode 2-byte millisecond offset timestamp
                        EndianOrder.BigEndian.CopyBytes((ushort)(Timestamp - m_baseTimeOffsets[m_timeIndex]).ToMilliseconds(), buffer, startIndex);
                    }
                    else
                    {
                        // Encode 4-byte ticks offset timestamp
                        EndianOrder.BigEndian.CopyBytes((uint)((long)Timestamp - m_baseTimeOffsets[m_timeIndex]), buffer, startIndex);
                    }
                }
                else
                {
                    // Encode 8-byte full fidelity timestamp
                    EndianOrder.BigEndian.CopyBytes((long)Timestamp, buffer, startIndex);
                }
            }

            return(length);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Maps <see cref="CompactMeasurementStateFlags"/> to <see cref="MeasurementStateFlags"/>.
        /// </summary>
        /// <param name="stateFlags">Flags to map.</param>
        /// <returns><see cref="MeasurementStateFlags"/> mapped from <see cref="CompactMeasurementStateFlags"/>.</returns>
        public static MeasurementStateFlags MapToFullFlags(this CompactMeasurementStateFlags stateFlags)
        {
            MeasurementStateFlags mappedStateFlags = MeasurementStateFlags.Normal;

            if ((stateFlags & CompactMeasurementStateFlags.DataRange) > 0)
            {
                mappedStateFlags |= DataRangeMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.DataQuality) > 0)
            {
                mappedStateFlags |= DataQualityMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.TimeQuality) > 0)
            {
                mappedStateFlags |= TimeQualityMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.SystemIssue) > 0)
            {
                mappedStateFlags |= SystemIssueMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.CalculatedValue) > 0)
            {
                mappedStateFlags |= CalculatedValueMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.DiscardedValue) > 0)
            {
                mappedStateFlags |= DiscardedValueMask;
            }

            return(mappedStateFlags);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Maps <see cref="MeasurementStateFlags"/> to <see cref="CompactMeasurementStateFlags"/>.
        /// </summary>
        /// <param name="stateFlags">Flags to map.</param>
        /// <returns><see cref="CompactMeasurementStateFlags"/> mapped from <see cref="MeasurementStateFlags"/>.</returns>
        public static CompactMeasurementStateFlags MapToCompactFlags(this MeasurementStateFlags stateFlags)
        {
            CompactMeasurementStateFlags mappedStateFlags = CompactMeasurementStateFlags.NoFlags;

            if ((stateFlags & DataRangeMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DataRange;
            }

            if ((stateFlags & DataQualityMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DataQuality;
            }

            if ((stateFlags & TimeQualityMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.TimeQuality;
            }

            if ((stateFlags & SystemIssueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.SystemIssue;
            }

            if ((stateFlags & CalculatedValueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.CalculatedValue;
            }

            if ((stateFlags & DiscardedValueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DiscardedValue;
            }

            return(mappedStateFlags);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes <see cref="CompactMeasurement"/> from the specified binary image.
        /// </summary>
        /// <param name="buffer">Buffer containing binary image to parse.</param>
        /// <param name="startIndex">0-based starting index in the <paramref name="buffer"/> to start parsing.</param>
        /// <param name="length">Valid number of bytes within <paramref name="buffer"/> from <paramref name="startIndex"/>.</param>
        /// <returns>The number of bytes used for initialization in the <paramref name="buffer"/> (i.e., the number of bytes parsed).</returns>
        /// <exception cref="InvalidOperationException">Not enough buffer available to deserialize measurement.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="startIndex"/> or <paramref name="length"/> is less than 0 -or-
        /// <paramref name="startIndex"/> and <paramref name="length"/> will exceed <paramref name="buffer"/> length.
        /// </exception>
        public int ParseBinaryImage(byte[] buffer, int startIndex, int length)
        {
            buffer.ValidateParameters(startIndex, length);

            if (length < 1)
            {
                throw new InvalidOperationException("Not enough buffer available to deserialize measurement.");
            }

            // Decode flags
            CompactMeasurementStateFlags flags = (CompactMeasurementStateFlags)buffer[startIndex];

            StateFlags            = flags.MapToFullFlags();
            m_timeIndex           = (flags & CompactMeasurementStateFlags.TimeIndex) > 0 ? 1 : 0;
            m_usingBaseTimeOffset = (flags & CompactMeasurementStateFlags.BaseTimeOffset) > 0;

            int index = startIndex + 1;

            // Decode runtime ID
            ushort id = EndianOrder.BigEndian.ToUInt16(buffer, index);

            index += 2;

            // Restore signal identification
            Tuple <Guid, string, uint> tuple;

            if (m_signalIndexCache.Reference.TryGetValue(id, out tuple))
            {
                ID  = tuple.Item1;
                Key = new MeasurementKey(tuple.Item1, tuple.Item3, tuple.Item2);
            }
            else
            {
                throw new InvalidOperationException("Failed to find associated signal identification for runtime ID " + id);
            }

            // Decode value
            Value  = EndianOrder.BigEndian.ToSingle(buffer, index);
            index += 4;

            if (m_includeTime)
            {
                if (m_usingBaseTimeOffset)
                {
                    long baseTimeOffset = m_baseTimeOffsets[m_timeIndex];

                    if (m_useMillisecondResolution)
                    {
                        // Decode 2-byte millisecond offset timestamp
                        if (baseTimeOffset > 0)
                        {
                            Timestamp = baseTimeOffset + EndianOrder.BigEndian.ToUInt16(buffer, index) * Ticks.PerMillisecond;
                        }

                        index += 2;
                    }
                    else
                    {
                        // Decode 4-byte tick offset timestamp
                        if (baseTimeOffset > 0)
                        {
                            Timestamp = baseTimeOffset + EndianOrder.BigEndian.ToUInt32(buffer, index);
                        }

                        index += 4;
                    }
                }
                else
                {
                    // Decode 8-byte full fidelity timestamp
                    Timestamp = EndianOrder.BigEndian.ToInt64(buffer, index);
                    index    += 8;
                }
            }

            return(index - startIndex);
        }