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