/// <summary>
 /// Initializes a new instance of the <see cref="AttributeValue"/> class.
 /// </summary>
 /// <param name="theDefinition">The definition.</param>
 /// <param name="theValue">The value.</param>
 /// <param name="theParentStruct">The parent struct.</param>
 public AttributeValue(AttributeDefinition theDefinition, Value theValue, StructureValue theParentStruct)
 {
     Definition = theDefinition;
     Name = theDefinition.Name;
     Value = theValue;
     ParentStruct = theParentStruct;
 }
        private string[] HandleLtFrame(StructureValue map27FrameStruct, double timestamp, string direction)
        {
            List<string> analysisReports = null;

            AttributeValue nsAttribute = (AttributeValue)map27FrameStruct.Attributes[1];

            ulong rxFrameNs = nsAttribute.Value.GetUlongValue();

            if (rxFrameNs == Nr)
            {
                Nr = Nr.PlusOneMod256();
            }
            else
            {
                if (rxFrameNs == Nr.LessOneMod256())
                {
                    // Retransmission of previous frames
                    analysisReports = AddStringToList(analysisReports, string.Format("{0} Retransmission N(S) = {1} ({2:F4}s)", direction, rxFrameNs, (timestamp - m_PreviousLtFrameTimestamp)));
                }
                else
                {
                    // Out of sequence frame
                    analysisReports = AddStringToList(analysisReports, string.Format("{0} Out of sequence frame: Current N(R) = {1}, received N(S) = {2}", direction, Nr, rxFrameNs));
                }
            }

            m_PreviousLtFrameTimestamp = timestamp;

            return analysisReports == null ? null : analysisReports.ToArray();
        }
        internal string[] HandleFrame(StructureValue map27SignalStruct, double timestamp, string direction)
        {
            AttributeValue map27FrameAttribute = (AttributeValue)map27SignalStruct.Attributes[0];
            StructureValue map27FrameStruct = (StructureValue)map27FrameAttribute.Value;

            string[] analysisReports = null;

            switch (map27FrameAttribute.Name)
            {
                case "LR":
                    Map27LinkState = Map27LinkState.LinkWait;
                    Nr = 1;
                    Ns = 0;
                    break;
                case "LA":
                    Map27LinkState = Map27LinkState.Ready;
                    break;
                case "LT":
                    analysisReports = HandleLtFrame(map27FrameStruct, timestamp, direction);
                    break;
            }

            return analysisReports;
        }
        /// <summary>
        /// Determines whether the specified value is the end marker
        /// </summary>
        /// <param name="theStructValue">The struct value.</param>
        /// <returns>
        ///   <c>true</c> if the specified value is the end marker; otherwise, <c>false</c>.
        /// </returns>
        private static bool IsEndMarker(StructureValue theStructValue)
        {
            if (!theStructValue.IsTlvStructure)
            {
                return false;
            }

            // End marker for a sequence of TLV items signalled by length and type attributes being zero
            bool isEndMarker = true;

            AttributeValue typeAttribute = theStructValue.Attributes[theStructValue.GetTlvTypeAttributeName()];
            if (typeAttribute.Value.FundamentalType.TypeId == TypeId.EnumType)
            {
                EnumValue enumValue = typeAttribute.Value as EnumValue;
                if (enumValue.IntegerValue != 0)
                {
                    isEndMarker = false;
                }
            }

            AttributeValue lengthAttribute = theStructValue.Attributes[theStructValue.GetTlvLengthAttributeName()];
            if (lengthAttribute.Value.FundamentalType.TypeId == TypeId.BaseType)
            {
                BaseTypeValue baseValue = lengthAttribute.Value as BaseTypeValue;
                int length = baseValue.IsSigned ? (int)baseValue.SignedValue : (int)baseValue.UnsignedValue;
                if (length != 0)
                {
                    isEndMarker = false;
                }
            }

            return isEndMarker;
        }
        /// <summary>
        /// Gets the discriminator value.
        /// </summary>
        /// <param name="theParentStruct">The parent struct.</param>
        /// <returns>Discriminator value</returns>
        public int GetDiscriminatorValue(StructureValue theParentStruct)
        {
            Value discriminatorValue = theParentStruct.Attributes[Discriminator.Name].Value;
            int discriminatorValueAsInteger = 0;
            if (discriminatorValue.FundamentalType.TypeId == TypeId.EnumType)
            {
                EnumValue discriminatorValueAsEnum = discriminatorValue as EnumValue;
                discriminatorValueAsInteger = discriminatorValueAsEnum.IntegerValue;
            }
            else if (discriminatorValue.FundamentalType.TypeId == TypeId.BaseType)
            {
                BaseTypeValue discriminatorValueAsBaseType = discriminatorValue as BaseTypeValue;
                discriminatorValueAsInteger = discriminatorValueAsBaseType.IsSigned ?
                    (int)discriminatorValueAsBaseType.SignedValue : (int)discriminatorValueAsBaseType.UnsignedValue;
            }
            else
            {
                throw new DataDictionaryException("SwitchDefinition {0}: DiscriminatorValue {1} is neither enum nor base type",
                    Name, discriminatorValue.FundamentalType.Name);
            }

            return discriminatorValueAsInteger;
        }
        /// <summary>
        /// Gets the switch case definition corresponding to the value of the discriminator in the parent structure
        /// or null if there's no match
        /// </summary>
        /// <param name="theParentStruct">The parent structure</param>
        /// <returns>The switch case definition corresponding to the value of the discriminator in the parent structure</returns>
        public SwitchCaseDefinition GetSwitchCaseDefinition(StructureValue theParentStruct)
        {
            SwitchCaseDefinition theCaseDefinition = null;
            int discriminatorValue = GetDiscriminatorValue(theParentStruct);
            bool valueFound = Cases.TryGetValue(discriminatorValue, out theCaseDefinition);

            if (!valueFound)
            {
                throw new DataDictionaryException("Parent {2} Case {0}: value {1} not found",
                    this.Name, discriminatorValue, theParentStruct.FundamentalType.Name);
            }

            return theCaseDefinition;
        }
 private static void ShowStructOnSingleLine(StringBuilder sb, StructureValue theStruct)
 {
     foreach (var attribute in theStruct.Attributes)
     {
         StructureValue theStructureValue = attribute.Value as StructureValue;
         EnumValue theEnumValue = null;
         if (theStructureValue != null)
         {
             sb.Append("{");
             ShowStructOnSingleLine(sb, theStructureValue);
             sb.Append("} ");
         }
         else if ((theEnumValue = attribute.Value as EnumValue) != null)
         {
             sb.AppendFormat("{0}:{1} ", attribute.Name, theEnumValue.StringValue, theEnumValue.IntegerValue);
         }
         else
         {
             sb.AppendFormat("{0}:{1} ", attribute.Name, attribute.Value);
         }
     }
 }
        private void ShowStructOnMultipleLines(StringBuilder sb, StructureValue theStruct, int indentCount)
        {
            string indentString = string.Format("\n{0}", new string(' ', indentCount));

            foreach (var attribute in theStruct.Attributes)
            {
                StructureValue theStructureValue = attribute.Value as StructureValue;
                EnumValue theEnumValue = null;
                if (theStructureValue != null)
                {
                    //sb.AppendFormat("{0}{{", indentString);
                    ShowStructOnMultipleLines(sb, theStructureValue, indentCount + 2);
                    //sb.AppendFormat("{0}}} ", indentString);
                }
                else if ((theEnumValue = attribute.Value as EnumValue) != null)
                {
                    sb.AppendFormat("{0}{1}:{2} ({3}) ", indentString, attribute.Name, theEnumValue.StringValue, theEnumValue.IntegerValue);
                }
                else
                {
                    sb.AppendFormat("{0}{1}:{2} ", indentString, attribute.Name, attribute.Value);
                }
            }
        }
        private void ShowTapFrameOnMultipleLines(StringBuilder sb, StructureValue tapFrameStruct, int indentCount)
        {
            string indentString = string.Format("\n{0}", new string(' ', indentCount));
            sb.AppendFormat("{0}{1} Block:{2} Count:{3} Command:{4}",
                indentString,
                "TAP",  // GetIntegerValue(tapFrameStruct.Attributes["Type"].Value),
                GetIntegerValue(tapFrameStruct.Attributes["Block"].Value),
                GetIntegerValue(tapFrameStruct.Attributes["Count"].Value),
                GetEnumValue(tapFrameStruct.Attributes["Command"].Value));

            if (tapFrameStruct.Attributes.Count == 5 && tapFrameStruct.Attributes[4].Value is StructureValue)
            {
                //sb.AppendFormat("{0}{{", indentString);
                ShowStructOnMultipleLines(sb, (StructureValue)tapFrameStruct.Attributes[4].Value, indentCount + 2);
                //sb.AppendFormat("{0}}} ", indentString);
            }
        }
 /// <summary>
 /// Encodes the type of the struct.
 /// </summary>
 /// <param name="structureValue">The structure value.</param>
 /// <param name="signalText">The signal text.</param>
 /// <param name="prefix">The prefix.</param>
 /// <param name="valueName">Name of the value.</param>
 private void EncodeStructType(StructureValue structureValue, StringBuilder signalText, string prefix, string valueName)
 {
     signalText.AppendFormat("{0}{1} {2}:\n", prefix, structureValue.InitialType.Name, valueName);
     foreach (var attribute in structureValue.Attributes)
     {
         EncodeSignalElement(attribute.Value, signalText, prefix, attribute.Name);
     }
 }