315 lines
12 KiB
C#
315 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace XYLEM.Base
|
|
{
|
|
internal static class ByteArrayExtensionClass
|
|
{
|
|
/// <summary>
|
|
/// Compare if values in to array's is equal
|
|
/// </summary>
|
|
/// <param name="array 1"></param>
|
|
/// <param name="array 2"></param>
|
|
/// <returns></returns>
|
|
public static bool Compare(this byte[] b1, byte[] b2)
|
|
{
|
|
// Validate buffers are the same length.
|
|
// This also ensures that the count does not exceed the length of either buffer.
|
|
return b1.SequenceEqual<byte>(b2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy a chunk of bytes from start index to a specific LongLength
|
|
/// </summary>
|
|
/// <param name="from"></param>
|
|
/// <param name="startIndex">start offset 0..x</param>
|
|
/// <param name="LongLength">LongLength of returned byte data array</param>
|
|
/// <returns>Return copy of byte data</returns>
|
|
public static byte[] Copy(this byte[] from, long startIndex, long LongLength)
|
|
{
|
|
try
|
|
{
|
|
byte[] bArray = new byte[LongLength];
|
|
Array.Copy(from, startIndex, bArray, 0, LongLength);
|
|
return bArray;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "Copy()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy a chunk of bytes to the end of array, starting from start offset
|
|
/// </summary>
|
|
/// <param name="from"></param>
|
|
/// <param name="startIndex">start offset 0..x</param>
|
|
/// <returns>Return copy of byte data</returns>
|
|
public static byte[] Copy(this byte[] from, long startIndex)
|
|
{
|
|
try
|
|
{
|
|
long LongLength = from.LongLength - startIndex;
|
|
byte[] bArray = new byte[LongLength];
|
|
Array.Copy(from, startIndex, bArray, 0, LongLength);
|
|
return bArray;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "Copy()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a chunk of bytes at the end of array, staring from offset index
|
|
/// </summary>
|
|
/// <param name="from"></param>
|
|
/// <param name="fromIndex">offset 0..x</param>
|
|
/// <returns>Return copy of byte data</returns>
|
|
public static byte[] Remove(this byte[] from, long fromIndex)
|
|
{
|
|
try
|
|
{
|
|
byte[] bArray = new byte[fromIndex];
|
|
if (bArray.LongLength < fromIndex)
|
|
{
|
|
return from;
|
|
}
|
|
Array.Copy(from, 0, bArray, 0, fromIndex);
|
|
return bArray;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "Remove()"));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Copy bytes until this character
|
|
/// </summary>
|
|
/// <param name="toInSeach">bytes to find character in</param>
|
|
/// <param name="untilThisCharacter">detection character</param>
|
|
/// <returns></returns>
|
|
internal static IEnumerable<byte> CopyUntil(this IEnumerable<byte> toInSeach, char untilThisCharacter)
|
|
{
|
|
try
|
|
{
|
|
if (toInSeach != null)
|
|
{
|
|
var withCharacter = toInSeach.TakeWhile(ch => ch != untilThisCharacter);
|
|
// has any data after this
|
|
if (withCharacter.Count() > 1)
|
|
{
|
|
return withCharacter;
|
|
}
|
|
}
|
|
return null; // nothing to return
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "CopyUntil()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy bytes after this character
|
|
/// </summary>
|
|
/// <param name="toInSeach">bytes to find character in</param>
|
|
/// <param name="afterFirstCharacterOfThis">detection character</param>
|
|
/// <returns></returns>
|
|
internal static IEnumerable<byte> CopyAfterThis(this IEnumerable<byte> toInSeach, char afterFirstCharacterOfThis)
|
|
{
|
|
try
|
|
{
|
|
if (toInSeach != null)
|
|
{
|
|
var withCharacter = toInSeach.SkipWhile(ch => ch != afterFirstCharacterOfThis);
|
|
// has any data after this
|
|
if (withCharacter.Count() > 1)
|
|
{
|
|
return withCharacter.Skip(1);
|
|
}
|
|
}
|
|
return null; // nothing to return
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "CopyAfterThis()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy bytes after this sequence of bytes
|
|
/// </summary>
|
|
/// <param name="toSeachIn">bytes to find character in</param>
|
|
/// <param name="afterFirstCharacterOfThis">detection sequence</param>
|
|
/// <returns></returns>
|
|
internal static IEnumerable<byte> CopyAfterThis(this IEnumerable<byte> toSeachIn, IEnumerable<byte> afterSequenceThis)
|
|
{
|
|
try
|
|
{
|
|
var toSeachNow = toSeachIn;
|
|
while ((toSeachNow != null) && (toSeachNow.Count() > 0) && (afterSequenceThis != null))
|
|
{
|
|
var startCh = afterSequenceThis.First();
|
|
var sequenceLng = afterSequenceThis.Count();
|
|
toSeachNow = toSeachNow.SkipWhile(ch => ch != startCh);
|
|
// If there is data after a possible sequence.. check if it have sequnece
|
|
if ((toSeachNow.Count() > sequenceLng) && afterSequenceThis.SequenceEqual(toSeachNow.Take(sequenceLng)))
|
|
{
|
|
if (toSeachNow.Count() > sequenceLng)
|
|
{
|
|
return toSeachNow.Skip(afterSequenceThis.Count());
|
|
}
|
|
return null; // nothing after sequence to return
|
|
}
|
|
// Not found
|
|
if ((toSeachNow == null) || (toSeachNow.Count() == 0))
|
|
{
|
|
return null; // nothing to return
|
|
}
|
|
// increase to next to find next start
|
|
toSeachNow = toSeachNow.Skip(1);
|
|
}
|
|
return null; // nothing to return
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "CopyAfterThis()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Swap high and low byte in a word(16bit) for all words in a byte array (use ex. to a line data correct for conversion to computer U16 from modbus u16)
|
|
/// </summary>
|
|
/// <param name="data">Data to swap (SWAP IS NOT DONE ON A COPY, BUT ON THE ARRAY GIVEN AS INPUT</param>
|
|
/// <returns>return swapped input array reference (done to help supporting single line code use ex. "var data = byteArrayNeedingSwap.SwapByteInWord();") </returns>
|
|
public static byte[] SwapByteInWord(this byte[] data)
|
|
{
|
|
try
|
|
{
|
|
if (data != null)
|
|
{
|
|
for (long i = 0; i < data.LongLength; i += 2)
|
|
{
|
|
byte b = data[i];
|
|
data[i] = data[i + 1];
|
|
data[i + 1] = b;
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "SwapByteInWord()"));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Compare if to array's has the same content (like array1 == array2)
|
|
/// </summary>
|
|
/// <param name="array1"></param>
|
|
/// <param name="array2"></param>
|
|
/// <returns>return true if the same</returns>
|
|
public static bool IsEqual(this byte[] array1, byte[] array2)
|
|
{
|
|
try
|
|
{
|
|
if ((array1 != null) && (array2 != null) && (array1.LongLength == array2.LongLength))
|
|
{
|
|
// To speed up
|
|
var result = array1.SequenceEqual(array2);
|
|
//{
|
|
//#if (!DEBUG)
|
|
//#error Test code!!!
|
|
//#endif
|
|
//if (!result) {
|
|
// var test = "Not the same!!";
|
|
// }
|
|
//}
|
|
return result;
|
|
}
|
|
return false;// not the same
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "IsEqual()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Slice an array of bytes in the same sizes
|
|
/// </summary>
|
|
/// <param name="source">Data to slice an array of bytes from</param>
|
|
/// <param name="startIndex">start in data for beginning slice of bytes</param>
|
|
/// <param name="eachSliceLength">The length of each slice of bytes</param>
|
|
/// <returns>List of byte slices with the same size</returns>
|
|
public static List<byte[]> SliceSameSize(this byte[] source, long startIndex, long eachSliceLength)
|
|
{
|
|
try
|
|
{
|
|
if (source == null)
|
|
{
|
|
return null;
|
|
}
|
|
var LongLength = source.LongLength;
|
|
var slices = new List<byte[]>();
|
|
for (long offset = startIndex; offset < LongLength; offset += eachSliceLength)
|
|
{
|
|
slices.Add(Copy(source, offset, eachSliceLength));
|
|
}
|
|
return slices;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "SliceSameSize()"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Slice a single array with a specific length
|
|
/// </summary>
|
|
/// <param name="source">Data to slice an array of bytes from </param>
|
|
/// <param name="startIndex">start in data for beginning slice of bytes</param>
|
|
/// <param name="length">how long is the slice from start index</param>
|
|
/// <returns></returns>
|
|
public static byte[] Slice(this byte[] source, long startIndex, long length)
|
|
{
|
|
try
|
|
{
|
|
var returnValue = new byte[length];
|
|
Array.Copy(source, startIndex, returnValue, 0, length);
|
|
return returnValue;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new InvalidOperationException(ex.ToFuncErrorText(typeof(ByteArrayExtensionClass).ToString(), "Slice()"));
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Fill or pad array with a specific value
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <param name="valueForFill"></param>
|
|
/// <returns></returns>
|
|
public static byte[] Fill(this byte[] data, byte valueForFill)
|
|
{
|
|
if (data != null)
|
|
{
|
|
for (long i = 0; i < data.LongLength; i++)
|
|
{
|
|
data[i] = valueForFill;
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
}
|
|
}
|