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());
}
}