Software / code / prosody
Comparison
util-src/encodings.c @ 415:3cf7deea9971
Added util-src/encodings.c - support for base64, stringprep and idna encodings
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Wed, 26 Nov 2008 01:45:25 +0500 |
| child | 417:d60e63379284 |
comparison
equal
deleted
inserted
replaced
| 414:405d414fbce2 | 415:3cf7deea9971 |
|---|---|
| 1 /* | |
| 2 * xxpath.c | |
| 3 * An implementation of a subset of xpath for Lua 5.1 | |
| 4 * Waqas Hussain <waqas20@gmail.com> | |
| 5 * 05 Oct 2008 15:28:15 | |
| 6 */ | |
| 7 | |
| 8 #include <string.h> | |
| 9 | |
| 10 #include "lua.h" | |
| 11 #include "lauxlib.h" | |
| 12 | |
| 13 /*const char* hex_tab = "0123456789abcdef"; | |
| 14 void toHex(const char* in, int length, char* out) { | |
| 15 int i; | |
| 16 for (i = 0; i < length; i++) { | |
| 17 out[i*2] = hex_tab[(in[i] >> 4) & 0xF]; | |
| 18 out[i*2+1] = hex_tab[(in[i]) & 0xF]; | |
| 19 } | |
| 20 //out[i*2] = 0; | |
| 21 }*/ | |
| 22 | |
| 23 /***************** BASE64 *****************/ | |
| 24 | |
| 25 #define uint unsigned int | |
| 26 | |
| 27 static const char code[]= | |
| 28 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| 29 | |
| 30 static void base64_encode(luaL_Buffer *b, uint c1, uint c2, uint c3, int n) | |
| 31 { | |
| 32 unsigned long tuple=c3+256UL*(c2+256UL*c1); | |
| 33 int i; | |
| 34 char s[4]; | |
| 35 for (i=0; i<4; i++) { | |
| 36 s[3-i] = code[tuple % 64]; | |
| 37 tuple /= 64; | |
| 38 } | |
| 39 for (i=n+1; i<4; i++) s[i]='='; | |
| 40 luaL_addlstring(b,s,4); | |
| 41 } | |
| 42 | |
| 43 static int Lbase64_encode(lua_State *L) /** encode(s) */ | |
| 44 { | |
| 45 size_t l; | |
| 46 const unsigned char *s=(const unsigned char*)luaL_checklstring(L,1,&l); | |
| 47 luaL_Buffer b; | |
| 48 int n; | |
| 49 luaL_buffinit(L,&b); | |
| 50 for (n=l/3; n--; s+=3) base64_encode(&b,s[0],s[1],s[2],3); | |
| 51 switch (l%3) | |
| 52 { | |
| 53 case 1: base64_encode(&b,s[0],0,0,1); break; | |
| 54 case 2: base64_encode(&b,s[0],s[1],0,2); break; | |
| 55 } | |
| 56 luaL_pushresult(&b); | |
| 57 return 1; | |
| 58 } | |
| 59 | |
| 60 static void base64_decode(luaL_Buffer *b, int c1, int c2, int c3, int c4, int n) | |
| 61 { | |
| 62 unsigned long tuple=c4+64L*(c3+64L*(c2+64L*c1)); | |
| 63 char s[3]; | |
| 64 switch (--n) | |
| 65 { | |
| 66 case 3: s[2]=tuple; | |
| 67 case 2: s[1]=tuple >> 8; | |
| 68 case 1: s[0]=tuple >> 16; | |
| 69 } | |
| 70 luaL_addlstring(b,s,n); | |
| 71 } | |
| 72 | |
| 73 static int Lbase64_decode(lua_State *L) /** decode(s) */ | |
| 74 { | |
| 75 size_t l; | |
| 76 const char *s=luaL_checklstring(L,1,&l); | |
| 77 luaL_Buffer b; | |
| 78 int n=0; | |
| 79 char t[4]; | |
| 80 luaL_buffinit(L,&b); | |
| 81 for (;;) | |
| 82 { | |
| 83 int c=*s++; | |
| 84 switch (c) | |
| 85 { | |
| 86 const char *p; | |
| 87 default: | |
| 88 p=strchr(code,c); if (p==NULL) return 0; | |
| 89 t[n++]= p-code; | |
| 90 if (n==4) | |
| 91 { | |
| 92 base64_decode(&b,t[0],t[1],t[2],t[3],4); | |
| 93 n=0; | |
| 94 } | |
| 95 break; | |
| 96 case '=': | |
| 97 switch (n) | |
| 98 { | |
| 99 case 1: base64_decode(&b,t[0],0,0,0,1); break; | |
| 100 case 2: base64_decode(&b,t[0],t[1],0,0,2); break; | |
| 101 case 3: base64_decode(&b,t[0],t[1],t[2],0,3); break; | |
| 102 } | |
| 103 case 0: | |
| 104 luaL_pushresult(&b); | |
| 105 return 1; | |
| 106 case '\n': case '\r': case '\t': case ' ': case '\f': case '\b': | |
| 107 break; | |
| 108 } | |
| 109 } | |
| 110 return 0; | |
| 111 } | |
| 112 | |
| 113 static const luaL_Reg Reg_base64[] = | |
| 114 { | |
| 115 { "encode", Lbase64_encode }, | |
| 116 { "decode", Lbase64_decode }, | |
| 117 { NULL, NULL } | |
| 118 }; | |
| 119 | |
| 120 /***************** STRINGPREP *****************/ | |
| 121 | |
| 122 #include <stringprep.h> | |
| 123 | |
| 124 static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) | |
| 125 { | |
| 126 size_t len; | |
| 127 const char *s = luaL_checklstring(L, 1, &len); | |
| 128 char string[1024]; | |
| 129 int ret; | |
| 130 if (len >= 1024) { | |
| 131 lua_pushnil(L); | |
| 132 return 1; // TODO return error message | |
| 133 } | |
| 134 strcpy(string, s); | |
| 135 ret = stringprep(string, 1024, 0, profile); | |
| 136 if (ret == STRINGPREP_OK) { | |
| 137 lua_pushstring(L, string); | |
| 138 return 1; | |
| 139 } else { | |
| 140 lua_pushnil(L); | |
| 141 return 1; // TODO return error message | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 #define MAKE_PREP_FUNC(myFunc, prep) \ | |
| 146 static int myFunc(lua_State *L) { return stringprep_prep(L, prep); } | |
| 147 | |
| 148 MAKE_PREP_FUNC(Lstringprep_nameprep, stringprep_nameprep) /** stringprep.nameprep(s) */ | |
| 149 MAKE_PREP_FUNC(Lstringprep_nodeprep, stringprep_xmpp_nodeprep) /** stringprep.nodeprep(s) */ | |
| 150 MAKE_PREP_FUNC(Lstringprep_resourceprep, stringprep_xmpp_resourceprep) /** stringprep.resourceprep(s) */ | |
| 151 MAKE_PREP_FUNC(Lstringprep_saslprep, stringprep_saslprep) /** stringprep.saslprep(s) */ | |
| 152 | |
| 153 static const luaL_Reg Reg_stringprep[] = | |
| 154 { | |
| 155 { "nameprep", Lstringprep_nameprep }, | |
| 156 { "nodeprep", Lstringprep_nodeprep }, | |
| 157 { "resourceprep", Lstringprep_resourceprep }, | |
| 158 { "saslprep", Lstringprep_saslprep }, | |
| 159 { NULL, NULL } | |
| 160 }; | |
| 161 | |
| 162 /***************** IDNA *****************/ | |
| 163 | |
| 164 #include <idna.h> | |
| 165 | |
| 166 static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ | |
| 167 { | |
| 168 size_t len; | |
| 169 const char *s = luaL_checklstring(L, 1, &len); | |
| 170 char* output = NULL; | |
| 171 int ret = idna_to_ascii_8z(s, &output, 0); | |
| 172 if (ret == IDNA_SUCCESS) { | |
| 173 lua_pushstring(L, output); | |
| 174 if (output) free(output); | |
| 175 return 1; | |
| 176 } else { | |
| 177 lua_pushnil(L); | |
| 178 if (output) free(output); | |
| 179 return 1; // TODO return error message | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ | |
| 184 { | |
| 185 size_t len; | |
| 186 const char *s = luaL_checklstring(L, 1, &len); | |
| 187 char* output = NULL; | |
| 188 int ret = idna_to_unicode_8z8z(s, &output, 0); | |
| 189 if (ret == IDNA_SUCCESS) { | |
| 190 lua_pushstring(L, output); | |
| 191 if (output) free(output); | |
| 192 return 1; | |
| 193 } else { | |
| 194 lua_pushnil(L); | |
| 195 if (output) free(output); | |
| 196 return 1; // TODO return error message | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 static const luaL_Reg Reg_idna[] = | |
| 201 { | |
| 202 { "to_ascii", Lidna_to_ascii }, | |
| 203 { "to_unicode", Lidna_to_unicode }, | |
| 204 { NULL, NULL } | |
| 205 }; | |
| 206 | |
| 207 /***************** end *****************/ | |
| 208 | |
| 209 static const luaL_Reg Reg[] = | |
| 210 { | |
| 211 { NULL, NULL } | |
| 212 }; | |
| 213 | |
| 214 LUALIB_API int luaopen_encodings(lua_State *L) | |
| 215 { | |
| 216 luaL_register(L, "encodings", Reg); | |
| 217 | |
| 218 lua_pushliteral(L, "base64"); | |
| 219 lua_newtable(L); | |
| 220 luaL_register(L, NULL, Reg_base64); | |
| 221 lua_settable(L,-3); | |
| 222 | |
| 223 lua_pushliteral(L, "stringprep"); | |
| 224 lua_newtable(L); | |
| 225 luaL_register(L, NULL, Reg_stringprep); | |
| 226 lua_settable(L,-3); | |
| 227 | |
| 228 lua_pushliteral(L, "idna"); | |
| 229 lua_newtable(L); | |
| 230 luaL_register(L, NULL, Reg_idna); | |
| 231 lua_settable(L,-3); | |
| 232 | |
| 233 lua_pushliteral(L, "version"); /** version */ | |
| 234 lua_pushliteral(L, "-3.14"); | |
| 235 lua_settable(L,-3); | |
| 236 return 1; | |
| 237 } |