예제 #1
0
 internal void AddField(int seq, CompiledMessageField cmf)
 {
     _fields.Add(seq, cmf);
     if (cmf.Content is MessageBitMap)
     {
         ((MessageBitMap)cmf.Content).FieldSeq = seq;
         _bitMap.Add((MessageBitMap)cmf.Content);
     }
 }
예제 #2
0
        public byte[] GetAllBytes()
        {
            ICollection <int> bitOnList = _fields.Keys;

            _bitMap.SetBitOn(bitOnList);

            //Don't include null BitMap (no bit on).
            List <MessageBitMap> bitMapList = _bitMap.ToList();

            for (int x = bitMapList.Count - 1; x >= 1; x--) //Excludes primary BitMap when checking
            {
                if (bitMapList[x].IsNull)
                {
                    _bitMap.SetBit(bitMapList[x].FieldSeq, false);
                }
            }

            int length = 0;

            foreach (MessageElement hdr in _headers)
            {
                length += hdr.Length;
            }
            foreach (CompiledMessageField fld in _fields.Values)
            {
                if (fld.Content is MessageBitMap && ((MessageBitMap)fld.Content).IsNull)
                {
                    continue;                                                                      //null BitMap not included
                }
                length += fld.Length;
            }

            byte[] bytes  = new byte[LengthHeader + length];
            byte[] lenHdr = MessageUtility.IntToBytes((ulong)length, LengthHeader);
            Array.Copy(lenHdr, 0, bytes, 0, LengthHeader);

            int i = LengthHeader;

            foreach (MessageElement hdr in _headers)
            {
                if (hdr.BytesValue == null)
                {
                    continue;
                }
                Array.Copy(hdr.BytesValue, 0, bytes, i, hdr.Length);
                i += hdr.Length;
            }

            //int[] bits = bitOnList.ToArray();
            //Array.Sort(bits); //Has been ordered by XmlConfigParser
            ICollection <int> bits = bitOnList;

            foreach (int j in bits)
            {
                CompiledMessageField fld = _fields[j];
                if (fld.Content.BytesValue == null)
                {
                    continue;
                }
                if (fld.Content is MessageBitMap && ((MessageBitMap)fld.Content).IsNull)
                {
                    continue;
                }
                if (fld.Header != null)
                {
                    Array.Copy(fld.Header, 0, bytes, i, fld.HeaderLength);
                }
                Array.Copy(fld.Content.BytesValue, 0, bytes, i + fld.HeaderLength, fld.Length - fld.HeaderLength);
                i += fld.Length;
            }
            return(bytes);
        }
예제 #3
0
        private void CompileFields()
        {
            String[] locMsgs = new String[] { "model element (id=" + (_modelCfg.Id == null?"":_modelCfg.Id) + ", class="
                                              + (_modelCfg.ClassType == null?"":_modelCfg.ClassType.FullName) + ") and property (name=", null, ")" };

            foreach (KeyValuePair <int, MessageFieldConfig> kvpFldCfg in _msgCfg.Fields)
            {
                MessageFieldConfig  fldCfg  = kvpFldCfg.Value;
                ModelPropertyConfig propCfg = _modelCfg.Properties.ContainsKey(fldCfg.Seq) ? _modelCfg.Properties[fldCfg.Seq] : null;
                MessageField        fld     = (MessageField)Activator.CreateInstance(fldCfg.FieldType);
                Object propVal = propCfg == null ? null : propCfg.PropertyInfo.GetValue(_model, null);
                byte[] fldVal  = null;

                if (fldCfg.FieldType != typeof(NullMessageField) && fldCfg.FieldType != typeof(MessageBitMap))
                {
                    if (/*propCfg==null ||*/ propVal == null)
                    {
                        if (_reqMsg != null && fldCfg.FromRequest)
                        {
                            IDictionary <int, MessageField> fields = _reqMsg.ParsedMessage.Fields;
                            fldVal = fields.ContainsKey(fldCfg.Seq) ? fields[fldCfg.Seq].BytesValue : null;
                        }
                    }
                    else if (propCfg.Tlv != null || !String.IsNullOrEmpty(propCfg.TlvTagName))
                    {
                        locMsgs[1] = propCfg.PropertyInfo.Name;
                        fldVal     = CompileTlv(propCfg.Tlv, propCfg.TlvTagName, propCfg.TlvLengthBytes, propVal,
                                                String.Join("", locMsgs));
                    }
                    else if (propCfg.BitContent != null)
                    {
                        fldVal = CompileBitContent(propCfg.BitContent, propVal);
                    }
                    else if (fldCfg.GetFieldBytesFunc != null)
                    {
                        fldVal = (byte[])fldCfg.GetFieldBytesFunc.DynamicInvoke(propVal);
                    }

                    byte[] header = null;
                    if (fldVal != null || (propVal != null && propCfg.SetValueFromProperty != null)) //propCfg != null ==> propVal != null
                    {
                        if (fldCfg.Length >= 0)
                        {
                            if (fldVal != null && fldVal.Length != fld.GetBytesLengthFromActualLength(fldCfg.Length))
                            {
                                throw new MessageCompilerException(
                                          "Incompatible length of bytes between compiled bytes length "
                                          + "and the defined one in configuration. Check the config for model (class="
                                          + _modelCfg.ClassType.FullName
                                          + ") and property (name=" + (propCfg != null ? propCfg.PropertyInfo.Name : "")
                                          + ") and also its mapped field in message (id="
                                          + _msgCfg.Id + ")");
                            }
                            fld.Length = fldCfg.Length;
                        }
                        if (propVal is NibbleList)
                        {
                            fld.IsOdd = ((NibbleList)propVal).IsOdd;
                        }
                        if (propCfg != null)
                        {
                            fld.FracDigits = propCfg.FracDigits;
                        }
                        fld.VarLength = (fldCfg.Length < 0);

                        if (fldVal != null)
                        {
                            fld.SetValue(fldVal);
                        }
                        else //if (propVal != null /* && propCfg != null */ && propCfg.SetValueFromProperty != null)
                        {
                            try
                            {
                                Type paramType = propCfg.SetValueFromProperty.GetParameters()[0].ParameterType;
                                propVal = Util.GetAssignableValue(paramType, propVal);
                                propCfg.SetValueFromProperty.Invoke(fld, new Object[] { propVal });
                            }
                            catch (Exception ex)
                            {
                                throw new MessageCompilerException(
                                          "Cannot convert a property value to the coresponding message field. "
                                          + "Check the config for model (class=" + _modelCfg.ClassType.FullName
                                          + ") and property (name=" + propCfg.PropertyInfo.Name
                                          + ") and also its mapped field in message (id="
                                          + _msgCfg.Id + ")", ex);
                            }
                        }

                        if (fldCfg.LengthHeader >= 0) //It must be fld.VarLength == true (See XmlConfigParser)
                        {
                            header = MessageUtility.IntToHex((ulong)fld.Length, fldCfg.LengthHeader);
                        }

                        CompiledMessageField cmf = new CompiledMessageField();
                        cmf.Header  = header;
                        cmf.Content = fld;
                        _struct.AddField(fldCfg.Seq, cmf);
                    }
                }
                else //field is NULL type or BitMap
                {
                    CompiledMessageField cmf = new CompiledMessageField();
                    cmf.Header  = null;
                    fld.Length  = fldCfg.Length;
                    cmf.Content = fld;
                    _struct.AddField(fldCfg.Seq, cmf);
                }
            }
        }