make functions in MD5 implementation local

also get rid of mostly unused helper libraries and some stylistic
oddities in the MD5 code
pull/1129/head
Hans-Werner Hilse 10 years ago
parent c8edd020f1
commit 78b098e47d

@ -7,9 +7,8 @@ local band = bit.band
local bor = bit.bor
local rshift = bit.rshift
local lshift = bit.lshift
require "memutils"
require "stringzutils"
local copy = ffi.copy
local fill = ffi.fill
ffi.cdef[[
typedef struct MD5Context {
@ -19,215 +18,208 @@ typedef struct MD5Context {
} MD5_CTX;
]]
MD5_CTX = ffi.typeof("MD5_CTX");
function byteReverse(buf, len)
local function byteReverse(buf, len)
-- TODO: implement for big-endian architectures?
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
local function F1(x, y, z) return bxor(z, band(x, bxor(y, z))) end
local function F2(x, y, z) return F1(z, x, y) end
local function F3(x, y, z) return bxor(x, y, z) end
local function F4(x, y, z) return bxor(y, bor(x, bnot(z))) end
function printmd5ctx(ctx)
for i=0,3 do
print(string.format("ctx.buf[%d]: 0x%x", i, ctx.buf[i]));
end
local 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
print(string.format("ctx.bits[0]: %d", ctx.bits[0]));
print(string.format("ctx.bits[1]: %d", ctx.bits[1]));
return w
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;
local 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] = band(buf[0] + a, 0xFFFFFFFF);
buf[1] = band(buf[1] + b, 0xFFFFFFFF);
buf[2] = band(buf[2] + c, 0xFFFFFFFF);
buf[3] = band(buf[3] + d, 0xFFFFFFFF);
local 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] = band(buf[0] + a, 0xFFFFFFFF)
buf[1] = band(buf[1] + b, 0xFFFFFFFF)
buf[2] = band(buf[2] + c, 0xFFFFFFFF)
buf[3] = band(buf[3] + d, 0xFFFFFFFF)
end
function MD5Update(ctx, buf, len)
local t;
local 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
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);
ctx.bits[1] = ctx.bits[1] + rshift(len, 29)
t = band(rshift(t, 3), 0x3f);
t = band(rshift(t, 3), 0x3f)
if (t > 0) then
p = ffi.cast("unsigned char *", ctx.input + t);
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
t = 64 - t
if (len < t) then
copy(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
copy(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
while (len >= 64) do
copy(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);
copy(ctx.input, buf, len)
end
function MD5Final(digest, ctx)
local function MD5Final(digest, ctx)
local count;
local p;
local count
local p
count = band(rshift(ctx.bits[0], 3), 0x3F);
count = band(rshift(ctx.bits[0], 3), 0x3F)
p = ctx.input + count;
p[0] = 0x80;
p = p + 1;
count = 64 - 1 - count;
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
if (count < 8) then
fill(p, count, 0)
byteReverse(ctx.input, 16)
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input))
fill(ctx.input, 56, 0)
else
fill(p, count - 8, 0)
end
byteReverse(ctx.input, 14);
byteReverse(ctx.input, 14)
ffi.cast("uint32_t *", ctx.input)[14] = ctx.bits[0];
ffi.cast("uint32_t *", ctx.input)[15] = ctx.bits[1];
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));
MD5Transform(ctx.buf, ffi.cast("uint32_t *", ctx.input))
byteReverse(ffi.cast("unsigned char *",ctx.buf), 4)
copy(digest, ctx.buf, 16)
fill(ffi.cast("char *", ctx), ffi.sizeof(ctx), 0)
end
local hex = ffi.new("const char[16]", "0123456789abcdef")
local function bin2str(output, input, len)
if len > 0 then
output[0] = hex[rshift(input[0], 4)]
output[1] = hex[band(input[0], 0xF)]
return bin2str(output+2, input+1, len-1)
end
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();
local function md5(luastr)
local buf = ffi.new("char[33]")
local hash = ffi.new("uint8_t[16]")
local ctx = ffi.new("MD5_CTX")
MD5Init(ctx);
MD5Init(ctx)
MD5Update(ctx, ffi.cast("const char*", luastr), #luastr)
MD5Final(hash, ctx)
MD5Update(ctx, p, len);
MD5Final(hash, ctx);
bin2str(buf, hash, ffi.sizeof(hash));
bin2str(buf, hash, ffi.sizeof(hash))
return ffi.string(buf);
return ffi.string(buf)
end
return md5

@ -1,7 +1,7 @@
--[[
A global LRU cache
]]--
require("MD5")
local md5 = require("MD5")
local lfs = require("libs/libkoreader-lfs")
local DEBUG = require("dbg")
@ -35,7 +35,7 @@ local cache_path = lfs.currentdir().."/cache/"
--[[
-- return a snapshot of disk cached items for subsequent check
--]]
function getDiskCache()
local function getDiskCache()
local cached = {}
for key_md5 in lfs.dir(cache_path) do
local file = cache_path..key_md5

@ -1,131 +0,0 @@
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,
}

@ -1,322 +0,0 @@
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,7 +1,7 @@
local DocumentRegistry = require("document/documentregistry")
local DocSettings = require("docsettings")
local DEBUG = require("dbg")
require("MD5")
local md5 = require("MD5")
-- lfs
local MyClipping = {

Loading…
Cancel
Save