cc-mc-server/mc/string_pack.lua

1 line
13 KiB
Lua
Raw Permalink Normal View History

2024-07-14 14:23:30 +01:00
local a=dofile"/rom/modules/main/cc/expect.lua".expect;local b={BIG_ENDIAN=1,LITTLE_ENDIAN=2}local c={b=1,B=1,h=1,H=1,l=1,L=1,j=1,J=1,T=1}local d={b=1,B=1,x=1,h=2,H=2,f=4,j=4,J=4,l=8,L=8,T=8,d=8,n=8}local function e(f)if f%1>=0.5 then return math.ceil(f)else return math.floor(f)end end;local function g(h)if h==0 then return 0 elseif h==-0 then return 0x80000000 elseif h==math.huge then return 0x7F800000 elseif h==-math.huge then return 0xFF800000 end;local i,j=math.frexp(h)if j>127 or j<-126 then error("number out of range",3)end;j,i=j+126,e((math.abs(i)-0.5)*0x1000000)if i>0x7FFFFF then j=j+1 end;return bit32.bor(h<0 and 0x80000000 or 0,bit32.lshift(bit32.band(j,0xFF),23),bit32.band(i,0x7FFFFF))end;local function k(h)if h==0 then return 0,0 elseif h==-0 then return 0x80000000,0 elseif h==math.huge then return 0x7FF00000,0 elseif h==-math.huge then return 0xFFF00000,0 end;local i,j=math.frexp(h)if j>1023 or j<-1022 then error("number out of range",3)end;j,i=j+1022,e((math.abs(i)-0.5)*0x20000000000000)if i>0xFFFFFFFFFFFFF then j=j+1 end;return bit32.bor(h<0 and 0x80000000 or 0,bit32.lshift(bit32.band(j,0x7FF),20),bit32.band(i/0x100000000,0xFFFFF)),bit32.band(i,0xFFFFFFFF)end;local function l(m)if m==0 then return 0 elseif m==0x80000000 then return-0 elseif m==0x7F800000 then return math.huge elseif m==0xFF800000 then return-math.huge end;local i,j=bit32.band(m,0x7FFFFF),bit32.band(bit32.rshift(m,23),0xFF)j,i=j-126,i/0x1000000+0.5;local f=math.ldexp(i,j)return bit32.btest(m,0x80000000)and-f or f end;local function n(o,p)if o==0 and p==0 then return 0 elseif o==0x80000000 and p==0 then return-0 elseif o==0x7FF00000 and p==0 then return math.huge elseif o==0xFFF00000 and p==0 then return-math.huge end;local i,j=bit32.band(o,0xFFFFF)*0x100000000+bit32.band(p,0xFFFFFFFF),bit32.band(bit32.rshift(o,20),0x7FF)j,i=j-1022,i/0x20000000000000+0.5;local f=math.ldexp(i,j)return bit32.btest(o,0x80000000)and-f or f end;local function q(r,s,t,u,v,w,x)local y=0;if u%math.min(s,v)~=0 and v>1 then local z=0;while u%math.min(s,v)~=0 and z<v do t[u]=0;u=u+1;y=y+1;z=z+1 end end;if w==b.BIG_ENDIAN then local A=0;if s>8 then for z=0,s-9 do t[u+z]=x and r>=2^(s*8-1)~=0 and 0xFF or 0;A=A+1;y=y+1 end end;for z=A,s-1 do t[u+z]=bit32.band(bit32.rshift(r,(s-z-1)*8),0xFF)y=y+1 end else for z=0,math.min(s,8)-1 do t[u+z]=r/2^(z*8)%256;y=y+1 end;for z=8,s-1 do t[u+z]=x and r>=2^(s*8-1)~=0 and 0xFF or 0;y=y+1 end end;return y end;local function B(C,u,s,w,v,x)local D,E=0,0;if u%math.min(s,v)~=0 and v>1 then for z=0,v-1 do if u%math.min(s,v)==0 then break end;u=u+1;E=E+1 end end;for z=0,s-1 do D=D+C:byte(u+z)*2^((w==b.BIG_ENDIAN and s-z-1 or z)*8)E=E+1 end;if x and D>=2^(s*8-1)then D=D-2^(s*8)end;return D,E end;local function F(G,v)local H=d[G]or 0;if v>1 and H%v~=0 then H=H+v-H%v end;return H end;local function I(...)local J=a(1,...,"string")local w=b.LITTLE_ENDIAN;local v=1;local K=1;local L=2;local t={}local z=1;while z<=#J do local M=J:sub(z,z)z=z+1;if M=='='or M=='<'then w=b.LITTLE_ENDIAN elseif M=='>'then w=b.BIG_ENDIAN elseif M=='!'then local s=-1;while z<=#J and J:sub(z,z):match("%d")do if s>=0xFFFFFFFF/10 then error("bad argument #1 to 'pack' (invalid format)",2)end;s=math.max(s,0)*10+tonumber(J:sub(z,z))z=z+1 end;if s>16 or s==0 then error(string.format("integral size (%d) out of limits [1,16]",s),2)elseif s==-1 then v=4 else v=s end elseif c[M]then local r=a(L,select(L,...),"number")L=L+1;if r>=math.pow(2,F(M,0)*8-(M:match("%l")and 1 or 0))or r<(M:match("%l")and-math.pow(2,F(M,0)*8-1)or 0)then error(string.format("bad argument #%d to 'pack' (integer overflow)",L-1),2)end;K=K+q(r,F(M,0),t,K,v,w,false)elseif M:lower()=='i'then local x=M=='i'local s=-1;while z<=#J and J:sub(z,z):match("%d")do if s>=0xFFFFFFFF/10 then error("bad argument #1 to 'pack' (invalid format)",2)end;s=math.max(s,0)*10+tonumber(J:sub(z,z))z=z+1 end;if s>16 or s==0 then error(string.format("integral size (%d) out of limits [1,16]",s),2)elseif v>1 and(s~=1 and s~=2 and s~=4 and s~=8 and s~=16)then error("bad argument #1 to 'pack' (format asks for alignment not power of 2)",2)else