예제 #1
0
        /// <summary>
        /// The ResolveGroupReference function resolves a group
        /// reference against the information in the dictionary.
        /// </summary>
        /// <param name="reference">
        /// The group reference to resolve.
        /// </param>
        /// <returns>
        /// An instance of FixDxResolvedGroup that contains all of
        /// the resolved information about the group.
        /// </returns>
        private FixDxResolvedGroup ResolveGroupReference(FixDxGroupReference reference)
        {
            if (string.IsNullOrEmpty(reference.Name))
            {
                string error = "The supplied group reference's name is null or empty.";
                throw new ArgumentException(error);
            }
            else
            {
                if (!_mapFieldsByName.ContainsKey(reference.Name))
                {
                    string error = string.Format("Repeating group {0}'s field couldn't be resolved.", reference.Name);
                    throw new ArgumentException(error);
                }
                else
                {
                    FixDxField         dxField = _mapFieldsByName[reference.Name];
                    FixDxResolvedGroup result  = new FixDxResolvedGroup(dxField.Tag, dxField.Name, reference.Required);
                    foreach (IFixDxElement element in Resolve(reference.Elements))
                    {
                        result.Elements.Add(element);
                    }

                    return(result);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// The ExportFields method is invoked to convert all of
        /// the field elements in an instance of a VersaFix data
        /// dictionary into corresponding entries in an instance
        /// of an XML representation of a QuickFix dictionary.
        /// </summary>
        /// <param name="src">
        /// The source dictionary for the field definitions.
        /// </param>
        /// <param name="dst">
        /// The target dictionary for the field definitions.
        /// </param>
        private void ExportFields(FixDictionary src, XmlQfxDictionary dst)
        {
            foreach (IFixDxElement dxElement in src.Fields)
            {
                FixDxField dxField = dxElement as FixDxField;
                if (dxField != null)
                {
                    XmlQfxField xmlField = new XmlQfxField();
                    xmlField.Name   = dxField.Name;
                    xmlField.Number = dxField.Tag.ToString();
                    xmlField.Type   = dxField.Type;

                    // REC: QuickFix stores the enumerators for each
                    // field inside the field definition, so we have
                    // to check if there is an enumeration associated
                    // with this field and add the enumeration to the
                    // field definition if one is found:
                    FixDxEnumeration dxEnum = src.Enums.GetElement(dxField.Name) as FixDxEnumeration;
                    if (dxEnum != null)
                    {
                        foreach (FixDxEnumerator dxEnumerator in dxEnum.Enumerators)
                        {
                            XmlQfxFieldEnumerator xmlEnumerator = new XmlQfxFieldEnumerator();
                            xmlEnumerator.Enum        = dxEnumerator.Value;
                            xmlEnumerator.Description = dxEnumerator.Description;
                            xmlField.Enumeration.Add(xmlEnumerator);
                        }
                    }

                    dst.Fields.Add(xmlField);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// The CloneField method creates a copy of an instance
        /// of a dictionary field entry.
        /// </summary>
        /// <param name="source">
        /// The dictionary field entry to duplicate.
        /// </param>
        /// <returns>
        /// The resulting clone of the supplied element.
        /// </returns>
        private FixDxField CloneField(FixDxField source)
        {
            FixDxField result = new FixDxField(source.Tag, source.Name, source.Type);

            result.Enumeration = source.Enumeration;
            result.LengthCoded = source.LengthCoded;
            result.LengthField = source.LengthField;
            return(result);
        }
예제 #4
0
        /// <summary>
        /// The ResolveFieldName function resolves a field reference
        /// against the information in the dictionary.
        /// </summary>
        /// <param name="reference">
        /// The field reference to resolve.
        /// </param>
        /// <returns>
        /// An instance of FixDxResolvedField that contains all of
        /// the resolved information about the field.
        /// </returns>
        private FixDxResolvedField ResolveFieldReference(FixDxFieldReference reference)
        {
            if (string.IsNullOrEmpty(reference.Name))
            {
                string error = "The supplied field reference has an empty or null name.";
                throw new ArgumentException(error);
            }
            else
            {
                if (!_mapFieldsByName.ContainsKey(reference.Name))
                {
                    string error = string.Format("The field reference {0} could not be resolved!", reference.Name);
                    throw new ArgumentException(error);
                }
                else
                {
                    FixDxField dxField = _mapFieldsByName[reference.Name];
                    if (dxField.LengthCoded == false)
                    {
                        FixDxResolvedField result = new FixDxResolvedField(dxField.Tag, dxField.Name,
                                                                           dxField.Type, reference.Required);

                        return(result);
                    }
                    else
                    {
                        // REC: The field is length encoded, so the field that
                        // contains the content length for this field also has
                        // to be resolved from the dictionary:
                        if (_mapFieldsByName.ContainsKey(dxField.LengthField))
                        {
                            FixDxField         dxLength = _mapFieldsByName[dxField.LengthField];
                            FixDxResolvedField result   = new FixDxResolvedField(dxField.Tag, dxField.Name,
                                                                                 dxField.Type, dxLength.Tag, reference.Required);

                            return(result);
                        }
                        else
                        {
                            string error = string.Format("The field reference {0}'s length field {1} couldn't be resolved!",
                                                         dxField.Name, dxField.LengthField);

                            throw new ArgumentException(error);
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// The PopulateFields method is invoked to convert all of
        /// the FIX field definitions in an instance of a QuickFix
        /// dictionary into their corresponding representations as
        /// elements of a VersaFix dictionary.
        /// </summary>
        /// <param name="src">
        /// The XML representation of a QuickFix dictionary that the
        /// fields are to be copied from.
        /// </param>
        /// <param name="dst">
        /// The VersaFix data dictionary that the field definitions
        /// are to be copied into.
        /// </param>
        private void PopulateFields(XmlQfxDictionary src, FixDictionary dst)
        {
            foreach (object field in src.Fields)
            {
                XmlQfxField xmlField = field as XmlQfxField;
                if (xmlField != null)
                {
                    if (!string.IsNullOrEmpty(xmlField.Name))
                    {
                        if (!string.IsNullOrEmpty(xmlField.Number))
                        {
                            int        nTag    = int.Parse(xmlField.Number);
                            FixDxField dxField = new FixDxField(nTag, xmlField.Name);

                            // REC: Determine if there's an enumeration that corresponds
                            // to the name of this field:
                            if (dst.Enums.GetElement(xmlField.Name) != null)
                            {
                                // REC: If an enumeration exists for this field
                                // then assign it to the VersaFix field:
                                dxField.Enumeration = xmlField.Name;
                            }

                            // REC: Assign the field's data type directly
                            // from the data type in the QuickFix field.
                            dxField.Type = xmlField.Type;

                            dst.Fields.Add(dxField);

                            // REC: The QuickFix dictionaries do not provide
                            // a separate section for data types, so we need
                            // to just copy the data type directly from each
                            // of the QuickFix fields into the data types of
                            // the VersaFix dictionary:
                            if (!string.IsNullOrEmpty(xmlField.Type))
                            {
                                IFixDxElement exists = dst.DataTypes.GetElement(xmlField.Type);
                                if (exists == null)
                                {
                                    dst.DataTypes.Add(new FixDxDataType(xmlField.Type));
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #6
0
 /// <summary>
 /// The PopulateFields method populates the fields section
 /// of the supplied VFX dictionary with all of the fields
 /// that are found in the supplied XML dictionary.
 /// </summary>
 /// <param name="source">
 /// The source dictionary for the field elements.
 /// </param>
 /// <param name="target">
 /// The target dictionary for the converted elements.
 /// </param>
 private static void PopulateFields(XmlDictionary source, FixDictionary target)
 {
     foreach (XmlFixDxField src in source.Fields.Entries)
     {
         if (src.LengthField == null)
         {
             FixDxField dst = new FixDxField(src.Tag, src.Name, src.Type);
             dst.Enumeration = src.Enumeration;
             target.AddField(dst);
         }
         else
         {
             FixDxField dst = new FixDxField(src.Tag, src.Name, src.Type, src.LengthField);
             dst.Enumeration = src.Enumeration;
             target.AddField(dst);
         }
     }
 }
예제 #7
0
        /// <summary>
        /// The AddField method attempts to add an instance of
        /// a FIX field definition to the dictionary. If there
        /// is already an entry in the dictionary that has the
        /// same identifying criteria the ArgumentException is
        /// thrown and the method fails; It's not possible for
        /// the dictionary to replace a redundant field, since
        /// there may be an entry in the name-based index that
        /// corresponds to a field with a *different* tag.
        /// </summary>
        /// <param name="dxField">
        /// The FIX field definition that is to be added.
        /// </param>
        public void AddField(FixDxField dxField)
        {
            if (_mapFieldsByTag.ContainsKey(dxField.Tag))
            {
                string error = string.Format("Dictionary already contains a field with tag {0}.", dxField.Tag);
                throw new ArgumentException(error);
            }

            if (_mapFieldsByName.ContainsKey(dxField.Name))
            {
                string error = string.Format("Dictionary already contains a field named {0}.", dxField.Name);
                throw new ArgumentException(error);
            }

            _mapFieldsByTag.Add(dxField.Tag, dxField);
            _mapFieldsByName.Add(dxField.Name, dxField);

            _fields.Add(dxField);

            _fldElements.Add(dxField);
        }
예제 #8
0
 /// <summary>
 /// The CloneField method creates a copy of an instance
 /// of a dictionary field entry.
 /// </summary>
 /// <param name="source">
 /// The dictionary field entry to duplicate.
 /// </param>
 /// <returns>
 /// The resulting clone of the supplied element.
 /// </returns>
 private FixDxField CloneField(FixDxField source)
 {
     FixDxField result = new FixDxField(source.Tag, source.Name, source.Type);
     result.Enumeration = source.Enumeration;
     result.LengthCoded = source.LengthCoded;
     result.LengthField = source.LengthField;
     return result;
 }
예제 #9
0
        /// <summary>
        /// The AddField method attempts to add an instance of
        /// a FIX field definition to the dictionary. If there
        /// is already an entry in the dictionary that has the
        /// same identifying criteria the ArgumentException is
        /// thrown and the method fails; It's not possible for 
        /// the dictionary to replace a redundant field, since 
        /// there may be an entry in the name-based index that
        /// corresponds to a field with a *different* tag.
        /// </summary>
        /// <param name="dxField">
        /// The FIX field definition that is to be added.
        /// </param>
        public void AddField(FixDxField dxField)
        {
            if (_mapFieldsByTag.ContainsKey(dxField.Tag))
            {
                string error = string.Format("Dictionary already contains a field with tag {0}.", dxField.Tag);
                throw new ArgumentException(error);
            }

            if (_mapFieldsByName.ContainsKey(dxField.Name))
            {
                string error = string.Format("Dictionary already contains a field named {0}.", dxField.Name);
                throw new ArgumentException(error);
            }

            _mapFieldsByTag.Add(dxField.Tag, dxField);
            _mapFieldsByName.Add(dxField.Name, dxField);

            _fields.Add(dxField);

            _fldElements.Add(dxField);
        }
예제 #10
0
 /// <summary>
 /// The PopulateFields method populates the fields section
 /// of the supplied VFX dictionary with all of the fields
 /// that are found in the supplied XML dictionary.
 /// </summary>
 /// <param name="source">
 /// The source dictionary for the field elements.
 /// </param>
 /// <param name="target">
 /// The target dictionary for the converted elements.
 /// </param>
 private static void PopulateFields(XmlDictionary source, FixDictionary target)
 {
     foreach (XmlFixDxField src in source.Fields.Entries)
     {
         if (src.LengthField == null)
         {
             FixDxField dst = new FixDxField(src.Tag, src.Name, src.Type);
             dst.Enumeration = src.Enumeration;
             target.AddField(dst);
         }
         else
         {
             FixDxField dst = new FixDxField(src.Tag, src.Name, src.Type, src.LengthField);
             dst.Enumeration = src.Enumeration;
             target.AddField(dst);
         }
     }
 }
예제 #11
0
        /// <summary>
        /// The Resolve method attempts to resolve all of the
        /// element references in a collection to the entries
        /// that correspond to them.
        /// </summary>
        /// <param name="elements">
        /// The collection of dictionary elements to resolve.
        /// </param>
        /// <returns>
        /// The resulting collection of resolved elements.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if any elements in the collection that is
        /// supplied to the method cannot be resolved.
        /// </exception>
        public FixDxCollection Resolve(FixDxCollection elements)
        {
            FixDxCollection result = new FixDxCollection();

            // REC: Iterate over all of the elements in the collection
            // and determine how to resolve each of them:
            foreach (IFixDxElement dxElement in elements)
            {
                if (dxElement is FixDxFieldReference)
                {
                    FixDxFieldReference fieldReference = dxElement as FixDxFieldReference;
                    result.Add(ResolveFieldReference(fieldReference));
                }
                else if (dxElement is FixDxGroupReference)
                {
                    FixDxGroupReference groupReference = dxElement as FixDxGroupReference;
                    result.Add(ResolveGroupReference(groupReference));
                }
                else if (dxElement is FixDxBlockReference)
                {
                    FixDxBlockReference blockReference = dxElement as FixDxBlockReference;
                    // REC: Determine what type of block the reference
                    // is referring to (component or repeating):
                    if (string.IsNullOrEmpty(blockReference.Name))
                    {
                        string error = "The supplied block reference's name is null or empty.";
                        throw new ArgumentException(error);
                    }
                    else if (!_mapBlocksByName.ContainsKey(blockReference.Name))
                    {
                        string error = string.Format("The block reference {0} couldn't be resolved.", blockReference.Name);
                        throw new ArgumentException(error);
                    }
                    else
                    {
                        FixDxBlock dxBlock = _mapBlocksByName[blockReference.Name];
                        if (dxBlock.Type == FixDxBlockTypes.Component)
                        {
                            foreach (IFixDxElement element in Resolve(Expand(dxBlock.Elements)))
                            {
                                result.Add(element);
                            }
                        }
                        else if (dxBlock.Type == FixDxBlockTypes.Repeating)
                        {
                            // REC: Attempt to resolve the field that the repeating
                            // block references as the start field for the group:
                            if (string.IsNullOrEmpty(dxBlock.Field))
                            {
                                string error = string.Format("Repeating Block {0}'s start field is null or empty.", dxBlock.Field);
                                throw new ArgumentException(error);
                            }
                            else if (!_mapFieldsByName.ContainsKey(dxBlock.Field))
                            {
                                string error = string.Format("Repeating block {0}'s start field can't be resolved.", dxBlock.Field);
                                throw new ArgumentException(error);
                            }
                            else
                            {
                                FixDxField         dxField = _mapFieldsByName[dxBlock.Field];
                                FixDxResolvedGroup dxGroup = new FixDxResolvedGroup(dxField.Tag, dxField.Name, false);
                                foreach (IFixDxElement element in Resolve(Expand(dxBlock.Elements)))
                                {
                                    dxGroup.Elements.Add(element);
                                }

                                result.Add(dxGroup);
                            }
                        }
                    }
                }
            }

            // REC: Patch from RC - sanity check all elements in the result
            // to ensure that there are no unresolved references.
            foreach (IFixDxElement e in result)
            {
                if (e is FixDxFieldReference || e is FixDxGroupReference || e is FixDxFieldReference)
                {
                    throw new Exception("unresolved references exist in the resolved collection");
                }
            }

            return(result);
        }