static int icu_normalizer_concat(lua_State *L) { const UChar* left = icu4lua_checkustring(L,1,NORMALIZER_UV_USTRING_META); int32_t left_length = (int32_t)icu4lua_ustrlen(L,1); const UChar* right = icu4lua_checkustring(L,2,NORMALIZER_UV_USTRING_META); int32_t right_length = (int32_t)icu4lua_ustrlen(L,2); UNormalizationMode mode = modes[luaL_checkoption(L,3,DEFAULT_MODE_OPTION, modeNames)]; int32_t options = luaL_optint(L,4,0); UChar* dest; int32_t dest_length; UErrorCode status = U_ZERO_ERROR; dest_length = unorm_concatenate(left, left_length, right, right_length, NULL, 0, mode, options, &status); if (U_FAILURE(status)) { lua_pushnil(L); lua_pushstring(L, u_errorName(status)); return 2; } dest = (UChar*)malloc(sizeof(UChar) * dest_length); status = U_ZERO_ERROR; unorm_concatenate(left, left_length, right, right_length, dest, dest_length, mode, options, &status); if (U_FAILURE(status)) { free(dest); lua_pushnil(L); lua_pushstring(L, u_errorName(status)); return 2; } icu4lua_pushustring(L, dest, dest_length, NORMALIZER_UV_USTRING_META, NORMALIZER_UV_USTRING_POOL); return 1; }
static int icu_collator_lessorequal(lua_State *L) { luaL_argcheck(L, lua_getmetatable(L,1) && lua_rawequal(L,-1,COLLATOR_UV_META), 1, "expecting collator"); lua_pop(L,1); icu4lua_checkustring(L,2,COLLATOR_UV_USTRING_META); icu4lua_checkustring(L,3,COLLATOR_UV_USTRING_META); lua_pushboolean(L, !ucol_greater( *(UCollator**)lua_touserdata(L,1), icu4lua_trustustring(L,2), (int32_t)icu4lua_ustrlen(L,2), icu4lua_trustustring(L,3), (int32_t)icu4lua_ustrlen(L,3))); return 1; }
static int icu_normalizer_lessorequal(lua_State *L) { const UChar* left = icu4lua_checkustring(L,1,NORMALIZER_UV_USTRING_META); int32_t left_length = (int32_t)icu4lua_ustrlen(L,1); const UChar* right = icu4lua_checkustring(L,2,NORMALIZER_UV_USTRING_META); int32_t right_length = (int32_t)icu4lua_ustrlen(L,2); int32_t options = luaL_optint(L,3,0); UErrorCode status = U_ZERO_ERROR; lua_pushboolean(L, unorm_compare(left, left_length, right, right_length, options, &status) <= 0); if (U_FAILURE(status)) { lua_pushstring(L, u_errorName(status)); return lua_error(L); } return 1; }
static int icu_normalizer_quickcheck(lua_State *L) { UNormalizationMode mode; UErrorCode status; UNormalizationCheckResult result; luaL_argcheck(L, lua_getmetatable(L,1) && lua_rawequal(L,-1,NORMALIZER_UV_USTRING_META), 1, "expecting ustring"); lua_pop(L,1); mode = modes[luaL_checkoption(L, 2, DEFAULT_MODE_OPTION, modeNames)]; status = U_ZERO_ERROR; result = unorm_quickCheckWithOptions( icu4lua_trustustring(L,1), (int32_t)icu4lua_ustrlen(L,1), mode, (int32_t)luaL_optnumber(L,3,0), &status); if (U_FAILURE(status)) { lua_pushstring(L, u_errorName(status)); return lua_error(L); } switch(result) { case UNORM_YES: lua_pushliteral(L, "yes"); break; case UNORM_NO: lua_pushliteral(L, "no"); break; case UNORM_MAYBE: default: lua_pushliteral(L, "maybe"); break; } return 1; }
static int icu_normalizer_normalize(lua_State *L) { const UChar* source = icu4lua_checkustring(L, 1, NORMALIZER_UV_USTRING_META); int32_t sourceLength = (int32_t)icu4lua_ustrlen(L, 1); UNormalizationMode mode; UChar* result; int32_t resultLength; UErrorCode status; int32_t options; mode = modes[luaL_checkoption(L, 2, DEFAULT_MODE_OPTION, modeNames)]; options = (int32_t)luaL_optnumber(L,3,0); status = U_ZERO_ERROR; resultLength = unorm_normalize(source, sourceLength, mode, options, NULL, 0, &status); if (status != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(status)) { lua_pushnil(L); lua_pushstring(L, u_errorName(status)); return 2; } result = (UChar*)malloc(sizeof(UChar) * resultLength); status = U_ZERO_ERROR; unorm_normalize(source, sourceLength, mode, options, result, resultLength, &status); if (U_FAILURE(status)) { free(result); lua_pushnil(L); lua_pushstring(L, u_errorName(status)); return 2; } icu4lua_pushustring(L, result, resultLength, NORMALIZER_UV_USTRING_META, NORMALIZER_UV_USTRING_POOL); free(result); return 1; }
static int icu_normalizer_isnormalized(lua_State *L) { UNormalizationMode mode; UErrorCode status; icu4lua_checkustring(L,1,NORMALIZER_UV_USTRING_META); mode = modes[luaL_checkoption(L,2,DEFAULT_MODE_OPTION,modeNames)]; status = U_ZERO_ERROR; lua_pushboolean(L, unorm_isNormalized(icu4lua_trustustring(L,1), (int32_t)icu4lua_ustrlen(L,1), mode, &status)); if (U_FAILURE(status)) { lua_pushstring(L, u_errorName(status)); return lua_error(L); } return 1; }
static int icu_ufile_write(lua_State *L) { int nargs = lua_gettop(L) - 1; int arg = 2; int status = 1; UFILE* ufile = icu4lua_checkopenufile(L,1,UFILE_UV_META); for (; nargs--; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { status = status && u_fprintf(ufile, LUA_NUMBER_FMT, lua_tonumber(L, arg))>0; } else { const UChar* ustr = icu4lua_checkustring(L, arg, UFILE_UV_USTRING_META); int32_t ustr_l = (int32_t)icu4lua_ustrlen(L, arg); status = status && (u_file_write(ustr, ustr_l, ufile) == ustr_l); } } return pushresult(L, status, NULL); }
static int read_chars(lua_State *L, UFILE *ufile, int32_t n) { int32_t rlen; // how much to read int32_t nr; // number of chars actually read luaL_Buffer b; luaL_buffinit(L, &b); rlen = ICU4LUA_UBUFFERSIZE; // try to read that much each time do { UChar* p = icu4lua_prepubuffer(&b); if (rlen > n) { rlen = n; // cannot read more than asked } nr = u_file_read(p, rlen, ufile); icu4lua_addusize(&b, nr); n -= nr; // still have to read `n' chars } while (n > 0 && nr == rlen); // until end of count or eof icu4lua_pushuresult(&b, UFILE_UV_USTRING_META, UFILE_UV_USTRING_POOL); if (icu4lua_ustrlen(L,-1) == 0 && n != 0) { return 0; } return 1; }
// Utility functions - based on equivalents in liolib.c static int read_line(lua_State *L, UFILE *ufile) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t l; UChar* p = icu4lua_prepubuffer(&b); if (u_fgets(p, ICU4LUA_UBUFFERSIZE, ufile) == NULL) { icu4lua_pushuresult(&b, UFILE_UV_USTRING_META, UFILE_UV_USTRING_POOL); if (icu4lua_ustrlen(L,-1) == 0) { return 0; } return 1; } l = u_strlen(p); if (l == 0 || p[l-1] != '\n') { icu4lua_addusize(&b, l); } else { icu4lua_addusize(&b, l - 1); icu4lua_pushuresult(&b, UFILE_UV_USTRING_META, UFILE_UV_USTRING_POOL); return 1; } } }