summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-04-22 08:57:42 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-04-22 08:57:42 +0000
commite429f1c5844a6efb3c013416e007e77775a16fa3 (patch)
tree3edb0805f07e90e2a4f360a006700d3a942805bc /pack.c
parent089d61b4247f5e7e95bfa7dd3c0daa6cbe45fe92 (diff)
1.1b9_14
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@182 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/pack.c b/pack.c
index 52a0dd5027..6cd644c331 100644
--- a/pack.c
+++ b/pack.c
@@ -83,6 +83,18 @@ static char *toofew = "too few arguments";
static void encodes();
+static void
+pack_add_ptr(str, add)
+ VALUE str, add;
+{
+#define STR_NO_ORIG FL_USER3 /* copied from string.c */
+ if (!RSTRING(str)->orig) {
+ RSTRING(str)->orig = ary_new();
+ FL_SET(str, STR_NO_ORIG);
+ }
+ ary_push(RSTRING(str)->orig, add);
+}
+
static VALUE
pack_pack(ary, fmt)
VALUE ary, fmt;
@@ -463,6 +475,22 @@ pack_pack(ary, fmt)
}
break;
+ case 'P':
+ len = 1;
+ /* FALL THROUGH */
+ case 'p':
+ while (len-- > 0) {
+ char *t;
+ from = NEXTFROM;
+ if (NIL_P(from)) t = "";
+ else {
+ t = STR2CSTR(from);
+ pack_add_ptr(res, from);
+ }
+ str_cat(res, (char*)&t, sizeof(char*));
+ }
+ break;
+
default:
break;
}
@@ -926,6 +954,36 @@ pack_unpack(str, fmt)
s += len;
break;
+ case 'P':
+ if (sizeof(char *) <= send - s) {
+ char *t;
+ VALUE str = str_new(0, 0);
+ memcpy(&t, s, sizeof(char *));
+ s += sizeof(char *);
+ if (t)
+ str_cat(str, t, len);
+ ary_push(ary, str);
+ }
+ break;
+
+ case 'p':
+ if (len > (send - s) / sizeof(char *))
+ len = (send - s) / sizeof(char *);
+ while (len-- > 0) {
+ if (send - s < sizeof(char *))
+ break;
+ else {
+ char *t;
+ VALUE str = str_new(0, 0);
+ memcpy(&t, s, sizeof(char *));
+ s += sizeof(char *);
+ if (t)
+ str_cat(str, t, strlen(t));
+ ary_push(ary, str);
+ }
+ }
+ break;
+
default:
break;
}