Browse Source

initial implementation of global object escape()

pull/1/head
Sami Vaarala 12 years ago
parent
commit
8abe227c63
  1. 73
      src/duk_builtin_global.c

73
src/duk_builtin_global.c

@ -167,9 +167,78 @@ int duk_builtin_global_object_encode_uri_component(duk_context *ctx) {
return DUK_RET_UNIMPLEMENTED_ERROR; /*FIXME*/
}
#if 1 /* FIXME: Section B */
#ifdef DUK_USE_SECTION_B
/* E5.1 Section B.2.2, step 7. */
#define _MKBITS(a,b,c,d,e,f,g,h) ((unsigned char) ( \
((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \
((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7) \
))
unsigned char duk_escape_as_is_table[16] = {
_MKBITS(0, 0, 0, 0, 0, 0, 0, 0), _MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x00-0x0f */
_MKBITS(0, 0, 0, 0, 0, 0, 0, 0), _MKBITS(0, 0, 0, 0, 0, 0, 0, 0), /* 0x10-0x1f */
_MKBITS(0, 0, 0, 0, 0, 0, 0, 0), _MKBITS(0, 0, 1, 1, 0, 1, 1, 1), /* 0x20-0x2f */
_MKBITS(1, 1, 1, 1, 1, 1, 1, 1), _MKBITS(1, 1, 0, 0, 0, 0, 0, 0), /* 0x30-0x3f */
_MKBITS(1, 1, 1, 1, 1, 1, 1, 1), _MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x40-0x4f */
_MKBITS(1, 1, 1, 1, 1, 1, 1, 1), _MKBITS(1, 1, 1, 0, 0, 0, 0, 1), /* 0x50-0x5f */
_MKBITS(0, 1, 1, 1, 1, 1, 1, 1), _MKBITS(1, 1, 1, 1, 1, 1, 1, 1), /* 0x60-0x6f */
_MKBITS(1, 1, 1, 1, 1, 1, 1, 1), _MKBITS(1, 1, 1, 0, 0, 0, 0, 0) /* 0x70-0x7f */
};
/* bit number in the byte is a bit counterintuitive, but minimizes ops */
#define ESCAPE_AS_IS(cp) (duk_escape_as_is_table[(cp) >> 3] & (1 << ((cp) & 0x07)))
/* FIXME: could this be implemented as a generic "transform" utility with
* a changing callback? What other functions could share the same helper?
*/
int duk_builtin_global_object_escape(duk_context *ctx) {
return DUK_RET_UNIMPLEMENTED_ERROR; /*FIXME*/
duk_hthread *thr = (duk_hthread *) ctx;
duk_hstring *h_str;
duk_hbuffer_growable *h_buf;
duk_u8 *p_start, *p_end, *p;
duk_u32 cp;
h_str = duk_to_hstring(ctx, 0);
DUK_ASSERT(h_str != NULL);
(void) duk_push_new_growable_buffer(ctx, 0);
h_buf = (duk_hbuffer_growable *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(h_buf != NULL);
DUK_ASSERT(DUK_HBUFFER_HAS_GROWABLE(h_buf));
p_start = DUK_HSTRING_GET_DATA(h_str);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);
p = p_start;
/* Since escape() is a legacy function, no fast path here to save space. */
while (p < p_end) {
duk_u8 buf[6];
size_t len;
cp = duk_unicode_xutf8_get_u32(thr, &p, p_start, p_end);
if ((cp < 128) && ESCAPE_AS_IS(cp)) {
buf[0] = (duk_u8) cp;
len = 1;
} else if (cp < 256) {
buf[0] = (duk_u8) '%';
buf[1] = (duk_u8) duk_uc_nybbles[cp >> 4];
buf[2] = (duk_u8) duk_uc_nybbles[cp & 0x0f];
len = 3;
} else {
/* FIXME: non-BMP chars will now be clipped */
buf[0] = (duk_u8) '%';
buf[1] = (duk_u8) 'u';
buf[2] = (duk_u8) duk_uc_nybbles[cp >> 12];
buf[3] = (duk_u8) duk_uc_nybbles[(cp >> 8) & 0x0f];
buf[4] = (duk_u8) duk_uc_nybbles[(cp >> 4) & 0x0f];
buf[5] = (duk_u8) duk_uc_nybbles[cp & 0x0f];
len = 6;
}
duk_hbuffer_append_bytes(thr, h_buf, buf, len);
}
duk_to_string(ctx, -1);
return 1;
}
int duk_builtin_global_object_unescape(duk_context *ctx) {

Loading…
Cancel
Save