Files
SuperVPN/output/Libraries/MessagingToolkit.QRCode/MessagingToolkit/QRCode/Codec/Reader/QRCodeDataBlockReader.cs
2025-10-09 09:57:24 +09:00

426 lines
8.7 KiB
C#

using System;
using System.IO;
using MessagingToolkit.QRCode.Codec.Util;
using MessagingToolkit.QRCode.ExceptionHandler;
namespace MessagingToolkit.QRCode.Codec.Reader;
public class QRCodeDataBlockReader
{
private const int MODE_NUMBER = 1;
private const int MODE_ROMAN_AND_NUMBER = 2;
private const int MODE_8BIT_BYTE = 4;
private const int MODE_KANJI = 8;
internal int[] blocks;
internal int dataLengthMode;
internal int blockPointer;
internal int bitPointer;
internal int dataLength;
internal int numErrorCorrectionCode;
internal DebugCanvas canvas;
private int[][] sizeOfDataLengthInfo = new int[3][]
{
new int[4] { 10, 9, 8, 8 },
new int[4] { 12, 11, 16, 10 },
new int[4] { 14, 13, 16, 12 }
};
internal virtual int NextMode
{
get
{
if (blockPointer > blocks.Length - numErrorCorrectionCode - 2)
{
return 0;
}
return getNextBits(4);
}
}
public virtual sbyte[] DataByte
{
get
{
canvas.println("Reading data blocks.");
MemoryStream memoryStream = new MemoryStream();
try
{
while (true)
{
int nextMode = NextMode;
switch (nextMode)
{
case 0:
if (memoryStream.Length > 0)
{
goto end_IL_0019;
}
throw new InvalidDataBlockException("Empty data block");
default:
if (nextMode != 8)
{
throw new InvalidDataBlockException("Invalid mode: " + nextMode + " in (block:" + blockPointer + " bit:" + bitPointer + ")");
}
break;
case 1:
case 2:
case 4:
break;
}
dataLength = getDataLength(nextMode);
if (dataLength < 1)
{
throw new InvalidDataBlockException("Invalid data length: " + dataLength);
}
switch (nextMode)
{
case 1:
{
sbyte[] array4 = SystemUtils.ToSByteArray(SystemUtils.ToByteArray(getFigureString(dataLength)));
memoryStream.Write(SystemUtils.ToByteArray(array4), 0, array4.Length);
break;
}
case 2:
{
sbyte[] array3 = SystemUtils.ToSByteArray(SystemUtils.ToByteArray(getRomanAndFigureString(dataLength)));
memoryStream.Write(SystemUtils.ToByteArray(array3), 0, array3.Length);
break;
}
case 4:
{
sbyte[] array2 = get8bitByteArray(dataLength);
memoryStream.Write(SystemUtils.ToByteArray(array2), 0, array2.Length);
break;
}
case 8:
{
sbyte[] array = SystemUtils.ToSByteArray(SystemUtils.ToByteArray(getKanjiString(dataLength)));
memoryStream.Write(SystemUtils.ToByteArray(array), 0, array.Length);
break;
}
}
bool flag = true;
continue;
end_IL_0019:
break;
}
}
catch (IndexOutOfRangeException throwable)
{
SystemUtils.WriteStackTrace(throwable, Console.Error);
throw new InvalidDataBlockException("Data Block Error in (block:" + blockPointer + " bit:" + bitPointer + ")");
}
catch (IOException ex)
{
throw new InvalidDataBlockException(ex.Message);
}
return SystemUtils.ToSByteArray(memoryStream.ToArray());
}
}
public virtual string DataString
{
get
{
canvas.println("Reading data blocks...");
string text = "";
while (true)
{
int nextMode = NextMode;
canvas.println("mode: " + nextMode);
if (nextMode == 0)
{
break;
}
if (nextMode == 1 || nextMode == 2 || nextMode == 4 || nextMode != 8)
{
}
dataLength = getDataLength(nextMode);
canvas.println(Convert.ToString(blocks[blockPointer]));
Console.Out.WriteLine("length: " + dataLength);
switch (nextMode)
{
case 1:
text += getFigureString(dataLength);
break;
case 2:
text += getRomanAndFigureString(dataLength);
break;
case 4:
text += get8bitByteString(dataLength);
break;
case 8:
text += getKanjiString(dataLength);
break;
}
bool flag = true;
}
Console.Out.WriteLine("");
return text;
}
}
public QRCodeDataBlockReader(int[] blocks, int version, int numErrorCorrectionCode)
{
blockPointer = 0;
bitPointer = 7;
dataLength = 0;
this.blocks = blocks;
this.numErrorCorrectionCode = numErrorCorrectionCode;
if (version <= 9)
{
dataLengthMode = 0;
}
else if (version >= 10 && version <= 26)
{
dataLengthMode = 1;
}
else if (version >= 27 && version <= 40)
{
dataLengthMode = 2;
}
canvas = QRCodeDecoder.Canvas;
}
internal virtual int getNextBits(int numBits)
{
int num = 0;
if (numBits < bitPointer + 1)
{
int num2 = 0;
for (int i = 0; i < numBits; i++)
{
num2 += 1 << i;
}
num2 <<= bitPointer - numBits + 1;
num = (blocks[blockPointer] & num2) >> bitPointer - numBits + 1;
bitPointer -= numBits;
return num;
}
if (numBits < bitPointer + 1 + 8)
{
int num3 = 0;
for (int i = 0; i < bitPointer + 1; i++)
{
num3 += 1 << i;
}
num = (blocks[blockPointer] & num3) << numBits - (bitPointer + 1);
blockPointer++;
num += blocks[blockPointer] >> 8 - (numBits - (bitPointer + 1));
bitPointer -= numBits % 8;
if (bitPointer < 0)
{
bitPointer = 8 + bitPointer;
}
return num;
}
if (numBits < bitPointer + 1 + 16)
{
int num3 = 0;
int num4 = 0;
for (int i = 0; i < bitPointer + 1; i++)
{
num3 += 1 << i;
}
int num5 = (blocks[blockPointer] & num3) << numBits - (bitPointer + 1);
blockPointer++;
int num6 = blocks[blockPointer] << numBits - (bitPointer + 1 + 8);
blockPointer++;
for (int i = 0; i < numBits - (bitPointer + 1 + 8); i++)
{
num4 += 1 << i;
}
num4 <<= 8 - (numBits - (bitPointer + 1 + 8));
int num7 = (blocks[blockPointer] & num4) >> 8 - (numBits - (bitPointer + 1 + 8));
num = num5 + num6 + num7;
bitPointer -= (numBits - 8) % 8;
if (bitPointer < 0)
{
bitPointer = 8 + bitPointer;
}
return num;
}
Console.Out.WriteLine("ERROR!");
return 0;
}
internal virtual int guessMode(int mode)
{
return mode switch
{
3 => 1,
5 => 4,
6 => 4,
7 => 4,
9 => 8,
10 => 8,
11 => 8,
12 => 4,
13 => 4,
14 => 4,
15 => 4,
_ => 8,
};
}
internal virtual int getDataLength(int modeIndicator)
{
int num = 0;
while (true)
{
bool flag = true;
if (modeIndicator >> num == 1)
{
break;
}
num++;
}
return getNextBits(sizeOfDataLengthInfo[dataLengthMode][num]);
}
internal virtual string getFigureString(int dataLength)
{
int num = dataLength;
int num2 = 0;
string text = "";
do
{
if (num >= 3)
{
num2 = getNextBits(10);
if (num2 < 100)
{
text += "0";
}
if (num2 < 10)
{
text += "0";
}
num -= 3;
}
else
{
switch (num)
{
case 2:
num2 = getNextBits(7);
if (num2 < 10)
{
text += "0";
}
num -= 2;
break;
case 1:
num2 = getNextBits(4);
num--;
break;
}
}
text += Convert.ToString(num2);
}
while (num > 0);
return text;
}
internal virtual string getRomanAndFigureString(int dataLength)
{
int num = dataLength;
int num2 = 0;
string text = "";
char[] array = new char[45]
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*',
'+', '-', '.', '/', ':'
};
do
{
if (num > 1)
{
num2 = getNextBits(11);
int num3 = num2 / 45;
int num4 = num2 % 45;
text += Convert.ToString(array[num3]);
text += Convert.ToString(array[num4]);
num -= 2;
}
else if (num == 1)
{
num2 = getNextBits(6);
text += Convert.ToString(array[num2]);
num--;
}
}
while (num > 0);
return text;
}
public virtual sbyte[] get8bitByteArray(int dataLength)
{
int num = dataLength;
int num2 = 0;
MemoryStream memoryStream = new MemoryStream();
do
{
canvas.println("Length: " + num);
num2 = getNextBits(8);
memoryStream.WriteByte((byte)num2);
num--;
}
while (num > 0);
return SystemUtils.ToSByteArray(memoryStream.ToArray());
}
internal virtual string get8bitByteString(int dataLength)
{
int num = dataLength;
int num2 = 0;
string text = "";
do
{
num2 = getNextBits(8);
text += (char)num2;
num--;
}
while (num > 0);
return text;
}
internal virtual string getKanjiString(int dataLength)
{
int num = dataLength;
int num2 = 0;
string text = "";
do
{
num2 = getNextBits(13);
int num3 = num2 % 192;
int num4 = num2 / 192;
int num5 = (num4 << 8) + num3;
int num6 = 0;
num6 = ((num5 + 33088 > 40956) ? (num5 + 49472) : (num5 + 33088));
text += new string(SystemUtils.ToCharArray(SystemUtils.ToByteArray(new sbyte[2]
{
(sbyte)(num6 >> 8),
(sbyte)(num6 & 0xFF)
})));
num--;
}
while (num > 0);
return text;
}
}