Example #1
0
        // REC: The PopulateQueue method is a recursive function
        // that loads all of the elements in a FixCollection into
        // an instance of a SrcField queue so that the validator
        // can then process all the elements sequentially:
        private void PopulateQueue(Queue <SrcField> queue, FixCollection elements)
        {
            foreach (IFixElement element in elements)
            {
                if (element is FixField)
                {
                    FixField msgField = element as FixField;
                    if (msgField != null)
                    {
                        // REC: Attempt to resolve the field's name
                        // by retrieving it using it's tag:
                        string fieldName = ResolveFieldName(msgField.Tag.ToString());
                        if (fieldName == null)
                        {
                            fieldName = "Unresolved";
                        }

                        // REC: Create a new instance of SrcField that
                        // represents the contents of this field:
                        SrcField srcField = new SrcField();
                        srcField.Tag   = msgField.Tag.ToString();
                        srcField.Name  = fieldName;
                        srcField.Value = msgField.Content;

                        queue.Enqueue(srcField);
                    }
                }
                else if (element is FixGroup)
                {
                    FixGroup msgGroup = element as FixGroup;
                    if (msgGroup != null)
                    {
                        string groupName = ResolveFieldName(msgGroup.Tag.ToString());
                        if (groupName == null)
                        {
                            groupName = "Unresolved";
                        }

                        // REC: Create a new instance of SrcField that
                        // represents the contents of the group:
                        SrcField srcField = new SrcField();
                        srcField.Tag   = msgGroup.Tag.ToString();
                        srcField.Name  = groupName;
                        srcField.Value = msgGroup.Content;

                        queue.Enqueue(srcField);

                        foreach (FixCollection instance in msgGroup.Instances)
                        {
                            PopulateQueue(queue, instance);
                        }
                    }
                }
            }
        }
Example #2
0
        // REC: The ProcessElements method compares the contents
        // of a message to the corresponding message layout and
        // returns a list of validation result entries for each
        // of the fields that were encountered in the message:
        private List <FixValidationResult> ProcessElements(Queue <SrcField> queue, MsgLayout layout)
        {
            List <FixValidationResult> result = new List <FixValidationResult>();

            int hdrIndex = 0;
            int msgIndex = 0;
            int trlIndex = 0;

            while (queue.Count > 0)
            {
                bool processed = false;

                // REC: Retrieve the next source field from
                // the sequential queue of message fields:
                SrcField current = queue.Dequeue();

                // REC: Scan the result set for a placeholder
                // for this field before checking the template:
                bool fieldOOS = false;
                foreach (FixValidationResult fvr in result)
                {
                    // REC: If the current field's tag matches the
                    // tag in the validation result, and the result's
                    // validation code is set to Field_Missing, then
                    // the result entry is a placeholder for the field:

                    if (fvr.ResultCode == FixValidationCode.Field_Missing)
                    {
                        if (current.Tag == fvr.FieldTag)
                        {
                            // REC: The fact that this entry is a placeholder
                            // means that it was previously passed over when
                            // a field was being matched. This means that the
                            // current field is out of sequence, or it would
                            // already be in the validation result set:
                            fvr.FieldValue = current.Value;

                            fvr.ResultCode = FixValidationCode.Field_Present;
                            fvr.ResultText = "Field Present";
                            if (fieldOOS == true)
                            {
                                fvr.ResultCode = FixValidationCode.Field_OOS;
                                fvr.ResultText = "Out of Sequence";
                            }

                            //VerifyFieldType(current, fvr);

                            if (fvr.Nodes.Count > 0)
                            {
                                fvr.Nodes = ValidateGroup(queue, fvr);
                            }

                            // REC: Remove the validation result from its
                            // current position in the result set...
                            result.Remove(fvr);

                            // REC: ...and add it to the end of the result
                            // set since that's where it was encountered in
                            // the source message:
                            result.Add(fvr);

                            // REC: Set the processed flag to true to indicate
                            // that this field in the source message has now
                            // been completely processed:
                            processed = true;
                            break;
                        }
                        else
                        {
                            // REC: The field is missing, but it doesn't match
                            // the current one. If the missing field is also a
                            // required field, then set the OOS flag:
                            if (fvr.FieldRequired == true)
                            {
                                fieldOOS = true;
                            }
                        }
                    }
                }

                // REC: If the current field in the message wasn't found
                // in the result set, as a placeholder, then scan the
                // elements in the message header for a match:
                if (processed == false)
                {
                    while (hdrIndex != layout.Header.Count)
                    {
                        // REC: Create a copy of the entry in the
                        // message header layout:
                        FixValidationResult src = layout.Header[hdrIndex++];
                        FixValidationResult dst = src.Clone() as FixValidationResult;

                        // REC: Add the copy of the entry to the
                        // result set in anticipation of the field
                        // being matched. If it's not matched, then
                        // the entry will act as a placeholder:
                        result.Add(dst);

                        if (current.Tag == src.FieldTag)
                        {
                            dst.FieldValue = current.Value;
                            dst.ResultCode = FixValidationCode.Field_Present;
                            dst.ResultText = "Field Present";

                            // REC: If the entry in the layout is a
                            // repeating group header, then attempt
                            // to validate as many instances of the
                            // repeating group as are indicated by
                            // the value of in the message's field:
                            if (src.Nodes.Count > 0)
                            {
                                dst.Nodes      = ValidateGroup(queue, dst);
                                dst.ResultCode = FixValidationCode.Group_Present;
                                dst.ResultText = "Group Present";
                            }

                            processed = true;
                        }
                    }

                    // REC: If the current field wasn't found in the
                    // result set, or in the layout for the message's
                    // header elements, then attempt to locate it in
                    // the message's content elements:
                    if (processed == false)
                    {
                        while (msgIndex != layout.Message.Count)
                        {
                            FixValidationResult src = layout.Message[msgIndex++];
                            FixValidationResult dst = src.Clone() as FixValidationResult;

                            // REC: Add the copy of the entry to the
                            // result set in anticipation of the field
                            // being matched. If it's not matched, then
                            // the entry will act as a placeholder:
                            result.Add(dst);

                            if (current.Tag == src.FieldTag)
                            {
                                dst.FieldValue = current.Value;
                                dst.ResultCode = FixValidationCode.Field_Present;
                                dst.ResultText = "Field Present";

                                // REC: If the entry in the layout is a
                                // repeating group header, then attempt
                                // to validate as many instances of the
                                // repeating group as are indicated by
                                // the value of in the message's field:
                                if (src.Nodes.Count > 0)
                                {
                                    dst.Nodes      = ValidateGroup(queue, dst);
                                    dst.ResultCode = FixValidationCode.Group_Present;
                                    dst.ResultText = "Group Present";
                                }

                                processed = true;
                                break;
                            }
                        }
                    }

                    // REC: If the field wasn't found in the header
                    // or in the body, then scan the message trailer:
                    if (processed == false)
                    {
                        // REC: Note that the trailer elements don't
                        // get copied into the result set unless there
                        // is a match for one of them; these elements
                        // should always be placed at the end of the
                        // result set if there is no match for them:
                        for (int i = trlIndex; i != layout.Trailer.Count; i++)
                        {
                            if (current.Tag == layout.Trailer[i].FieldTag)
                            {
                                while (trlIndex != layout.Trailer.Count)
                                {
                                    FixValidationResult src = layout.Trailer[trlIndex++];
                                    FixValidationResult dst = src.Clone() as FixValidationResult;

                                    result.Add(dst);
                                    if (current.Tag == src.FieldTag)
                                    {
                                        dst.FieldValue = current.Value;
                                        dst.ResultCode = FixValidationCode.Field_Present;
                                        dst.ResultText = "Field Present";

                                        if (src.Nodes.Count > 0)
                                        {
                                            dst.Nodes = ValidateGroup(queue, dst);

                                            dst.ResultCode = FixValidationCode.Group_Present;
                                            dst.ResultText = "Group Present";
                                        }

                                        processed = true;
                                        break;
                                    }
                                }
                            }
                        }

                        // REC: If the field wasn't found in the trailer
                        // layout, then it's a UDF and can just be added
                        // to the result set where it's found:
                        if (processed == false)
                        {
                            FixValidationResult dst = new FixValidationResult();
                            dst.FieldTag   = current.Tag;
                            dst.FieldName  = current.Name;
                            dst.FieldValue = current.Value;
                            dst.ResultCode = FixValidationCode.Field_Present;
                            dst.ResultText = "User-defined Field";

                            result.Add(dst);
                        }
                    }
                }
            }

            return(result);
        }
Example #3
0
        // REC: The ValidateGroup method validates a repeating group
        // that is encountered in the source message, against the
        // group's layout as defined in the FIX dictionary:
        private List <FixValidationResult> ValidateGroup(Queue <SrcField> queue, FixValidationResult group)
        {
            List <FixValidationResult> result = new List <FixValidationResult>();

            List <FixValidationResult> template = new List <FixValidationResult>();

            // REC: Attempt to convert the group's value
            // from a string into an integer that indicates
            // the number of repeating groups that follow:
            int nCount = -1;

            if (int.TryParse(group.FieldValue, out nCount) == false)
            {
                // REC: If the group entry's value is not an
                // integer, the repeating groups cannot be
                // parsed from the message:
                return(result);
            }
            else
            {
                for (int i = 0; i != nCount; i++)
                {
                    foreach (FixValidationResult srcFvr in group.Nodes)
                    {
                        FixValidationResult child = srcFvr.Clone() as FixValidationResult;
                        template.Add(child);
                    }
                }
            }

            // REC: Attempt to validate N instances of the
            // group, as defined by the group's template:
            while (queue.Count > 0)
            {
                bool processed = false;

                // REC: Commented this out - we need to peek
                // at the message rather than dequeue it:
                //SrcField current = queue.Dequeue();
                SrcField current = queue.Peek();

                if (template.Count > 0)
                {
                    // REC: Maintain a remove list for the template
                    // elements since lists cannot be modified during
                    // an enumeration over their elements:
                    List <FixValidationResult> listRemove = new List <FixValidationResult>();
                    foreach (FixValidationResult r in template)
                    {
                        // REC: Add the current element to the remove
                        // list so that it can be removed from the template
                        // after being added to the result set:
                        listRemove.Add(r);

                        // REC: Move the template element into the
                        // validation result set:
                        result.Add(r);

                        if (current.Tag == r.FieldTag)
                        {
                            r.FieldValue = current.Value;
                            r.ResultCode = FixValidationCode.Field_Present;
                            r.ResultText = "Field Present";

                            // REC: Since a match has been found, the element
                            // can be removed from the queue at this point:
                            queue.Dequeue();

                            if (r.Nodes.Count > 0)
                            {
                                r.Nodes = ValidateGroup(queue, r);
                            }

                            processed = true;
                            break;
                        }
                    }

                    foreach (FixValidationResult target in listRemove)
                    {
                        template.Remove(target);
                    }
                }

                if (processed == false)
                {
                    bool fieldOOS = false;
                    foreach (FixValidationResult m in result)
                    {
                        if (m.ResultCode == FixValidationCode.Field_Missing)
                        {
                            if (current.Tag == m.FieldTag)
                            {
                                m.FieldValue = current.Value;
                                m.ResultCode = FixValidationCode.Field_Present;
                                m.ResultText = "Field Present";
                                if (fieldOOS == true)
                                {
                                    m.ResultCode = FixValidationCode.Field_OOS;
                                    m.ResultText = "Out of Sequence";
                                }

                                // REC: Since a match has been found, the element
                                // can be removed from the queue at this point:
                                queue.Dequeue();

                                if (m.Nodes.Count > 0)
                                {
                                    m.Nodes = ValidateGroup(queue, m);
                                }

                                processed = true;
                                result.Remove(m);
                                result.Add(m);
                                break;
                            }
                            else
                            {
                                // REC: The field is missing, but it doesn't match
                                // the current one. If the missing field is also a
                                // required field, then set the OOS flag:
                                if (m.FieldRequired == true)
                                {
                                    fieldOOS = true;
                                }
                            }
                        }
                    }
                }

                if (processed == false)
                {
                    break;
                }
            }

            return(result);
        }
Example #4
0
        // REC: The PopulateQueue method is a recursive function
        // that loads all of the elements in a FixCollection into
        // an instance of a SrcField queue so that the validator
        // can then process all the elements sequentially:
        private void PopulateQueue(Queue<SrcField> queue, FixCollection elements)
        {
            foreach (IFixElement element in elements)
            {
                if (element is FixField)
                {
                    FixField msgField = element as FixField;
                    if (msgField != null)
                    {
                        // REC: Attempt to resolve the field's name
                        // by retrieving it using it's tag:
                        string fieldName = ResolveFieldName(msgField.Tag.ToString());
                        if (fieldName == null)
                        {
                            fieldName = "Unresolved";
                        }

                        // REC: Create a new instance of SrcField that
                        // represents the contents of this field:
                        SrcField srcField = new SrcField();
                        srcField.Tag = msgField.Tag.ToString();
                        srcField.Name = fieldName;
                        srcField.Value = msgField.Content;

                        queue.Enqueue(srcField);
                    }
                }
                else if (element is FixGroup)
                {
                    FixGroup msgGroup = element as FixGroup;
                    if (msgGroup != null)
                    {
                        string groupName = ResolveFieldName(msgGroup.Tag.ToString());
                        if (groupName == null)
                        {
                            groupName = "Unresolved";
                        }

                        // REC: Create a new instance of SrcField that
                        // represents the contents of the group:
                        SrcField srcField = new SrcField();
                        srcField.Tag = msgGroup.Tag.ToString();
                        srcField.Name = groupName;
                        srcField.Value = msgGroup.Content;

                        queue.Enqueue(srcField);

                        foreach (FixCollection instance in msgGroup.Instances)
                        {
                            PopulateQueue(queue, instance);
                        }
                    }
                }
            }
        }