summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-10-23 01:38:45 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-10-24 17:50:35 +0900
commitb69c38e62e0b7006d2c345a88a400f2fe2cb80b9 (patch)
treedb96ec396012c86db047f6a2c61fd68a37ae2f80 /pack.c
parent8d6e9b66580278900020abf77dc1aa6427a060f9 (diff)
Refactor associated pointer
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5014
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c68
1 files changed, 25 insertions, 43 deletions
diff --git a/pack.c b/pack.c
index 031071b440..e6a729ab08 100644
--- a/pack.c
+++ b/pack.c
@@ -135,7 +135,23 @@ str_associate(VALUE str, VALUE add)
static VALUE
str_associated(VALUE str)
{
- return rb_ivar_lookup(str, id_associated, Qfalse);
+ VALUE associates = rb_ivar_lookup(str, id_associated, Qfalse);
+ if (!associates)
+ rb_raise(rb_eArgError, "no associated pointer");
+ return associates;
+}
+
+static VALUE
+associated_pointer(VALUE associates, const char *t)
+{
+ const VALUE *p = RARRAY_CONST_PTR(associates);
+ const VALUE *pend = p + RARRAY_LEN(associates);
+ for (; p < pend; p++) {
+ VALUE tmp = *p;
+ if (RB_TYPE_P(tmp, T_STRING) && RSTRING_PTR(tmp) == t) return tmp;
+ }
+ rb_raise(rb_eArgError, "non associated pointer");
+ UNREACHABLE_RETURN(Qnil);
}
static void
@@ -933,7 +949,7 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
#define hexdigits ruby_hexdigits
char *s, *send;
char *p, *pend;
- VALUE ary;
+ VALUE ary, associates = Qfalse;
char type;
long len;
AVOID_CC_BUG long tmp_len;
@@ -1540,29 +1556,11 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
UNPACK_FETCH(&t, char *);
if (t) {
- VALUE a;
- const VALUE *p, *pend;
-
- if (!(a = str_associated(str))) {
- rb_raise(rb_eArgError, "no associated pointer");
- }
- p = RARRAY_CONST_PTR(a);
- pend = p + RARRAY_LEN(a);
- while (p < pend) {
- if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
- if (len < RSTRING_LEN(*p)) {
- tmp = rb_str_new(t, len);
- str_associate(tmp, a);
- }
- else {
- tmp = *p;
- }
- break;
- }
- p++;
- }
- if (p == pend) {
- rb_raise(rb_eArgError, "non associated pointer");
+ if (!associates) associates = str_associated(str);
+ tmp = associated_pointer(associates, t);
+ if (len < RSTRING_LEN(tmp)) {
+ tmp = rb_str_new(t, len);
+ str_associate(tmp, associates);
}
}
UNPACK_PUSH(tmp);
@@ -1581,24 +1579,8 @@ pack_unpack_internal(VALUE str, VALUE fmt, int mode)
UNPACK_FETCH(&t, char *);
if (t) {
- VALUE a;
- const VALUE *p, *pend;
-
- if (!(a = str_associated(str))) {
- rb_raise(rb_eArgError, "no associated pointer");
- }
- p = RARRAY_CONST_PTR(a);
- pend = p + RARRAY_LEN(a);
- while (p < pend) {
- if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
- tmp = *p;
- break;
- }
- p++;
- }
- if (p == pend) {
- rb_raise(rb_eArgError, "non associated pointer");
- }
+ if (!associates) associates = str_associated(str);
+ tmp = associated_pointer(associates, t);
}
UNPACK_PUSH(tmp);
}