diff options
| author | Tomoyuki Sahara <[email protected]> | 2015-05-22 11:38:39 +0900 |
|---|---|---|
| committer | Tomoyuki Sahara <[email protected]> | 2015-05-22 11:38:39 +0900 |
| commit | 2ba4933158c3c7635deaefa70cee661a0d60be9e (patch) | |
| tree | 88dfc3d0fd58e1189ac0588684150652737124b8 /src | |
| parent | 15de80a7cdf3a21ebedc5c39b8ec3478098279b9 (diff) | |
| download | mruby-2ba4933158c3c7635deaefa70cee661a0d60be9e.tar.gz mruby-2ba4933158c3c7635deaefa70cee661a0d60be9e.zip | |
refactor "AaZ". fixes #6.
Diffstat (limited to 'src')
| -rw-r--r-- | src/pack.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/pack.c b/src/pack.c index 6dfcab29e..dcc03e0e5 100644 --- a/src/pack.c +++ b/src/pack.c @@ -357,7 +357,9 @@ pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u else pad = ' '; - if (count == -1) { + if (count == 0) { + return 0; + } else if (count == -1) { copylen = slen; padlen = (flags & PACK_FLAG_Z) ? 1 : 0; } else if (count < slen) { @@ -383,29 +385,31 @@ static int unpack_a(mrb_state *mrb, const void *src, int slen, mrb_value ary, long count, unsigned int flags) { mrb_value dst; - const char *sptr; - char *dptr; + const char *cp, *sptr; + long copylen; sptr = src; + if (count != -1 && count < slen) { + slen = count; + } + copylen = slen; - if (count == -1 || count > slen) - count = slen; - - dst = mrb_str_new(mrb, NULL, count); - dptr = RSTRING_PTR(dst); - - memcpy(dptr, sptr, count); - if (flags & PACK_FLAG_Z) { - if (count > 0 && dptr[count - 1] == '\0') - count--; - } else if (!(flags & PACK_FLAG_a)) { - while (count > 0 && (dptr[count - 1] == '\0' || isspace(dptr[count - 1]))) - count--; + if (flags & PACK_FLAG_Z) { /* "Z" */ + if ((cp = memchr(sptr, '\0', slen)) != NULL) { + copylen = cp - sptr; + if (count == -1) { + slen = copylen + 1; + } + } + } else if (!(flags & PACK_FLAG_a)) { /* "A" */ + while (copylen > 0 && (sptr[copylen - 1] == '\0' || isspace(sptr[copylen - 1]))) { + copylen--; + } } - dst = mrb_str_resize(mrb, dst, count); + dst = mrb_str_new(mrb, sptr, copylen); mrb_ary_push(mrb, ary, dst); - return count; + return slen; } @@ -909,6 +913,10 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) default: break; } + if (dir == PACK_DIR_STR) { /* always consumes 1 entry */ + aidx++; + break; + } if (count > 0) { count--; } |
