diff options
| author | Tomoyuki Sahara <[email protected]> | 2017-02-09 11:07:55 +0900 |
|---|---|---|
| committer | Tomoyuki Sahara <[email protected]> | 2017-02-09 11:07:55 +0900 |
| commit | 88a7fedea413568a1ff0410e109ff55a03b63a5f (patch) | |
| tree | b489a66b51e9a8f0e30542e1c831ca396dcca2ff | |
| parent | f2d4880098d4e3661fba1dc5e38861006089f9e8 (diff) | |
| download | mruby-88a7fedea413568a1ff0410e109ff55a03b63a5f.tar.gz mruby-88a7fedea413568a1ff0410e109ff55a03b63a5f.zip | |
support "x".
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | packtest.rb | 3 | ||||
| -rw-r--r-- | src/pack.c | 55 |
3 files changed, 49 insertions, 11 deletions
@@ -40,9 +40,11 @@ There is no dependency on other mrbgems. - s : 16-bit signed, native endian (`int16_t`) - V : 32-bit unsigned, VAX (little-endian) byte order - v : 16-bit unsigned, VAX (little-endian) byte order + - x : null byte - Z : same as "a", except that null is added with * + ## License Copyright (c) 2012 Internet Initiative Japan Inc. diff --git a/packtest.rb b/packtest.rb index e8be7c76c..459447af7 100644 --- a/packtest.rb +++ b/packtest.rb @@ -152,3 +152,6 @@ packtest [1, 2], "\x01\x02", "CyC" packtest [65], "A", 'U' packtest [59411], "\xEE\xA0\x93", 'U' + +pptest [1], "\x00\x01", "xC" +unpacktest [2], "\xcc\x02", "xC" diff --git a/src/pack.c b/src/pack.c index 9095ad03b..6a0075f5a 100644 --- a/src/pack.c +++ b/src/pack.c @@ -22,19 +22,20 @@ struct tmpl { }; enum { - PACK_DIR_CHAR, /* C */ - PACK_DIR_SHORT, /* S */ - PACK_DIR_LONG, /* L */ - PACK_DIR_QUAD, /* Q */ - //PACK_DIR_INT, /* i */ + PACK_DIR_CHAR, /* C */ + PACK_DIR_SHORT, /* S */ + PACK_DIR_LONG, /* L */ + 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 */ - PACK_DIR_STR, /* A */ - PACK_DIR_HEX, /* h */ - PACK_DIR_BASE64, /* m */ + PACK_DIR_DOUBLE, /* E */ + PACK_DIR_FLOAT, /* f */ + PACK_DIR_STR, /* A */ + PACK_DIR_HEX, /* h */ + PACK_DIR_BASE64, /* m */ + PACK_DIR_NUL, /* x */ PACK_DIR_INVALID }; @@ -731,6 +732,26 @@ done: return sptr - sptr0; } +static int +pack_x(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +{ + long i; + + dst = str_len_ensure(mrb, dst, didx + count); + for (i = 0; i < count; i++) { + RSTRING_PTR(dst)[didx] = '\0'; + } + return count; +} + +static int +unpack_x(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) +{ + if (slen < count) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "x outside of string"); + } + return count; +} static void prepare_tmpl(mrb_state *mrb, struct tmpl *tmpl) @@ -911,6 +932,10 @@ alias: size = 2; flags |= PACK_FLAG_LT; break; + case 'x': + dir = PACK_DIR_NUL; + type = PACK_TYPE_NONE; + break; case 'Z': dir = PACK_DIR_STR; type = PACK_TYPE_STRING; @@ -982,6 +1007,10 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) if (dir == PACK_DIR_INVALID) continue; + else if (dir == PACK_DIR_NUL) { + ridx += pack_x(mrb, mrb_nil_value(), result, ridx, count, flags); + continue; + } for (; aidx < RARRAY_LEN(ary); aidx++) { if (count == 0 && !(flags & PACK_FLAG_WIDTH)) @@ -1073,6 +1102,10 @@ mrb_pack_unpack(mrb_state *mrb, mrb_value str) if (dir == PACK_DIR_INVALID) continue; + else if (dir == PACK_DIR_NUL) { + srcidx += unpack_x(mrb, sptr, srclen - srcidx, result, count, flags); + continue; + } if (flags & PACK_FLAG_COUNT2) { sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; |
