Created
January 15, 2014 16:05
-
-
Save xjdrew/8438953 to your computer and use it in GitHub Desktop.
lualib, 把字符串从utf8解成utf-16;并返回长度,解码失败,返回nil;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <assert.h> | |
#include <stdint.h> | |
#include "lua.h" | |
#include "lauxlib.h" | |
inline int | |
_bytes(uint8_t c) { | |
if(c < 0x80) return 1; | |
if(c < 0xc0) return 0; | |
if(c < 0xe0) return 2; | |
if(c < 0xf0) return 3; | |
if(c < 0xf8) return 4; | |
return 0; | |
} | |
inline uint32_t | |
_value(const char *str, int i, int step) { | |
uint8_t c = str[i]; | |
uint32_t v = c & (0xff >> step); | |
int j = 1; | |
for(;j<step; j++) { | |
v = v << 6; | |
v = v | (str[i+j] & 0x3f); | |
} | |
return v; | |
} | |
static int | |
_utf8(lua_State *L) { | |
size_t len; | |
const char* str = luaL_checklstring(L, 1, &len); | |
luaL_checktype(L, 2, LUA_TTABLE); | |
int count = 0; | |
int i, step; | |
uint8_t c; | |
for(i=0;i<len;) { | |
c = str[i]; | |
step = _bytes(c); | |
if(step == 0 || len < i + step) { | |
count = 0; | |
break; | |
} | |
lua_pushnumber(L, _value(str, i, step)); | |
count = count + 1; | |
lua_rawseti(L, 2, count); | |
i = i + step; | |
} | |
if(count == 0) { | |
lua_pushnil(L); | |
} else { | |
lua_pushinteger(L, count); | |
} | |
return 1; | |
} | |
int | |
luaopen_utf8_c(lua_State *L) { | |
luaL_checkversion(L); | |
lua_pushcfunction(L, _utf8); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment