Beispiel #1
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);
        }
Beispiel #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;
        }
Beispiel #3
0
        // REC: Validate an instance of the FixMessage class against
        // the header/message/trailer definition in the dictionaries:
        public List <FixValidationResult> Validate(FixMessage msg)
        {
            List <FixValidationResult> result = new List <FixValidationResult>();

            // REC: Build a queue of all of the FIX elements that
            // are contained in the message:
            Queue <SrcField> srcFields = new Queue <SrcField>();

            // REC: Add the elements that are in the message's
            // header to the queue of source fields:
            PopulateQueue(srcFields, msg.Header);

            // REC: Add the elements that are in the message's
            // body to the queue of source fields:
            PopulateQueue(srcFields, msg.Content);

            // REC: Add the elements that are in the message's
            // trailer to the queue of source fields:
            PopulateQueue(srcFields, msg.Trailer);


            // REC: Create the MsgLayout structure that defines
            // the layout of a message as it is defined in the
            // configured FIX dictionaries:
            MsgLayout msgLayout = new MsgLayout();

            // REC: The message layout's header entries are
            // copied from the cached list of entries that is
            // created when the validator is configured:
            foreach (FixValidationResult hdrEntry in _cachedHeader)
            {
                msgLayout.Header.Add(hdrEntry.Clone() as FixValidationResult);
            }

            // REC: The message layout's content entries are
            // only configured if the corresponding message
            // type can be found in the dictionaries:
            FixField fldMsgType = msg.Header.GetField(35);

            if (fldMsgType != null)
            {
                string strMsgType = fldMsgType.Content;
                foreach (FixDictionary dx in _settings.Dictionaries)
                {
                    FixDxMessage dxMessage = dx.GetMessageByType(strMsgType);
                    if (dxMessage != null)
                    {
                        // REC: Expand the list of elements contained
                        // in the message's definition and populate the
                        // message layout element list with them:
                        FixDxCollection msgElements = dx.Resolve(dxMessage.Elements);
                        foreach (IFixDxElement msgElement in msgElements)
                        {
                            msgLayout.Message.Add(CreateResult(msgElement));
                        }

                        break;
                    }
                }
            }

            // REC: the message layout's trailer entries are
            // copied from the cached list of entries that is
            // created when the validator is configured:
            foreach (FixValidationResult trlEntry in _cachedTrailer)
            {
                msgLayout.Trailer.Add(trlEntry.Clone() as FixValidationResult);
            }


            // REC: After the message layout has been defined
            // the validator can compare the content of the
            // source message to the layout definition:
            return(ProcessElements(srcFields, msgLayout));
        }
Beispiel #4
0
        // REC: Validate an instance of the FixMessage class against
        // the header/message/trailer definition in the dictionaries:
        public List<FixValidationResult> Validate(FixMessage msg)
        {
            List<FixValidationResult> result = new List<FixValidationResult>();

            // REC: Build a queue of all of the FIX elements that
            // are contained in the message:
            Queue<SrcField> srcFields = new Queue<SrcField>();

            // REC: Add the elements that are in the message's
            // header to the queue of source fields:
            PopulateQueue(srcFields, msg.Header);

            // REC: Add the elements that are in the message's
            // body to the queue of source fields:
            PopulateQueue(srcFields, msg.Content);

            // REC: Add the elements that are in the message's
            // trailer to the queue of source fields:
            PopulateQueue(srcFields, msg.Trailer);

            // REC: Create the MsgLayout structure that defines
            // the layout of a message as it is defined in the
            // configured FIX dictionaries:
            MsgLayout msgLayout = new MsgLayout();

            // REC: The message layout's header entries are
            // copied from the cached list of entries that is
            // created when the validator is configured:
            foreach (FixValidationResult hdrEntry in _cachedHeader)
            {
                msgLayout.Header.Add(hdrEntry.Clone() as FixValidationResult);
            }

            // REC: The message layout's content entries are
            // only configured if the corresponding message
            // type can be found in the dictionaries:
            FixField fldMsgType = msg.Header.GetField(35);
            if (fldMsgType != null)
            {
                string strMsgType = fldMsgType.Content;
                foreach (FixDictionary dx in _settings.Dictionaries)
                {
                    FixDxMessage dxMessage = dx.GetMessageByType(strMsgType);
                    if (dxMessage != null)
                    {
                        // REC: Expand the list of elements contained
                        // in the message's definition and populate the
                        // message layout element list with them:
                        FixDxCollection msgElements = dx.Resolve(dxMessage.Elements);
                        foreach (IFixDxElement msgElement in msgElements)
                        {
                            msgLayout.Message.Add(CreateResult(msgElement));
                        }

                        break;
                    }
                }
            }

            // REC: the message layout's trailer entries are
            // copied from the cached list of entries that is
            // created when the validator is configured:
            foreach (FixValidationResult trlEntry in _cachedTrailer)
            {
                msgLayout.Trailer.Add(trlEntry.Clone() as FixValidationResult);
            }

            // REC: After the message layout has been defined
            // the validator can compare the content of the
            // source message to the layout definition:
            return ProcessElements(srcFields, msgLayout);
        }