using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XYLEM.Base
{
internal static class ByteArrayExtensionClass
{
///
/// Compare if values in to array's is equal
///
///
///
///
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(b2);
}
///
/// Copy a chunk of bytes from start index to a specific LongLength
///
///
/// start offset 0..x
/// LongLength of returned byte data array
/// Return copy of byte data
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()"));
}
}
///
/// Copy a chunk of bytes to the end of array, starting from start offset
///
///
/// start offset 0..x
/// Return copy of byte data
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()"));
}
}
///
/// Remove a chunk of bytes at the end of array, staring from offset index
///
///
/// offset 0..x
/// Return copy of byte data
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()"));
}
}
///
/// Copy bytes until this character
///
/// bytes to find character in
/// detection character
///
internal static IEnumerable CopyUntil(this IEnumerable 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()"));
}
}
///
/// Copy bytes after this character
///
/// bytes to find character in
/// detection character
///
internal static IEnumerable CopyAfterThis(this IEnumerable 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()"));
}
}
///
/// Copy bytes after this sequence of bytes
///
/// bytes to find character in
/// detection sequence
///
internal static IEnumerable CopyAfterThis(this IEnumerable toSeachIn, IEnumerable 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()"));
}
}
///
/// 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)
///
/// Data to swap (SWAP IS NOT DONE ON A COPY, BUT ON THE ARRAY GIVEN AS INPUT
/// return swapped input array reference (done to help supporting single line code use ex. "var data = byteArrayNeedingSwap.SwapByteInWord();")
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()"));
}
}
///
/// Compare if to array's has the same content (like array1 == array2)
///
///
///
/// return true if the same
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()"));
}
}
///
/// Slice an array of bytes in the same sizes
///
/// Data to slice an array of bytes from
/// start in data for beginning slice of bytes
/// The length of each slice of bytes
/// List of byte slices with the same size
public static List SliceSameSize(this byte[] source, long startIndex, long eachSliceLength)
{
try
{
if (source == null)
{
return null;
}
var LongLength = source.LongLength;
var slices = new List();
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()"));
}
}
///
/// Slice a single array with a specific length
///
/// Data to slice an array of bytes from
/// start in data for beginning slice of bytes
/// how long is the slice from start index
///
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()"));
}
}
///
/// Fill or pad array with a specific value
///
///
///
///
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;
}
}
}