diff options
Diffstat (limited to 'mrbgems/mruby-pack/src')
| -rw-r--r-- | mrbgems/mruby-pack/src/pack.c | 134 |
1 files changed, 119 insertions, 15 deletions
diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 73b6ce635..e222cd946 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -2,7 +2,7 @@ ** pack.c - Array#pack, String#unpack */ -#include "mruby.h" +#include <mruby.h> #include "mruby/error.h" #include "mruby/array.h" #include "mruby/class.h" @@ -13,7 +13,6 @@ #include <ctype.h> #include <errno.h> #include <limits.h> -#include <stdio.h> #include <string.h> struct tmpl { @@ -213,6 +212,59 @@ pack_l(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl return 4; } +#ifndef MRB_INT64 +static void +u32tostr(char *buf, size_t len, uint32_t n) +{ +#ifdef MRB_DISABLE_STDIO + char *bufend = buf + len; + char *p = bufend - 1; + + if (len < 1) { + return; + } + + *p -- = '\0'; + len --; + + if (n > 0) { + for (; len > 0 && n > 0; len --, n /= 10) { + *p -- = '0' + (n % 10); + } + p ++; + } + else if (len > 0) { + *p = '0'; + len --; + } + + memmove(buf, p, bufend - p); +#else + snprintf(buf, len, "%" PRIu32, n); +#endif /* MRB_DISABLE_STDIO */ +} + +static void +i32tostr(char *buf, size_t len, int32_t n) +{ +#ifdef MRB_DISABLE_STDIO + if (len < 1) { + return; + } + + if (n < 0) { + *buf ++ = '-'; + len --; + n = -n; + } + + u32tostr(buf, len, (uint32_t)n); +#else + snprintf(buf, len, "%" PRId32, n); +#endif /* MRB_DISABLE_STDIO */ +} +#endif /* MRB_INT64 */ + static int unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) { @@ -237,16 +289,16 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un int32_t sl = ul; #ifndef MRB_INT64 if (!FIXABLE(sl)) { - snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %" PRId32, sl); - mrb_raise(mrb, E_RANGE_ERROR, msg); + i32tostr(msg, sizeof(msg), sl); + mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg); } #endif n = sl; } else { #ifndef MRB_INT64 if (!POSFIXABLE(ul)) { - snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %" PRIu32, ul); - mrb_raise(mrb, E_RANGE_ERROR, msg); + u32tostr(msg, sizeof(msg), ul); + mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg); } #endif n = ul; @@ -284,6 +336,57 @@ pack_q(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl return 8; } +static void +u64tostr(char *buf, size_t len, uint64_t n) +{ +#ifdef MRB_DISABLE_STDIO + char *bufend = buf + len; + char *p = bufend - 1; + + if (len < 1) { + return; + } + + *p -- = '\0'; + len --; + + if (n > 0) { + for (; len > 0 && n > 0; len --, n /= 10) { + *p -- = '0' + (n % 10); + } + p ++; + } + else if (len > 0) { + *p = '0'; + len --; + } + + memmove(buf, p, bufend - p); +#else + snprintf(buf, len, "%" PRIu64, n); +#endif /* MRB_DISABLE_STDIO */ +} + +static void +i64tostr(char *buf, size_t len, int64_t n) +{ +#ifdef MRB_DISABLE_STDIO + if (len < 1) { + return; + } + + if (n < 0) { + *buf ++ = '-'; + len --; + n = -n; + } + + u64tostr(buf, len, (uint64_t)n); +#else + snprintf(buf, len, "%" PRId64, n); +#endif /* MRB_DISABLE_STDIO */ +} + static int unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) { @@ -307,16 +410,16 @@ unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un if (flags & PACK_FLAG_SIGNED) { int64_t sll = ull; if (!FIXABLE(sll)) { - snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %" PRId64, sll); - mrb_raise(mrb, E_RANGE_ERROR, msg); + i64tostr(msg, sizeof(msg), sll); + mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg); } - n = sll; + n = (mrb_int)sll; } else { if (!POSFIXABLE(ull)) { - snprintf(msg, sizeof(msg), "cannot unpack to Fixnum: %" PRIu64, ull); - mrb_raise(mrb, E_RANGE_ERROR, msg); + u64tostr(msg, sizeof(msg), ull); + mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg); } - n = ull; + n = (mrb_int)ull; } mrb_ary_push(mrb, ary, mrb_fixnum_value(n)); return 8; @@ -725,7 +828,7 @@ unpack_h(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, un } } - dst = mrb_str_resize(mrb, dst, dptr - dptr0); + dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0)); mrb_ary_push(mrb, ary, dst); return (int)(sptr - sptr0); } @@ -848,7 +951,7 @@ unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int } done: - dst = mrb_str_resize(mrb, dst, dptr - dptr0); + dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0)); mrb_ary_push(mrb, ary, dst); return (int)(sptr - sptr0); } @@ -1195,7 +1298,8 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) default: break; } - if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64) { /* always consumes 1 entry */ + if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64 || dir == PACK_DIR_HEX) { + /* always consumes 1 entry */ aidx++; break; } |
