From e330f90d24ca3acdf78dbaeeb851f3d51fa4a39f Mon Sep 17 00:00:00 2001 From: Sergey Batanov Date: Thu, 12 Oct 2023 00:58:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D1=83=D1=84=D0=B5=D1=80=D0=94=D0=B2?= =?UTF-8?q?=D0=BE=D0=B8=D1=87=D0=BD=D1=8B=D1=85=D0=94=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85.=D0=A0=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B8=D1=82?= =?UTF-8?q?=D1=8C().?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Тест + реализация в лоб для варианта с одним разделителем. --- .../Library/Binary/BinaryDataBuffer.cs | 83 ++++++++++++++++--- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/src/ScriptEngine.HostedScript/Library/Binary/BinaryDataBuffer.cs b/src/ScriptEngine.HostedScript/Library/Binary/BinaryDataBuffer.cs index f11bf92f3..ee332a93c 100644 --- a/src/ScriptEngine.HostedScript/Library/Binary/BinaryDataBuffer.cs +++ b/src/ScriptEngine.HostedScript/Library/Binary/BinaryDataBuffer.cs @@ -521,27 +521,88 @@ public ulong ReadInt64(int position, IValue byteOrder = null) /// - /// Разделить буфер на части по заданному разделителю. - /// - /// НЕ РЕАЛИЗОВАН + /// Разделить буфер на части по заданному разделителю или массиву разделителей (Не реализовано). /// /// - /// - /// - /// По двоичному буферу - /// - /// /// /// Разделитель. /// - /// + /// Массив из буферов двоичных данных /// [ContextMethod("Разделить", "Split")] - public IValue Split(IValue separator) + public ArrayImpl Split(IValue separator) { - throw new NotImplementedException(); + var rawSeparator = separator?.GetRawValue(); + if (rawSeparator is BinaryDataBuffer buffer) + { + if (buffer._buffer.LongLength == 0) + { + throw RuntimeException.InvalidArgumentValue(); + } + return SplitWithOne(buffer); + } + + if (rawSeparator is ArrayImpl) + { + throw new NotImplementedException(); + } + + throw RuntimeException.InvalidArgumentType(); } + private ArrayImpl SplitWithOne(BinaryDataBuffer splitter) + { + var result = new List(); + long start = 0; + long index = Find(_buffer, splitter._buffer, start); + while (index != -1) + { + var length = index - start; + result.Add(new BinaryDataBuffer(Copy(start, length), ByteOrder)); + start = index + splitter._buffer.LongLength; + index = Find(_buffer, splitter._buffer, start); + } + + // хвостовой элемент + result.Add(new BinaryDataBuffer(Copy(start, _buffer.LongLength - start))); + return new ArrayImpl(result); + } + + private byte[] Copy(long start, long length) + { + if (length == 0) return Array.Empty(); + var partition = new byte[length]; + Array.Copy(_buffer, start, partition, 0, length); + return partition; + } + + private static long Find(byte[] buffer, byte[] sub, long start) + { + var maxI = buffer.LongLength - sub.LongLength; + for (var i = start; i < maxI; i++) + { + if (SubsequenceEquals(buffer, i, sub)) + { + return i; + } + } + + return -1; + } + + private static bool SubsequenceEquals(byte[] sequence, long start, byte[] subsequence) + { + for (long j = 0; j < subsequence.LongLength; j++) + { + if (subsequence[j] != sequence[start + j]) + { + return false; + } + } + + return true; + } + /// /// /// Создает копию массива.