public static byte[] decode(
byte[] rec_fragments,
final int Nrec,
final CosetIDAParameters p) //throws Exception
{
byte[] rec_message = new byte[p.getMessageLength()];//p.getMessageLength()
int ExpFE;
final int numSegments = p.getSegmentsPerSlice();
final int logOfField = p.getLogOfFieldLength();
final int[] COLBIT = InitField.getCOLBIT(logOfField);
final int[] BIT = InitField.getBIT(logOfField);
final int[] ExptoFE = InitField.getExptoFE(logOfField);
final int[] FEtoExp = InitField.getFEtoExp(logOfField);
final int numDataSlices = p.getNumDataSlices();
final int numCodeSlices = p.getNumCodeSlices();
Integer key = new Integer(p.getNumDataSlices() + numSegments * p.getNumCodeSlices()
* logOfField);
FiniteStack stack = (FiniteStack) _decodeTable.get(key);
if (stack == null)
{
synchronized (_decodeTable)
{
if ((stack = (FiniteStack) _decodeTable.get(key)) == null)
{
Object bucket = null;
stack = new FiniteStack(STACK_SIZE);
if ((bucket = _decodeTable.put(key, stack)) != null)
System.err.println("CosetDecode.decode: bucket=" + bucket
+ " for key=" + key + " stack=" + stack);
}
}
}
ArrayObj arrayObj = (ArrayObj) stack.pop();
if (arrayObj == null)
arrayObj = new ArrayObj(p.getNumDataSlices(), p.getNumCodeSlices(), numSegments, logOfField);
int[] Rec_index = arrayObj.Rec_index;
int[] Col_Ind = arrayObj.Col_Ind;
int[] Row_Ind = arrayObj.Row_Ind;
byte[] M = arrayObj.M;
int[] C = arrayObj.C;
int[] D = arrayObj.D;
int[] E = arrayObj.E;
int[] F = arrayObj.F;
if (Nrec < p.getNumDataSlices()+p.getNumCodeSlices())
{
//throw new Exception("Decode error!!!!");
System.out.println("Decode error!!!!=========="+Nrec+"tot:"+(p.getNumDataSlices()+p.getNumCodeSlices()));
}
// coset ==================================================coset begin===============
// For Loop Iterators
int itr, row, col, rowEquation, columnEquation;
// Miscellaneous variables used in code slice calculation
int sliceArrayPosition, messageArrayPosition;
int ExpFEplusRow;
int arrayPositionDifference, sliceArrayPositionPlusNumSegments;
int sliceArrayIterator;
final int[] equationBitMask = InitField.getBIT(p.getLogOfFieldLength());
final int[] exponentToFiniteFieldElement = InitField.getExptoFE(p.getLogOfFieldLength());
final int[] finiteFieldElementToExponent = InitField.getFEtoExp(p.getLogOfFieldLength());
final int multFieldSize = p.getMultiplicationFieldSize();
InitField.generateG(logOfField, numDataSlices, numCodeSlices);
final int[][] G= InitField.getG();
for ( row = 0; row <numDataSlices; row++)
{
/**
* Compute values of equations applied to message and fill into
* fragment(row+DataSlices).
*/
final int rowOffset = ((row) * p.getSliceLength()); // p.getTotalSliceLength()
/**
* Second, fill in contents relevant portions of fragment
*/
for ( col = 0; col < numDataSlices+numCodeSlices ; col++)
{
//message->code
messageArrayPosition = col * (p.getSliceLength()+1)+1;
//if(messageArrayPosition==0)messageArrayPosition=1;
// System.out.println("messageArrayPosition:"+messageArrayPosition);
/* ExpFE = (multFieldSize - finiteFieldElementToExponent[row ^ col ^ COLBIT[0]])
% multFieldSize;*/
// System.out.println("row:"+row+"col:"+col);
// System.out.println("G[row][col]:"+G[row][col]);
ExpFE = finiteFieldElementToExponent[G[row][col]];
for (rowEquation = 0; rowEquation < logOfField; rowEquation++)
{
ExpFEplusRow = ExpFE + rowEquation;
sliceArrayPosition = rowOffset + (rowEquation * numSegments);
// System.out.println("rowOffset:"+rowOffset);
// System.out.println("sliceArrayPosition:"+sliceArrayPosition);
for (columnEquation = 0; columnEquation < logOfField; columnEquation++)
{
// System.out.print((exponentToFiniteFieldElement[ExpFE + columnEquation] & equationBitMask[rowEquation])>0?1:0);
// System.out.println("columnEquation"+columnEquation+"ExpFEplusRow");
if ((exponentToFiniteFieldElement[ExpFE + columnEquation] & equationBitMask[rowEquation]) > 0)
{
/*
* Warning: the following code is heavily optimized and difficult to read
* The following loop is the result of much optimization
* and is an attempt to use as few instructions as possible
* within this very deeply nested loop.
*/
arrayPositionDifference = ((columnEquation * numSegments + messageArrayPosition) - sliceArrayPosition);
sliceArrayPositionPlusNumSegments = sliceArrayPosition + numSegments;
sliceArrayIterator = sliceArrayPosition;
// System.out.println("numSegments"+numSegments+"sliceArrayPosition"+sliceArrayPosition+"sliceArrayPositionPlusNumSegments"+sliceArrayPositionPlusNumSegments+"sliceArrayIterator + arrayPositionDifference:"+(sliceArrayIterator + arrayPositionDifference));
assert(sliceArrayPosition<rec_message.length);
while (sliceArrayIterator < sliceArrayPositionPlusNumSegments)
{
// System.out.println("sliceArrayIterator"+sliceArrayIterator+" arrayPositionDifference:"+( arrayPositionDifference));
//if(sliceArrayIterator==4144) sliceArrayIterator=4143;
rec_message[sliceArrayIterator] ^= rec_fragments[sliceArrayIterator + arrayPositionDifference];
sliceArrayIterator++;
}
}
}
// System.out.print("/n");
}
}
}
/* System.out.println("=======================rec_message=====================:"+rec_message.length);
printHexString(rec_message);
System.out.println("=======================rec_message=====================");*/
return rec_message;
}