diff options
-rw-r--r-- | include/Handle.h | 1 | ||||
-rw-r--r-- | lib/Handle.cc | 38 | ||||
-rw-r--r-- | lib/LuaHandle.cc | 25 |
3 files changed, 61 insertions, 3 deletions
diff --git a/include/Handle.h b/include/Handle.h index a22c8e0..9a3cf41 100644 --- a/include/Handle.h +++ b/include/Handle.h @@ -74,6 +74,7 @@ class Handle : public Base { #ifdef HAVE_UCL static int ucl_compress(Handle * in, Handle * out, int len_in = -1) throw (GeneralException); static int ucl_decompress(Handle * in, Handle * out, unsigned int len_out, int len_in = -1) throw (GeneralException); + static int ucl_overlap(Handle * in, unsigned int len_out, int len_in = -1) throw (GeneralException); #endif protected: Handle(int h); diff --git a/lib/Handle.cc b/lib/Handle.cc index 110fcca..c0b3d94 100644 --- a/lib/Handle.cc +++ b/lib/Handle.cc @@ -891,7 +891,7 @@ int Handle::ucl_compress(Handle * in, Handle * out, int len_in) throw (GeneralEx int r = ucl_nrv2e_99_compress(b_in, len_in, b_out, &len_out, NULL, 10, NULL, NULL); if (r != UCL_E_OK) - throw GeneralException("Error happened during ucl_nrv2b_99_compress"); + throw GeneralException("Error happened during ucl_nrv2e_99_compress: " + String(r)); out->write(b_out, len_out); @@ -913,9 +913,9 @@ int Handle::ucl_decompress(Handle * in, Handle * out, unsigned int len_out, int b_out = (unsigned char *) malloc(len_out); in->read(b_in, len_in); - int r = ucl_nrv2e_decompress_8(b_in, len_in, b_out, &len_out, NULL); + int r = ucl_nrv2e_decompress_safe_8(b_in, len_in, b_out, &len_out, NULL); if (r != UCL_E_OK) - throw GeneralException("Error happened during ucl_nrv2b_decompress_32"); + throw GeneralException("Error happened during ucl_nrv2e_decompress_8: " + String(r)); out->write(b_out, len_out); @@ -924,4 +924,36 @@ int Handle::ucl_decompress(Handle * in, Handle * out, unsigned int len_out, int return len_out; } + +int Handle::ucl_overlap(Handle * in, unsigned int len_out, int len_in) throw (GeneralException) { + if (ucl_init() != UCL_E_OK) + throw GeneralException("ucl_init failed"); + + if (len_in < 0) len_in = in->GetSize() - in->tell(); + + unsigned char * buff = 0; + unsigned int len_out_t, pad = 0, offset = len_out - len_in; + + while (true) { + len_out_t = len_out; + buff = (unsigned char *) realloc(buff, len_out + pad); + in->read(buff + offset, len_in); + in->seek(-len_in, SEEK_CUR); + + int r = ucl_nrv2e_test_overlap_8(buff, offset, len_in, &len_out_t, NULL); + switch (r) { + case UCL_E_OVERLAP_OVERRUN: + pad++; + offset++; + break; + case UCL_E_OK: + free(buff); + return pad; + default: + throw GeneralException("Error happened during ucl_nrv2e_test_overlap_8: " + String(r)); + } + } + + throw GeneralException("Shouldn't arrive here."); +} #endif diff --git a/lib/LuaHandle.cc b/lib/LuaHandle.cc index 329c7e7..ce6d48c 100644 --- a/lib/LuaHandle.cc +++ b/lib/LuaHandle.cc @@ -75,6 +75,7 @@ class sLuaHandle : public Base { #ifdef HAVE_UCL static int ucl_compress(lua_State * L); static int ucl_decompress(lua_State * L); + static int ucl_overlap(lua_State * L); #endif private: static int read(lua_State * L, int); @@ -632,6 +633,29 @@ int sLuaHandle::ucl_decompress(lua_State * __L) { return 1; } + +int sLuaHandle::ucl_overlap(lua_State * __L) { + Lua * L = Lua::find(__L); + int n = L->gettop(); + Handle * s, * d; + int r, l, l_in = -1; + + if (!((n >= 2) && (n <= 3)) || (!L->isnumber(2))) { + L->error("Incorrect arguments to method `Handle::ucl_overlap'"); + } + + s = L->recast<Handle>(1); + l = L->tonumber(2); + if (n == 3) { + l_in = L->tonumber(3); + } + + r = Handle::ucl_overlap(s, l, l_in); + + L->push((lua_Number) r); + + return 1; +} #endif int sLuaHandle::seek(lua_State * __L) { @@ -875,5 +899,6 @@ void LuaHandle::pushconstruct(Lua * L) { #ifdef HAVE_UCL L->declarefunc("ucl_compress", sLuaHandle::ucl_compress); L->declarefunc("ucl_decompress", sLuaHandle::ucl_decompress); + L->declarefunc("ucl_overlap", sLuaHandle::ucl_overlap); #endif } |