示例#1
0
        public bool Supports(MesgDefinition mesgDef)
        {
            if (mesgDef == null)
            {
                return(false);
            }

            if (GlobalMesgNum != mesgDef.GlobalMesgNum)
            {
                return(false);
            }

            if (LocalMesgNum != mesgDef.LocalMesgNum)
            {
                return(false);
            }

            foreach (FieldDefinition fieldDef in mesgDef.GetFields())
            {
                FieldDefinition supportedFieldDef = GetField(fieldDef.Num);

                if (supportedFieldDef == null)
                {
                    return(false);
                }
                if (fieldDef.Size > supportedFieldDef.Size)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#2
0
        /// <summary>
        /// Validate if a MessageDefinition is compatible with a protocol version
        /// </summary>
        /// <param name="defn">Definition to validate</param>
        /// <returns>true if definition is compatible. false otherwise</returns>
        public bool ValidateMesgDefn(MesgDefinition defn)
        {
            if (m_validator == null)
            {
                return(true);
            }

            return(m_validator.ValidateMesgDefn(defn));
        }
示例#3
0
 public void Write(MesgDefinition mesgDefinition)
 {
     if (open == false)
     {
         throw new FitException("Encode:Write - Encode not opened yet, must call Encode:Open()");
     }
     mesgDefinition.Write(fitDest);
     lastMesgDef[mesgDefinition.LocalMesgNum] = mesgDefinition;
 }
示例#4
0
        public MesgDefinition(MesgDefinition mesgDef)
        {
            LocalMesgNum  = mesgDef.LocalMesgNum;
            GlobalMesgNum = mesgDef.GlobalMesgNum;
            architecture  = mesgDef.IsBigEndian ? Fit.BigEndian : Fit.LittleEndian;
            NumFields     = mesgDef.NumFields;

            foreach (FieldDefinition fieldDef in mesgDef.fieldDefs)
            {
                fieldDefs.Add(new FieldDefinition(fieldDef));
            }
        }
示例#5
0
        public MesgDefinition(MesgDefinition mesgDef)
        {
            LocalMesgNum = mesgDef.LocalMesgNum;
             GlobalMesgNum = mesgDef.GlobalMesgNum;
             architecture = mesgDef.IsBigEndian ? Fit.BigEndian : Fit.LittleEndian;
             NumFields = mesgDef.NumFields;

             foreach (FieldDefinition fieldDef in mesgDef.fieldDefs)
             {
            fieldDefs.Add(new FieldDefinition(fieldDef));
             }
        }
示例#6
0
        public bool Supports(MesgDefinition mesgDef)
        {
            if (mesgDef == null)
            {
                return(false);
            }

            if (GlobalMesgNum != mesgDef.GlobalMesgNum)
            {
                return(false);
            }

            if (LocalMesgNum != mesgDef.LocalMesgNum)
            {
                return(false);
            }

            foreach (FieldDefinition fieldDef in mesgDef.GetFields())
            {
                FieldDefinition supportedFieldDef = GetField(fieldDef.Num);

                if (supportedFieldDef == null)
                {
                    return(false);
                }

                if (fieldDef.Size > supportedFieldDef.Size)
                {
                    return(false);
                }
            }

            foreach (DeveloperFieldDefinition fieldDef in mesgDef.DeveloperFieldDefinitions)
            {
                var supportedFieldDef =
                    GetDeveloperFieldDefinition(fieldDef.FieldNum, fieldDef.DeveloperDataIndex);

                if (supportedFieldDef == null)
                {
                    return(false);
                }

                if (fieldDef.Size > supportedFieldDef.Size)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#7
0
        public void Write(MesgDefinition mesgDefinition)
        {
            if (open == false)
            {
                throw new FitException("Encode:Write - Encode not opened yet, must call Encode:Open()");
            }

            if (!validator.ValidateMesgDefn(mesgDefinition))
            {
                throw new FitException("Encode:Write - mesgDefinition contains incompatible protocol Features");
            }

            mesgDefinition.Write(fitDest);
            lastMesgDef[mesgDefinition.LocalMesgNum] = mesgDefinition;
        }
示例#8
0
        public void Read(Stream inStream, MesgDefinition defnMesg)
        {
            inStream.Position = 1;
            EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian);

            LocalNum = defnMesg.LocalMesgNum;

            foreach (FieldDefinition fieldDef in defnMesg.GetFields())
            {
                // It's possible the field type found in the field definition may
                // not agree with the type defined in the profile.  The profile
                // type will be preferred for decode.
                Field field = GetField(fieldDef.Num);
                if (field == null)
                {
                    // We normally won't have fields attached to our skeleton message,
                    // as we add values we need to add the fields too based on the mesg,field
                    // combo in the profile.  Must derive from the profile so the scale etc
                    // is correct
                    field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num));
                    if (field.Num == Fit.FieldNumInvalid)
                    {
                        // If there was no info in the profile the FieldNum will get set to invalid
                        // so preserve the unknown fields info while we know it
                        field.Num = fieldDef.Num;
                        field.SetType(fieldDef.Type);
                    }
                    SetField(field);
                }

                ReadFieldValue(field, fieldDef.Size, mesgReader);
            }

            foreach (DeveloperFieldDefinition fldDef in defnMesg.DeveloperFieldDefinitions)
            {
                DeveloperField fld = GetDeveloperField(fldDef.FieldNum, fldDef.DeveloperDataIndex);
                if (ReferenceEquals(fld, null))
                {
                    fld = new DeveloperField(fldDef);
                    SetDeveloperField(fld);
                }

                ReadFieldValue(fld, fldDef.Size, mesgReader);
            }
        }
示例#9
0
        public void Write(Stream outStream, MesgDefinition mesgDef)
        {
            if (mesgDef == null)
            {
                mesgDef = new MesgDefinition(this);
            }

            EndianBinaryWriter bw = new EndianBinaryWriter(outStream, mesgDef.IsBigEndian);

            bw.Write(LocalNum);

            foreach (FieldDefinition fieldDef in mesgDef.GetFields())
            {
                Field field = GetField(fieldDef.Num);
                if (null == field)
                {
                    field = Profile.GetField(this.Num, fieldDef.Num);
                    if (null != field)
                    {
                        FieldsList.Add(field);
                    }
                    else
                    {
                        //Field does not exist in profile, continue to next field
                        continue;
                    }
                }

                WriteField(field, fieldDef.Size, bw);
            }

            foreach (DeveloperFieldDefinition fieldDef in mesgDef.DeveloperFieldDefinitions)
            {
                DeveloperField field = GetDeveloperField(fieldDef.FieldNum, fieldDef.DeveloperDataIndex);

                if (field == null)
                {
                    field = new DeveloperField(fieldDef);
                    SetDeveloperField(field);
                }

                WriteField(field, fieldDef.Size, bw);
            }
        }
示例#10
0
        /// <summary>
        /// Validate if a MessageDefinition is compatible with a protocol version
        /// </summary>
        /// <param name="defn">Definition to validate</param>
        /// <returns>true if definition is compatible. false otherwise</returns>
        public bool ValidateMesgDefn(MesgDefinition defn)
        {
            if (defn.DeveloperFieldDefinitions.Any())
            {
                return(false);
            }

            foreach (var fld in defn.GetFields())
            {
                int typeNum = fld.Type & Fit.BaseTypeNumMask;

                if (typeNum > Fit.Byte)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#11
0
 public Mesg(Stream fitStream, MesgDefinition defnMesg)
     : this(defnMesg.GlobalMesgNum)
 {
     Read(fitStream, defnMesg);
 }
示例#12
0
 public void OnMesgDefinition(MesgDefinition newMesgDefinition)
 {
     Write(newMesgDefinition);
 }
 public MesgDefinitionEventArgs(MesgDefinition newDefn)
 {
     mesgDef = new MesgDefinition(newDefn);
 }
示例#14
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.GetMesg(MesgNum.Record).GetField("Timestamp"));
                timestampField.SetValue(timestamp);

                byte 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 + " at stream position " + fitStream.Position);
                }
                int fieldsSize = localMesgDefs[localMesgNum].GetMesgSize() - 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);
                }

                Mesg newMesg = new Mesg(mesgBuffer, localMesgDefs[localMesgNum]);
                newMesg.InsertField(0, timestampField);
                RaiseMesgEvent(newMesg);
            }
            // Is it a mesg def?
            else if ((nextByte & Fit.MesgDefinitionMask) == Fit.MesgDefinitionMask)
            {
                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);
                }

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

                byte 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 + " at stream position " + fitStream.Position);
                }
                int fieldsSize = localMesgDefs[localMesgNum].GetMesgSize() - 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);
                }

                Mesg 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)
                {
                    object tsValue = timestampField.GetValue();
                    if (tsValue != null)
                    {
                        timestamp      = (uint)tsValue;
                        lastTimeOffset = (int)timestamp & Fit.CompressedTimeMask;
                    }
                }

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

                            foreach (Field fieldIn in newMesg.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(newMesg.Num, field.Num, value);
                        }
                    }
                }

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

                RaiseMesgEvent(newMesg);
            }
            else
            {
                throw new FitException("Decode:Read - FIT decode error: Unexpected Record Header Byte 0x" + nextByte.ToString("X") + " at stream position: " + fitStream.Position);
            }
        }
示例#15
0
文件: Mesg.cs 项目: dgaff/fitsdk
        public void Read(Stream inStream, MesgDefinition defnMesg)
        {
            inStream.Position = 1;
             EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian);

             LocalNum = defnMesg.LocalMesgNum;

             foreach (FieldDefinition fieldDef in defnMesg.GetFields())
             {
            // It's possible the field type found in the field definition may
            // not agree with the type defined in the profile.  The profile
            // type will be preferred for decode.
            Field field = GetField(fieldDef.Num);
            if (field == null)
            {
               // We normally won't have fields attached to our skeleton message,
               // as we add values we need to add the fields too based on the mesg,field
               // combo in the profile.  Must derive from the profile so the scale etc
               // is correct
               field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num));
               if (field.Num == Fit.FieldNumInvalid)
               {
                  // If there was no info in the profile the FieldNum will get set to invalid
                  // so preserve the unknown fields info while we know it
                  field.Num = fieldDef.Num;
                  field.Type = fieldDef.Type;
               }
               SetField(field);
            }

            object value;

            // strings may be an array and are of variable length
            if ((field.Type & Fit.BaseTypeNumMask) == Fit.String)
            {
               List<byte> utf8Bytes = new List<byte>();
               byte b = new byte();

               for (int i=0; i<fieldDef.Size; i++)
               {
                  b = mesgReader.ReadByte();
                  if (b == 0x00)
                  {
                     field.AddValue(utf8Bytes.ToArray());
                     utf8Bytes.Clear();
                  }
                  else
                  {
                     utf8Bytes.Add(b);
                  }
               }
               if (utf8Bytes.Count != 0)
               {
                  field.AddValue(utf8Bytes.ToArray());
                  utf8Bytes.Clear();
               }
            }
            else
            {
               int numElements = (int)fieldDef.Size / Fit.BaseType[field.Type & Fit.BaseTypeNumMask].size;
               for (int i=0; i < numElements; i++)
               {
                  switch (field.Type & Fit.BaseTypeNumMask)
                  {
                     case Fit.Enum:
                     case Fit.Byte:
                     case Fit.UInt8:
                     case Fit.UInt8z:
                        value = mesgReader.ReadByte();
                        break;

                     case Fit.SInt8:
                        value = mesgReader.ReadSByte();
                        break;

                     case Fit.SInt16:
                        value = mesgReader.ReadInt16();
                        break;

                     case Fit.UInt16:
                     case Fit.UInt16z:
                        value = mesgReader.ReadUInt16();
                        break;

                     case Fit.SInt32:
                        value = mesgReader.ReadInt32();
                        break;

                     case Fit.UInt32:
                     case Fit.UInt32z:
                        value = mesgReader.ReadUInt32();
                        break;

                     case Fit.Float32:
                        value = mesgReader.ReadSingle();
                        break;

                     case Fit.Float64:
                        value = mesgReader.ReadDouble();
                        break;

                     default:
                        value = mesgReader.ReadBytes(fieldDef.Size);
                        break;
                  }
                  field.SetRawValue(i, value);
               }
            }
             }
        }
示例#16
0
文件: Encode.cs 项目: phleb3/ReadFit
 public void Write(MesgDefinition mesgDefinition)
 {
     if (open == false)
      {
     throw new FitException("Encode:Write - Encode not opened yet, must call Encode:Open()");
      }
      mesgDefinition.Write(fitDest);
      lastMesgDef[mesgDefinition.LocalMesgNum] = mesgDefinition;
 }
示例#17
0
文件: Encode.cs 项目: phleb3/ReadFit
 public void OnMesgDefinition(MesgDefinition newMesgDefinition)
 {
     Write(newMesgDefinition);
 }
示例#18
0
文件: Mesg.cs 项目: dgaff/fitsdk
 public Mesg(Stream fitStream, MesgDefinition defnMesg)
     : this(defnMesg.GlobalMesgNum)
 {
     Read(fitStream, defnMesg);
 }
示例#19
0
文件: Decode.cs 项目: phleb3/ReadFit
        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.mesgs[Profile.RecordIndex].GetField("Timestamp"));
            timestampField.SetValue(timestamp);

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

            Mesg 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)
             {
            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);
            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);
            }

            MesgDefinition 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)
             {
            MemoryStream mesgBuffer = new MemoryStream();

            byte 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 (IOException e)
            {
               throw new FitException("Decode:DecodeNextMessage - Data Message unexpected end of file.  Wanted " + fieldsSize + " bytes at stream position " + fitStream.Position, e);
            }

            Mesg 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;
            }

            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"));
             }
        }
示例#20
0
        public void Write(Stream outStream, MesgDefinition mesgDef)
        {
            if (mesgDef == null)
            {
                mesgDef = new MesgDefinition(this);
            }

            EndianBinaryWriter bw = new EndianBinaryWriter(outStream, mesgDef.IsBigEndian);

            bw.Write(LocalNum);

            foreach (FieldDefinition fieldDef in mesgDef.GetFields())
            {
                Field field = GetField(fieldDef.Num);
                if (field == null)
                {
                    field = Profile.GetField(this.Num, fieldDef.Num);
                    fields.Add(field);
                }
                // The field could be blank, correctly formed or partially filled
                while (field.GetSize() < fieldDef.Size)
                {
                    field.AddValue(Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue);
                }

                for (int i = 0; i < field.GetNumValues(); i++)
                {
                    object value = field.GetRawValue(i);
                    if (value == null)
                    {
                        value = Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue;
                    }
                    switch (fieldDef.Type & Fit.BaseTypeNumMask)
                    {
                    case Fit.Enum:
                    case Fit.Byte:
                    case Fit.UInt8:
                    case Fit.UInt8z:
                        bw.Write((byte)value);
                        break;

                    case Fit.SInt8:
                        bw.Write((sbyte)value);
                        break;

                    case Fit.SInt16:
                        bw.Write((short)value);
                        break;

                    case Fit.UInt16:
                    case Fit.UInt16z:
                        bw.Write((ushort)value);
                        break;

                    case Fit.SInt32:
                        bw.Write((int)value);
                        break;

                    case Fit.UInt32:
                    case Fit.UInt32z:
                        bw.Write((uint)value);
                        break;

                    case Fit.Float32:
                        bw.Write((float)value);
                        break;

                    case Fit.Float64:
                        bw.Write((double)value);
                        break;

                    case Fit.String:
                        bw.Write((byte[])value);
                        // Write the null terminator
                        bw.Write((byte)0x00);
                        break;

                    default:
                        break;
                    }
                }
            }
        }
示例#21
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.mesgs[Profile.RecordIndex].GetField("Timestamp"));
                timestampField.SetValue(timestamp);

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

                Mesg 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)
            {
                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);
                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);
                }

                MesgDefinition 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)
            {
                MemoryStream mesgBuffer = new MemoryStream();

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

                Mesg 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"));
            }
        }
示例#22
0
        public bool Supports(MesgDefinition mesgDef)
        {
            if (mesgDef == null)
             {
            return false;
             }

             if (GlobalMesgNum != mesgDef.GlobalMesgNum)
             {
            return false;
             }

             if (LocalMesgNum != mesgDef.LocalMesgNum)
             {
            return false;
             }

             foreach (FieldDefinition fieldDef in mesgDef.GetFields())
             {
            FieldDefinition supportedFieldDef = GetField(fieldDef.Num);

            if (supportedFieldDef == null)
            {
               return false;
            }
            if (fieldDef.Size > supportedFieldDef.Size)
            {
               return false;
            }
             }
             return true;
        }
示例#23
0
        public void Write(Stream outStream, MesgDefinition mesgDef)
        {
            if (mesgDef == null)
            {
                mesgDef = new MesgDefinition(this);
            }

            EndianBinaryWriter bw = new EndianBinaryWriter(outStream, mesgDef.IsBigEndian);

            bw.Write(LocalNum);

            foreach (FieldDefinition fieldDef in mesgDef.GetFields())
            {
                Field field = GetField(fieldDef.Num);
                if (null == field)
                {
                    field = Profile.GetField(this.Num, fieldDef.Num);
                    if (null != field)
                    {
                        fields.Add(field);
                    }
                    else
                    {
                        //Field does not exist in profile, continue to next field
                        continue;
                    }
                }
                // The field could be blank, correctly formed or partially filled
                while (field.GetSize() < fieldDef.Size)
                {
                    if ((field.GetNumValues() == 1) && ((fieldDef.Type & Fit.BaseTypeNumMask) == Fit.String))
                    {
                        //Has to be a string.
                        try
                        {
                            byte[]      value = (byte[])field.GetValue();
                            List <byte> temp  = new List <byte>(value);
                            while (temp.Count < fieldDef.Size)
                            {
                                temp.Add(Convert.ToByte(Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue));
                            }
                            field.SetValue(temp.ToArray());
                        }
                        catch (Exception) { throw new FitException("Exception occurred while resizing field to match definition."); }
                    }
                    else
                    {
                        field.AddValue(Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue);
                    }
                }

                for (int i = 0; i < field.GetNumValues(); i++)
                {
                    object value = field.GetRawValue(i);
                    if (value == null)
                    {
                        value = Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue;
                    }
                    switch (fieldDef.Type & Fit.BaseTypeNumMask)
                    {
                    case Fit.Enum:
                    case Fit.Byte:
                    case Fit.UInt8:
                    case Fit.UInt8z:
                        bw.Write((byte)value);
                        break;

                    case Fit.SInt8:
                        bw.Write((sbyte)value);
                        break;

                    case Fit.SInt16:
                        bw.Write((short)value);
                        break;

                    case Fit.UInt16:
                    case Fit.UInt16z:
                        bw.Write((ushort)value);
                        break;

                    case Fit.SInt32:
                        bw.Write((int)value);
                        break;

                    case Fit.UInt32:
                    case Fit.UInt32z:
                        bw.Write((uint)value);
                        break;

                    case Fit.Float32:
                        bw.Write((float)value);
                        break;

                    case Fit.Float64:
                        bw.Write((double)value);
                        break;

                    case Fit.String:
                        bw.Write((byte[])value);
                        // Write the null terminator
                        bw.Write((byte)0x00);
                        break;

                    default:
                        break;
                    }
                }
            }
        }
示例#24
0
        public void Read(Stream inStream, MesgDefinition defnMesg)
        {
            inStream.Position = 1;
            EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian);

            LocalNum = defnMesg.LocalMesgNum;

            foreach (FieldDefinition fieldDef in defnMesg.GetFields())
            {
                // It's possible the field type found in the field definition may
                // not agree with the type defined in the profile.  The profile
                // type will be preferred for decode.
                Field field = GetField(fieldDef.Num);
                if (field == null)
                {
                    // We normally won't have fields attached to our skeleton message,
                    // as we add values we need to add the fields too based on the mesg,field
                    // combo in the profile.  Must derive from the profile so the scale etc
                    // is correct
                    field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num));
                    if (field.Num == Fit.FieldNumInvalid)
                    {
                        // If there was no info in the profile the FieldNum will get set to invalid
                        // so preserve the unknown fields info while we know it
                        field.Num  = fieldDef.Num;
                        field.Type = fieldDef.Type;
                    }
                    SetField(field);
                }

                object value;

                // strings may be an array and are of variable length
                if ((field.Type & Fit.BaseTypeNumMask) == Fit.String)
                {
                    List <byte> utf8Bytes = new List <byte>();
                    byte        b         = new byte();

                    for (int i = 0; i < fieldDef.Size; i++)
                    {
                        b = mesgReader.ReadByte();
                        if (b == 0x00)
                        {
                            field.AddValue(utf8Bytes.ToArray());
                            utf8Bytes.Clear();
                        }
                        else
                        {
                            utf8Bytes.Add(b);
                        }
                    }
                    if (utf8Bytes.Count != 0)
                    {
                        field.AddValue(utf8Bytes.ToArray());
                        utf8Bytes.Clear();
                    }
                }
                else
                {
                    int numElements = (int)fieldDef.Size / Fit.BaseType[field.Type & Fit.BaseTypeNumMask].size;
                    for (int i = 0; i < numElements; i++)
                    {
                        bool invalid = true;
                        switch (field.Type & Fit.BaseTypeNumMask)
                        {
                        case Fit.Enum:
                        case Fit.Byte:
                        case Fit.UInt8:
                        case Fit.UInt8z:
                            value = mesgReader.ReadByte();
                            if ((byte)value != (byte)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.SInt8:
                            value = mesgReader.ReadSByte();
                            if ((sbyte)value != (sbyte)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.SInt16:
                            value = mesgReader.ReadInt16();
                            if ((short)value != (short)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.UInt16:
                        case Fit.UInt16z:
                            value = mesgReader.ReadUInt16();
                            if ((ushort)value != (ushort)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.SInt32:
                            value = mesgReader.ReadInt32();
                            if ((int)value != (int)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.UInt32:
                        case Fit.UInt32z:
                            value = mesgReader.ReadUInt32();
                            if ((uint)value != (uint)Fit.BaseType[field.Type & Fit.BaseTypeNumMask].invalidValue)
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.Float32:
                            value = mesgReader.ReadSingle();
                            // TODO! Unless we find a different way to store floats, we dont have a good way to compare
                            if (!float.IsNaN((float)value))
                            {
                                invalid = false;
                            }
                            break;

                        case Fit.Float64:
                            value = mesgReader.ReadDouble();
                            // TODO! Unless we find a different way to store floats, we dont have a good way to compare
                            if (!double.IsNaN((double)value))
                            {
                                invalid = false;
                            }
                            break;

                        default:
                            value = mesgReader.ReadBytes(fieldDef.Size);
                            break;
                        }

                        if (!invalid || numElements > 1)
                        {
                            field.SetRawValue(i, value);
                        }
                    }
                }
            }
        }
示例#25
0
 public MesgDefinitionEventArgs(MesgDefinition newDefn)
 {
     mesgDef = new MesgDefinition(newDefn);
 }
示例#26
0
文件: Mesg.cs 项目: dgaff/fitsdk
        public void Write(Stream outStream, MesgDefinition mesgDef)
        {
            if (mesgDef == null)
             {
            mesgDef = new MesgDefinition(this);
             }

             EndianBinaryWriter bw = new EndianBinaryWriter(outStream, mesgDef.IsBigEndian);
             bw.Write(LocalNum);

             foreach (FieldDefinition fieldDef in mesgDef.GetFields())
             {
            Field field = GetField(fieldDef.Num);
            if (field == null)
            {
               field = Profile.GetField(this.Num, fieldDef.Num);
               fields.Add(field);
            }
            // The field could be blank, correctly formed or partially filled
            while (field.GetSize() < fieldDef.Size)
            {
               field.AddValue(Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue);
            }

            for (int i=0; i<field.GetNumValues(); i++)
            {
               object value = field.GetRawValue(i);
               if (value == null)
               {
                  value = Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].invalidValue;
               }
               switch (fieldDef.Type & Fit.BaseTypeNumMask)
               {
                  case Fit.Enum:
                  case Fit.Byte:
                  case Fit.UInt8:
                  case Fit.UInt8z:
                     bw.Write((byte)value);
                     break;

                  case Fit.SInt8:
                     bw.Write((sbyte)value);
                     break;

                  case Fit.SInt16:
                     bw.Write((short)value);
                     break;

                  case Fit.UInt16:
                  case Fit.UInt16z:
                     bw.Write((ushort)value);
                     break;

                  case Fit.SInt32:
                     bw.Write((int)value);
                     break;

                  case Fit.UInt32:
                  case Fit.UInt32z:
                     bw.Write((uint)value);
                     break;

                  case Fit.Float32:
                     bw.Write((float)value);
                     break;

                  case Fit.Float64:
                     bw.Write((double)value);
                     break;

                  case Fit.String:
                     bw.Write((byte[])value);
                     // Write the null terminator
                     bw.Write((byte)0x00);
                     break;

                  default:
                     break;
               }
            }
             }
        }
示例#27
0
        public void Read(Stream inStream, MesgDefinition defnMesg)
        {
            inStream.Position = 1;
            EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian);

            LocalNum = defnMesg.LocalMesgNum;

            foreach (FieldDefinition fieldDef in defnMesg.GetFields())
            {
                // It's possible the field type found in the field definition may
                // not agree with the type defined in the profile.  The profile
                // type will be preferred for decode.
                Field field = GetField(fieldDef.Num);
                if (field == null)
                {
                    // We normally won't have fields attached to our skeleton message,
                    // as we add values we need to add the fields too based on the mesg,field
                    // combo in the profile.  Must derive from the profile so the scale etc
                    // is correct
                    field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num));
                    if (field.Num == Fit.FieldNumInvalid)
                    {
                        // If there was no info in the profile the FieldNum will get set to invalid
                        // preserve the the unknown fields info while we know it
                        field.Num  = fieldDef.Num;
                        field.Type = fieldDef.Type;
                    }
                    SetField(field);
                }

                object value;

                // strings may be an array and are of variable length
                if ((field.Type & Fit.BaseTypeNumMask) == Fit.String)
                {
                    List <byte> utf8Bytes = new List <byte>();
                    byte        b         = new byte();

                    for (int i = 0; i < fieldDef.Size; i++)
                    {
                        b = mesgReader.ReadByte();
                        if (b == 0x00)
                        {
                            field.AddValue(utf8Bytes.ToArray());
                            utf8Bytes.Clear();
                        }
                        else
                        {
                            utf8Bytes.Add(b);
                        }
                    }
                    if (utf8Bytes.Count != 0)
                    {
                        field.AddValue(utf8Bytes.ToArray());
                        utf8Bytes.Clear();
                    }
                }
                else
                {
                    int numElements = (int)fieldDef.Size / Fit.BaseType[field.Type & Fit.BaseTypeNumMask].size;
                    for (int i = 0; i < numElements; i++)
                    {
                        switch (field.Type & Fit.BaseTypeNumMask)
                        {
                        case Fit.Enum:
                        case Fit.Byte:
                        case Fit.UInt8:
                        case Fit.UInt8z:
                            value = mesgReader.ReadByte();
                            break;

                        case Fit.SInt8:
                            value = mesgReader.ReadSByte();
                            break;

                        case Fit.SInt16:
                            value = mesgReader.ReadInt16();
                            break;

                        case Fit.UInt16:
                        case Fit.UInt16z:
                            value = mesgReader.ReadUInt16();
                            break;

                        case Fit.SInt32:
                            value = mesgReader.ReadInt32();
                            break;

                        case Fit.UInt32:
                        case Fit.UInt32z:
                            value = mesgReader.ReadUInt32();
                            break;

                        case Fit.Float32:
                            value = mesgReader.ReadSingle();
                            break;

                        case Fit.Float64:
                            value = mesgReader.ReadDouble();
                            break;

                        default:
                            value = mesgReader.ReadBytes(fieldDef.Size);
                            break;
                        }
                        field.SetRawValue(i, value);
                    }
                }
                if ((field.values.Count > 0) && (field.components.Count > 0))
                {
                    int offset = 0;

                    foreach (FieldComponent component in field.components)
                    {
                        if (component.fieldNum != Fit.FieldNumInvalid)
                        {
                            Field componentField = new Field(Profile.GetMesg(this.Num).GetField(component.fieldNum));

                            long?bitsValue = field.GetBitsValue(offset, component.bits, componentField.Type);
                            if (bitsValue == null)
                            {
                                break;
                            }

                            if (component.accumulate == true)
                            {
                                bitsValue = component.Accumulate(bitsValue.Value);
                            }
                            // Remove containing field scale and offset
                            float fbitsValue = Convert.ToSingle(bitsValue);
                            fbitsValue = ((float)fbitsValue / component.scale) - component.offset;

                            if (this.HasField(componentField.Num) == true)
                            {
                                this.GetField(componentField.Num).SetValue(this.GetField(componentField.Num).values.Count, fbitsValue);
                            }
                            else
                            {
                                componentField.SetValue(fbitsValue);
                                this.SetField(componentField);
                            }
                        }
                        offset += component.bits;
                    }
                }
            }
        }
示例#28
0
        public void Read(Stream inStream, MesgDefinition defnMesg)
        {
            inStream.Position = 1;
            EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian);

            LocalNum = defnMesg.LocalMesgNum;

            foreach (FieldDefinition fieldDef in defnMesg.GetFields())
            {
                bool read = true;

                // It's possible the field type found in the field definition may
                // not agree with the type defined in the profile.  The profile
                // type will be preferred for decode.
                Field field = GetField(fieldDef.Num);
                if (field == null)
                {
                    // We normally won't have fields attached to our skeleton message,
                    // as we add values we need to add the fields too based on the mesg,field
                    // combo in the profile.  Must derive from the profile so the scale etc
                    // is correct
                    field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num));
                    if (field.Num == Fit.FieldNumInvalid)
                    {
                        // If there was no info in the profile the FieldNum will get set to invalid
                        // so preserve the unknown fields info while we know it
                        field.Num = fieldDef.Num;
                        field.SetType(fieldDef.Type);
                    }
                    SetField(field);
                }

                if (field.Type != fieldDef.Type)
                {
                    int fieldSize = Fit.BaseType[field.Type & Fit.BaseTypeNumMask].size;
                    int defSize   = Fit.BaseType[fieldDef.Type & Fit.BaseTypeNumMask].size;

                    if (defSize < fieldSize)
                    {
                        field.SetType(fieldDef.Type);
                    }
                    else if (defSize != fieldSize)
                    {
                        // Demotion is hard. Don't read the field if the
                        // sizes are different. Use the profile type if the
                        // signedness of the field has changed.
                        read = false;
                    }
                }

                if (read)
                {
                    ReadFieldValue(field, fieldDef.Size, mesgReader);
                }
                else
                {
                    // Skip the bytes for the field if we aren't going to bother reading them
                    mesgReader.ReadBytes(fieldDef.Size);
                }
            }

            foreach (DeveloperFieldDefinition fldDef in defnMesg.DeveloperFieldDefinitions)
            {
                DeveloperField fld = GetDeveloperField(fldDef.FieldNum, fldDef.DeveloperDataIndex);
                if (ReferenceEquals(fld, null))
                {
                    fld = new DeveloperField(fldDef);
                    SetDeveloperField(fld);
                }

                ReadFieldValue(fld, fldDef.Size, mesgReader);
            }
        }