226 lines
6.6 KiB
C#
226 lines
6.6 KiB
C#
// Converts integers to characters and back. Mainly used by save transfer.
|
|
// -------------------------------------------------------------------
|
|
|
|
//Binary compression (file version, 241 allowed characters)
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
//Creates byte lookup table
|
|
function ndCreateByte241Table()
|
|
{
|
|
$ND::Byte241Lookup = "";
|
|
|
|
//This will map uints 0-241 to chars 15-255, starting after \r
|
|
for(%i = 15; %i < 256; %i++)
|
|
{
|
|
%char = collapseEscape("\\x" @
|
|
getSubStr("0123456789abcdef", (%i & 0xf0) >> 4, 1) @
|
|
getSubStr("0123456789abcdef", %i & 0x0f, 1));
|
|
|
|
$ND::Byte241ToChar[%i - 15] = %char;
|
|
$ND::Byte241Lookup = $ND::Byte241Lookup @ %char;
|
|
}
|
|
|
|
$ND::Byte241TableCreated = true;
|
|
}
|
|
|
|
//Packs uint in single byte
|
|
function ndPack241_1(%num)
|
|
{
|
|
return $ND::Byte241ToChar[%num];
|
|
}
|
|
|
|
//Packs uint in two bytes
|
|
function ndPack241_2(%num)
|
|
{
|
|
return $ND::Byte241ToChar[(%num / 241) | 0] @ $ND::Byte241ToChar[%num % 241];
|
|
}
|
|
|
|
//Packs uint in three bytes
|
|
function ndPack241_3(%num)
|
|
{
|
|
return
|
|
$ND::Byte241ToChar[(((%num / 241) | 0) / 241) | 0] @
|
|
$ND::Byte241ToChar[((%num / 241) | 0) % 241] @
|
|
$ND::Byte241ToChar[%num % 241];
|
|
}
|
|
|
|
//Packs uint in four bytes
|
|
function ndPack241_4(%num)
|
|
{
|
|
return
|
|
$ND::Byte241ToChar[(((((%num / 241) | 0) / 241) | 0) / 241) | 0] @
|
|
$ND::Byte241ToChar[((((%num / 241) | 0) / 241) | 0) % 241] @
|
|
$ND::Byte241ToChar[((%num / 241) | 0) % 241] @
|
|
$ND::Byte241ToChar[%num % 241];
|
|
}
|
|
|
|
//Unpacks uint from single byte
|
|
function ndUnpack241_1(%subStr)
|
|
{
|
|
return strStr($ND::Byte241Lookup, %subStr);
|
|
}
|
|
|
|
//Unpacks uint from two bytes
|
|
function ndUnpack241_2(%subStr)
|
|
{
|
|
return
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 0, 1)) * 241 +
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 1, 1));
|
|
}
|
|
|
|
//Unpacks uint from three bytes
|
|
function ndUnpack241_3(%subStr)
|
|
{
|
|
return
|
|
((strStr($ND::Byte241Lookup, getSubStr(%subStr, 0, 1)) * 58081) | 0) +
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 1, 1)) * 241 +
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 2, 1));
|
|
}
|
|
|
|
//Unpacks uint from four bytes
|
|
function ndUnpack241_4(%subStr)
|
|
{
|
|
return
|
|
((strStr($ND::Byte241Lookup, getSubStr(%subStr, 0, 1)) * 13997521) | 0) +
|
|
((strStr($ND::Byte241Lookup, getSubStr(%subStr, 1, 1)) * 58081) | 0) +
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 2, 1)) * 241 +
|
|
strStr($ND::Byte241Lookup, getSubStr(%subStr, 3, 1));
|
|
}
|
|
|
|
|
|
|
|
//Binary compression (command version, 255 allowed characters)
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
//Creates byte lookup table
|
|
function ndCreateByte255Table()
|
|
{
|
|
$ND::Byte255Lookup = "";
|
|
|
|
//This will map uints 0-254 to chars 1-255, starting after \x00
|
|
for(%i = 1; %i < 256; %i++)
|
|
{
|
|
%char = collapseEscape("\\x" @
|
|
getSubStr("0123456789abcdef", (%i & 0xf0) >> 4, 1) @
|
|
getSubStr("0123456789abcdef", %i & 0x0f, 1));
|
|
|
|
$ND::Byte255ToChar[%i - 1] = %char;
|
|
$ND::Byte255Lookup = $ND::Byte255Lookup @ %char;
|
|
}
|
|
|
|
$ND::Byte255TableCreated = true;
|
|
}
|
|
|
|
//Packs uint in single byte
|
|
function ndPack255_1(%num)
|
|
{
|
|
return $ND::Byte255ToChar[%num];
|
|
}
|
|
|
|
//Packs uint in two bytes
|
|
function ndPack255_2(%num)
|
|
{
|
|
return $ND::Byte255ToChar[(%num / 255) | 0] @ $ND::Byte255ToChar[%num % 255];
|
|
}
|
|
|
|
//Packs uint in three bytes
|
|
function ndPack255_3(%num)
|
|
{
|
|
return
|
|
$ND::Byte255ToChar[(((%num / 255) | 0) / 255) | 0] @
|
|
$ND::Byte255ToChar[((%num / 255) | 0) % 255] @
|
|
$ND::Byte255ToChar[%num % 255];
|
|
}
|
|
|
|
//Packs uint in four bytes
|
|
function ndPack255_4(%num)
|
|
{
|
|
return
|
|
$ND::Byte255ToChar[(((((%num / 255) | 0) / 255) | 0) / 255) | 0] @
|
|
$ND::Byte255ToChar[((((%num / 255) | 0) / 255) | 0) % 255] @
|
|
$ND::Byte255ToChar[((%num / 255) | 0) % 255] @
|
|
$ND::Byte255ToChar[%num % 255];
|
|
}
|
|
|
|
//Unpacks uint from single byte
|
|
function ndUnpack255_1(%subStr)
|
|
{
|
|
return strStr($ND::Byte255Lookup, %subStr);
|
|
}
|
|
|
|
//Unpacks uint from two bytes
|
|
function ndUnpack255_2(%subStr)
|
|
{
|
|
return
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 0, 1)) * 255 +
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 1, 1));
|
|
}
|
|
|
|
//Unpacks uint from three bytes
|
|
function ndUnpack255_3(%subStr)
|
|
{
|
|
return
|
|
((strStr($ND::Byte255Lookup, getSubStr(%subStr, 0, 1)) * 65025) | 0) +
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 1, 1)) * 255 +
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 2, 1)) | 0;
|
|
}
|
|
|
|
//Unpacks uint from four bytes
|
|
function ndUnpack255_4(%subStr)
|
|
{
|
|
return
|
|
((strStr($ND::Byte255Lookup, getSubStr(%subStr, 0, 1)) * 16581375) | 0) +
|
|
((strStr($ND::Byte255Lookup, getSubStr(%subStr, 1, 1)) * 65025) | 0) +
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 2, 1)) * 255 +
|
|
strStr($ND::Byte255Lookup, getSubStr(%subStr, 3, 1)) | 0;
|
|
}
|
|
|
|
//Some tests for the packing functions
|
|
function ndTestPack255()
|
|
{
|
|
echo("Testing 1 byte");
|
|
echo(ndUnpack255_1(ndPack255_1(0)) == 0);
|
|
echo(ndUnpack255_1(ndPack255_1(123)) == 123);
|
|
echo(ndUnpack255_1(ndPack255_1(231)) == 231);
|
|
echo(ndUnpack255_1(ndPack255_1(254)) == 254);
|
|
|
|
echo("Testing 2 byte");
|
|
echo(ndUnpack255_2(ndPack255_2(0)) == 0);
|
|
echo(ndUnpack255_2(ndPack255_2(123)) == 123);
|
|
echo(ndUnpack255_2(ndPack255_2(231)) == 231);
|
|
echo(ndUnpack255_2(ndPack255_2(254)) == 254);
|
|
echo(ndUnpack255_2(ndPack255_2(12345)) == 12345);
|
|
echo(ndUnpack255_2(ndPack255_2(32145)) == 32145);
|
|
echo(ndUnpack255_2(ndPack255_2(65024)) == 65024);
|
|
|
|
echo("Testing 3 byte");
|
|
echo(ndUnpack255_3(ndPack255_3(0)) == 0);
|
|
echo(ndUnpack255_3(ndPack255_3(123)) == 123);
|
|
echo(ndUnpack255_3(ndPack255_3(231)) == 231);
|
|
echo(ndUnpack255_3(ndPack255_3(254)) == 254);
|
|
echo(ndUnpack255_3(ndPack255_3(12345)) == 12345);
|
|
echo(ndUnpack255_3(ndPack255_3(32145)) == 32145);
|
|
echo(ndUnpack255_3(ndPack255_3(65024)) == 65024);
|
|
echo(ndUnpack255_3(ndPack255_3(11234567)) == 11234567);
|
|
echo(ndUnpack255_3(ndPack255_3(14132451)) == 14132451);
|
|
echo(ndUnpack255_3(ndPack255_3(16581374)) == 16581374);
|
|
|
|
echo("Testing 4 byte");
|
|
echo(ndUnpack255_4(ndPack255_4(0)) == 0);
|
|
echo(ndUnpack255_4(ndPack255_4(123)) == 123);
|
|
echo(ndUnpack255_4(ndPack255_4(231)) == 231);
|
|
echo(ndUnpack255_4(ndPack255_4(254)) == 254);
|
|
echo(ndUnpack255_4(ndPack255_4(12345)) == 12345);
|
|
echo(ndUnpack255_4(ndPack255_4(32145)) == 32145);
|
|
echo(ndUnpack255_4(ndPack255_4(65024)) == 65024);
|
|
echo(ndUnpack255_4(ndPack255_4(11234567)) == 11234567);
|
|
echo(ndUnpack255_4(ndPack255_4(14132451)) == 14132451);
|
|
echo(ndUnpack255_4(ndPack255_4(16581374)) == 16581374);
|
|
echo(ndUnpack255_4(ndPack255_4(1234567890)) == 1234567890);
|
|
|
|
//Appearantly tork uses uint and normal int randomly in
|
|
//seperate places so we can't use the full uint range
|
|
echo(ndUnpack255_4(ndPack255_4(2147483647)) == 2147483647);
|
|
echo(ndUnpack255_4(ndPack255_4(2147483648)) != 2147483648);
|
|
}
|