FixAntenna/NetCore/Message/MessageStorage.cs (155 lines of code) (raw):

// Copyright (c) 2021 EPAM Systems // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Text; using Epam.FixAntenna.NetCore.Common.Utils; using Epam.FixAntenna.NetCore.Message.Format; namespace Epam.FixAntenna.NetCore.Message { internal abstract class MessageStorage { public abstract void ClearAll(); public abstract void Add(int tagIndex, byte[] value, int offset, int length); public abstract void SetValue(int tagIndex, string value, int offset, int length); public abstract void SetValue(int tagIndex, long value, int length); public abstract void SetPaddedValue(int tagIndex, long value, int length); public abstract int SetValue(int tagIndex, double value, int precision, int length); public abstract void SetValue(int tagIndex, string value, int length); public abstract void SetCalendarValue(int index, IFixDateFormatter fixDateFormatter, DateTimeOffset value, int length); public abstract void SetTimeValue(int index, DateTime value, TimestampPrecision precision, int length); public abstract void SetTimeValue(int index, DateTimeOffset value, TimestampPrecision precision, int length); public abstract void SetDateTimeValue(int index, DateTime value, TimestampPrecision precision, int length); public abstract void SetDateTimeValue(int index, DateTimeOffset value, TimestampPrecision precision, int length); public abstract byte[] GetByteArray(int index); public abstract bool IsEmpty { get; } public virtual int GetAsByteArray(int index, IFieldIndexData fieldsIndex, byte[] dest, int destOffset) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); var fieldDataLength = fieldsIndex.GetLength(index); Array.Copy(fieldData, fieldDataOffset, dest, destOffset, fieldDataLength); return fieldDataLength; } public virtual byte GetAsByte(int index, IFieldIndexData fieldsIndex, int offset) { var fieldData = GetByteArray(index); if (offset > fieldsIndex.GetLength(index)) { throw new ArgumentException("offset argument is greater than actual value length"); } return fieldData[fieldsIndex.GetOffset(index) + offset]; } public virtual long GetAsLong(int index, IFieldIndexData fieldsIndex) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); return FixTypes.ParseInt(fieldData, fieldDataOffset, fieldDataLength); } public virtual double GetAsDouble(int index, IFieldIndexData fieldsIndex) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); return FixTypes.ParseFloat(fieldData, fieldDataOffset, fieldDataLength); } public virtual bool GetAsBoolean(int index, IFieldIndexData fieldsIndex) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); return FixTypes.ParseBoolean(fieldData, fieldDataOffset, fieldDataLength); } public virtual string GetAsString(int index, IFieldIndexData fieldsIndex) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); return Encoding.UTF8.GetString(fieldData, fieldDataOffset, fieldDataLength); } public virtual void GetAsStringBuffer(int index, IFieldIndexData fieldsIndex, StringBuilder dest) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); dest.Length = fieldDataLength; for (var j = 0; j < fieldDataLength; j++) { dest[j] = (char)fieldData[fieldDataOffset + j]; } } public virtual void GetAsReusableString(int index, IFieldIndexData fieldsIndex, ReusableString dest) { var fieldData = GetByteArray(index); var fieldDataLength = fieldsIndex.GetLength(index); var fieldDataOffset = fieldsIndex.GetOffset(index); dest.SetLength(fieldDataLength); for (var j = 0; j < fieldDataLength; j++) { dest.SetCharAt(j, (char)fieldData[fieldDataOffset + j]); } } public virtual void UpdateValue(int index, IFieldIndexData fieldsIndex, ReadOnlySpan<byte> value) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); var fieldDataLength = fieldsIndex.GetLength(index); value.CopyTo(fieldData.AsSpan(fieldDataOffset)); if (fieldDataLength <= value.Length) return; for (var i = value.Length; i < fieldDataLength; i++) { fieldData[fieldDataOffset + i] = (byte)' '; } } public virtual void UpdateValue(int index, IFieldIndexData fieldsIndex, long value) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); var oldLength = fieldsIndex.GetLength(index); FixTypes.FormatIntWithPadding(value, oldLength, fieldData.AsSpan(fieldDataOffset)); } public virtual void UpdateValue(int index, IFieldIndexData fieldsIndex, double value, int precision) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); var oldLength = fieldsIndex.GetLength(index); FixTypes.FormatDoubleWithPadding(value, precision, oldLength, fieldData, fieldDataOffset); } public virtual void UpdateCalendarValue(int index, IFieldIndexData fieldsIndex, IFixDateFormatter fixDateFormatter, DateTimeOffset value) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); fixDateFormatter.Format(value, fieldData, fieldDataOffset); } public virtual void UpdateTimeValue(int index, IFieldIndexData fieldsIndex, DateTime value, TimestampPrecision precision) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); HighPrecisionDateTimeFormatters.formatTimeOnly(fieldData, value, precision, fieldDataOffset); } public virtual void UpdateTimeValue(int index, IFieldIndexData fieldsIndex, DateTimeOffset value, TimestampPrecision precision) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); HighPrecisionDateTimeFormatters.formatTZTimeOnly(fieldData, value, precision, fieldDataOffset); } public virtual void UpdateDateTimeValue(int index, IFieldIndexData fieldsIndex, DateTime value, TimestampPrecision precision) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); HighPrecisionDateTimeFormatters.FormatTimestamp(fieldData, value, precision, fieldDataOffset); } public virtual void UpdateDateTimeValue(int index, IFieldIndexData fieldsIndex, DateTimeOffset value, TimestampPrecision precision) { var fieldData = GetByteArray(index); var fieldDataOffset = fieldsIndex.GetOffset(index); HighPrecisionDateTimeFormatters.FormatTzTimestamp(fieldData, value, precision, fieldDataOffset); } } }