mirror of https://github.com/koreader/koreader
serialize the most recently used blitbuffer/koptcontext
to speedup koreader startup for PDF/DJVU documents especially when reflowingpull/562/head
parent
f9302cd17d
commit
775e5ea3b4
@ -0,0 +1,233 @@
|
||||
|
||||
local ffi = require "ffi"
|
||||
local bit = require "bit"
|
||||
local bxor = bit.bxor
|
||||
local bnot = bit.bnot
|
||||
local band = bit.band
|
||||
local bor = bit.bor
|
||||
local rshift = bit.rshift
|
||||
local lshift = bit.lshift
|
||||
|
||||
require "memutils"
|
||||
require "stringzutils"
|
||||
|
||||
ffi.cdef[[
|
||||
typedef struct MD5Context {
|
||||
uint32_t buf[4];
|
||||
uint32_t bits[2];
|
||||
unsigned char input[64];
|
||||
} MD5_CTX;
|
||||
]]
|
||||
|
||||
MD5_CTX = ffi.typeof("MD5_CTX");
|
||||
|
||||
function byteReverse(buf, len)
|
||||
end
|
||||
|
||||
function F1(x, y, z) return bxor(z, band(x, bxor(y, z))) end
|
||||
function F2(x, y, z) return F1(z, x, y) end
|
||||
function F3(x, y, z) return bxor(x, y, z) end
|
||||
function F4(x, y, z) return bxor(y, bor(x, bnot(z))) end
|
||||
|
||||
function MD5STEP(f, w, x, y, z, data, s)
|
||||
w = w + f(x, y, z) + data;
|
||||
w = bor(lshift(w,s), rshift(w,(32-s)))
|
||||
w = w + x;
|
||||
|
||||
return w;
|
||||
end
|
||||
|
||||
function printmd5ctx(ctx)
|
||||
for i=0,3 do
|
||||
print(string.format("ctx.buf[%d]: 0x%x", i, ctx.buf[i]));
|
||||
end
|
||||
|
||||
print(string.format("ctx.bits[0]: %d", ctx.bits[0]));
|
||||
print(string.format("ctx.bits[1]: %d", ctx.bits[1]));
|
||||
end
|
||||
|
||||
-- Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
-- initialization constants.
|
||||
function MD5Init(ctx)
|
||||
ctx.buf[0] = 0x67452301;
|
||||
ctx.buf[1] = 0xefcdab89;
|
||||
ctx.buf[2] = 0x98badcfe;
|
||||
ctx.buf[3] = 0x10325476;
|
||||
|
||||
ctx.bits[0] = 0;
|
||||
ctx.bits[1] = 0;
|
||||
end
|
||||
|
||||
function MD5Transform(buf, input)
|
||||
local a = buf[0];
|
||||
local b = buf[1];
|
||||
local c = buf[2];
|
||||
local d = buf[3];
|
||||
|
||||
a = MD5STEP(F1, a, b, c, d, input[0] + 0xd76aa478, 7);
|
||||
d = MD5STEP(F1, d, a, b, c, input[1] + 0xe8c7b756, 12);
|
||||
c = MD5STEP(F1, c, d, a, b, input[2] + 0x242070db, 17);
|
||||
b = MD5STEP(F1, b, c, d, a, input[3] + 0xc1bdceee, 22);
|
||||
a = MD5STEP(F1, a, b, c, d, input[4] + 0xf57c0faf, 7);
|
||||
d = MD5STEP(F1, d, a, b, c, input[5] + 0x4787c62a, 12);
|
||||
c = MD5STEP(F1, c, d, a, b, input[6] + 0xa8304613, 17);
|
||||
b = MD5STEP(F1, b, c, d, a, input[7] + 0xfd469501, 22);
|
||||
a = MD5STEP(F1, a, b, c, d, input[8] + 0x698098d8, 7);
|
||||
d = MD5STEP(F1, d, a, b, c, input[9] + 0x8b44f7af, 12);
|
||||
c = MD5STEP(F1, c, d, a, b, input[10] + 0xffff5bb1, 17);
|
||||
b = MD5STEP(F1, b, c, d, a, input[11] + 0x895cd7be, 22);
|
||||
a = MD5STEP(F1, a, b, c, d, input[12] + 0x6b901122, 7);
|
||||
d = MD5STEP(F1, d, a, b, c, input[13] + 0xfd987193, 12);
|
||||
c = MD5STEP(F1, c, d, a, b, input[14] + 0xa679438e, 17);
|
||||
b = MD5STEP(F1, b, c, d, a, input[15] + 0x49b40821, 22);
|
||||
|
||||
a = MD5STEP(F2, a, b, c, d, input[1] + 0xf61e2562, 5);
|
||||
d = MD5STEP(F2, d, a, b, c, input[6] + 0xc040b340, 9);
|
||||
c = MD5STEP(F2, c, d, a, b, input[11] + 0x265e5a51, 14);
|
||||
b = MD5STEP(F2, b, c, d, a, input[0] + 0xe9b6c7aa, 20);
|
||||
a = MD5STEP(F2, a, b, c, d, input[5] + 0xd62f105d, 5);
|
||||
d = MD5STEP(F2, d, a, b, c, input[10] + 0x02441453, 9);
|
||||
c = MD5STEP(F2, c, d, a, b, input[15] + 0xd8a1e681, 14);
|
||||
b = MD5STEP(F2, b, c, d, a, input[4] + 0xe7d3fbc8, 20);
|
||||
a = MD5STEP(F2, a, b, c, d, input[9] + 0x21e1cde6, 5);
|
||||
d = MD5STEP(F2, d, a, b, c, input[14] + 0xc33707d6, 9);
|
||||
c = MD5STEP(F2, c, d, a, b, input[3] + 0xf4d50d87, 14);
|
||||
b = MD5STEP(F2, b, c, d, a, input[8] + 0x455a14ed, 20);
|
||||
a = MD5STEP(F2, a, b, c, d, input[13] + 0xa9e3e905, 5);
|
||||
d = MD5STEP(F2, d, a, b, c, input[2] + 0xfcefa3f8, 9);
|
||||
c = MD5STEP(F2, c, d, a, b, input[7] + 0x676f02d9, 14);
|
||||
b = MD5STEP(F2, b, c, d, a, input[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
a = MD5STEP(F3, a, b, c, d, input[5] + 0xfffa3942, 4);
|
||||
d = MD5STEP(F3, d, a, b, c, input[8] + 0x8771f681, 11);
|
||||
c = MD5STEP(F3, c, d, a, b, input[11] + 0x6d9d6122, 16);
|
||||
b = MD5STEP(F3, b, c, d, a, input[14] + 0xfde5380c, 23);
|
||||
a = MD5STEP(F3, a, b, c, d, input[1] + 0xa4beea44, 4);
|
||||
d = MD5STEP(F3, d, a, b, c, input[4] + 0x4bdecfa9, 11);
|
||||
c = MD5STEP(F3, c, d, a, b, input[7] + 0xf6bb4b60, 16);
|
||||
b = MD5STEP(F3, b, c, d, a, input[10] + 0xbebfbc70, 23);
|
||||
a = MD5STEP(F3, a, b, c, d, input[13] + 0x289b7ec6, 4);
|
||||
d = MD5STEP(F3, d, a, b, c, input[0] + 0xeaa127fa, 11);
|
||||
c = MD5STEP(F3, c, d, a, b, input[3] + 0xd4ef3085, 16);
|
||||
b = MD5STEP(F3, b, c, d, a, input[6] + 0x04881d05, 23);
|
||||
a = MD5STEP(F3, a, b, c, d, input[9] + 0xd9d4d039, 4);
|
||||
d = MD5STEP(F3, d, a, b, c, input[12] + 0xe6db99e5, 11);
|
||||
c = MD5STEP(F3, c, d, a, b, input[15] + 0x1fa27cf8, 16);
|
||||
b = MD5STEP(F3, b, c, d, a, input[2] + 0xc4ac5665, 23);
|
||||
|
||||
a = MD5STEP(F4, a, b, c, d, input[0] + 0xf4292244, 6);
|
||||
d = MD5STEP(F4, d, a, b, c, input[7] + 0x432aff97, 10);
|
||||
c = MD5STEP(F4, c, d, a, b, input[14] + 0xab9423a7, 15);
|
||||
b = MD5STEP(F4, b, c, d, a, input[5] + 0xfc93a039, 21);
|
||||
a = MD5STEP(F4, a, b, c, d, input[12] + 0x655b59c3, 6);
|
||||
d = MD5STEP(F4, d, a, b, c, input[3] + 0x8f0ccc92, 10);
|
||||
c = MD5STEP(F4, c, d, a, b, input[10] + 0xffeff47d, 15);
|
||||
b = MD5STEP(F4, b, c, d, a, input[1] + 0x85845dd1, 21);
|
||||
a = MD5STEP(F4, a, b, c, d, input[8] + 0x6fa87e4f, 6);
|
||||
d = MD5STEP(F4, d, a, b, c, input[15] + 0xfe2ce6e0, 10);
|
||||
c = MD5STEP(F4, c, d, a, b, input[6] + 0xa3014314, 15);
|
||||
b = MD5STEP(F4, b, c, d, a, input[13] + 0x4e0811a1, 21);
|
||||
a = MD5STEP(F4, a, b, c, d, input[4] + 0xf7537e82, 6);
|
||||
d = MD5STEP(F4, d, a, b, c, input[11] + 0xbd3af235, 10);
|
||||
c = MD5STEP(F4, c, d, a, b, input[2] + 0x2ad7d2bb, 15);
|
||||
b = MD5STEP(F4, b, c, d, a, input[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] = (buf[0] + a)%0xffffffff;
|
||||
buf[1] = (buf[1] + b)%0xffffffff;
|
||||
buf[2] = (buf[2] + c)%0xffffffff;
|
||||
buf[3] = (buf[3] + d)%0xffffffff;
|
||||
end
|
||||
|
||||
function MD5Update(ctx, buf, len)
|
||||
local t;
|
||||
|
||||
t = ctx.bits[0];
|
||||
ctx.bits[0] = t + lshift( len, 3)
|
||||
if (ctx.bits[0] < t) then
|
||||
ctx.bits[1] = ctx.bits[1] + 1;
|
||||
end
|
||||
|
||||
ctx.bits[1] = ctx.bits[1] + rshift(len, 29);
|
||||
|
||||
t = band(rshift(t, 3), 0x3f);
|
||||
|
||||
if (t > 0) then
|
||||
p = ffi.cast("unsigned char *", ctx.input + t);
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) then
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
end
|
||||
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx.input, 16);
|
||||
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
|
||||
buf = buf + t;
|
||||
len = len - t;
|
||||
end
|
||||
|
||||
while (len >= 64) do
|
||||
memcpy(ctx.input, buf, 64);
|
||||
byteReverse(ctx.input, 16);
|
||||
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
|
||||
buf = buf + 64;
|
||||
len = len - 64;
|
||||
end
|
||||
|
||||
memcpy(ctx.input, buf, len);
|
||||
end
|
||||
|
||||
function MD5Final(digest, ctx)
|
||||
|
||||
local count;
|
||||
local p;
|
||||
|
||||
count = band(rshift(ctx.bits[0], 3), 0x3F);
|
||||
|
||||
p = ctx.input + count;
|
||||
p[0] = 0x80;
|
||||
p = p + 1;
|
||||
count = 64 - 1 - count;
|
||||
|
||||
if (count < 8) then
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx.input, 16);
|
||||
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
|
||||
memset(ctx.input, 0, 56);
|
||||
else
|
||||
memset(p, 0, count - 8);
|
||||
end
|
||||
|
||||
byteReverse(ctx.input, 14);
|
||||
|
||||
ffi.cast("uint32_t *", ctx.input)[14] = ctx.bits[0];
|
||||
ffi.cast("uint32_t *", ctx.input)[15] = ctx.bits[1];
|
||||
|
||||
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input));
|
||||
byteReverse(ffi.cast("unsigned char *",ctx.buf), 4);
|
||||
memcpy(digest, ctx.buf, 16);
|
||||
memset(ffi.cast("char *", ctx), 0, ffi.sizeof(ctx));
|
||||
end
|
||||
|
||||
|
||||
function md5(luastr)
|
||||
local buf = ffi.new("char[33]");
|
||||
local hash = ffi.new("uint8_t[16]");
|
||||
local len = #luastr
|
||||
local p = ffi.cast("const char *", luastr);
|
||||
|
||||
local ctx = MD5_CTX();
|
||||
|
||||
MD5Init(ctx);
|
||||
|
||||
MD5Update(ctx, p, len);
|
||||
MD5Final(hash, ctx);
|
||||
bin2str(buf, hash, ffi.sizeof(hash));
|
||||
|
||||
return ffi.string(buf);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
local ffi = require "ffi"
|
||||
local bit = require "bit"
|
||||
local band = bit.band
|
||||
local bor = bit.bor
|
||||
local rshift = bit.rshift
|
||||
local lshift = bit.lshift
|
||||
|
||||
|
||||
|
||||
|
||||
ffi.cdef[[
|
||||
void * malloc ( size_t size );
|
||||
void free ( void * ptr );
|
||||
void * realloc ( void * ptr, size_t size );
|
||||
]]
|
||||
|
||||
function bzero(dest, nbytes)
|
||||
ffi.fill(dest, nbytes)
|
||||
return dest
|
||||
end
|
||||
|
||||
function bcopy(src, dest, nbytes)
|
||||
ffi.copy(dest, src, nbytes)
|
||||
end
|
||||
|
||||
function bcmp(ptr1, ptr2, nbytes)
|
||||
for i=0,nbytes do
|
||||
if ptr1[i] ~= ptr2[i] then return -1 end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
|
||||
function memset(dest, c, len)
|
||||
ffi.fill(dest, len, c)
|
||||
return dest
|
||||
end
|
||||
|
||||
function memcpy(dest, src, nbytes)
|
||||
ffi.copy(dest, src, nbytes)
|
||||
end
|
||||
|
||||
function memcmp(ptr1, ptr2, nbytes)
|
||||
local p1 = ffi.cast("const uint8_t *", ptr1)
|
||||
local p2 = ffi.cast("const uint8_t *", ptr2)
|
||||
|
||||
for i=0,nbytes do
|
||||
if p1[i] ~= p2[i] then return -1 end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function memchr(ptr, value, num)
|
||||
local p = ffi.cast("const uint8_t *", ptr)
|
||||
for i=0,num-1 do
|
||||
if p[i] == value then return p+i end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function memmove(dst, src, num)
|
||||
local srcptr = ffi.cast("const uint8_t*", src)
|
||||
|
||||
-- If equal, just return
|
||||
if dst == srcptr then return dst end
|
||||
|
||||
|
||||
if srcptr < dst then
|
||||
-- copy from end
|
||||
for i=num-1,0, -1 do
|
||||
dst[i] = srcptr[i];
|
||||
end
|
||||
else
|
||||
-- copy from beginning
|
||||
for i=0,num-1 do
|
||||
dst[i] = srcptr[i];
|
||||
end
|
||||
end
|
||||
return dst
|
||||
end
|
||||
|
||||
local function memreverse(buff, bufflen)
|
||||
local i = 0;
|
||||
local tmp
|
||||
|
||||
while (i < (bufflen)/2) do
|
||||
tmp = buff[i];
|
||||
buff[i] = buff[bufflen-i-1];
|
||||
buff[bufflen-i-1] = tmp;
|
||||
|
||||
i = i + 1;
|
||||
end
|
||||
return buff
|
||||
end
|
||||
|
||||
local function getreverse(src, len)
|
||||
if not len then
|
||||
if type(src) == "string" then
|
||||
len = #src
|
||||
else
|
||||
return nil, "unknown length"
|
||||
end
|
||||
end
|
||||
|
||||
local srcptr = ffi.cast("const uint8_t *", src);
|
||||
local dst = ffi.new("uint8_t[?]", len)
|
||||
|
||||
for i = 0, len-1 do
|
||||
dst[i] = srcptr[len-1-i];
|
||||
end
|
||||
|
||||
return dst, len
|
||||
end
|
||||
|
||||
return {
|
||||
bcmp = bcmp,
|
||||
bcopy = bcopy,
|
||||
bzero = bzero,
|
||||
|
||||
memchr = memchr,
|
||||
memcpy = memcpy,
|
||||
memcmp = memcmp,
|
||||
memmove = memmove,
|
||||
memset = memset,
|
||||
|
||||
memreverse = memreverse,
|
||||
}
|
@ -0,0 +1,322 @@
|
||||
local ffi = require "ffi"
|
||||
local bit = require "bit"
|
||||
local band = bit.band
|
||||
local bor = bit.bor
|
||||
local rshift = bit.rshift
|
||||
local lshift = bit.lshift
|
||||
|
||||
--[[
|
||||
String Functions
|
||||
|
||||
strlen
|
||||
strndup
|
||||
strdup
|
||||
strcpy
|
||||
strlcpy
|
||||
strlcat
|
||||
|
||||
strchr
|
||||
strcmp
|
||||
strncmp
|
||||
strcasecmp
|
||||
strncasecmp
|
||||
|
||||
strrchr
|
||||
strstr
|
||||
|
||||
strpbrk
|
||||
|
||||
bin2str
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
function strcmp(s1, s2)
|
||||
local s1ptr = ffi.cast("const uint8_t *", s1);
|
||||
local s2ptr = ffi.cast("const uint8_t *", s2);
|
||||
|
||||
-- uint8_t
|
||||
local uc1;
|
||||
local uc2;
|
||||
|
||||
-- Move s1 and s2 to the first differing characters
|
||||
-- in each string, or the ends of the strings if they
|
||||
-- are identical.
|
||||
while (s1ptr[0] ~= 0 and s1ptr[0] == s2ptr[0]) do
|
||||
s1ptr = s1ptr + 1
|
||||
s2ptr = s2ptr + 1
|
||||
end
|
||||
|
||||
-- Compare the characters as unsigned char and
|
||||
-- return the difference.
|
||||
uc1 = s1ptr[0];
|
||||
uc2 = s2ptr[0];
|
||||
|
||||
if (uc1 < uc2) then
|
||||
return -1
|
||||
elseif (uc1 > uc2) then
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
function strncmp(str1, str2, num)
|
||||
local ptr1 = ffi.cast("const uint8_t*", str1)
|
||||
local ptr2 = ffi.cast("const uint8_t*", str2)
|
||||
|
||||
for i=0,num-1 do
|
||||
if str1[i] == 0 or str2[i] == 0 then return 0 end
|
||||
|
||||
if ptr1[i] > ptr2[i] then return 1 end
|
||||
if ptr1[i] < ptr2[i] then return -1 end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function strncasecmp(str1, str2, num)
|
||||
local ptr1 = ffi.cast("const uint8_t*", str1)
|
||||
local ptr2 = ffi.cast("const uint8_t*", str2)
|
||||
|
||||
for i=0,num-1 do
|
||||
if str1[i] == 0 or str2[i] == 0 then return 0 end
|
||||
|
||||
if ptr1[i] > ptr2[i] then return 1 end
|
||||
if ptr1[i] < ptr2[i] then return -1 end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
function strcasecmp(str1, str2)
|
||||
local ptr1 = ffi.cast("const uint8_t*", str1)
|
||||
local ptr2 = ffi.cast("const uint8_t*", str2)
|
||||
|
||||
local num = math.min(strlen(ptr1), strlen(ptr2))
|
||||
for i=0,num-1 do
|
||||
if str1[i] == 0 or str2[i] == 0 then return 0 end
|
||||
|
||||
if tolower(ptr1[i]) > tolower(ptr2[i]) then return 1 end
|
||||
if tolower(ptr1[i]) < tolower(ptr2[i]) then return -1 end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function strlen(str)
|
||||
local ptr = ffi.cast("uint8_t *", str);
|
||||
local idx = 0
|
||||
while ptr[idx] ~= 0 do
|
||||
idx = idx + 1
|
||||
end
|
||||
|
||||
return idx
|
||||
end
|
||||
|
||||
function strndup(str,n)
|
||||
local len = strlen(str)
|
||||
local len = math.min(n,len)
|
||||
|
||||
local newstr = ffi.new("char["..(len+1).."]");
|
||||
ffi.copy(newstr, str, len)
|
||||
newstr[len] = 0
|
||||
|
||||
return newstr
|
||||
end
|
||||
|
||||
function strdup(str)
|
||||
-- In the case of a Lua string
|
||||
-- create a VLA and initialize
|
||||
if type(str) == "string" then
|
||||
return ffi.new("uint8_t [?]", #str+1, str)
|
||||
end
|
||||
|
||||
-- Most dangerous, assuming it's a null terminated
|
||||
-- string.
|
||||
local len = strlen(str)
|
||||
local newstr = ffi.new("char[?]", (len+1));
|
||||
local strptr = ffi.cast("const char *", str)
|
||||
|
||||
ffi.copy(newstr, ffi.cast("const char *", str), len)
|
||||
newstr[len] = 0
|
||||
|
||||
return newstr
|
||||
end
|
||||
|
||||
function strcpy(dst, src)
|
||||
local dstptr = ffi.cast("char *", dst)
|
||||
local srcptr = ffi.cast("const char *", src)
|
||||
|
||||
-- Do the copying in a loop.
|
||||
while (srcptr[0] ~= 0) do
|
||||
dstptr[0] = srcptr[0];
|
||||
dstptr = dstptr + 1;
|
||||
srcptr = srcptr + 1;
|
||||
end
|
||||
|
||||
-- Return the destination string.
|
||||
return dst;
|
||||
end
|
||||
|
||||
function strlcpy(dst, src, size)
|
||||
local dstptr = ffi.cast("char *", dst)
|
||||
local srcptr = ffi.cast("const char *", src)
|
||||
|
||||
local len = strlen(src)
|
||||
local len = math.min(size-1,len)
|
||||
|
||||
ffi.copy(dstptr, srcptr, len)
|
||||
dstptr[len] = 0
|
||||
|
||||
return len
|
||||
end
|
||||
|
||||
function strlcat(dst, src, size)
|
||||
local dstptr = ffi.cast("char *", dst)
|
||||
local srcptr = ffi.cast("const char *", src)
|
||||
|
||||
local dstlen = strlen(dstptr);
|
||||
local dstremaining = size-dstlen-1
|
||||
local srclen = strlen(srcptr);
|
||||
local len = math.min(dstremaining, srclen)
|
||||
|
||||
|
||||
for idx=dstlen,dstlen+len do
|
||||
dstptr[idx] = srcptr[idx-dstlen];
|
||||
end
|
||||
|
||||
return dstlen+len
|
||||
end
|
||||
|
||||
|
||||
|
||||
function strchr(s, c)
|
||||
local p = ffi.cast("const char *", s);
|
||||
|
||||
while p[0] ~= c do
|
||||
if p[0] == 0 then
|
||||
return nil
|
||||
end
|
||||
p = p + 1;
|
||||
end
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
function strrchr(s, c)
|
||||
local p = ffi.cast("const char *", s);
|
||||
local offset = strlen(p);
|
||||
|
||||
while offset >= 0 do
|
||||
if p[offset] == c then
|
||||
return p+offset
|
||||
end
|
||||
offset = offset - 1;
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function strstr(str, target)
|
||||
|
||||
if (target == nil or target[0] == 0) then
|
||||
return str;
|
||||
end
|
||||
|
||||
local p1 = ffi.cast("const char *", str);
|
||||
|
||||
while (p1[0] ~= 0) do
|
||||
|
||||
local p1Begin = p1;
|
||||
local p2 = target;
|
||||
|
||||
while (p1[0]~=0 and p2[0]~=0 and p1[0] == p2[0]) do
|
||||
p1 = p1 + 1;
|
||||
p2 = p2 + 1;
|
||||
end
|
||||
|
||||
if (p2[0] == 0) then
|
||||
return p1Begin;
|
||||
end
|
||||
|
||||
p1 = p1Begin + 1;
|
||||
end
|
||||
|
||||
return nil;
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
String Helpers
|
||||
--]]
|
||||
|
||||
-- Given two null terminated strings
|
||||
-- return how many bytes they have in common
|
||||
-- this is for prefix matching
|
||||
function string_same(a, b)
|
||||
local p1 = ffi.cast("const char *", a);
|
||||
local p2 = ffi.cast("const char *", b);
|
||||
|
||||
local bytes = 0;
|
||||
|
||||
while (p1[bytes] ~= 0 and p2[bytes] ~= 0 and p1[bytes] == p2[bytes]) do
|
||||
bytes = bytes+1
|
||||
end
|
||||
|
||||
return bytes;
|
||||
end
|
||||
|
||||
-- Stringify binary data. Output buffer must be twice as big as input,
|
||||
-- because each byte takes 2 bytes in string representation
|
||||
|
||||
local hex = strdup("0123456789abcdef")
|
||||
|
||||
function bin2str(to, p, len)
|
||||
--print("bin2str, len: ", len);
|
||||
local off1, off2;
|
||||
while (len > 0) do
|
||||
off1 = rshift(p[0], 4)
|
||||
|
||||
to[0] = hex[off1];
|
||||
to = to + 1;
|
||||
off2 = band(p[0], 0x0f);
|
||||
to[0] = hex[off2];
|
||||
to = to + 1;
|
||||
p = p + 1;
|
||||
len = len - 1;
|
||||
|
||||
-- print(off1, off2);
|
||||
end
|
||||
to[0] = 0;
|
||||
end
|
||||
|
||||
|
||||
local function bintohex(s)
|
||||
return (s:gsub('(.)', function(c)
|
||||
return string.format('%02x', string.byte(c))
|
||||
end))
|
||||
end
|
||||
|
||||
local function hextobin(s)
|
||||
return (s:gsub('(%x%x)', function(hex)
|
||||
return string.char(tonumber(hex, 16))
|
||||
end))
|
||||
end
|
||||
|
||||
return {
|
||||
strchr = strchr,
|
||||
strcmp = strcmp,
|
||||
strncmp = strncmp,
|
||||
strncasecmp = strncasecmp,
|
||||
strcpy = strcpy,
|
||||
strndup = strndup,
|
||||
strdup = strdup,
|
||||
|
||||
strlen = strlen,
|
||||
|
||||
bintohex = bintohex,
|
||||
hextobin = hextobin,
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit acbcbe71d2c2086afe1b044edebe98833980d0bf
|
||||
Subproject commit 3b566385128b722594cde00fa599f035621168fa
|
Loading…
Reference in New Issue