示例#1
0
            /// <summary>
            /// Checks if the reference fields in a given message indicate the subfield (alternate)
            /// definition should be used
            /// </summary>
            /// <param name="mesg">message of interest</param>
            /// <returns>true if the subfield is active</returns>
            internal bool CanMessageSupport(Message mesg)
            {
                Field field = mesg.GetField(refFieldNum);

                if (field != null)
                {
                    object value = field.GetValue(0, Fit.SubfieldIndexMainField);
                    // Float refvalues are not supported
                    if (Convert.ToInt64(value) == Convert.ToInt64(refFieldValue))
                    {
                        return(true);
                    }
                }
                return(false);
            }
示例#2
0
        public void DecodeNextMessage(Stream fitStream)
        {
            BinaryReader br       = new BinaryReader(fitStream);
            byte         nextByte = br.ReadByte();

            // Is it a compressed timestamp mesg?
            if ((nextByte & Fit.CompressedHeaderMask) == Fit.CompressedHeaderMask)
            {
                MemoryStream mesgBuffer = new MemoryStream();

                int timeOffset = nextByte & Fit.CompressedTimeMask;
                timestamp     += (uint)((timeOffset - lastTimeOffset) & Fit.CompressedTimeMask);
                lastTimeOffset = timeOffset;
                Field timestampField = new Field(Profile.GetMessage(MessageNum.Record).GetField("Timestamp"));
                timestampField.SetValue(timestamp);

                byte localMessageNum = (byte)((nextByte & Fit.CompressedLocalMessageNumMask) >> 5);
                mesgBuffer.WriteByte(localMessageNum);
                if (localMessageDefs[localMessageNum] == null)
                {
                    throw new FitException("Decode:DecodeNextMessage - FIT decode error: Missing message definition for local message number " + localMessageNum + " at stream position " + fitStream.Position);
                }
                int fieldsSize = localMessageDefs[localMessageNum].GetMessageSize() - 1;
                try
                {
                    byte[] read = br.ReadBytes(fieldsSize);
                    if (read.Length < fieldsSize)
                    {
                        throw new Exception("Field size mismatch, expected: " + fieldsSize + "received: " + read.Length);
                    }
                    mesgBuffer.Write(read, 0, fieldsSize);
                }
                catch (Exception e)
                {
                    throw new FitException("Decode:DecodeNextMessage - Compressed Data Message unexpected end of file.  Wanted " + fieldsSize + " bytes at stream position " + fitStream.Position, e);
                }

                Message newMessage = new Message(mesgBuffer, localMessageDefs[localMessageNum]);
                newMessage.InsertField(0, timestampField);
                RaiseMessageEvent(newMessage);
            }
            // Is it a mesg def?
            else if ((nextByte & Fit.MessageDefinitionMask) == Fit.MessageDefinitionMask)
            {
                MemoryStream mesgDefBuffer = new MemoryStream();

                // Figure out number of fields (length) of our defn and build buffer
                mesgDefBuffer.WriteByte(nextByte);
                mesgDefBuffer.Write(br.ReadBytes(4), 0, 4);
                byte numFields = br.ReadByte();
                mesgDefBuffer.WriteByte(numFields);
                int numBytes = numFields * 3; //3 Bytes per field
                try
                {
                    byte[] read = br.ReadBytes(numBytes);
                    if (read.Length < numBytes)
                    {
                        throw new Exception("Message Definition size mismatch, expected: " + numBytes + "received: " + read.Length);
                    }
                    mesgDefBuffer.Write(read, 0, numBytes);

                    if ((nextByte & Fit.DevDataMask) == Fit.DevDataMask)
                    {
                        // Definition Contains Dev Data
                        byte numDevFields = br.ReadByte();
                        mesgDefBuffer.WriteByte(numDevFields);

                        numBytes = numDevFields * 3;
                        read     = br.ReadBytes(numBytes);
                        if (read.Length < numBytes)
                        {
                            throw new Exception("Message Definition size mismatch, expected: " + numBytes + "received: " + read.Length);
                        }

                        // Read Dev Data
                        mesgDefBuffer.Write(read, 0, numBytes);
                    }
                }
                catch (Exception e)
                {
                    throw new FitException("Decode:DecodeNextMessage - Defn Message unexpected end of file.  Wanted " + numBytes + " bytes at stream position " + fitStream.Position, e);
                }

                MessageDefinition newMessageDef = new MessageDefinition(mesgDefBuffer, m_lookup);
                localMessageDefs[newMessageDef.LocalMessageNum] = newMessageDef;
                if (MessageDefinitionEvent != null)
                {
                    MessageDefinitionEvent(this, new MessageDefinitionEventArgs(newMessageDef));
                }
            }
            // Is it a data mesg?
            else if ((nextByte & Fit.MessageDefinitionMask) == Fit.MessageHeaderMask)
            {
                MemoryStream mesgBuffer = new MemoryStream();

                byte localMessageNum = (byte)(nextByte & Fit.LocalMessageNumMask);
                mesgBuffer.WriteByte(localMessageNum);
                if (localMessageDefs[localMessageNum] == null)
                {
                    throw new FitException("Decode:DecodeNextMessage - FIT decode error: Missing message definition for local message number " + localMessageNum + " at stream position " + fitStream.Position);
                }
                int fieldsSize = localMessageDefs[localMessageNum].GetMessageSize() - 1;
                try
                {
                    byte[] read = br.ReadBytes(fieldsSize);
                    if (read.Length < fieldsSize)
                    {
                        throw new Exception("Field size mismatch, expected: " + fieldsSize + "received: " + read.Length);
                    }
                    mesgBuffer.Write(read, 0, fieldsSize);
                }
                catch (Exception e)
                {
                    throw new FitException("Decode:DecodeNextMessage - Data Message unexpected end of file.  Wanted " + fieldsSize + " bytes at stream position " + fitStream.Position, e);
                }

                Message newMessage = new Message(mesgBuffer, localMessageDefs[localMessageNum]);

                // If the new message contains a timestamp field, record the value to use as
                // a reference for compressed timestamp headers
                Field timestampField = newMessage.GetField("Timestamp");
                if (timestampField != null)
                {
                    object tsValue = timestampField.GetValue();
                    if (tsValue != null)
                    {
                        timestamp      = (uint)tsValue;
                        lastTimeOffset = (int)timestamp & Fit.CompressedTimeMask;
                    }
                }

                foreach (Field field in newMessage.FieldsList)
                {
                    if (field.IsAccumulated)
                    {
                        int i;
                        for (i = 0; i < field.GetNumValues(); i++)
                        {
                            long value = Convert.ToInt64(field.GetRawValue(i));

                            foreach (Field fieldIn in newMessage.FieldsList)
                            {
                                foreach (FieldComponent fc in fieldIn.components)
                                {
                                    if ((fc.fieldNum == field.Num) && (fc.accumulate))
                                    {
                                        value = (long)((((value / field.Scale) - field.Offset) + fc.offset) * fc.scale);
                                    }
                                }
                            }
                            accumulator.Set(newMessage.MessageNumber, field.Num, value);
                        }
                    }
                }

                // Now that the entire message is decoded we can evaluate subfields and expand any components
                newMessage.ExpandComponents(accumulator);

                RaiseMessageEvent(newMessage);
            }
            else
            {
                throw new FitException("Decode:Read - FIT decode error: Unexpected Object Header Byte 0x" + nextByte.ToString("X") + " at stream position: " + fitStream.Position);
            }
        }