public void UpdateFixGroupByGroupId(long groupId, FixGroup fixGroupBo)//测试成功辉煌
        {
            if (groupId <= 0)
            {
                throw new ArgumentException();
            }
            var g = (from groupp in _db.FixGroup.Include(a => a.ClassInfo).Include(b => b.Leader)

                     where groupp.Id == groupId
                     select groupp).SingleOrDefault();

            if (g == null)
            {
                throw new FixGroupNotFoundException();
            }
            //Console.WriteLine(g.Id + "  " + g.ClassInfo.Id + "  " + g.Leader.Id);
            g.Id        = fixGroupBo.Id;
            g.ClassInfo = (from c in _db.ClassInfo
                           where c.Id == fixGroupBo.ClassInfo.Id
                           select c).SingleOrDefault();
            g.Leader = (from u in _db.UserInfo
                        where u.Id == fixGroupBo.Leader.Id
                        select u).SingleOrDefault();
            _db.SaveChanges();
        }
        /// <summary>
        /// 用户解绑.学生解绑账号
        /// @author dwy
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <returns>true 解绑成功 false 解绑失败</returns>
        /// <seealso cref="M:Xmu.Crms.Shared.Service.IClassService.DeleteCourseSelectionById(System.Int64,System.Int64)"/>
        /// <exception cref="T:System.ArgumentException">id格式错误</exception>
        /// <exception cref="T:Xmu.Crms.Shared.Exceptions.UserNotFoundException">未找到对应用户</exception>
        public void DeleteStudentAccount(long userId)
        {
            if (userId < 0)
            {
                throw new ArgumentException("userId格式错误");
            }
            var user = _db.UserInfo.Find(userId) ??
                       throw new UserNotFoundException();
            IList <ClassInfo>    courses = _classService.ListClassByUserId(userId);                    //根据学生ID获取班级列表
            IList <SeminarGroup> groups  = _seminarGroupService.ListSeminarGroupIdByStudentId(userId); //获取学生的所有讨论课小组

            foreach (SeminarGroup s in groups)
            {
                if (userId == _seminarGroupService.GetSeminarGroupLeaderByGroupId(s.Id)) //如果是组长
                {
                    _seminarGroupService.ResignLeaderById(s.Id, userId);                 //组长辞职
                }
                _seminarGroupService.DeleteSeminarGroupMemberById(s.Id, userId);         //在小组中删除该成员
            }
            foreach (ClassInfo c in courses)
            {
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(userId, c.Id); //找到学生所在的固定小组
                _fixGroupService.DeleteFixGroupUserById(fixGroup.Id, userId);         //将学生从固定小组中删去
                _classService.DeleteCourseSelectionById(userId, c.Id);                //学生按班级ID取消选择班级
            }

            _db.RemoveRange(_db.UserInfo.Where(u => u.Id == userId));//删除学生账号
            _db.SaveChanges();
        }
        //public IList<FixGroupMember> GetFixGroupByGroupId(long groupId)//方法已删除
        //{

        //    throw new NotImplementedException();
        //}

        public long InsertFixGroupByClassId(long classId, long userId)//测试成功
        {
            if (classId <= 0 || userId <= 0)
            {
                throw new ArgumentException();
            }

            var class1 = (from class2 in _db.ClassInfo
                          where class2.Id == classId
                          select class2).SingleOrDefault();

            if (class1 == null)
            {
                throw new ClassNotFoundException();
            }

            FixGroup a = new FixGroup();

            a.ClassInfo = (from u in _db.ClassInfo
                           where u.Id == classId
                           select u).SingleOrDefault();
            a.Leader = (from v in _db.UserInfo
                        where v.Id == userId
                        select v).SingleOrDefault();
            //a.ClassInfo.Id = classId;
            //a.Leader = new UserInfo();
            //a.Leader.Id = userId;
            _db.FixGroup.Add(a);
            _db.SaveChanges();
            var b = (from user in _db.FixGroup
                     where user.ClassInfo.Id == classId && user.Leader.Id == userId
                     select user).SingleOrDefault();

            return(b.Id);
        }
Example #4
0
        public IActionResult RemoveMemberIntoClassGroup(long classId, [FromBody] dynamic json)
        {
            try
            {
                //Authentication  权限不足(不是该小组的成员/组长)
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(User.Id(), classId);
                if (fixGroup.LeaderId != User.Id() || json.StudentId == User.Id())
                {
                    return(Forbid());
                }

                long studentId = json.StudentId;
                // Remove student from this classgroup database
                _fixGroupService.DeleteFixGroupUserById(fixGroup.Id, studentId);

                // Success
                return(NoContent());
            }
            catch (FixGroupNotFoundException) { return(NotFound("1")); }
            catch (UserNotFoundException) { return(NotFound("2")); }
            catch (ArgumentException)
            {
                return(BadRequest());
            }
        }
Example #5
0
        public IActionResult AddMemberIntoClassGroup(long classId, [FromBody] dynamic json)
        {
            try
            {
                //Authentication 学生不是该小组成员
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(User.Id(), classId);
                if (fixGroup.LeaderId != User.Id())
                {
                    return(Forbid());
                }

                long     studentId    = json.StudentId;
                FixGroup studentGroup = _fixGroupService.GetFixedGroupById(studentId, classId);
                if (studentGroup != null)
                {
                    return(Forbid());
                }

                // Add student in classgroup database
                var addId = _fixGroupService.InsertStudentIntoGroup(studentId, fixGroup.Id);

                // Success
                return(NoContent());
            }
            catch (FixGroupNotFoundException) { return(NotFound("1")); }
            catch (UserNotFoundException) { return(NotFound("2")); }
            catch (InvalidOperationException) { return(StatusCode(409)); }
            catch (ArgumentException)
            {
                return(BadRequest());
            }
        }
Example #6
0
        public IActionResult GetClassGroup(long classId)
        {
            //Authentication
            // 教师访问,返回403
            if (User.Type() == Shared.Models.Type.Teacher)
            {
                return(Forbid());
            }
            try
            {
                //找到学生所属小组
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(User.Id(), classId);
                if (fixGroup == null)
                {
                    throw new FixGroupNotFoundException();
                }
                //得到组员
                IList <UserInfo> groupMember = _fixGroupService.ListFixGroupMemberByGroupId(fixGroup.Id);

                ClassGroupVO classGroupVO = new ClassGroupVO(fixGroup, groupMember);
                // Success
                return(Json(classGroupVO));
            }
            catch (ClassNotFoundException) { return(NotFound()); }
            catch (UserNotFoundException) { return(NotFound()); }
            catch (FixGroupNotFoundException) { return(NotFound()); }
            //错误的ID格式,返回400
            catch (ArgumentException)
            {
                return(BadRequest());
            }
        }
Example #7
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 #8
0
 /// <summary>
 /// The RegisterGroup method registers an instance of a
 /// repeating group with the assembler. The assembler will
 /// use this group when it construct a message that contains
 /// a repeating group with this tag.
 /// </summary>
 /// <param name="group">
 /// The repeating group being registered.
 /// </param>
 public void RegisterGroup(FixGroup group)
 {
     if (!_mapGroups.ContainsKey(group.Tag))
     {
         _mapGroups.Add(group.Tag, group);
     }
     else
     {
         _mapGroups[group.Tag] = group;
     }
 }
Example #9
0
 /// <summary>
 /// 根据fixGroup构造
 /// @author Group ViceVersa
 /// </summary>
 /// <param name="fixGroup">固定分组信息</param>
 /// <param name="groupMember">组员信息</param>
 public ClassGroupVO(FixGroup fixGroup, IList <UserInfo> groupMember)
 {
     Members = new List <UserVO>();
     Leader  = fixGroup.Leader;
     foreach (UserInfo u in groupMember)
     {
         if (u.Id == Leader.Id)
         {
             continue;
         }
         Members.Add(u);
     }
 }
Example #10
0
        private void HandleWork_SendMessages(object state)
        {
            int orderId = 1;

            IVfxFixAppSession session = state as IVfxFixAppSession;

            for (int i = 0; i != 5; i++)
            {
                FixMessage msg = new FixMessage();

                msg.Header.SetField(new FixField(35, "8"));

                msg.Content.SetField(new FixField(37, orderId++.ToString()));
                msg.Content.SetField(new FixField(17, "5000"));
                msg.Content.SetField(new FixField(20, "0"));
                msg.Content.SetField(new FixField(150, "0"));
                msg.Content.SetField(new FixField(39, "0"));
                msg.Content.SetField(new FixField(55, "AAPL"));
                msg.Content.SetField(new FixField(54, "1"));
                msg.Content.SetField(new FixField(151, "3000"));
                msg.Content.SetField(new FixField(14, "0"));
                msg.Content.SetField(new FixField(6, "0"));

                FixGroup      grpTest     = new FixGroup(382, "2");
                FixCollection grpInstance = new FixCollection();
                grpInstance.AddField(new FixField(375, "foo"));
                grpInstance.AddField(new FixField(337, "bar"));
                grpTest.Instances.Add(grpInstance);
                grpTest.Instances.Add(grpInstance);

                msg.Content.AddGroup(grpTest);

                session.Send(msg);
            }

            if (session != null)
            {
                for (int i = 0; i != 10000; i++)
                {
                    FixMessage message = new FixMessage();

                    message.Header.AddField(new FixField(35, "D"));
                    session.Send(message);
                }
            }
        }
Example #11
0
        private void HandleWork_SendMessages(object state)
        {
            int orderId = 1;

            IVfxFixAppSession session = state as IVfxFixAppSession;

            for (int i = 0; i != 5; i++)
            {
                FixMessage msg = new FixMessage();

                msg.Header.SetField(new FixField(35, "8"));

                msg.Content.SetField(new FixField(37, orderId++.ToString()));
                msg.Content.SetField(new FixField(17, "5000"));
                msg.Content.SetField(new FixField(20, "0"));
                msg.Content.SetField(new FixField(150, "0"));
                msg.Content.SetField(new FixField(39, "0"));
                msg.Content.SetField(new FixField(55, "AAPL"));
                msg.Content.SetField(new FixField(54, "1"));
                msg.Content.SetField(new FixField(151, "3000"));
                msg.Content.SetField(new FixField(14, "0"));
                msg.Content.SetField(new FixField(6, "0"));

                FixGroup grpTest = new FixGroup(382, "2");
                FixCollection grpInstance = new FixCollection();
                grpInstance.AddField(new FixField(375, "foo"));
                grpInstance.AddField(new FixField(337, "bar"));
                grpTest.Instances.Add(grpInstance);
                grpTest.Instances.Add(grpInstance);

                msg.Content.AddGroup(grpTest);

                session.Send(msg);
            }

            if (session != null)
            {
                for (int i = 0; i != 10000; i++)
                {
                    FixMessage message = new FixMessage();

                    message.Header.AddField(new FixField(35, "D"));
                    session.Send(message);
                }
            }
        }
        /// <summary>
        /// 用户解绑.学生解绑账号
        /// @author dwy
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <returns>true 解绑成功 false 解绑失败</returns>
        /// <seealso cref="M:Xmu.Crms.Shared.Service.IClassService.DeleteCourseSelectionById(System.Int64,System.Int64)"/>
        /// <exception cref="T:System.ArgumentException">id格式错误</exception>
        /// <exception cref="T:Xmu.Crms.Shared.Exceptions.UserNotFoundException">未找到对应用户</exception>
        public void DeleteStudentAccount(long userId)
        {
            if (userId < 0)
            {
                throw new ArgumentException("userId格式错误");
            }
            var user = _db.UserInfo.Find(userId) ??
                       throw new UserNotFoundException();
            IList <ClassInfo> courses = _classService.ListClassByUserId(userId);//根据学生ID获取班级列表

            foreach (ClassInfo c in courses)
            {
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(userId, c.Id); //找到学生所在的固定小组
                _fixGroupService.DeleteFixGroupUserById(fixGroup.Id, userId);         //将学生从固定小组中删去
                _classService.DeleteCourseSelectionById(userId, c.Id);                //学生按班级ID取消选择班级
            }
            _db.RemoveRange(_db.UserInfo.Where(u => u.Id == userId));                 //删除学生账号
            _db.SaveChanges();
        }
Example #13
0
        public IActionResult GetStudentListUnderClass(long classId, [FromQuery] string studentNumber, [FromQuery] string studentName)
        {
            try
            {
                if (studentNumber == null)
                {
                    studentNumber = "";
                }
                if (studentName == null)
                {
                    studentName = "";
                }
                IList <UserInfo> studentList = _userService.ListUserByClassId(classId, studentNumber, studentName);

                //找到学生所属小组
                FixGroup fixGroup = _fixGroupService.GetFixedGroupById(User.Id(), classId);
                if (fixGroup != null)
                {
                    IList <UserInfo> groupMember = _fixGroupService.ListFixGroupMemberByGroupId(fixGroup.Id);
                    foreach (UserInfo u in groupMember)
                    {
                        studentList.Remove(u);
                    }
                }

                List <UserVO> studentVO = new List <UserVO>();
                foreach (UserInfo u in studentList)
                {
                    studentVO.Add(u);
                }

                return(Json(studentVO));
            }
            catch (ClassNotFoundException) { return(NotFound(new { msg = "未找到该班级!" })); }
            catch (UserNotFoundException) { return(NotFound()); }
            catch (FixGroupNotFoundException) { return(NotFound()); }
            catch (ArgumentException)
            {
                return(BadRequest());
            }
        }
Example #14
0
        public IActionResult UpdateGroupById([FromRoute] long groupId, [FromBody] /*SeminarGroup*/ FixGroup updated)
        {
            try
            {
                if (User.Type() != Type.Teacher)
                {
                    return(StatusCode(403, new { msg = "权限不足" }));
                }

                _fixGroupService.UpdateFixGroupByGroupId(groupId, updated);
                return(NoContent());
            }
            catch (GroupNotFoundException)
            {
                return(StatusCode(404, new { msg = "没有找到组" }));
            }
            catch (ArgumentException)
            {
                return(StatusCode(400, new { msg = "组号格式错误" }));
            }
        }
Example #15
0
 public IActionResult UpdateUserClassGroupByClassId([FromRoute] long classId, [FromRoute] long groupId,
                                                    [FromBody] FixGroup fixGroupBo)
 {
     try
     {
         var user = _userService.GetUserByUserId(User.Id());
         if (user.Type != Shared.Models.Type.Teacher)
         {
             return(StatusCode(403, new { msg = "权限不足" }));
         }
         _fixGroupService.UpdateFixGroupByGroupId(groupId, fixGroupBo);
         return(NoContent());
     }catch (ClassNotFoundException)
     {
         return(StatusCode(404, new { msg = "未找到班级" }));
     }catch (FixGroupNotFoundException)
     {
         return(StatusCode(404, new { msg = "未找到该小组" }));
     }catch (ArgumentException)
     {
         return(StatusCode(400, new { msg = "ID格式错误" }));
     }
 }
Example #16
0
 /// <summary>
 /// The RegisterGroup method registers an instance of a 
 /// repeating group with the assembler. The assembler will
 /// use this group when it construct a message that contains
 /// a repeating group with this tag.
 /// </summary>
 /// <param name="group">
 /// The repeating group being registered.
 /// </param>
 public void RegisterGroup(FixGroup group)
 {
     if (!_mapGroups.ContainsKey(group.Tag))
     {
         _mapGroups.Add(group.Tag, group);
     }
     else
     {
         _mapGroups[group.Tag] = group;
     }
 }
Example #17
0
        /// <summary>
        /// The ParseHeader method attempts to parse the header of
        /// a FIX message from the buffer in the parser's context:
        /// </summary>
        /// <param name="ctx">
        /// The parser's current context.
        /// </param>
        /// <param name="result">
        /// The parser's result information.
        /// </param>
        private void ParseHeader(ParseContext ctx, VfxFixParserResult result)
        {
            // REC: Default to success, let the parse logic
            // override this if an error occurs:
            result.Status = VfxFixParserStatus.MsgComplete;

            // REC: Start extracting FIX fields from the buffer:
            while (ctx.Index < ctx.Buffer.Length)
            {
                // REC: Reset index value in case there
                // is an error parsing the buffer:
                int idxRst = ctx.Index;

                int idxSep = ctx.Buffer.IndexOf('=', ctx.Index);
                int idxSoh = ctx.Buffer.IndexOf('\x01', idxSep + 1);

                // REC: If the separator or SOH fields were not
                // found, then the header is incomplete and the
                // parsing cannot continue:
                if ((idxSep == -1) || (idxSoh == -1))
                {
                    result.Consumed = 0;
                    result.Status = VfxFixParserStatus.MsgExhausted;
                    return;
                }

                // REC: Extract the field's tag from the message:
                string strTag = ctx.Buffer.Substring(ctx.Index, idxSep - ctx.Index);

                // REC: Convert the field's tag from its string
                // form into its corresponding integer value:
                int nTag = -1;
                if (int.TryParse(strTag, out nTag) == false)
                {
                    // REC: If the field cannot be converted into
                    // an integer, the message is malformed:
                    result.Consumed = 0;
                    result.Status = VfxFixParserStatus.MsgMalformed;
                    return;
                }

                // REC: If the FIX BeginString has already been parsed
                // from the buffer, and is encountered again, then the
                // message was incomplete and cannot be parsed:
                if (nTag == 8)
                {
                    if (result.Message.Header.GetField(8) != null)
                    {
                        // REC: Reset the index into the message:
                        ctx.Index = idxRst;
                        // REC: Adjust the result accordingly:
                        result.Consumed = 0;
                        result.Status = VfxFixParserStatus.MsgIncomplete;
                        return;
                    }
                }

                // REC: Determine whether or not the version of the
                // session protocol has been discovered yet:
                if (ctx.HdrElements != null)
                {
                    IFixDxElement hdrElement = ctx.HdrElements.GetElement(nTag);
                    if (hdrElement != null)
                    {
                        if (hdrElement is FixDxResolvedField)
                        {
                            // REC: Retrieve the field's value:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            FixField field = new FixField(nTag, strVal);
                            result.Message.Header.AddField(field);

                            ctx.Index = idxSoh + 1;
                        }
                        else if (hdrElement is FixDxResolvedGroup)
                        {
                            FixDxResolvedGroup groupEntry = hdrElement as FixDxResolvedGroup;

                            // REC: Since this field is a group entry it's ok
                            // to assume that the value is the number of groups
                            // that follow the group tag:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            // REC: Convert the value into an integer and then
                            // attempt to exract that number of repeating groups:
                            int nGroups = 0;
                            if (int.TryParse(strVal, out nGroups) == true)
                            {
                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;

                                FixGroup group = new FixGroup(nTag, strVal);

                                // REC: Try to parse N instances of the
                                // repeating group from the message:
                                ParseGroupResult parseResult = ParseGroup(ctx, groupEntry, nGroups);

                                if (parseResult.Status != VfxFixParserStatus.MsgComplete)
                                {
                                    return;
                                }

                                foreach (FixCollection instance in parseResult.Instances)
                                {
                                    group.Instances.Add(instance);
                                }

                                result.Message.Header.AddGroup(group);
                            }
                            else
                            {
                                // REC: The value in the group tag couldn't
                                // be converted into an integer, so the
                                // number of repeating groups is unknown.
                                FixGroup group = new FixGroup(nTag, strVal);
                                result.Message.Header.AddGroup(group);

                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;
                            }

                        }
                    }
                    else
                    {
                        // REC: The parser doesn't support UDFs in the
                        // header section of the message, so the result
                        // is considered complete if we hit a field that
                        // isn't in the session protocol dictionary:
                        break;
                    }
                }
                else
                {
                    // REC: The session protocol isn't known yet, so the
                    // field is considered a plain FIX field and added to
                    // the message's header:
                    string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                    FixField field = new FixField(nTag, strVal);
                    result.Message.Header.AddField(field);
                    ctx.Index = idxSoh + 1;

                    // REC: Attempt to determine the session layer protocol
                    // based on the header elements that have been parsed:
                    ctx.SxVersion = _vxMatcher.GetVersion(result.Message.Header, "session");
                    if (ctx.SxVersion == null)
                    {
                        // REC: If no session layer dictionary matched the
                        // elements that have been parsed so far, check for
                        // a combined version definition in case the session
                        // is running FIX versions 4.0-4.4 which do not have
                        // separate session and application layer versions:
                        ctx.SxVersion = _vxMatcher.GetVersion(result.Message.Header, "combined");
                    }

                    // REC: The elements in the message header correspond
                    // to a specific data dictionary, so that should be
                    // used for parsing the header and trailer elements:
                    if (ctx.SxVersion != null)
                    {
                        InitCachedHdrElements(ctx.SxVersion);
                        InitCachedTrlElements(ctx.SxVersion);

                        // REC: Assign the cached sets of resolved header
                        // and trailer elements to the parse context:
                        ctx.HdrElements = _hdrElements[ctx.SxVersion];
                        ctx.TrlElements = _trlElements[ctx.SxVersion];
                    }
                }
            }

            // REC: Determine if the message belongs to the session
            // layer protocol as opposed to the application layer:
            if (ctx.SxVersion != null)
            {
                // REC: Retrieve the FIX message type:
                FixField msgType = result.Message.Header.GetField(35);
                if (!string.IsNullOrEmpty(msgType.Content))
                {
                    // REC: Check the version definition registry for the
                    // corresponding protocol version definition:
                    VfxFixVxRecord vxDefinition = this._vxRegistry.Get(ctx.SxVersion);
                    if (vxDefinition != null)
                    {
                        // REC: Retrieve the associated dictionary from the
                        // configured FIX dictionary registry:
                        FixDictionary dxInstance = this._dxRegistry.GetEntry(vxDefinition.Dictionaries[0].Name);
                        if (dxInstance != null)
                        {
                            // REC: Check if the message is defined within the
                            // dictionary for the session layer:
                            FixDxMessage sxMessage = dxInstance.GetMessageByType(msgType.Content);
                            if (sxMessage != null)
                            {
                                if ((!_msgElements.ContainsKey(ctx.SxVersion)) || (!_msgElements[ctx.SxVersion].Elements.ContainsKey(msgType.Content)))
                                {
                                    InitCachedMsgElements(ctx, msgType.Content);
                                }

                                // REC: Look in the message definition cache
                                // for this particular message type:
                                if (_msgElements[ctx.SxVersion].Elements.ContainsKey(msgType.Content))
                                {
                                    ctx.MsgElements = _msgElements[ctx.SxVersion].Elements[msgType.Content];
                                }

                                // REC: The context is now initialized to parse the
                                // session layer message's content, so we're done:
                                return;
                            }
                        }
                    }
                }
            }

            // REC: If an override version has been specified for the
            // application layer, use that instead of hunting for it:
            if (ctx.AxVersion == null)
            {
                // REC: Now that the entire header of the message has been
                // extracted from the buffer, test the header contents and
                // determine the application protocol version:
                ctx.AxVersion = _vxMatcher.GetVersion(result.Message.Header, "application");
                if (ctx.AxVersion == null)
                {
                    // REC: If the application layer version cannot be
                    // determined, it may be a FIX 4.0-4.4 message, so
                    // check the combined versions as well:
                    ctx.AxVersion = _vxMatcher.GetVersion(result.Message.Header, "combined");
                    if(ctx.AxVersion == null)
                    {
                        // REC: If the application layer could not be
                        // resolved, then switch to the default:
                        ctx.AxVersion = ctx.AxDefault;
                    }
                }
            }

            if (ctx.AxVersion != null)
            {
                // REC: Now that the application version has been
                // determined, retrieve the message elements for
                // the type of message being parsed, initializing
                // the local message elements cache if needed:
                FixField msgType = result.Message.Header.GetField(35);
                if (msgType != null)
                {
                    if ((!_msgElements.ContainsKey(ctx.AxVersion)) || (!_msgElements[ctx.AxVersion].Elements.ContainsKey(msgType.Content)))
                    {
                        InitCachedMsgElements(ctx, msgType.Content);
                    }

                    // REC: Look in the message definition cache
                    // for this particular message type:
                    if (_msgElements[ctx.AxVersion].Elements.ContainsKey(msgType.Content))
                    {
                        ctx.MsgElements = _msgElements[ctx.AxVersion].Elements[msgType.Content];
                    }
                }
            }
        }
Example #18
0
        /// <summary>
        /// The ParseGroup method attempts to parse all of the group
        /// instances from a repeating group.
        /// </summary>
        /// <param name="ctx">
        /// The parser's current parsing context.
        /// </param>
        /// <param name="group">
        /// The resolved group information for the repeating group
        /// that is being extracted from the message.
        /// </param>
        /// <param name="count">
        /// The number of instances of the repeating group that the
        /// parser should expect to encounter.
        /// </param>
        /// <returns></returns>
        private ParseGroupResult ParseGroup(ParseContext ctx, FixDxResolvedGroup group, int count)
        {
            ParseGroupResult result = new ParseGroupResult();

            // Build a temporary map of flags that indicate whether
            // or not a specific element of the repeating group has
            // been encountered during the parsing of an instance:
            Dictionary<int, bool> mapEncountered = new Dictionary<int, bool>();

            foreach (IFixDxElement element in group.Elements)
            {
                if (!mapEncountered.ContainsKey(element.Tag))
                {
                    mapEncountered.Add(element.Tag, false);
                }
                else
                {
                    mapEncountered[element.Tag] = false;
                }
            }

            // REC: Extract the FIX tag of the first field in
            // the repeating group; this is needed to determine
            // when one instance stops and another starts:
            IFixDxElement startField = group.Elements.First();
            int nStartField = startField.Tag;

            // REC: Default to the complete status when parsing
            // a group, so that zero-instance groups don't cause
            // a problem; a zero-instance group is okay in terms
            // of parsing, and should only be flagged as a fault
            // when validation is run...
            result.Status = VfxFixParserStatus.MsgComplete;
            for (int i = 0; i != count; i++)
            {
                FixCollection collection = new FixCollection();

                List<int> listEncounterMapKeys = new List<int>();
                foreach (int key in mapEncountered.Keys)
                {
                    listEncounterMapKeys.Add(key);
                }

                // REC: Reset the encounter map for all of the
                // tags that can be encountered in an instance
                // of the repeating group:
                foreach (int key in listEncounterMapKeys)
                {
                    mapEncountered[key] = false;
                }

                while (ctx.Index < ctx.Buffer.Length)
                {
                    // REC: Ignore leading SOH characters:
                    while (ctx.Buffer[ctx.Index] == '\x01')
                    {
                        ctx.Index++;
                        if (ctx.Index >= ctx.Buffer.Length)
                        {
                            return result;
                        }
                    }

                    // REC: Locate the next tag/value separator:
                    int idxSep = ctx.Buffer.IndexOf('=', ctx.Index);
                    if (idxSep == -1)
                    {
                        // REC: If the next separator couldn't
                        // be found, the message is incomplete:
                        result.Status = VfxFixParserStatus.MsgIncomplete;
                        return result;
                    }

                    // REC: If the field doesn't have a tag then
                    // the parsing of the groups can't continue:
                    if (idxSep == ctx.Index)
                    {
                        result.Status = VfxFixParserStatus.MsgMalformed;
                        return result;
                    }

                    // REC: Attempt to locate the end of the field:
                    int idxSoh = ctx.Buffer.IndexOf('\x01', idxSep + 1);
                    if (idxSoh == -1)
                    {
                        result.Status = VfxFixParserStatus.MsgIncomplete;
                        return result;
                    }

                    string strTag = ctx.Buffer.Substring(ctx.Index, idxSep - ctx.Index);
                    if (strTag != null)
                    {
                        int nTag;
                        if (int.TryParse(strTag, out nTag) == false)
                        {
                            result.Status = VfxFixParserStatus.MsgMalformed;
                            return result;
                        }

                        string strVal = null;

                        // REC: Determine whether or not the tag
                        // is a valid member of the current group:
                        IFixDxElement element = group.Elements.GetElement(nTag);
                        if (element == null)
                        {
                            // REC: The parsing of a repeating group
                            // should cease if a tag that is not a
                            // member of the group is encountered:
                            result.Instances.Add(collection);
                            // REC: Set the status so that the caller knows
                            // the group was successfully parsed:
                            result.Status = VfxFixParserStatus.MsgComplete;
                            return result;
                        }

                        // REC: Determine whether or not the tag
                        // has already been encountered during
                        // the parsing of the current instance:
                        if (mapEncountered[nTag] == true)
                        {
                            // REC: Determine whether or not the
                            // redundant tag is the first tag in
                            // the repeating group's layout:
                            if (nTag == nStartField)
                            {
                                // REC: This field is the start tag
                                // for another instance of the group:
                                result.Instances.Add(collection);
                                break;
                            }

                            return result;
                        }

                        mapEncountered[nTag] = true;

                        // REC: Determine whether or not the element
                        // represents a length encoded field:
                        if (element is FixDxResolvedField)
                        {
                            FixDxResolvedField fieldEntry = element as FixDxResolvedField;
                            if (fieldEntry.LengthCoded == true)
                            {
                                // REC: Determine whether or not the
                                // corresponding length field exists:
                                string strLen = collection.GetField(fieldEntry.LengthField).Content;
                                if (strLen != null)
                                {
                                    int nLen = -1;
                                    if (int.TryParse(strLen, out nLen) == true)
                                    {
                                        // REC: Determine whether or not there
                                        // are enough characters remaining in
                                        // the buffer to parse the contents:
                                        if ((idxSep + nLen) >= ctx.Buffer.Length)
                                        {
                                            result.Status = VfxFixParserStatus.MsgIncomplete;
                                            return result;
                                        }

                                        strVal = ctx.Buffer.Substring(idxSep + 1, nLen);
                                        // REC: Adjust the context's read index:
                                        ctx.Index = (idxSep + 1) + nLen;
                                    }
                                }
                                else
                                {
                                    // REC: The encoded length field couldn't
                                    // be located, so the contents will be
                                    // parsed as though they were any other
                                    // normal field's contents:
                                    strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));
                                    // REC: Adjust the context's read index:
                                    ctx.Index = idxSoh + 1;
                                }
                            }
                            else
                            {
                                strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));
                                // REC: Adjust the context's read index:
                                ctx.Index = idxSoh + 1;
                            }

                            collection.AddField(new FixField(nTag, strVal));

                        }
                        else if (element is FixDxResolvedGroup)
                        {
                            // REC: If the group field's value isn't set
                            // to a specific value, then add a null group
                            // entry to the collection and continue:
                            if (idxSoh == idxSep + 1)
                            {
                                FixGroup parsedGroup = new FixGroup(nTag, null);
                                collection.AddGroup(parsedGroup);
                                result.Instances.Add(collection);
                                ctx.Index = idxSoh + 1;
                            }
                            else
                            {
                                // REC: Attempt to convert the field's value
                                // into an integer that represents the number
                                // of repeating groups that should follow:
                                strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                                // REC: This might have been the issue with nested repeating
                                // groups becoming a problem:
                                ctx.Index = idxSoh + 1;

                                int nInstances = -1;
                                if (int.TryParse(strVal, out nInstances) == true)
                                {
                                    FixDxResolvedGroup subGroup = element as FixDxResolvedGroup;
                                    ParseGroupResult subResult = ParseGroup(ctx, subGroup, nInstances);
                                    if (subResult.Status != VfxFixParserStatus.MsgComplete)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        FixGroup parsedGroup = new FixGroup(nTag, strVal);
                                        foreach (FixCollection instance in subResult.Instances)
                                        {
                                            parsedGroup.Instances.Add(instance);
                                        }

                                        collection.AddGroup(parsedGroup);

                                        // REC: Adjust the context's read index:
                                        //ctx.Index = idxSoh + 1;
                                    }
                                }
                                else
                                {
                                    // REC: The instance count couldn't be converted
                                    // to an integer, so the message is malformed:
                                    result.Status = VfxFixParserStatus.MsgMalformed;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }
Example #19
0
        /// <summary>
        /// The ParseContent method attempts to parse the message body
        /// from an instance of a FIX message.
        /// </summary>
        /// <param name="ctx">
        /// The parser's context information.
        /// </param>
        /// <param name="result">
        /// The parser's result information.
        /// </param>
        private void ParseContent(ParseContext ctx, VfxFixParserResult result)
        {
            // REC: Attempt to retrieve the FIX message type
            // from the header of the message:
            FixField msgType = result.Message.Header.GetField(35);

            while (ctx.Index < ctx.Buffer.Length)
            {
                int idxSep = ctx.Buffer.IndexOf('=', ctx.Index);
                int idxSoh = ctx.Buffer.IndexOf('\x01', idxSep + 1);

                // REC: If the separator or SOH fields were not
                // found, then the message is incomplete and the
                // parsing cannot continue:
                if ((idxSep == -1) || (idxSoh == -1))
                {
                    result.Status = VfxFixParserStatus.MsgExhausted;
                    return;
                }

                // REC: Extract the field's tag from the message:
                string strTag = ctx.Buffer.Substring(ctx.Index, idxSep - ctx.Index);
                // REC: Convert the field's tag to an integer:
                int nTag;
                if (int.TryParse(strTag, out nTag) == false)
                {
                    result.Status = VfxFixParserStatus.MsgMalformed;
                    return;
                }

                // REC: Test for premature message termination:
                if (nTag == 8)
                {
                    result.Status = VfxFixParserStatus.MsgMalformed;
                    return;
                }

                if (ctx.MsgElements != null)
                {
                    IFixDxElement element = ctx.MsgElements.GetElement(nTag);
                    if (element != null)
                    {
                        if (element is FixDxResolvedField)
                        {
                            // REC: Retrieve the field's value:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            // REC: Create a new field to represent
                            // the parsed field/value pair:
                            FixField field = new FixField(nTag, strVal);
                            result.Message.AddField(field);
                            ctx.Index = idxSoh + 1;
                        }
                        else if (element is FixDxResolvedGroup)
                        {
                            // REC: Since this field is a group entry it's ok
                            // to assume that the value is the number of groups
                            // that follow the group tag:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            // REC: Convert the value into an integer and then
                            // attempt to exract that number of repeating groups:
                            int nGroups = 0;
                            if (int.TryParse(strVal, out nGroups) == true)
                            {
                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;

                                FixGroup group = new FixGroup(nTag, strVal);

                                // REC: Try to parse N instances of the
                                // repeating group from the message:
                                FixDxResolvedGroup resolvedGroup = element as FixDxResolvedGroup;
                                ParseGroupResult parseResult = ParseGroup(ctx, resolvedGroup, nGroups);

                                if (parseResult.Status != VfxFixParserStatus.MsgComplete)
                                {
                                    result.Status = parseResult.Status;
                                    return;
                                }

                                foreach (FixCollection instance in parseResult.Instances)
                                {
                                    group.Instances.Add(instance);
                                }

                                result.Message.AddGroup(group);

                            }
                            else
                            {
                                // REC: The value in the group tag couldn't
                                // be converted into an integer, so the
                                // number of repeating groups is unknown.
                                FixGroup group = new FixGroup(nTag, strVal);
                                result.Message.AddGroup(group);

                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;
                            }
                        }
                    }
                    else
                    {
                        // REC: The tag wasn't found in the map of elements
                        // that are known for this message type, so determine
                        // whether it is a UDF or a field from the trailer:
                        if (ctx.TrlElements.GetElement(nTag) != null)
                        {
                            // REC: The field is a trailer element
                            // so content parsing is now complete:
                            return;
                        }
                        else
                        {
                            // REC: The field is just a UDF so it can be added
                            // to the message body:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            FixField field = new FixField(nTag, strVal);
                            result.Message.AddField(field);

                            ctx.Index = idxSoh + 1;
                        }
                    }
                }
                else
                {
                    // REC: There is no cached set of elements for this
                    // type of message, so the field is either a trailer
                    // field or it is a user-defined field:
                    if (ctx.TrlElements.GetElement(nTag) != null)
                    {
                        // REC: The field is a trailer element
                        // so content parsing is now complete:
                        return;
                    }
                    else
                    {
                        // REC: The field is just a UDF so it can be added
                        // to the message body:
                        string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                        FixField field = new FixField(nTag, strVal);
                        result.Message.AddField(field);

                        ctx.Index = idxSoh + 1;
                    }
                }
            }
        }
Example #20
0
        private void ParseTrailer(ParseContext ctx, VfxFixParserResult result)
        {
            while (ctx.Index < ctx.Buffer.Length)
            {
                int idxSep = ctx.Buffer.IndexOf('=', ctx.Index);
                int idxSoh = ctx.Buffer.IndexOf('\x01', idxSep + 1);

                // REC: If the separator or SOH fields were not
                // found, then the message is incomplete and the
                // parsing cannot continue:
                if ((idxSep == -1) || (idxSoh == -1))
                {
                    // result.Consumed = 0;
                    result.Status = VfxFixParserStatus.MsgExhausted;
                    return;
                }

                // REC: Extract the field's tag from the message:
                string strTag = ctx.Buffer.Substring(ctx.Index, idxSep - ctx.Index);

                // REC: Convert the field's tag to an integer:
                int nTag;
                if (int.TryParse(strTag, out nTag) == false)
                {
                    result.Status = VfxFixParserStatus.MsgMalformed;
                    return;
                }

                if (ctx.TrlElements != null)
                {
                    IFixDxElement element = ctx.TrlElements.GetElement(nTag);
                    if(element != null)
                    {
                        if (element is FixDxResolvedField)
                        {
                            // REC: Retrieve the field's value:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            // REC: Create a new field to represent
                            // the parsed field/value pair:
                            FixField field = new FixField(nTag, strVal);
                            result.Message.Trailer.AddField(field);
                            ctx.Index = idxSoh + 1;
                        }
                        else if (element is FixDxResolvedGroup)
                        {
                            FixDxResolvedGroup groupEntry = element as FixDxResolvedGroup;
                            // REC: Since this field is a group entry it's ok
                            // to assume that the value is the number of groups
                            // that follow the group tag:
                            string strVal = ctx.Buffer.Substring(idxSep + 1, idxSoh - (idxSep + 1));

                            // REC: Convert the value into an integer and then
                            // attempt to exract that number of repeating groups:
                            int nGroups = 0;
                            if (int.TryParse(strVal, out nGroups) == true)
                            {
                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;

                                FixGroup group = new FixGroup(nTag, strVal);

                                // REC: Try to parse N instances of the
                                // repeating group from the message:
                                ParseGroupResult parseResult = ParseGroup(ctx, groupEntry, nGroups);

                                if (parseResult.Status != VfxFixParserStatus.MsgComplete)
                                {
                                    result.Status = parseResult.Status;
                                    return;
                                }

                                foreach (FixCollection instance in parseResult.Instances)
                                {
                                    group.Instances.Add(instance);
                                }

                                result.Message.Trailer.AddGroup(group);

                            }
                            else
                            {
                                // REC: The value in the group tag couldn't
                                // be converted into an integer, so the
                                // number of repeating groups is unknown.
                                FixGroup group = new FixGroup(nTag, strVal);
                                result.Message.Trailer.AddGroup(group);

                                // REC: Move the context's read index ahead
                                // to compensate for reading the repeating
                                // group's tag and associated value:
                                ctx.Index = idxSoh + 1;
                            }
                        }
                    }
                    else
                    {
                        // REC: If the element is not in the set of trailer
                        // elements, then the parsing is complete.
                        return;
                    }
                }
                else
                {
                    result.Status = VfxFixParserStatus.MsgUnkSxProtocol;
                    return;
                }
            }
        }