public DecompressionExitCode GetMeasurement()
{
TryAgain:
PointMetaData nextPoint = null;
if (m_buffer.Position == m_length && m_bitStream.IsEmpty)
{
return(DecompressionExitCode.EndOfStreamOccured);
}
int code = m_lastPoint.ReadCode(m_bitStream);
if (code >= MeasurementStreamCodes.NewPointId && code <= MeasurementStreamCodes.FlushBits)
{
if (code == MeasurementStreamCodes.NewPointId)
{
MeasurementTypeCode type = (MeasurementTypeCode)m_buffer.Data[m_buffer.Position++];
PointMetaData point;
switch (type)
{
case MeasurementTypeCode.Int32:
case MeasurementTypeCode.UInt32:
case MeasurementTypeCode.Single:
point = new PointMetaDataInt32(m_buffer, m_bitStream, type, m_points.Count);
break;
case MeasurementTypeCode.UInt64:
case MeasurementTypeCode.Int64:
case MeasurementTypeCode.Double:
point = new PointMetaDataInt64(m_buffer, m_bitStream, type, m_points.Count);
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
NewMeasurementRegisteredTypeCode = type;
NewMeasurementRegisteredId = point.ReferenceId;
m_lastPoint.PrevNextPointId1 = point.ReferenceId;
m_points.Add(point);
NewMeasurementRegisteredMetadataLength = (int)Encoding7Bit.ReadUInt32(m_buffer.Data, ref m_buffer.Position);
while (NewMeasurementRegisteredMetadata.Length < NewMeasurementRegisteredMetadataLength)
{
NewMeasurementRegisteredMetadata = new byte[NewMeasurementRegisteredMetadata.Length * 2];
}
Array.Copy(m_buffer.Data, m_buffer.Position, NewMeasurementRegisteredMetadata, 0, NewMeasurementRegisteredMetadataLength);
m_buffer.Position += NewMeasurementRegisteredMetadataLength;
return(DecompressionExitCode.NewMeasurementRegistered);
}
else if (code == MeasurementStreamCodes.UserCommand)
{
UserCommand = (long)Encoding7Bit.ReadUInt64(m_buffer.Data, ref m_buffer.Position);
return(DecompressionExitCode.UserData);
}
else if (code == MeasurementStreamCodes.UserCommandWithData)
{
UserCommand = (long)Encoding7Bit.ReadUInt64(m_buffer.Data, ref m_buffer.Position);
UserCommandDataLength = (int)Encoding7Bit.ReadUInt32(m_buffer.Data, ref m_buffer.Position);
while (UserCommandData.Length < UserCommandDataLength)
{
UserCommandData = new byte[UserCommandData.Length * 2];
}
Array.Copy(m_buffer.Data, m_buffer.Position, UserCommandData, 0, UserCommandDataLength);
m_buffer.Position += UserCommandDataLength;
return(DecompressionExitCode.UserDataWithValue);
}
else if (code == MeasurementStreamCodes.FlushBits)
{
m_bitStream.Clear();
goto TryAgain;
}
else
{
throw new Exception("Programming Error.");
}
}
if (code < MeasurementStreamCodes.PointIDXOR4)
{
throw new Exception("Expecting higher code");
}
if (code <= MeasurementStreamCodes.PointIDXOR32)
{
if (code == MeasurementStreamCodes.PointIDXOR4)
{
m_lastPoint.PrevNextPointId1 ^= m_bitStream.ReadBits4();
}
else if (code == MeasurementStreamCodes.PointIDXOR8)
{
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++];
}
else if (code == MeasurementStreamCodes.PointIDXOR12)
{
m_lastPoint.PrevNextPointId1 ^= m_bitStream.ReadBits4();
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 4;
}
else if (code == MeasurementStreamCodes.PointIDXOR16)
{
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++];
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 8;
}
else if (code == MeasurementStreamCodes.PointIDXOR20)
{
m_lastPoint.PrevNextPointId1 ^= m_bitStream.ReadBits4();
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 4;
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 12;
}
else if (code == MeasurementStreamCodes.PointIDXOR24)
{
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++];
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 8;
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 16;
}
else if (code == MeasurementStreamCodes.PointIDXOR32)
{
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++];
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 8;
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 16;
m_lastPoint.PrevNextPointId1 ^= m_buffer.Data[m_buffer.Position++] << 24;
}
else
{
throw new Exception("Programming Error.");
}
code = m_lastPoint.ReadCode(m_bitStream);
}
if (code < MeasurementStreamCodes.TimeDelta1Forward)
{
throw new Exception("Expecting higher code");
}
ID = m_lastPoint.PrevNextPointId1;
nextPoint = m_points[m_lastPoint.PrevNextPointId1];
Quality = nextPoint.PrevQuality1;
if (code <= MeasurementStreamCodes.TimeXOR7Bit)
{
if (code == MeasurementStreamCodes.TimeDelta1Forward)
{
Timestamp = m_prevTimestamp1 + m_prevTimeDelta1;
}
else if (code == MeasurementStreamCodes.TimeDelta2Forward)
{
Timestamp = m_prevTimestamp1 + m_prevTimeDelta2;
}
else if (code == MeasurementStreamCodes.TimeDelta3Forward)
{
Timestamp = m_prevTimestamp1 + m_prevTimeDelta3;
}
else if (code == MeasurementStreamCodes.TimeDelta4Forward)
{
Timestamp = m_prevTimestamp1 + m_prevTimeDelta4;
}
else if (code == MeasurementStreamCodes.TimeDelta1Reverse)
{
Timestamp = m_prevTimestamp1 - m_prevTimeDelta1;
}
else if (code == MeasurementStreamCodes.TimeDelta2Reverse)
{
Timestamp = m_prevTimestamp1 - m_prevTimeDelta2;
}
else if (code == MeasurementStreamCodes.TimeDelta3Reverse)
{
Timestamp = m_prevTimestamp1 - m_prevTimeDelta3;
}
else if (code == MeasurementStreamCodes.TimeDelta4Reverse)
{
Timestamp = m_prevTimestamp1 - m_prevTimeDelta4;
}
else if (code == MeasurementStreamCodes.Timestamp2)
{
Timestamp = m_prevTimestamp2;
}
else if (code == MeasurementStreamCodes.TimeXOR7Bit)
{
Timestamp = m_prevTimestamp1 ^ (long)Encoding7Bit.ReadUInt64(m_buffer.Data, ref m_buffer.Position);
}
else
{
throw new Exception("Programming Error.");
}
//Save the smallest delta time
long minDelta = Math.Abs(m_prevTimestamp1 - Timestamp);
if (minDelta < m_prevTimeDelta4 && minDelta != m_prevTimeDelta1 && minDelta != m_prevTimeDelta2 && minDelta != m_prevTimeDelta3)
{
if (minDelta < m_prevTimeDelta1)
{
m_prevTimeDelta4 = m_prevTimeDelta3;
m_prevTimeDelta3 = m_prevTimeDelta2;
m_prevTimeDelta2 = m_prevTimeDelta1;
m_prevTimeDelta1 = minDelta;
}
else if (minDelta < m_prevTimeDelta2)
{
m_prevTimeDelta4 = m_prevTimeDelta3;
m_prevTimeDelta3 = m_prevTimeDelta2;
m_prevTimeDelta2 = minDelta;
}
else if (minDelta < m_prevTimeDelta3)
{
m_prevTimeDelta4 = m_prevTimeDelta3;
m_prevTimeDelta3 = minDelta;
}
else
{
m_prevTimeDelta4 = minDelta;
}
}
m_prevTimestamp2 = m_prevTimestamp1;
m_prevTimestamp1 = Timestamp;
code = m_lastPoint.ReadCode(m_bitStream);
}
else
{
Timestamp = m_prevTimestamp1;
}
if (code < MeasurementStreamCodes.Quality2)
{
throw new Exception("Expecting higher code");
}
if (code <= MeasurementStreamCodes.Quality7Bit32)
{
if (code == MeasurementStreamCodes.Quality2)
{
Quality = nextPoint.PrevQuality2;
}
else if (code == MeasurementStreamCodes.Quality7Bit32)
{
Quality = Encoding7Bit.ReadUInt32(m_buffer.Data, ref m_buffer.Position);
}
nextPoint.PrevQuality2 = nextPoint.PrevQuality1;
nextPoint.PrevQuality1 = Quality;
code = m_lastPoint.ReadCode(m_bitStream);
}
else
{
Quality = nextPoint.PrevQuality1;
}
if (code < 32)
{
throw new Exception("Programming Error. Expecting a value quality code.");
}
nextPoint.ReadValue(code, Value);
Value.Code = nextPoint.Code;
m_lastPoint = nextPoint;
return(DecompressionExitCode.MeasurementRead);
}