Skip to content

Commit

Permalink
БуферДвоичныхДанных.Разделить().
Browse files Browse the repository at this point in the history
Тест + реализация в лоб для варианта с одним разделителем.
  • Loading branch information
dmpas committed Oct 11, 2023
1 parent a7eccac commit 889d8c0
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 11 deletions.
83 changes: 72 additions & 11 deletions src/ScriptEngine.HostedScript/Library/Binary/BinaryDataBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -521,27 +521,88 @@ public ulong ReadInt64(int position, IValue byteOrder = null)


/// <summary>
/// Разделить буфер на части по заданному разделителю.
///
/// НЕ РЕАЛИЗОВАН
/// Разделить буфер на части по заданному разделителю или массиву разделителей (Не реализовано).
/// </summary>
///
/// <remarks>
///
/// По двоичному буферу
/// </remarks>
///
/// <param name="separator">
/// Разделитель. </param>
///
/// <returns name="Array"/>
/// <returns name="Array">Массив из буферов двоичных данных</returns>
///
[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<BinaryDataBuffer>();
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<byte>();
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;
}

/// <summary>
///
/// Создает копию массива.
Expand Down
26 changes: 26 additions & 0 deletions tests/binary-objects.os
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоМетодОткрытьПотокДляЧтенияВозвращаетПотокТолькоДляЧтения");
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоХешированиеРаботаетСПотоком");
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоХешированиеРаботаетСДвоичнымиДанными");

ВсеТесты.Добавить("ТестДолжен_ПроверитьРазделениеБуфераДвоичныхДанныхОднимБуфером");

Возврат ВсеТесты;

Expand Down Expand Up @@ -351,3 +353,27 @@
НРег(ПолучитьHexСтрокуИзДвоичныхДанных(Хеширование.ХешСумма)));

КонецПроцедуры

Процедура ТестДолжен_ПроверитьРазделениеБуфераДвоичныхДанныхОднимБуфером() Экспорт

Подстроки = Новый Массив;
Подстроки.Добавить("Часть1");
Подстроки.Добавить("Часть2");
Подстроки.Добавить("Часть3");
РазделительТекстом = "123";

ТестовыйБуфер = ПолучитьБуферДвоичныхДанныхИзСтроки(СтрСоединить(Подстроки, РазделительТекстом));
Разделитель = ПолучитьБуферДвоичныхДанныхИзСтроки(РазделительТекстом);

РазделенныеДанные = ТестовыйБуфер.Разделить(Разделитель);

юТест.ПроверитьРавенство(РазделенныеДанные.Количество(), 3, "два разделителя - три элемента");

Для Инд = 0 По Подстроки.ВГраница() Цикл

СтрокаИзБуфера = ПолучитьСтрокуИзБуфераДвоичныхДанных(РазделенныеДанные[Инд]);
юТест.ПроверитьРавенство(СтрокаИзБуфера, Подстроки[Инд], "сравнение строк после разделения буфера");

КонецЦикла;

КонецПроцедуры

0 comments on commit 889d8c0

Please sign in to comment.