Merge pull request #10 from dabroz/master

Added 'U' pack support.
This commit is contained in:
Tomoyuki Sahara
2016-07-19 09:44:14 +09:00
committed by GitHub
2 changed files with 50 additions and 1 deletions
+3
View File
@@ -149,3 +149,6 @@ pptest ["1","2"], "1\0002", "Z*Z"
unpacktest ["1","3"], "1\00023", "Z3Z"
packtest [1, 2], "\x01\x02", "CyC"
packtest [65], "A", 'U'
packtest [59411], "\xEE\xA0\x93", 'U'
+47 -1
View File
@@ -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 */
@@ -408,6 +408,45 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar
return 4;
}
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)
{
@@ -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;
}