private void ProcessBinaryMeasurements(IEnumerable <IBinaryMeasurement> measurements, long frameLevelTimestamp, bool useCompactMeasurementFormat, bool usePayloadCompression)
        {
            // Create working buffer
            using (BlockAllocatedMemoryStream workingBuffer = new BlockAllocatedMemoryStream())
            {
                // Serialize data packet flags into response
                DataPacketFlags flags = DataPacketFlags.Synchronized;

                if (m_compressionModes.HasFlag(CompressionModes.TSSC))
                {
                    flags |= DataPacketFlags.Compressed;
                }
                else
                {
                    if (useCompactMeasurementFormat)
                    {
                        flags |= DataPacketFlags.Compact;
                    }
                }

                workingBuffer.WriteByte((byte)flags);

                // Serialize frame timestamp into data packet - this only occurs in synchronized data packets,
                // unsynchronized subscriptions always include timestamps in the serialized measurements
                workingBuffer.Write(BigEndian.GetBytes(frameLevelTimestamp), 0, 8);

                // Serialize total number of measurement values to follow
                workingBuffer.Write(BigEndian.GetBytes(measurements.Count()), 0, 4);

                if (usePayloadCompression && m_compressionModes.HasFlag(CompressionModes.TSSC))
                {
                    if ((object)m_compressionBlock == null)
                    {
                        m_compressionBlock = new MeasurementCompressionBlock();
                    }
                    else
                    {
                        m_compressionBlock.Clear();
                    }

                    foreach (CompactMeasurement measurement in measurements.Cast <CompactMeasurement>())
                    {
                        if (m_compressionBlock.CanAddMeasurements)
                        {
                            m_compressionBlock.AddMeasurement(measurement.RuntimeID, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue);
                        }
                        else
                        {
                            m_compressionBlock.CopyTo(workingBuffer);
                            m_compressionBlock.Clear();
                            m_compressionBlock.AddMeasurement(measurement.RuntimeID, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue);
                        }
                    }

                    m_compressionBlock.CopyTo(workingBuffer);
                }
                else
                {
                    // Attempt compression when requested - encoding of compressed buffer only happens if size would be smaller than normal serialization
                    if (!usePayloadCompression || !measurements.Cast <CompactMeasurement>().CompressPayload(workingBuffer, m_compressionStrength, false, ref flags))
                    {
                        // Serialize measurements to data buffer
                        foreach (IBinaryMeasurement measurement in measurements)
                        {
                            measurement.CopyBinaryImageToStream(workingBuffer);
                        }
                    }

                    // Update data packet flags if it has updated compression flags
                    if ((flags & DataPacketFlags.Compressed) > 0)
                    {
                        workingBuffer.Seek(0, SeekOrigin.Begin);
                        workingBuffer.WriteByte((byte)flags);
                    }
                }

                // Publish data packet to client
                if ((object)m_parent != null)
                {
                    m_parent.SendClientResponse(m_clientID, ServerResponse.DataPacket, ServerCommand.Subscribe, workingBuffer.ToArray());
                }
            }
        }
Esempio n. 2
0
        private void ProcessBinaryMeasurements(IEnumerable <IBinaryMeasurement> measurements, bool useCompactMeasurementFormat, bool usePayloadCompression)
        {
            // Create working buffer
            using (BlockAllocatedMemoryStream workingBuffer = new BlockAllocatedMemoryStream())
            {
                // Serialize data packet flags into response
                DataPacketFlags flags = DataPacketFlags.NoFlags; // No flags means bit is cleared, i.e., unsynchronized

                if (m_compressionModes.HasFlag(CompressionModes.TSSC))
                {
                    flags |= DataPacketFlags.Compressed;
                }
                else
                {
                    if (useCompactMeasurementFormat)
                    {
                        flags |= DataPacketFlags.Compact;
                    }
                }

                workingBuffer.WriteByte((byte)flags);

                // No frame level timestamp is serialized into the data packet since all data is unsynchronized and essentially
                // published upon receipt, however timestamps are optionally included in the serialized measurements.

                // Serialize total number of measurement values to follow
                workingBuffer.Write(BigEndian.GetBytes(measurements.Count()), 0, 4);

                if (usePayloadCompression && m_compressionModes.HasFlag(CompressionModes.TSSC))
                {
                    if ((object)m_compressionBlock == null)
                    {
                        m_compressionBlock = new MeasurementCompressionBlock();
                    }
                    else
                    {
                        m_compressionBlock.Clear();
                    }

                    foreach (CompactMeasurement measurement in measurements.Cast <CompactMeasurement>())
                    {
                        if (m_compressionBlock.CanAddMeasurements)
                        {
                            m_compressionBlock.AddMeasurement(measurement.RuntimeID, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue);
                        }
                        else
                        {
                            m_compressionBlock.CopyTo(workingBuffer);
                            m_compressionBlock.Clear();
                            m_compressionBlock.AddMeasurement(measurement.RuntimeID, measurement.Timestamp.Value, (uint)measurement.StateFlags, (float)measurement.AdjustedValue);
                        }
                    }

                    m_compressionBlock.CopyTo(workingBuffer);
                }
                else
                {
                    // Attempt compression when requested - encoding of compressed buffer only happens if size would be smaller than normal serialization
                    if (!usePayloadCompression || !measurements.Cast <CompactMeasurement>().CompressPayload(workingBuffer, m_compressionStrength, m_includeTime, ref flags))
                    {
                        // Serialize measurements to data buffer
                        foreach (IBinaryMeasurement measurement in measurements)
                        {
                            measurement.CopyBinaryImageToStream(workingBuffer);
                        }
                    }

                    // Update data packet flags if it has updated compression flags
                    if ((flags & DataPacketFlags.Compressed) > 0)
                    {
                        workingBuffer.Seek(0, SeekOrigin.Begin);
                        workingBuffer.WriteByte((byte)flags);
                    }
                }

                // Publish data packet to client
                if ((object)m_parent != null)
                {
                    m_parent.SendClientResponse(m_clientID, ServerResponse.DataPacket, ServerCommand.Subscribe, workingBuffer.ToArray());
                }

                // Track last publication time
                m_lastPublishTime = DateTime.UtcNow.Ticks;
            }
        }