Add decode/encode URI functions.

This commit is contained in:
Tor Andersson
2014-02-06 18:19:07 +01:00
parent 20a9d52657
commit bc6da35e59
3 changed files with 139 additions and 29 deletions
+110
View File
@@ -66,6 +66,111 @@ static int jsB_isFinite(js_State *J, int argc)
return 1;
}
static int Encode(js_State *J, const char *str, const char *unescaped)
{
struct sbuffer *sb = NULL;
static const char *HEX = "0123456789ABCDEF";
while (*str) {
int c = (unsigned char) *str++;
if (strchr(unescaped, c))
sb = sb_putc(sb, c);
else {
sb = sb_putc(sb, '%');
sb = sb_putc(sb, HEX[(c >> 4) & 0xf]);
sb = sb_putc(sb, HEX[c & 0xf]);
}
}
sb = sb_putc(sb, 0);
if (js_try(J)) {
free(sb);
js_throw(J);
}
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
free(sb);
return 1;
}
static inline int ishex(int c)
{
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
static inline int tohex(int c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 0xA;
if (c >= 'A' && c <= 'F') return c - 'A' + 0xA;
return 0;
}
static int Decode(js_State *J, const char *str, const char *reserved)
{
struct sbuffer *sb = NULL;
int a, b;
while (*str) {
int c = (unsigned char) *str++;
if (c != '%')
sb = sb_putc(sb, c);
else {
if (!str[0] || !str[1])
js_urierror(J, "truncated escape sequence");
a = *str++;
b = *str++;
if (!ishex(a) || !ishex(b))
js_urierror(J, "invalid escape sequence");
c = tohex(a) << 4 | tohex(b);
if (!strchr(reserved, c))
sb = sb_putc(sb, c);
else {
sb = sb_putc(sb, '%');
sb = sb_putc(sb, a);
sb = sb_putc(sb, b);
}
}
}
sb = sb_putc(sb, 0);
if (js_try(J)) {
free(sb);
js_throw(J);
}
js_pushstring(J, sb ? sb->s : "");
js_endtry(J);
free(sb);
return 1;
}
#define URIRESERVED ";/?:@&=+$,"
#define URIALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define URIDIGIT "0123456789"
#define URIMARK "-_.!~*`()"
#define URIUNESCAPED URIALPHA URIDIGIT URIMARK
static int jsB_decodeURI(js_State *J, int argc)
{
return Decode(J, js_tostring(J, 1), URIRESERVED "#");
}
static int jsB_decodeURIComponent(js_State *J, int argc)
{
return Decode(J, js_tostring(J, 1), "");
}
static int jsB_encodeURI(js_State *J, int argc)
{
return Encode(J, js_tostring(J, 1), URIUNESCAPED URIRESERVED "#");
}
static int jsB_encodeURIComponent(js_State *J, int argc)
{
return Encode(J, js_tostring(J, 1), URIUNESCAPED);
}
void jsB_init(js_State *J)
{
/* Create the prototype objects here, before the constructors */
@@ -114,4 +219,9 @@ void jsB_init(js_State *J)
jsB_globalf(J, "parseFloat", jsB_parseFloat, 1);
jsB_globalf(J, "isNaN", jsB_isNaN, 1);
jsB_globalf(J, "isFinite", jsB_isFinite, 1);
jsB_globalf(J, "decodeURI", jsB_decodeURI, 1);
jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1);
jsB_globalf(J, "encodeURI", jsB_encodeURI, 1);
jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1);
}
+29
View File
@@ -17,4 +17,33 @@ void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n);
void jsB_propn(js_State *J, const char *name, double number);
void jsB_props(js_State *J, const char *name, const char *string);
struct sbuffer { int n, m; char s[64]; };
static struct sbuffer *sb_putc(struct sbuffer *sb, int c)
{
if (!sb) {
sb = malloc(sizeof *sb);
sb->n = 0;
sb->m = sizeof sb->s;
} else if (sb->n == sb->m) {
sb = realloc(sb, (sb->m *= 2) + offsetof(struct sbuffer, s));
}
sb->s[sb->n++] = c;
return sb;
}
static inline struct sbuffer *sb_puts(struct sbuffer *sb, const char *s)
{
while (*s)
sb = sb_putc(sb, *s++);
return sb;
}
static inline struct sbuffer *sb_putm(struct sbuffer *sb, const char *s, const char *e)
{
while (s < e)
sb = sb_putc(sb, *s++);
return sb;
}
#endif
-29
View File
@@ -7,35 +7,6 @@
#define nelem(a) (sizeof (a) / sizeof (a)[0])
struct sbuffer { int n, m; char s[64]; };
static struct sbuffer *sb_putc(struct sbuffer *sb, int c)
{
if (!sb) {
sb = malloc(sizeof *sb);
sb->n = 0;
sb->m = sizeof sb->s;
} else if (sb->n == sb->m) {
sb = realloc(sb, (sb->m *= 2) + offsetof(struct sbuffer, s));
}
sb->s[sb->n++] = c;
return sb;
}
static struct sbuffer *sb_puts(struct sbuffer *sb, const char *s)
{
while (*s)
sb = sb_putc(sb, *s++);
return sb;
}
static struct sbuffer *sb_putm(struct sbuffer *sb, const char *s, const char *e)
{
while (s < e)
sb = sb_putc(sb, *s++);
return sb;
}
static int jsB_new_String(js_State *J, int argc)
{
js_newstring(J, argc > 0 ? js_tostring(J, 1) : "");