diff --git a/Claunia.ReedSolomon/Claunia.ReedSolomon.csproj b/Claunia.ReedSolomon/Claunia.ReedSolomon.csproj
index cc01394..c83a388 100644
--- a/Claunia.ReedSolomon/Claunia.ReedSolomon.csproj
+++ b/Claunia.ReedSolomon/Claunia.ReedSolomon.csproj
@@ -38,6 +38,7 @@
+
diff --git a/Claunia.ReedSolomon/CodingLoopBase.cs b/Claunia.ReedSolomon/CodingLoopBase.cs
new file mode 100644
index 0000000..ce3a177
--- /dev/null
+++ b/Claunia.ReedSolomon/CodingLoopBase.cs
@@ -0,0 +1,64 @@
+/**
+ * Common implementations for coding loops.
+ *
+ * Copyright 2015, Backblaze, Inc. All rights reserved.
+ * Copyright © 2019 Natalia Portillo
+ */
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Claunia.ReedSolomon
+{
+ public abstract class CodingLoopBase : ICodingLoop
+ {
+ ///
+ /// All of the available coding loop algorithms. The different choices nest the three loops in different orders,
+ /// and either use the log/exponents tables, or use the multiplication table. The naming of the three loops is (with
+ /// number of loops in benchmark): "byte" - Index of byte within shard. (200,000 bytes in each shard) "input" -
+ /// Which input shard is being read. (17 data shards) "output" - Which output shard is being computed. (3 parity
+ /// shards) And the naming for multiplication method is: "table" - Use the multiplication table. "exp" - Use the
+ /// logarithm/exponent table. The ReedSolomonBenchmark class compares the performance of the different loops, which
+ /// will depend on the specific processor you're running on. This is the inner loop. It needs to be fast. Be careful
+ /// if you change it. I have tried inlining Galois.multiply(), but it doesn't make things any faster. The JIT compiler
+ /// is known to inline methods, so it's probably already doing so.
+ ///
+ [SuppressMessage("ReSharper", "InconsistentNaming")]
+ public static readonly ICodingLoop[] ALL_CODING_LOOPS =
+ {
+ /*new ByteInputOutputExpCodingLoop(), new ByteInputOutputTableCodingLoop(),
+ new ByteOutputInputExpCodingLoop(), new ByteOutputInputTableCodingLoop(),
+ new InputByteOutputExpCodingLoop(), new InputByteOutputTableCodingLoop(),
+ new InputOutputByteExpCodingLoop(), new InputOutputByteTableCodingLoop(),
+ new OutputByteInputExpCodingLoop(), new OutputByteInputTableCodingLoop(),
+ new OutputInputByteExpCodingLoop(), new OutputInputByteTableCodingLoop()*/
+ };
+
+ public abstract void CodeSomeShards(byte[][] matrixRows, byte[][] inputs, int inputCount, byte[][] outputs,
+ int outputCount, int offset, int byteCount);
+
+ public virtual bool CheckSomeShards(byte[][] matrixRows, byte[][] inputs, int inputCount, byte[][] toCheck,
+ int checkCount, int offset, int byteCount, byte[] tempBuffer)
+ {
+ // This is the loop structure for ByteOutputInput, which does not
+ // require temporary buffers for checking.
+ byte[][] table = Galois.MULTIPLICATION_TABLE;
+
+ for(int iByte = offset; iByte < offset + byteCount; iByte++)
+ {
+ for(int iOutput = 0; iOutput < checkCount; iOutput++)
+ {
+ byte[] matrixRow = matrixRows[iOutput];
+ int value = 0;
+
+ for(int iInput = 0; iInput < inputCount; iInput++)
+ value ^= table[matrixRow[iInput] & 0xFF][inputs[iInput][iByte] & 0xFF];
+
+ if(toCheck[iOutput][iByte] != (byte)value)
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file