internal static void SetPropertyValue(BaseSegment segmentInstance, Property segmentProperty, string segmentPropValue) { if (segmentProperty.CanWrite) { PropertiesService.SetPropertyValue(segmentInstance, segmentProperty.Name, segmentPropValue); } }
internal static List <SegmentCollection> ParseSegments(Hl7Encoding definedEncoding, List <string> allSegments) { var returnValue = new List <SegmentCollection>(); if (allSegments == null) { return(returnValue); } short ordinal = 1; string previous = string.Empty; List <BaseSegment> currentSegments = new List <BaseSegment>(); foreach (string strSegment in allSegments.Where(s => !string.IsNullOrWhiteSpace(s))) { BaseSegment newSegment = CreateSegment(strSegment, definedEncoding); previous = previous == string.Empty ? newSegment.Name : previous; if (previous != newSegment.Name) { returnValue.Add(new SegmentCollection(previous, ordinal, currentSegments)); currentSegments = new List <BaseSegment>(); ordinal++; previous = newSegment.Name; } currentSegments.Add(newSegment); } returnValue.Add(new SegmentCollection(previous, ordinal, currentSegments)); return(returnValue); }
internal static Result <MessageElement> TryGetField(BaseSegment segment, ElementIndex elementIndex) { if (!TryGetField(segment.FieldList, elementIndex.FieldIndex, out _).DecomposeResult(out BaseField field, out string?error)) { ErrorReturn(error ?? "unknown error trying to get field"); } if (elementIndex.SubFieldIndex?.HasValue == true) { if (!(field is RepetitionField rf)) { return(ErrorReturn <MessageElement>($"failed to find RepititionField({elementIndex.SubFieldIndex}) on message with {elementIndex}, as the field was not a repetition field")); } if (!TryGetField(rf.Repetitions, elementIndex.SubFieldIndex, out _).DecomposeResult(out field, out error)) { ErrorReturn(error ?? "unknown error trying to get subfield"); } if (field == null) { return(ErrorReturn <MessageElement>($"failed to find RepititionField({elementIndex.SubFieldIndex}) on message with {elementIndex}")); } } if (elementIndex.ComponentIndex?.HasValue == true) { if (field == null) { return(ErrorReturn <MessageElement>($"failed to find component({elementIndex.ComponentIndex}) on message with {elementIndex}, as the field was not found")); } return(TryGetComponent(field, elementIndex)); } else { return(new Result <MessageElement>(field, null)); } }
public static BaseSegment SetSegmentOrdinal(this BaseSegment segment, int?ordinal) { List <BaseField> fieldList = segment.FieldList.ToList(); fieldList[0] = new ValueField(ordinal.HasValue ? ordinal.Value.ToString() : string.Empty, segment.Encoding); //NOTE add logic here if we have other segment types return(new Segment(segment.Encoding, segment.Name, fieldList)); }
public static BaseSegment AddNewField(this BaseSegment segment, string content, bool isDelimiters = false, int position = 0) { if (isDelimiters) { return(segment.AddNewField(new DelimitersField(segment.Encoding), position)); } return(segment.AddNewField(CreateField(segment.Encoding, content), position)); }
public static Result <string?> TryGetMessageType(this BaseSegment segment) { var field = segment?.FieldList?.ElementAtOrDefault(7); if (field == null) { return(ErrorReturn <string?>("Did not find the required segment type field on the MSH segment of the segment")); } return(new Result <string?>(value: field.GetRawValue()));//this could be a value field, or a componentized field (probably not a delimited field), in any case return the raw value }
public static BaseSegment AddNewField(this BaseSegment segment, BaseField field, int position = 0) { if (position <= 0) { return(CreateSegment(segment, segment.FieldList.Add(field))); } else { return(CreateSegment(segment, segment.FieldList.Insert(position - 1, field))); } }
/// <summary> /// 序列化某一个酷Q码 /// </summary> /// <param name="msg"></param> /// <returns></returns> public static string SerializeSegment(this SoraSegment msg) { if (msg.MessageType == SegmentType.Text) { return(((TextSegment)msg.Data).Content.CQCodeEncode()); } var ret = new StringBuilder(); ret.Append("[CQ:"); //CQ码类型 string typeName = Helper.GetFieldDesc(msg.MessageType); if (string.IsNullOrEmpty(typeName)) { return(string.Empty); } ret.Append(typeName); BaseSegment data = msg.Data; Type dataType = data.GetType(); PropertyInfo[] dataFields = dataType.GetProperties(); foreach (PropertyInfo field in dataFields) { List <JsonPropertyAttribute> jsonPropertyArr = field.GetCustomAttributes <JsonPropertyAttribute>(true).ToList(); if (jsonPropertyArr.Count != 1) { continue; } JsonPropertyAttribute jsonProperty = jsonPropertyArr.First(); string key = jsonProperty.PropertyName; object propData = field.GetValue(data); if (string.IsNullOrWhiteSpace(key) || propData == null) { continue; } string value = propData.GetType().IsEnum ? Helper.GetFieldDesc(propData) : (propData.ToString() ?? "").CQCodeEncode(true); ret.Append(',').Append(key).Append('=').Append(value); } ret.Append(']'); return(ret.ToString()); }
/// <summary> /// Builds an ACK or NACK message for this message /// </summary> /// <param name="code">ack code like AA, AR, AE</param> /// <param name="errMsg">error message to be sent with NACK -- infers that this is a NACK</param> /// <returns>An ACK or NACK message if success, otherwise null</returns> private static Result <Message> CreateAckorNackMessage(this Message message, string?code = null, string?nackErrorMessage = null) { BaseSegment msh = MshMessageHelper.CreateResponseMshSegment(message); string responseCode = code ?? (string.IsNullOrWhiteSpace(nackErrorMessage) ? (message.GetAcceptAckType() ?? AA) : AE);//is acceptacktype a good default? List <BaseField> fields = FieldHelper.ParseFields(new string?[] { responseCode, message.GetMessageControlId() ?? string.Empty, nackErrorMessage }, message.Encoding, false, false); BaseSegment msa = SegmentHelper.CreateSegment(message.Encoding, MessageHelper.MSA, fields); return(CreateMessageFromSegmentCollections(new List <SegmentCollection> { new SegmentCollection(msh.Name, 1, new List <BaseSegment> { msh }), new SegmentCollection(msa.Name, 2, new List <BaseSegment> { msa }) })); }
protected void Calculate(int row, int col, BaseSegment segment) { segment.Height = CONSTS.COMPARING_MARKER_DIAMETER / CountY; segment.Width = CONSTS.COMPARING_MARKER_DIAMETER / CountX; SegmentPoint[] lastPoints = new SegmentPoint[4]; if (col != 0) { lastPoints = segments.FirstOrDefault(x => x.Index == segment.Index - 1).Points; } int Row = row; int Col = col; segment.Points = new SegmentPoint[4]; if (lastPoints == null || lastPoints[1] == null && lastPoints[2] == null) //nov red { segment.Points[0] = new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2 - (segment.Width / 2) * Row, segment.Height * Row); segment.Points[1] = segment.Points[0]; segment.Points[2] = new SegmentPoint(segment.Points[0].X + segment.Width / 2, segment.Points[0].Y + segment.Height); segment.Points[3] = new SegmentPoint(segment.Points[0].X - segment.Width / 2, segment.Points[0].Y + segment.Height); } else { if (Col % 2 == 0) //vseki 4eten element (pravilen) { segment.Points[0] = lastPoints[1]; //gore segment.Points[1] = segment.Points[0]; //gore segment.Points[2] = new SegmentPoint(lastPoints[2].X + segment.Width, lastPoints[2].Y); //dolu segment.Points[3] = lastPoints[2]; //dolu } else//(oburnat nadolu) { segment.Points[0] = lastPoints[0]; //gore segment.Points[1] = new SegmentPoint(lastPoints[0].X + segment.Width, lastPoints[0].Y); //gore segment.Points[2] = lastPoints[2]; //dolu segment.Points[3] = segment.Points[2]; //dolu } } }
/// <summary> /// /// </summary> /// <param name="message">The message to which to add the segment</param> /// <param name="newSegment">The segment to add</param> /// <param name="segmentCollectionOrdinal">The location of the segment collection in the overall collection of segment collections, if null /// the first one will be used </param> /// <returns> A new version of the message</returns> public static Result <Message> AddNewSegment(this Message message, BaseSegment newSegment, int?segmentCollectionOrdinal = null) { var segmentCollections = message.GetSegmentCollections(); var segmentCollection = segmentCollections.FirstOrDefault(sc => sc.SegmentName == newSegment.Name && (segmentCollectionOrdinal == null || sc.SegmentOrdinal == segmentCollectionOrdinal)); if (segmentCollection != null) {//existing, add the segment to it List <BaseSegment> newSegments; if (newSegment.Ordinal.HasValue) {//inject into the right place newSegments = segmentCollection.Segments.Where(s => s.Ordinal < newSegment.Ordinal).ToList(); newSegments.Add(newSegment); newSegments.AddRange(segmentCollection.Segments.Where(s => s.Ordinal >= newSegment.Ordinal).Select(s => SetSegmentOrdinal(s, s.Ordinal + 1))); } else { newSegments = segmentCollection.Segments.ToList(); newSegments.Add(newSegment); } segmentCollections[segmentCollections.IndexOf(segmentCollection)] = new SegmentCollection(segmentCollection.SegmentName, segmentCollection.SegmentOrdinal, newSegments); return(new Result <Message>(new Message(segmentCollections, segmentCollections.First().Segments.First().Encoding))); } else {//this is a new segment collection, if it has an ordinal use that, if no ordinal, then put at the end int?segmentOrdinal = segmentCollections.Max(s => s.SegmentOrdinal) + 1; if (segmentCollectionOrdinal.HasValue && segmentCollectionOrdinal > segmentOrdinal) { return(ErrorReturn <Message>($"requested segment collection ordinal for new segment ({segmentCollectionOrdinal}) is beyond the size of the maximum + 1 ({segmentOrdinal})")); } segmentOrdinal = segmentCollectionOrdinal ?? segmentOrdinal; //renumber the segments as needed, and add our new segment var newSegmentList = segmentCollections.Where(s => s.SegmentOrdinal < segmentOrdinal).ToList(); newSegmentList.Add(new SegmentCollection(newSegment.Name, segmentOrdinal.Value, new List <BaseSegment> { newSegment })); newSegmentList.AddRange(segmentCollections.Where(s => s.SegmentOrdinal >= segmentOrdinal).Select(s => new SegmentCollection(s.SegmentName, s.SegmentOrdinal + 1, s.Segments))); return(new Result <Message>(new Message(newSegmentList, message.Encoding))); } }
private static Result <T> TryGetMshProperty <T>(this BaseSegment segment, int index, int width, bool required, Func <string, T> parser, T defaultValue = default) //T is type, index is 0 based { if (segment == null) { return(ErrorReturn <T>("Attempted to get MSH property on a null segment")); } if (!segment.IsMsh()) { return(ErrorReturn <T>("Attempted to get MSH property on a segment that was not MSH")); } var field = segment.FieldList?.ElementAtOrDefault(index); if (field == null) { if (required) { return(ErrorReturn <T>("requested required field not found")); } return(new Result <T>(defaultValue)); } if (!(field is ValueField vf)) { return(ErrorReturn <T>("Attempted to get MSH property on a non-value field")); } string workingValue = vf.value; workingValue = workingValue.Substring(0, workingValue.Length > width ? width : workingValue.Length); if (workingValue.Length <= 0) { if (required) { return(ErrorReturn <T>("Attempted to get required MSH property, but the field was empty")); } return(new Result <T>(defaultValue));//treat emptry strings differently? } return(new Result <T>(parser.Invoke(workingValue))); }
private static Result <string?> TryGetStringProperty(this BaseSegment segment, int index, int width, bool required = false, bool UseEmptyStringForNoValue = true) => TryGetMshProperty <string?>(segment, index, width, required, s => s, UseEmptyStringForNoValue ? string.Empty : null);
public static string?GetMessageType(this BaseSegment segment) => InvokeProperty <string?>(() => TryGetMessageType(segment), "Did not find segment type");
public static string?GetPrincipalLanguage(this BaseSegment segment) => GetStringProperty(segment, 17, 3);
public static string?GetCharacterSet(this BaseSegment segment) => GetStringProperty(segment, 16, 6);
public static DateTime?GetMessageDateTime(this BaseSegment segment) => GetMshProperty <DateTime>(segment, 5, 26, s => DateTime.ParseExact(s, segment.Encoding.DateTimeFormat, CultureInfo.InvariantCulture));
public static string?GetContinuationPointer(this BaseSegment segment) => GetStringProperty(segment, 12, 180);
public static string?GetReceivingApplication(this BaseSegment segment) => GetStringProperty(segment, 3, 180);
public static string?GetProcessingId(this BaseSegment segment) => GetStringProperty(segment, 9, 3, true); //required public static Result <string?> TryGetProcessingId(this BaseSegment segment) => TryGetStringProperty(segment, 9, 3, true); //required
public static string?GetMessageControlId(this BaseSegment segment) => GetStringProperty(segment, 8, 20, true); //required public static Result <string?> TryGetMessageControlId(this BaseSegment segment) => TryGetStringProperty(segment, 8, 20, true); //required
public static string?GetSecurity(this BaseSegment segment) => GetStringProperty(segment, 6, 40);
private static T GetMshProperty <T>(this BaseSegment segment, int index, int width, Func <string, T> parser, bool required = false, T defaultValue = default) => InvokeProperty <T>(() => TryGetMshProperty <T>(segment, index, width, required, parser, defaultValue), $"unknown error parsing MSH value at index {index}");
public static string?GetAppAckType(this BaseSegment segment) => GetStringProperty(segment, 14, 2);
private static string?GetStringProperty(this BaseSegment segment, int index, int width, bool required = false) => InvokeProperty(() => TryGetStringProperty(segment, index, width, required), $"unknown error parsing MSH string value at index {index}");
public static string?GetCountryCode(this BaseSegment segment) => GetStringProperty(segment, 15, 2);
public static string?GetVersionId(this BaseSegment segment) => GetStringProperty(segment, 10, 8, true); //required public static Result <string?> TryGetVersionId(this BaseSegment segment) => TryGetStringProperty(segment, 10, 8, true); //required
public static string?GetReceivingFacility(this BaseSegment segment) => GetStringProperty(segment, 4, 180);
private static BaseSegment GenerateGeneralSegment(RawSegment rawStringSegment) { BaseSegment segmentInstance = null; Type segmentTypeDefinition = null; var rawSegment = rawStringSegment.SegmentString; switch (rawStringSegment.SegmentType) { case SegmentType.Header: segmentInstance = new HeaderSegment(); segmentTypeDefinition = typeof(HeaderFieldDefinition); break; case SegmentType.CustomerRemarks: segmentInstance = new CustomerRemarkSegment(); segmentTypeDefinition = typeof(CustomerRemarkFieldDefinition); break; case SegmentType.Passenger: segmentInstance = new PassengerSegment(); segmentTypeDefinition = typeof(PassengerFieldDefinition); break; case SegmentType.FareValue: segmentInstance = new FareValueSegment(); segmentTypeDefinition = typeof(FareValueFieldDefinition); break; case SegmentType.A16Hotel: segmentInstance = new A16HotelSegment(); segmentTypeDefinition = typeof(HotelFieldDefinition); break; case SegmentType.A16Car: segmentInstance = new A16CarSegment(); segmentTypeDefinition = typeof(CarFieldDefinition); break; default: return(null); } var previousSegmentPropIsNotPresent = false; var rawSegmentLastPosition = 0; var segmentProperties = PropertiesService.GetDynamicProperties(segmentInstance); var segmentDMLPropertyValues = PropertiesService.GetDynamicPropertyValues(segmentTypeDefinition); foreach (var segmentProperty in segmentProperties) { if (previousSegmentPropIsNotPresent) { previousSegmentPropIsNotPresent = false; continue; } var parentSegmentPropName = segmentProperty.Name.Contains("_") ? segmentProperty.Name.Split("_").First() : segmentProperty.Name; var childSegmentPropName = segmentProperty.Name.Contains("_") ? segmentProperty.Name.Split("_").Last() : string.Empty; var dmlPropValue = segmentDMLPropertyValues.FirstOrDefault(pv => pv.Name.StartsWith(parentSegmentPropName)); if (dmlPropValue != null) { var segmentPropValue = ""; var fieldDefinition = dmlPropValue.Value as FieldDefinition; if (fieldDefinition.HasNestedFields && !string.IsNullOrEmpty(childSegmentPropName)) { var childFieldDefinition = fieldDefinition.NestedFields.FirstOrDefault(_ => _.Name == childSegmentPropName); if (childFieldDefinition != null) { fieldDefinition = childFieldDefinition; } else { continue; } } if (fieldDefinition.IsComplexField && fieldDefinition.HasCodeId) { var segmentChunks = rawSegment.Split("|"); var complexField = string.Empty; if (fieldDefinition.IsOptionalContained) { complexField = segmentChunks .FirstOrDefault(_ => _ .StartsWith(fieldDefinition.CodeId) ); if (!complexField.IsNullOrEmpty()) { segmentPropValue = complexField .Replace(fieldDefinition.CodeId, string.Empty) .Substring(fieldDefinition.SegmentPosition); } } else { foreach (var chunk in segmentChunks) { var optionalDelimitedChunks = chunk.Split(fieldDefinition.Delimitator); complexField = optionalDelimitedChunks .FirstOrDefault(_ => _ .Contains(fieldDefinition.CodeId) ); if (!complexField.IsNullOrEmpty()) { complexField = complexField .Replace(fieldDefinition.CodeId, string.Empty); if (fieldDefinition.IsNestedDelimitatorDriven) { complexField = complexField.Split(fieldDefinition.NestedDelimitator).First(); complexField = complexField.Substring(0, complexField.Length - fieldDefinition.CropIndex); } segmentPropValue = complexField; break; } } } } else { var rawSegmentStartPosition = GetRawSegmentStartPosition(fieldDefinition, rawSegmentLastPosition); rawSegmentLastPosition = rawSegmentStartPosition + fieldDefinition.Length; if (rawSegment.Length >= rawSegmentLastPosition) { var propValue = rawSegment.Substring(rawSegmentStartPosition, fieldDefinition.Length); if (fieldDefinition.IsOptionalField) { if (fieldDefinition.HasCodeId) { if (string.IsNullOrEmpty(fieldDefinition.CodeId) || propValue != fieldDefinition.CodeId) { rawSegmentLastPosition = rawSegmentStartPosition; previousSegmentPropIsNotPresent = true; continue; } } } segmentPropValue = propValue; } } SetPropertyValue(segmentInstance, segmentProperty, segmentPropValue); } } return(segmentInstance); }
public static Result <string?> TryGetVersionId(this BaseSegment segment) => TryGetStringProperty(segment, 10, 8, true); //required public static string?GetSequenceNumber(this BaseSegment segment) => GetStringProperty(segment, 11, 15);