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);
        }
Esempio n. 2
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;
 }
        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));
            }
        }
Esempio n. 4
0
 public void OnMesgDefinition(MesgDefinition newMesgDefinition)
 {
     Write(newMesgDefinition);
 }
Esempio n. 5
0
 public MesgDefinitionEventArgs(MesgDefinition newDefn)
 {
     mesgDef = new MesgDefinition(newDefn);
 }
Esempio n. 6
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"));
            }
        }
Esempio n. 7
0
 public Mesg(Stream fitStream, MesgDefinition defnMesg) : this(defnMesg.GlobalMesgNum)
 {
     Read(fitStream, defnMesg);
 }
Esempio n. 8
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;
                    }
                }
            }
        }
Esempio n. 9
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++)
                    {
                        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);
                    }
                }
            }
        }