diff options
| author | Tomasz Dąbrowski <[email protected]> | 2016-07-18 16:04:26 +0200 |
|---|---|---|
| committer | Tomasz Dąbrowski <[email protected]> | 2016-07-18 16:06:01 +0200 |
| commit | 26c1dedcabf6c845356653570f4dadd594c45709 (patch) | |
| tree | 8e3126939f51b69febd79c00b96e750e13dfa115 /src | |
| parent | e8efd10bd9750fd3769b46a0b2888ef9ae215991 (diff) | |
| download | mruby-26c1dedcabf6c845356653570f4dadd594c45709.tar.gz mruby-26c1dedcabf6c845356653570f4dadd594c45709.zip | |
Added 'U' pack support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/pack.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/pack.c b/src/pack.c index 1ceda8c11..d8bd68d4c 100644 --- a/src/pack.c +++ b/src/pack.c @@ -28,7 +28,7 @@ enum { PACK_DIR_QUAD, /* Q */ //PACK_DIR_INT, /* i */ //PACK_DIR_VAX, - //PACK_DIR_UTF8, /* U */ + PACK_DIR_UTF8, /* U */ //PACK_DIR_BER, PACK_DIR_DOUBLE, /* E */ PACK_DIR_FLOAT, /* f */ @@ -409,6 +409,45 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar } static int +pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count, unsigned int flags) +{ + char utf8[4]; + int len; + + unsigned long c = mrb_fixnum(o); + + /* Unicode character */ + /* from mruby-compiler gem */ + if (c < 0x80) { + utf8[0] = (char)c; + len = 1; + } + else if (c < 0x800) { + utf8[0] = (char)(0xC0 | (c >> 6)); + utf8[1] = (char)(0x80 | (c & 0x3F)); + len = 2; + } + else if (c < 0x10000) { + utf8[0] = (char)(0xE0 | (c >> 12) ); + utf8[1] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[2] = (char)(0x80 | ( c & 0x3F)); + len = 3; + } + else { + utf8[0] = (char)(0xF0 | (c >> 18) ); + utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F)); + utf8[2] = (char)(0x80 | ((c >> 6) & 0x3F)); + utf8[3] = (char)(0x80 | ( c & 0x3F)); + len = 4; + } + + str = str_len_ensure(mrb, str, sidx + len); + memcpy(RSTRING_PTR(str) + sidx, utf8, len); + + return len; +} + +static int pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) { int copylen, slen, padlen; @@ -856,6 +895,10 @@ alias: size = 2; flags |= PACK_FLAG_SIGNED; break; + case 'U': + dir = PACK_DIR_UTF8; + type = PACK_TYPE_INTEGER; + break; case 'V': /* = "L<" */ dir = PACK_DIR_LONG; type = PACK_TYPE_INTEGER; @@ -989,6 +1032,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) case PACK_DIR_FLOAT: ridx += pack_float(mrb, o, result, ridx, flags); break; + case PACK_DIR_UTF8: + ridx += pack_utf8(mrb, o, result, ridx, count, flags); + break; default: break; } |
