Ejemplo n.º 1
0
        public void DecodeNextMessage(Stream fitStream)
        {
            var br = new BinaryReader(fitStream);
            byte nextByte = br.ReadByte();

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

                int timeOffset = nextByte & Fit.CompressedTimeMask;
                timestamp += (uint)((timeOffset - lastTimeOffset) & Fit.CompressedTimeMask);
                lastTimeOffset = timeOffset;
                var timestampField = new Field(Profile.mesgs[Profile.RecordIndex].GetField("Timestamp"));
                timestampField.SetValue(timestamp);

                var localMesgNum = (byte)((nextByte & Fit.CompressedLocalMesgNumMask) >> 5);
                mesgBuffer.WriteByte(localMesgNum);
                if (localMesgDefs[localMesgNum] == null)
                {
                    throw new FitException(
                        "Decode:DecodeNextMessage - FIT decode error: Missing message definition for local message number " + localMesgNum +
                        ".");
                }

                int fieldsSize = localMesgDefs[localMesgNum].GetMesgSize() - 1;
                try
                {
                    mesgBuffer.Write(br.ReadBytes(fieldsSize), 0, fieldsSize);
                }
                catch (IOException e)
                {
                    throw new FitException(
                        "Decode:DecodeNextMessage - Compressed Data Message unexpected end of file.  Wanted " + fieldsSize +
                        " bytes at stream position " + fitStream.Position, e);
                }

                var newMesg = new Mesg(mesgBuffer, localMesgDefs[localMesgNum]);
                newMesg.InsertField(0, timestampField);
                if (MesgEvent != null)
                {
                    MesgEvent(this, new MesgEventArgs(newMesg));
                }
            }

                // Is it a mesg def?
            else if ((nextByte & Fit.HeaderTypeMask) == Fit.MesgDefinitionMask)
            {
                var 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);
                try
                {
                    mesgDefBuffer.Write(br.ReadBytes(numfields*3), 0, numfields*3);
                }
                catch (IOException e)
                {
                    throw new FitException(
                        "Decode:DecodeNextMessage - Defn Message unexpected end of file.  Wanted " + (numfields*3) +
                        " bytes at stream position " + fitStream.Position, e);
                }

                var newMesgDef = new MesgDefinition(mesgDefBuffer);
                localMesgDefs[newMesgDef.LocalMesgNum] = newMesgDef;
                if (MesgDefinitionEvent != null)
                {
                    MesgDefinitionEvent(this, new MesgDefinitionEventArgs(newMesgDef));
                }
            }
                // Is it a data mesg?
            else if ((nextByte & Fit.HeaderTypeMask) == Fit.MesgHeaderMask)
            {
                var mesgBuffer = new MemoryStream();

                var localMesgNum = (byte) (nextByte & Fit.LocalMesgNumMask);
                mesgBuffer.WriteByte(localMesgNum);
                if (localMesgDefs[localMesgNum] == null)
                {
                    throw new FitException(
                        "Decode:DecodeNextMessage - FIT decode error: Missing message definition for local message number " + localMesgNum +
                        ".");
                }
                int fieldsSize = localMesgDefs[localMesgNum].GetMesgSize() - 1;
                try
                {
                    mesgBuffer.Write(br.ReadBytes(fieldsSize), 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);
                }

                var newMesg = new Mesg(mesgBuffer, localMesgDefs[localMesgNum]);

                // If the new message contains a timestamp field, record the value to use as
                // a reference for compressed timestamp headers
                Field timestampField = newMesg.GetField("Timestamp");
                if (timestampField != null)
                {
                    timestamp = (uint) timestampField.GetValue();
                    lastTimeOffset = (int) timestamp & Fit.CompressedTimeMask;
                }
                // Now that the entire message is decoded we can evaluate subfields and expand any components
                newMesg.ExpandComponents();

                if (MesgEvent != null)
                {
                    MesgEvent(this, new MesgEventArgs(newMesg));
                }
            }
            else
            {
                throw new FitException("Decode:Read - FIT decode error: Unexpected Record Header Byte 0x" + nextByte.ToString("X"));
            }
        }