Skip to content

Instantly share code, notes, and snippets.

@xjdrew
Created January 15, 2014 16:05
Show Gist options
  • Save xjdrew/8438953 to your computer and use it in GitHub Desktop.
Save xjdrew/8438953 to your computer and use it in GitHub Desktop.
lualib, 把字符串从utf8解成utf-16;并返回长度,解码失败,返回nil;
#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