summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-pack/src
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-pack/src')
-rw-r--r--mrbgems/mruby-pack/src/pack.c134
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;
}