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); }
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()); } }
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()); } }
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()); } }
// 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); } } } } }
/// <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; } }
/// <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); } }
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(); }
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()); } }
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 = "组号格式错误" })); } }
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格式错误" })); } }
/// <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]; } } } }
/// <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; }
/// <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; } } } }
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; } } }