using System;
using System.Diagnostics;
namespace ConsoleApplication1 {
internal class Program {
/// Looks for the next occurrence of a sequence in a byte array
/// Array that will be scanned
/// Index in the array at which scanning will begin
/// Sequence the array will be scanned for
///
/// The index of the next occurrence of the sequence of -1 if not found
///
private static int findSequence(byte[] array, int start, byte[] sequence) {
int end = array.Length - sequence.Length; // past here no match is possible
byte firstByte = sequence[0]; // cached to tell compiler there's no aliasing
while(start <= end) {
// scan for first byte only. compiler-friendly.
if(array[start] == firstByte) {
// scan for rest of sequence
for (int offset = 1;; ++offset) {
if(offset == sequence.Length) { // full sequence matched?
return start;
} else if(array[start + offset] != sequence[offset]) {
break;
}
}
}
++start;
}
// end of array reached without match
return -1;
}
private static void checkSingleByteSequence() {
byte[] sequence = new byte[] { 123 };
Debug.Assert(findSequence(new byte[] { 123 }, 0, sequence) == 0);
Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 123, 124, 125 }, 0, sequence) == 0);
Debug.Assert(findSequence(new byte[] { 122, 123, 124 }, 0, sequence) == 1);
Debug.Assert(findSequence(new byte[] { 121, 122, 123 }, 0, sequence) == 2);
Debug.Assert(findSequence(new byte[] { 123, 124, 125, 126 }, 1, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 122, 123, 124, 125 }, 2, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 123, 124, 123, 124 }, 1, sequence) == 2);
Debug.Assert(findSequence(new byte[] { 120, 121, 122, 123 }, 3, sequence) == 3);
Debug.Assert(findSequence(new byte[] { 121, 122, 123, 124 }, 3, sequence) == -1);
}
private static void checkThreeByteSequence() {
byte[] sequence = new byte[] { 150, 150, 160 };
Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 200 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 110 }, 1, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 110, 120 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 110, 120, 130 }, 3, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 150 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 150 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 150, 150 }, 1, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 100, 150, 150, 150 }, 0, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 150, 150, 120, 150 }, 3, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 0, sequence) == 0);
Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 1, sequence) == -1);
Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 0, sequence) == 1);
Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 1, sequence) == 1);
Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 2, sequence) == -1);
}
public static void Main(string[] args) {
checkSingleByteSequence();
checkThreeByteSequence();
}
}
}