From a226dc348c4cab94f30473943b8a236af2fb6b31 Mon Sep 17 00:00:00 2001 From: Alexandre Erwin Ittner Date: Wed, 6 Jul 2005 01:17:02 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: file:///var/svn/lua-iconv/trunk@8 9538949d-8f27-0410-946f-ce01ef448559 --- luaiconv.c | 102 +++++++++++++++++++++++++++++++++++++++++++++---- test_iconv.lua | 19 +++++---- 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/luaiconv.c b/luaiconv.c index 7b4682f..f571c71 100644 --- a/luaiconv.c +++ b/luaiconv.c @@ -27,7 +27,9 @@ #include #include #include + #include +#include #define LIB_NAME "iconv" #define ICONV_TYPENAME "iconv_t" @@ -35,6 +37,23 @@ #define getstring luaL_checkstring #define getostring(L, i) luaL_optstring(L, i, NULL) +#define ERROR_NO_MEMORY 1 +#define ERROR_INVALID 2 +#define ERROR_INCOMPLETE 3 +#define ERROR_UNKNOWN 4 + + + + +/* Table assumed on top */ +#define tblseticons(L, c, v) \ + lua_pushliteral(L, c); \ + lua_pushnumber(L, v); \ + lua_settable(L, -3); + + + + static void push_iconv_t(lua_State *L, iconv_t cd) { @@ -60,10 +79,10 @@ static iconv_t get_iconv_t(lua_State *L, int i) -static int Linconv_open(lua_State *L) +static int Liconv_open(lua_State *L) { - const char *fromcode = getstring(L, 1); - const char *tocode = getstring(L, 2); + const char *tocode = getstring(L, 1); + const char *fromcode = getstring(L, 2); iconv_t cd = iconv_open(tocode, fromcode); if(cd != (iconv_t)(-1)) push_iconv_t(L, cd); /* ok */ @@ -73,6 +92,69 @@ static int Linconv_open(lua_State *L) } +static int Liconv(lua_State *L) +{ + iconv_t cd = get_iconv_t(L, 1); + size_t ibleft = lua_strlen(L, 2); + char *inbuf = (char*) getstring(L, 2); + char *outbuf; + char *outbufs; + size_t bsize = ibleft; + size_t obleft = ibleft; + size_t ret = -1; + + outbuf = (char*) malloc(ibleft * sizeof(char)); + outbufs = outbuf; + if(outbuf == NULL) + { + lua_pushstring(L, ""); + lua_pushnumber(L, ERROR_NO_MEMORY); + return 2; + } + + do + { + ret = iconv(cd, &inbuf, &ibleft, &outbuf, &obleft); + if(ret == (size_t)(-1)) + { + if(errno == EILSEQ) + { + lua_pushlstring(L, outbufs, bsize-obleft); + lua_pushnumber(L, ERROR_INVALID); + free(outbufs); + return 2; /* Invalid character sequence */ + } + else if(errno == EINVAL) + { + lua_pushlstring(L, outbufs, bsize-obleft); + lua_pushnumber(L, ERROR_INCOMPLETE); + free(outbufs); + return 2; /* Incomplete character sequence */ + } + else if(errno == E2BIG) + { + bsize += 2 * ibleft; + obleft += 2 * ibleft; + outbufs = (char*) realloc(outbufs, bsize * sizeof(char)); + puts("REALOQUEI"); + } + else + { + lua_pushlstring(L, outbufs, bsize-obleft); + lua_pushnumber(L, ERROR_UNKNOWN); + free(outbufs); + return 2; /* Unknown error */ + } + } + } + while(ret != (size_t) 0); + + lua_pushlstring(L, outbufs, bsize-obleft); + free(outbufs); + return 1; /* Done */ +} + + static int Liconv_close(lua_State *L) { iconv_t cd = get_iconv_t(L, 1); @@ -82,8 +164,8 @@ static int Liconv_close(lua_State *L) lua_pushnil(L); /* erro */ return 1; } - + @@ -92,9 +174,9 @@ static int Liconv_close(lua_State *L) static const luaL_reg inconvFuncs[] = { - { "open", Linconv_open }, - { "new", Linconv_open }, - { "iconv", Linconv_open }, + { "open", Liconv_open }, + { "new", Liconv_open }, + { "iconv", Liconv }, { NULL, NULL } }; @@ -106,11 +188,15 @@ static const luaL_reg iconvMT[] = }; - int luaopen_iconv(lua_State *L) { luaL_openlib(L, LIB_NAME, inconvFuncs, 0); + tblseticons(L, "ERROR_NO_MEMORY", ERROR_NO_MEMORY); + tblseticons(L, "ERROR_INVALID", ERROR_INVALID); + tblseticons(L, "ERROR_INCOMPLETE", ERROR_INCOMPLETE); + tblseticons(L, "ERROR_UNKNOWN", ERROR_UNKNOWN); + lua_pushliteral(L, "metatable"); /* metatable */ luaL_newmetatable(L, ICONV_TYPENAME); lua_pushliteral(L, "__index"); diff --git a/test_iconv.lua b/test_iconv.lua index 752ba6b..bda54b8 100644 --- a/test_iconv.lua +++ b/test_iconv.lua @@ -1,17 +1,20 @@ +assert(loadlib("./libluaiconv.so", "luaopen_iconv"))() + cd = iconv.new("utf-8", "iso-8859-1") --- cd = iconv.new("utf-8//IGNORE", "iso-8859-1") --- cd = iconv.new("utf-8//TRANSLIT", "iso-8859-1") +--cd = iconv.new("us-ascii//IGNORE", "iso-8859-1") +--cd = iconv.new("us-ascii//TRANSLIT", "iso-8859-1") -assert(cd, 'Invalid conversion') +assert(cd, "Invalid conversion") -ret, err = cd:iconv('Isso é um teste com acentuação') +-- ret, err = cd:iconv("Isso é um teste com acentuação") +ret, err = cd:iconv("çãÃÉÍÓÚÇÑÿ") if err == iconv.ERROR_INCOMPLETE then - print('Error: Incomplete input.') + print("Error: Incomplete input.") elseif err == iconv.ERROR_INVALID then - print('Error: Invalid input.') -elseif err == nil then - print('Result: ', ret) + print("Error: Invalid input.") end +print("Result: ", ret) +