FixAntenna/NetCore/Message/Rg/RepeatingGroupArray.cs (335 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; namespace Epam.FixAntenna.NetCore.Message.Rg { using static RepeatingGroupStorage; internal class RepeatingGroupArray { private int[][] _rgArray; public RepeatingGroupArray(int[][] rgArray) { _rgArray = rgArray; } public virtual void SetRgArray(int[][] rgArray) { _rgArray = rgArray; } public virtual int GetRgLeadingTag(int rgIndex) { return _rgArray[rgIndex][RgHashTag]; } public virtual int GetRgLeadingTag(int[] repeatingGroup) { return repeatingGroup[RgHashTag]; } public virtual void SetRgLeadingTag(int rgIndex, int value) { _rgArray[rgIndex][RgHashTag] = value; } public virtual void SetRgLeadingTag(int[] repeatingGroup, int value) { repeatingGroup[RgHashTag] = value; } public virtual int GetRgId(int rgIndex) { return _rgArray[rgIndex][RgHashId]; } public virtual int GetRgId(int[] repeatingGroup) { return repeatingGroup[RgHashId]; } public virtual void SetRgId(int rgIndex, int value) { _rgArray[rgIndex][RgHashId] = value; } public virtual void SetRgArrayEnd(int rgIndex, int value) { _rgArray[rgIndex][RgHashLastEntryPointer] = value; } public virtual void SetRgArrayEnd(int[] repeatingGroup, int value) { repeatingGroup[RgHashLastEntryPointer] = value; } public virtual void IncrementRgArrayEnd(int rgIndex) { _rgArray[rgIndex][RgHashLastEntryPointer] += RgHashEntrySize; } public virtual void IncrementRgArrayEnd(int[] repeatingGroup) { repeatingGroup[RgHashLastEntryPointer] += RgHashEntrySize; } public virtual int GetRgArrayEnd(int rgIndex) { return _rgArray[rgIndex][RgHashLastEntryPointer]; } public virtual int GetRgArrayEnd(int[] repeatingGroup) { return repeatingGroup[RgHashLastEntryPointer]; } public virtual void SetZeroSize(int rgIndex) { _rgArray[rgIndex][RgHashLastEntryPointer] = RgHashHeaderSize; } public virtual void SetZeroSize(int[] repeatingGroup) { repeatingGroup[RgHashLastEntryPointer] = RgHashHeaderSize; } public virtual void AddEntry(int rgIndex, int entryLink) { var repeatingGroup = _rgArray[rgIndex]; repeatingGroup[GetRgArrayEnd(repeatingGroup)] = entryLink; IncrementRgArrayEnd(repeatingGroup); } public virtual void AddEntry(int[] repeatingGroup, int entryLink) { repeatingGroup[GetRgArrayEnd(repeatingGroup)] = entryLink; IncrementRgArrayEnd(repeatingGroup); } public virtual void AddEntryAtIndex(int[] repeatingGroup, int index, int entryLink) { var startPos = RgHashHeaderSize + index * RgHashEntrySize; var destPos = RgHashHeaderSize + (index + 1) * RgHashEntrySize; var size = GetRgArrayEnd(repeatingGroup) - startPos; Array.Copy(repeatingGroup, startPos, repeatingGroup, destPos, size); SetEntryLink(repeatingGroup, startPos, entryLink); IncrementRgArrayEnd(repeatingGroup); } public virtual int GetLastEntryLink(int rgIndex) { return _rgArray[rgIndex][_rgArray[rgIndex][RgHashLastEntryPointer] - 1]; } public virtual int GetLastEntryLink(int[] repeatingGroup) { return repeatingGroup[repeatingGroup[RgHashLastEntryPointer] - 1]; } public virtual int GetEntryLink(int rgIndex, int entryIndex) { return _rgArray[rgIndex][entryIndex + RgHashEntryLinkIndex]; } public virtual int GetEntryLink(int[] repeatingGroup, int entryIndex) { return repeatingGroup[entryIndex + RgHashEntryLinkIndex]; } public virtual void SetEntryLink(int rgIndex, int entryIndex, int value) { _rgArray[rgIndex][entryIndex + RgHashEntryLinkIndex] = value; } public virtual void SetEntryLink(int[] repeatingGroup, int entryIndex, int value) { repeatingGroup[entryIndex + RgHashEntryLinkIndex] = value; } public virtual int GetRgLeadingTagIndexInFixMsg(int rgIndex) { return GetRgLeadingTagIndexInFixMsg(_rgArray[rgIndex]); } public virtual int GetRgLeadingTagIndexInFixMsg(int[] repeatingGroup) { return repeatingGroup[RgHashTagLink]; } public virtual void SetRgLeadingTagIndexInFixMsg(int rgIndex, int value) { _rgArray[rgIndex][RgHashTagLink] = value; } public virtual void SetRgLeadingTagIndexInFixMsg(int[] repeatingGroup, int value) { repeatingGroup[RgHashTagLink] = value; } public virtual void AddRgLeadingTagIndexInFixMsg(int[] repeatingGroup, int appendValue) { repeatingGroup[RgHashTagLink] += appendValue; } public virtual void AddRgLeadingTagIndexInFixMsg(int rgIndex, int appendValue) { _rgArray[RgHashTagLink][rgIndex] += appendValue; } public virtual void SetRgId(int[] repeatingGroup, int value) { repeatingGroup[RgHashId] = value; } public virtual int GetParentEntryIndex(int rgIndex) { return _rgArray[rgIndex][RgHashParentEntryLink]; } public virtual int GetParentEntryIndex(int[] repeatingGroup) { return repeatingGroup[RgHashParentEntryLink]; } public virtual void SetParentEntryIndex(int rgIndex, int value) { _rgArray[rgIndex][RgHashParentEntryLink] = value; } public virtual void SetParentEntryIndex(int[] repeatingGroup, int value) { repeatingGroup[RgHashParentEntryLink] = value; } public virtual int GetVirtualLeadingTagIndex(int rgIndex) { return _rgArray[rgIndex][RgHashVirtualTagLink]; } public virtual int GetVirtualLeadingTagIndex(int[] repeatingGroup) { return repeatingGroup[RgHashVirtualTagLink]; } public virtual void SetVirtualLeadingTagIndex(int rgIndex, int value) { _rgArray[rgIndex][RgHashVirtualTagLink] = value; } public virtual void SetVirtualLeadingTagIndex(int[] repeatingGroup, int value) { repeatingGroup[RgHashVirtualTagLink] = value; } /// /// <param name="repeatingGroup"> </param> /// <param name="index"> index for entry. For first entry - 0, for second - 1, so on </param> /// <returns> link to entry in entries array </returns> public virtual int GetEntryLinkByIndex(int[] repeatingGroup, int index) { return repeatingGroup[index * RgHashEntrySize + RgHashHeaderSize]; } public virtual void RemoveEntryByIndex(int rgIndex, int index) { RemoveEntryByIndex(_rgArray[rgIndex], index); } /// /// <param name="rgEntryIndex"> index for entry in repeating group. For first entry index equals to 0, for second - 1 and so on </param> /// <returns> pointer to entry in repeating group array. </returns> public virtual int GetIndexInRgArray(int rgEntryIndex) { return rgEntryIndex * RgHashEntrySize + RgHashHeaderSize; } public virtual void RemoveEntryByIndex(int[] repeatingGroup, int entryIndexInRg) { var start = GetIndexInRgArray(entryIndexInRg + 1); var dest = GetIndexInRgArray(entryIndexInRg); int size; if (dest == repeatingGroup[RgHashLastEntryPointer]) { size = RgHashEntrySize; } else { size = GetRgArrayEnd(repeatingGroup) - dest; } Array.Copy(repeatingGroup, start, repeatingGroup, dest, size); repeatingGroup[repeatingGroup[RgHashLastEntryPointer]] = 0; repeatingGroup[RgHashLastEntryPointer] -= RgHashEntrySize; } public virtual int GetRgIndexByEntryIndex(int entryIndex) { for (var i = 0; i < _rgArray.Length; i++) { var repeatingGroup = _rgArray[i]; if (repeatingGroup != null) { for (var j = RgHashHeaderSize; j < GetRgArrayEnd(repeatingGroup); j += RgHashEntrySize) { if (GetEntryLink(repeatingGroup, j) == entryIndex) { return i; } } } } return -1; } public virtual int[] GetRgArrayByEntryIndex(int entryIndex) { return _rgArray[GetRgIndexByEntryIndex(entryIndex)]; } public virtual int GetIndexByEntryIndex(int[] repeatingGroup, int entryIndex) { int index; int indexInRg; if (repeatingGroup == null) { return -1; } for (index = 0; (indexInRg = index * RgHashEntrySize + RgHashHeaderSize) < repeatingGroup.Length; index++) { if (repeatingGroup[indexInRg + RgHashEntryLinkIndex] == entryIndex) { break; } } if (indexInRg >= repeatingGroup.Length) { return -1; } return index; } public virtual int[] GetRgArrayById(int tag, int rgId) { var rgIndex = FindRgIndex(tag, rgId); if (rgIndex == -1) { return null; } return _rgArray[rgIndex]; } public virtual int GetRgLeadingTagIndexById(int tag, int rgId) { var rgIndex = FindRgIndex(tag, rgId); return GetRgLeadingTagIndexInFixMsg(rgIndex); } public virtual int FindNotShowedGroup(int leadingTag) { for (var i = 0; i < _rgArray.Length; i++) { var repeatingGroup = _rgArray[i]; if (repeatingGroup == null) { break; } if (GetRgLeadingTag(repeatingGroup) == leadingTag && GetRgId(repeatingGroup) == -1) { return i; } } return IndexedStorage.NotFound; } public virtual int FindRgIndex(int leadingTag) { for (var i = 0; i < _rgArray.Length; i++) { var repeatingGroup = _rgArray[i]; if (repeatingGroup == null) { break; } if (GetRgLeadingTag(repeatingGroup) == leadingTag && GetRgId(repeatingGroup) != -1) { return i; } } return IndexedStorage.NotFound; } public virtual int FindRgIndex(int leadingTag, int rgId) { for (var i = 0; i < _rgArray.Length; i++) { var repeatingGroup = _rgArray[i]; if (repeatingGroup == null) { break; } if (GetRgLeadingTag(repeatingGroup) == leadingTag && GetRgId(repeatingGroup) == rgId) { return i; } } return IndexedStorage.NotFound; } public virtual int[] GetRepeatingGroup(int rgIndex) { return _rgArray[rgIndex]; } public virtual int GetPrevEntryLink(int[] repeatingGroup, int entryIndex) { for (var i = RgHashHeaderSize + RgHashEntrySize; i < GetRgArrayEnd(repeatingGroup); i += RgHashEntrySize) { if (GetEntryLink(repeatingGroup, i) == entryIndex) { return GetEntryLink(repeatingGroup, i - RgHashEntrySize); } } return -1; } } }