public override string Encode(byte[] data)
{
if (data == null || data.Length == 0)
return "";
int blockBitsCount, blockCharsCount;
if (!MaxCompression)
{
blockBitsCount = BlockBitsCount;
blockCharsCount = BlockCharsCount;
}
else
{
blockBitsCount = data.Length * 8;
blockCharsCount = (int)Math.Ceiling(blockBitsCount * Math.Log(2, Alphabet.Length));
PreparePowN(blockCharsCount);
}
int mainBitsLength = (data.Length * 8 / blockBitsCount) * blockBitsCount;
int tailBitsLength = data.Length * 8 - mainBitsLength;
int globalBitsLength = mainBitsLength + tailBitsLength;
int mainCharsCount = mainBitsLength * blockCharsCount / blockBitsCount;
int tailCharsCount = (tailBitsLength * blockCharsCount + blockBitsCount - 1) / blockBitsCount;
int globalCharsCount = mainCharsCount + tailCharsCount;
int iterationCount = mainCharsCount / blockCharsCount;
var result = new char[globalCharsCount];
if (!Parallel)
EncodeBlock(data, result, 0, iterationCount, blockBitsCount, blockCharsCount);
else
{
int processorCount = Math.Min(iterationCount, Environment.ProcessorCount);
System.Threading.Tasks.Parallel.For(0, processorCount, i =>
{
int beginInd = i * iterationCount / processorCount;
int endInd = (i + 1) * iterationCount / processorCount;
EncodeBlock(data, result, beginInd, endInd, blockBitsCount, blockCharsCount);
});
}
if (tailBitsLength != 0)
{
BigInteger bits = GetBitsN(data, mainBitsLength, tailBitsLength);
BitsToChars(result, mainCharsCount, tailCharsCount, bits);
}
return new string(result);
}