예제 #1
0
 public void Reset()
 {
     m_lastPoint         = new PointMetaData();
     m_lastPoint.PointID = -1;
     m_previousTimestamp = 0;
     m_points.Clear();
     Clear();
 }
예제 #2
0
 public void Reset()
 {
     m_lastPoint = new PointMetaData();
     m_lastPoint.PointID = -1;
     m_previousTimestamp = 0;
     m_points.Clear();
     Clear();
 }
예제 #3
0
 public void Reset()
 {
     m_lastPoint = new PointMetaData();
     m_lastPoint.PointID = -1;
     m_timeBucket = 0;
     m_nextRunLength = 0;
     m_startIndex = 0;
     m_stopIndex = 0;
     m_points.Clear();
 }
예제 #4
0
        public MeasurementCompressionBlock()
        {
            m_lastPoint = new PointMetaData();
            m_lastPoint.PointID = -1;
            m_buffer = new byte[BufferSize];
            m_previousTimestamp = 0;
            m_points = new Dictionary<ushort, PointMetaData>();

            Clear();
        }
예제 #5
0
 public void Reset()
 {
     m_lastPoint         = new PointMetaData();
     m_lastPoint.PointID = -1;
     m_timeBucket        = 0;
     m_nextRunLength     = 0;
     m_startIndex        = 0;
     m_stopIndex         = 0;
     m_points.Clear();
 }
예제 #6
0
        public MeasurementCompressionBlock()
        {
            m_lastPoint         = new PointMetaData();
            m_lastPoint.PointID = -1;
            m_buffer            = new byte[BufferSize];
            m_previousTimestamp = 0;
            m_points            = new Dictionary <ushort, PointMetaData>();

            Clear();
        }
예제 #7
0
        public MeasurementDecompressionBlock()
        {
            m_lastPoint = new PointMetaData();
            m_lastPoint.PointID = -1;

            m_points = new List<PointMetaData>();
            m_timeBucket = 0;
            m_nextRunLength = 0;

            m_buffer = new byte[BufferSize];
        }
예제 #8
0
        public MeasurementDecompressionBlock()
        {
            m_lastPoint         = new PointMetaData();
            m_lastPoint.PointID = -1;

            m_points        = new List <PointMetaData>();
            m_timeBucket    = 0;
            m_nextRunLength = 0;

            m_buffer = new byte[BufferSize];
        }
예제 #9
0
        public unsafe DecompressionExitCode GetMeasurement(out ushort id, out long timestamp, out uint quality, out float value, out byte userCommand)
        {
            id = 0;
            timestamp = 0;
            quality = 0;
            value = 0;
            userCommand = 0;

            TryAgain:
            int index = m_startIndex;

            if (IsEndOfStream())
                return DecompressionExitCode.EndOfStreamOccured;

            byte code;

            if (m_nextRunLength > 0)
            {
                m_nextRunLength--;
                code = m_lastPoint.ExpectedNextCode;
            }
            else
            {
                code = m_buffer[index++];
                m_lastPoint.ExpectedNextCode = code;
                m_nextRunLength = code >> 6;
            }

            PointMetaData point;

            if ((code & 7) == 5)
            {
                point = new PointMetaData();

                fixed (byte* signalID = &m_buffer[index])
                    point.SignalID = *(ushort*)signalID;

                index += 2;

                point.PointID = m_points.Count;
                m_lastPoint.ExpectedNextPointID = m_points.Count;
                m_points.Add(point);
                m_startIndex = index;

                goto TryAgain;
            }

            if ((code & 7) == 6)
                throw new NotSupportedException();

            if ((code & 7) == 7)
            {
                userCommand = m_buffer[index++];
                m_startIndex = index;

                return DecompressionExitCode.CommandRead;
            }

            if ((code & 32) == 0)
            {
                point = m_points[m_lastPoint.ExpectedNextPointID];
            }
            else
            {
                point = m_points[(int)Encoding7Bit.ReadUInt32(m_buffer, ref index)];
                m_lastPoint.ExpectedNextPointID = point.PointID;
            }

            if ((code & 16) != 0)
                point.LastQuality = (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16 | m_buffer[index++] << 24);

            if ((code & 7) == 1)
                point.LastValue ^= m_buffer[index++];
            else if ((code & 7) == 2)
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8);
            else if ((code & 7) == 3)
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16);
            else if ((code & 7) == 4)
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16 | m_buffer[index++] << 24);

            if ((code & 8) == 0)
            {
                timestamp = m_timeBucket;
            }
            else
            {
                timestamp = m_timeBucket ^ (long)Encoding7Bit.ReadUInt64(m_buffer, ref index);
                m_timeBucket = timestamp;
            }

            id = point.SignalID;
            quality = point.LastQuality;
            uint lastValue = point.LastValue;
            value = *(float*)&lastValue;

            m_lastPoint = point;
            m_startIndex = index;

            return DecompressionExitCode.MeasurementRead;
        }
예제 #10
0
        public unsafe void AddMeasurement(ushort id, long timestamp, uint quality, float value)
        {
            if (!CanAddMeasurements)
                throw new Exception("Not enough buffer space to add a new measurement.");

            byte[] buffer = m_buffer;
            int index = m_index;

            PointMetaData point;

            if (!m_points.TryGetValue(id, out point))
            {
                m_lastMeasurementHeaderIndex = -1;
                point = new PointMetaData();
                point.PointID = m_points.Count;
                m_lastPoint.ExpectedNextPointID = point.PointID;
                m_points.Add(id, point);
                buffer[index++] = 5;
                Buffer.BlockCopy(BitConverter.GetBytes(id), 0, buffer, index, 2);
                index += 2;
            }

            byte code = 0;

            if (m_lastPoint.ExpectedNextPointID != point.PointID)
            {
                code |= 32;
                m_lastPoint.ExpectedNextPointID = point.PointID;
            }

            if (quality != point.LastQuality)
            {
                code |= 16;
                point.LastQuality = quality;
            }

            if (timestamp != m_previousTimestamp)
                code |= 8;

            uint bitsChanged = (*(uint*)&value) ^ point.LastValue;

            point.LastValue ^= bitsChanged;

            if (bitsChanged > 0xFFFFFFu)
                code |= 4;
            else if (bitsChanged > 0xFFFFu)
                code |= 3;
            else if (bitsChanged > 0xFFu)
                code |= 2;
            else if (bitsChanged > 0u)
                code |= 1;
            else
                code |= 0;

            // If the computed code is the same as what is expected based on the last measurement,
            // and there are enough bits available in the last encoded header to skip writing this code then do so.
            if (m_lastPoint.ExpectedNextCode == code && m_lastMeasurementHeaderIndex >= 0)
            {
                // Increment the previous code to increase the run length of headers that don't need to be changed.
                buffer[m_lastMeasurementHeaderIndex] += 64;

                if (buffer[m_lastMeasurementHeaderIndex] >= 192)
                    m_lastMeasurementHeaderIndex = -1;
            }
            else
            {
                // Write the code to the stream and updated expected values.
                m_lastMeasurementHeaderIndex = index;
                m_lastPoint.ExpectedNextCode = code;
                buffer[index++] = code;
            }

            if ((code & 32) != 0)
                Encoding7Bit.Write(buffer, ref index, (uint)point.PointID);

            if ((code & 16) != 0)
            {
                buffer[index++] = (byte)quality;
                buffer[index++] = (byte)(quality >> 8);
                buffer[index++] = (byte)(quality >> 16);
                buffer[index++] = (byte)(quality >> 24);
            }

            if (bitsChanged > 0xFFFFFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
                buffer[index++] = (byte)(bitsChanged >> 16);
                buffer[index++] = (byte)(bitsChanged >> 24);
            }
            else if (bitsChanged > 0xFFFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
                buffer[index++] = (byte)(bitsChanged >> 16);
            }
            else if (bitsChanged > 0xFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
            }
            else if (bitsChanged > 0u)
            {
                buffer[index++] = (byte)bitsChanged;
            }

            if (timestamp != m_previousTimestamp)
            {
                Encoding7Bit.Write(buffer, ref index, (ulong)(timestamp ^ m_previousTimestamp));
                m_previousTimestamp = timestamp;
            }

            m_lastPoint = point;
            m_index = index;
        }
예제 #11
0
        public unsafe DecompressionExitCode GetMeasurement(out ushort id, out long timestamp, out uint quality, out float value, out byte userCommand)
        {
            id          = 0;
            timestamp   = 0;
            quality     = 0;
            value       = 0;
            userCommand = 0;

TryAgain:
            int index = m_startIndex;

            if (IsEndOfStream())
            {
                return(DecompressionExitCode.EndOfStreamOccured);
            }

            byte code;

            if (m_nextRunLength > 0)
            {
                m_nextRunLength--;
                code = m_lastPoint.ExpectedNextCode;
            }
            else
            {
                code = m_buffer[index++];
                m_lastPoint.ExpectedNextCode = code;
                m_nextRunLength = code >> 6;
            }

            PointMetaData point;

            if ((code & 7) == 5)
            {
                point = new PointMetaData();

                fixed(byte *signalID = &m_buffer[index])
                point.SignalID = *(ushort *)signalID;

                index += 2;

                point.PointID = m_points.Count;
                m_lastPoint.ExpectedNextPointID = m_points.Count;
                m_points.Add(point);
                m_startIndex = index;

                goto TryAgain;
            }

            if ((code & 7) == 6)
            {
                throw new NotSupportedException();
            }

            if ((code & 7) == 7)
            {
                userCommand  = m_buffer[index++];
                m_startIndex = index;

                return(DecompressionExitCode.CommandRead);
            }

            if ((code & 32) == 0)
            {
                point = m_points[m_lastPoint.ExpectedNextPointID];
            }
            else
            {
                point = m_points[(int)Encoding7Bit.ReadUInt32(m_buffer, ref index)];
                m_lastPoint.ExpectedNextPointID = point.PointID;
            }

            if ((code & 16) != 0)
            {
                point.LastQuality = (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16 | m_buffer[index++] << 24);
            }

            if ((code & 7) == 1)
            {
                point.LastValue ^= m_buffer[index++];
            }
            else if ((code & 7) == 2)
            {
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8);
            }
            else if ((code & 7) == 3)
            {
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16);
            }
            else if ((code & 7) == 4)
            {
                point.LastValue ^= (uint)(m_buffer[index++] | m_buffer[index++] << 8 | m_buffer[index++] << 16 | m_buffer[index++] << 24);
            }

            if ((code & 8) == 0)
            {
                timestamp = m_timeBucket;
            }
            else
            {
                timestamp    = m_timeBucket ^ (long)Encoding7Bit.ReadUInt64(m_buffer, ref index);
                m_timeBucket = timestamp;
            }

            id      = point.SignalID;
            quality = point.LastQuality;
            uint lastValue = point.LastValue;

            value = *(float *)&lastValue;

            m_lastPoint  = point;
            m_startIndex = index;

            return(DecompressionExitCode.MeasurementRead);
        }
예제 #12
0
        public unsafe void AddMeasurement(ushort id, long timestamp, uint quality, float value)
        {
            if (!CanAddMeasurements)
            {
                throw new Exception("Not enough buffer space to add a new measurement.");
            }

            byte[] buffer = m_buffer;
            int    index  = m_index;

            PointMetaData point;

            if (!m_points.TryGetValue(id, out point))
            {
                m_lastMeasurementHeaderIndex = -1;
                point         = new PointMetaData();
                point.PointID = m_points.Count;
                m_lastPoint.ExpectedNextPointID = point.PointID;
                m_points.Add(id, point);
                buffer[index++] = 5;
                Buffer.BlockCopy(BitConverter.GetBytes(id), 0, buffer, index, 2);
                index += 2;
            }

            byte code = 0;

            if (m_lastPoint.ExpectedNextPointID != point.PointID)
            {
                code |= 32;
                m_lastPoint.ExpectedNextPointID = point.PointID;
            }

            if (quality != point.LastQuality)
            {
                code |= 16;
                point.LastQuality = quality;
            }

            if (timestamp != m_previousTimestamp)
            {
                code |= 8;
            }

            uint bitsChanged = (*(uint *)&value) ^ point.LastValue;

            point.LastValue ^= bitsChanged;

            if (bitsChanged > 0xFFFFFFu)
            {
                code |= 4;
            }
            else if (bitsChanged > 0xFFFFu)
            {
                code |= 3;
            }
            else if (bitsChanged > 0xFFu)
            {
                code |= 2;
            }
            else if (bitsChanged > 0u)
            {
                code |= 1;
            }
            else
            {
                code |= 0;
            }

            // If the computed code is the same as what is expected based on the last measurement,
            // and there are enough bits available in the last encoded header to skip writing this code then do so.
            if (m_lastPoint.ExpectedNextCode == code && m_lastMeasurementHeaderIndex >= 0)
            {
                // Increment the previous code to increase the run length of headers that don't need to be changed.
                buffer[m_lastMeasurementHeaderIndex] += 64;

                if (buffer[m_lastMeasurementHeaderIndex] >= 192)
                {
                    m_lastMeasurementHeaderIndex = -1;
                }
            }
            else
            {
                // Write the code to the stream and updated expected values.
                m_lastMeasurementHeaderIndex = index;
                m_lastPoint.ExpectedNextCode = code;
                buffer[index++] = code;
            }

            if ((code & 32) != 0)
            {
                Encoding7Bit.Write(buffer, ref index, (uint)point.PointID);
            }

            if ((code & 16) != 0)
            {
                buffer[index++] = (byte)quality;
                buffer[index++] = (byte)(quality >> 8);
                buffer[index++] = (byte)(quality >> 16);
                buffer[index++] = (byte)(quality >> 24);
            }

            if (bitsChanged > 0xFFFFFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
                buffer[index++] = (byte)(bitsChanged >> 16);
                buffer[index++] = (byte)(bitsChanged >> 24);
            }
            else if (bitsChanged > 0xFFFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
                buffer[index++] = (byte)(bitsChanged >> 16);
            }
            else if (bitsChanged > 0xFFu)
            {
                buffer[index++] = (byte)bitsChanged;
                buffer[index++] = (byte)(bitsChanged >> 8);
            }
            else if (bitsChanged > 0u)
            {
                buffer[index++] = (byte)bitsChanged;
            }

            if (timestamp != m_previousTimestamp)
            {
                Encoding7Bit.Write(buffer, ref index, (ulong)(timestamp ^ m_previousTimestamp));
                m_previousTimestamp = timestamp;
            }

            m_lastPoint = point;
            m_index     = index;
        }