Ruby  2.4.2p198(2017-09-14revision59899)
pack.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  pack.c -
4 
5  $Author: naruse $
6  created at: Thu Feb 10 15:17:05 JST 1994
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "internal.h"
13 #include <sys/types.h>
14 #include <ctype.h>
15 #include <errno.h>
16 
17 /*
18  * It is intentional that the condition for natstr is HAVE_TRUE_LONG_LONG
19  * instead of HAVE_LONG_LONG or LONG_LONG.
20  * This means q! and Q! means always the standard long long type and
21  * causes ArgumentError for platforms which has no long long type,
22  * even if the platform has an implementation specific 64bit type.
23  * This behavior is consistent with the document of pack/unpack.
24  */
25 #ifdef HAVE_TRUE_LONG_LONG
26 static const char natstr[] = "sSiIlLqQjJ";
27 #else
28 static const char natstr[] = "sSiIlLjJ";
29 #endif
30 static const char endstr[] = "sSiIlLqQjJ";
31 
32 #ifdef HAVE_TRUE_LONG_LONG
33 /* It is intentional to use long long instead of LONG_LONG. */
34 # define NATINT_LEN_Q NATINT_LEN(long long, 8)
35 #else
36 # define NATINT_LEN_Q 8
37 #endif
38 
39 #if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
40 # define NATINT_PACK
41 #endif
42 
43 #ifdef DYNAMIC_ENDIAN
44  /* for universal binary of NEXTSTEP and MacOS X */
45  /* useless since autoconf 2.63? */
46  static int
47  is_bigendian(void)
48  {
49  static int init = 0;
50  static int endian_value;
51  char *p;
52 
53  if (init) return endian_value;
54  init = 1;
55  p = (char*)&init;
56  return endian_value = p[0]?0:1;
57  }
58 # define BIGENDIAN_P() (is_bigendian())
59 #elif defined(WORDS_BIGENDIAN)
60 # define BIGENDIAN_P() 1
61 #else
62 # define BIGENDIAN_P() 0
63 #endif
64 
65 #ifdef NATINT_PACK
66 # define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len))
67 #else
68 # define NATINT_LEN(type,len) ((int)sizeof(type))
69 #endif
70 
71 typedef union {
72  float f;
74  char buf[4];
76 typedef union {
77  double d;
79  char buf[8];
81 #define swapf(x) swap32(x)
82 #define swapd(x) swap64(x)
83 
84 #define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
85 #define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
86 #define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x))
87 #define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x))
88 #define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x))
89 #define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x))
90 #define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
91 #define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))
92 
93 #define FLOAT_CONVWITH(x) FLOAT_SWAPPER x;
94 #define HTONF(x) ((x).u = rb_htonf((x).u))
95 #define HTOVF(x) ((x).u = rb_htovf((x).u))
96 #define NTOHF(x) ((x).u = rb_ntohf((x).u))
97 #define VTOHF(x) ((x).u = rb_vtohf((x).u))
98 
99 #define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x;
100 #define HTOND(x) ((x).u = rb_htond((x).u))
101 #define HTOVD(x) ((x).u = rb_htovd((x).u))
102 #define NTOHD(x) ((x).u = rb_ntohd((x).u))
103 #define VTOHD(x) ((x).u = rb_vtohd((x).u))
104 
105 #define MAX_INTEGER_PACK_SIZE 8
106 
107 static const char toofew[] = "too few arguments";
108 
109 static void encodes(VALUE,const char*,long,int,int);
110 static void qpencode(VALUE,VALUE,long);
111 
112 static unsigned long utf8_to_uv(const char*,long*);
113 
115 
116 static void
118 {
119  /* assert(NIL_P(rb_attr_get(str, id_associated))); */
120  rb_ivar_set(str, id_associated, add);
121 }
122 
123 static VALUE
125 {
126  return rb_ivar_lookup(str, id_associated, Qfalse);
127 }
128 
129 void
131 {
132  ONLY_FOR_INTERNAL_USE("rb_str_associate()");
133 }
134 
135 VALUE
137 {
138  ONLY_FOR_INTERNAL_USE("rb_str_associated()");
139 }
140 
141 /*
142  * call-seq:
143  * arr.pack( aTemplateString ) -> aBinaryString
144  * arr.pack( aTemplateString, buffer: aBufferString ) -> aBufferString
145  *
146  * Packs the contents of <i>arr</i> into a binary sequence according to
147  * the directives in <i>aTemplateString</i> (see the table below)
148  * Directives ``A,'' ``a,'' and ``Z'' may be followed by a count,
149  * which gives the width of the resulting field. The remaining
150  * directives also may take a count, indicating the number of array
151  * elements to convert. If the count is an asterisk
152  * (``<code>*</code>''), all remaining array elements will be
153  * converted. Any of the directives ``<code>sSiIlL</code>'' may be
154  * followed by an underscore (``<code>_</code>'') or
155  * exclamation mark (``<code>!</code>'') to use the underlying
156  * platform's native size for the specified type; otherwise, they use a
157  * platform-independent size. Spaces are ignored in the template
158  * string. See also <code>String#unpack</code>.
159  *
160  * a = [ "a", "b", "c" ]
161  * n = [ 65, 66, 67 ]
162  * a.pack("A3A3A3") #=> "a b c "
163  * a.pack("a3a3a3") #=> "a\000\000b\000\000c\000\000"
164  * n.pack("ccc") #=> "ABC"
165  *
166  * If <i>aBufferString</i> is specified and its capacity is enough,
167  * +pack+ uses it as the buffer and returns it.
168  * When the offset is specified by the beginning of <i>aTemplateString</i>,
169  * the result is filled after the offset.
170  * If original contents of <i>aBufferString</i> exists and it's longer than
171  * the offset, the rest of <i>offsetOfBuffer</i> are overwritten by the result.
172  * If it's shorter, the gap is filled with ``<code>\0</code>''.
173  *
174  * Note that ``buffer:'' option does not guarantee not to allocate memory
175  * in +pack+. If the capacity of <i>aBufferString</i> is not enough,
176  * +pack+ allocates memory.
177  *
178  * Directives for +pack+.
179  *
180  * Integer | Array |
181  * Directive | Element | Meaning
182  * ----------------------------------------------------------------------------
183  * C | Integer | 8-bit unsigned (unsigned char)
184  * S | Integer | 16-bit unsigned, native endian (uint16_t)
185  * L | Integer | 32-bit unsigned, native endian (uint32_t)
186  * Q | Integer | 64-bit unsigned, native endian (uint64_t)
187  * J | Integer | pointer width unsigned, native endian (uintptr_t)
188  * | | (J is available since Ruby 2.3.)
189  * | |
190  * c | Integer | 8-bit signed (signed char)
191  * s | Integer | 16-bit signed, native endian (int16_t)
192  * l | Integer | 32-bit signed, native endian (int32_t)
193  * q | Integer | 64-bit signed, native endian (int64_t)
194  * j | Integer | pointer width signed, native endian (intptr_t)
195  * | | (j is available since Ruby 2.3.)
196  * | |
197  * S_ S! | Integer | unsigned short, native endian
198  * I I_ I! | Integer | unsigned int, native endian
199  * L_ L! | Integer | unsigned long, native endian
200  * Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
201  * | | if the platform has no long long type.)
202  * | | (Q_ and Q! is available since Ruby 2.1.)
203  * J! | Integer | uintptr_t, native endian (same with J)
204  * | | (J! is available since Ruby 2.3.)
205  * | |
206  * s_ s! | Integer | signed short, native endian
207  * i i_ i! | Integer | signed int, native endian
208  * l_ l! | Integer | signed long, native endian
209  * q_ q! | Integer | signed long long, native endian (ArgumentError
210  * | | if the platform has no long long type.)
211  * | | (q_ and q! is available since Ruby 2.1.)
212  * j! | Integer | intptr_t, native endian (same with j)
213  * | | (j! is available since Ruby 2.3.)
214  * | |
215  * S> s> S!> s!> | Integer | same as the directives without ">" except
216  * L> l> L!> l!> | | big endian
217  * I!> i!> | | (available since Ruby 1.9.3)
218  * Q> q> Q!> q!> | | "S>" is same as "n"
219  * J> j> J!> j!> | | "L>" is same as "N"
220  * | |
221  * S< s< S!< s!< | Integer | same as the directives without "<" except
222  * L< l< L!< l!< | | little endian
223  * I!< i!< | | (available since Ruby 1.9.3)
224  * Q< q< Q!< q!< | | "S<" is same as "v"
225  * J< j< J!< j!< | | "L<" is same as "V"
226  * | |
227  * n | Integer | 16-bit unsigned, network (big-endian) byte order
228  * N | Integer | 32-bit unsigned, network (big-endian) byte order
229  * v | Integer | 16-bit unsigned, VAX (little-endian) byte order
230  * V | Integer | 32-bit unsigned, VAX (little-endian) byte order
231  * | |
232  * U | Integer | UTF-8 character
233  * w | Integer | BER-compressed integer
234  *
235  * Float | Array |
236  * Directive | Element | Meaning
237  * ---------------------------------------------------------------------------
238  * D d | Float | double-precision, native format
239  * F f | Float | single-precision, native format
240  * E | Float | double-precision, little-endian byte order
241  * e | Float | single-precision, little-endian byte order
242  * G | Float | double-precision, network (big-endian) byte order
243  * g | Float | single-precision, network (big-endian) byte order
244  *
245  * String | Array |
246  * Directive | Element | Meaning
247  * ---------------------------------------------------------------------------
248  * A | String | arbitrary binary string (space padded, count is width)
249  * a | String | arbitrary binary string (null padded, count is width)
250  * Z | String | same as ``a'', except that null is added with *
251  * B | String | bit string (MSB first)
252  * b | String | bit string (LSB first)
253  * H | String | hex string (high nibble first)
254  * h | String | hex string (low nibble first)
255  * u | String | UU-encoded string
256  * M | String | quoted printable, MIME encoding (see RFC2045)
257  * m | String | base64 encoded string (see RFC 2045, count is width)
258  * | | (if count is 0, no line feed are added, see RFC 4648)
259  * P | String | pointer to a structure (fixed-length string)
260  * p | String | pointer to a null-terminated string
261  *
262  * Misc. | Array |
263  * Directive | Element | Meaning
264  * ---------------------------------------------------------------------------
265  * @ | --- | moves to absolute position
266  * X | --- | back up a byte
267  * x | --- | null byte
268  */
269 
270 static VALUE
272 {
273  static const char nul10[] = "\0\0\0\0\0\0\0\0\0\0";
274  static const char spc10[] = " ";
275  const char *p, *pend;
276  VALUE fmt, opt = Qnil, res, from, associates = 0, buffer = 0;
277  char type;
278  long len, idx, plen;
279  const char *ptr;
280  int enc_info = 1; /* 0 - BINARY, 1 - US-ASCII, 2 - UTF-8 */
281 #ifdef NATINT_PACK
282  int natint; /* native integer */
283 #endif
284  int integer_size, bigendian_p;
285 
286  rb_scan_args(argc, argv, "10:", &fmt, &opt);
287 
288  StringValue(fmt);
289  p = RSTRING_PTR(fmt);
290  pend = p + RSTRING_LEN(fmt);
291  if (!NIL_P(opt)) {
292  static ID keyword_ids[1];
293  if (!keyword_ids[0])
294  CONST_ID(keyword_ids[0], "buffer");
295 
296  rb_get_kwargs(opt, keyword_ids, 0, 1, &buffer);
297 
298  if (buffer != Qundef && !RB_TYPE_P(buffer, T_STRING))
299  rb_raise(rb_eTypeError, "buffer must be String, not %s", rb_obj_classname(buffer));
300  }
301  if (buffer)
302  res = buffer;
303  else
304  res = rb_str_buf_new(0);
305 
306  idx = 0;
307 
308 #define TOO_FEW (rb_raise(rb_eArgError, toofew), 0)
309 #define MORE_ITEM (idx < RARRAY_LEN(ary))
310 #define THISFROM (MORE_ITEM ? RARRAY_AREF(ary, idx) : TOO_FEW)
311 #define NEXTFROM (MORE_ITEM ? RARRAY_AREF(ary, idx++) : TOO_FEW)
312 
313  while (p < pend) {
314  int explicit_endian = 0;
315  if (RSTRING_PTR(fmt) + RSTRING_LEN(fmt) != pend) {
316  rb_raise(rb_eRuntimeError, "format string modified");
317  }
318  type = *p++; /* get data type */
319 #ifdef NATINT_PACK
320  natint = 0;
321 #endif
322 
323  if (ISSPACE(type)) continue;
324  if (type == '#') {
325  while ((p < pend) && (*p != '\n')) {
326  p++;
327  }
328  continue;
329  }
330 
331  {
332  modifiers:
333  switch (*p) {
334  case '_':
335  case '!':
336  if (strchr(natstr, type)) {
337 #ifdef NATINT_PACK
338  natint = 1;
339 #endif
340  p++;
341  }
342  else {
343  rb_raise(rb_eArgError, "'%c' allowed only after types %s", *p, natstr);
344  }
345  goto modifiers;
346 
347  case '<':
348  case '>':
349  if (!strchr(endstr, type)) {
350  rb_raise(rb_eArgError, "'%c' allowed only after types %s", *p, endstr);
351  }
352  if (explicit_endian) {
353  rb_raise(rb_eRangeError, "Can't use both '<' and '>'");
354  }
355  explicit_endian = *p++;
356  goto modifiers;
357  }
358  }
359 
360  if (*p == '*') { /* set data length */
361  len = strchr("@Xxu", type) ? 0
362  : strchr("PMm", type) ? 1
363  : RARRAY_LEN(ary) - idx;
364  p++;
365  }
366  else if (ISDIGIT(*p)) {
367  errno = 0;
368  len = STRTOUL(p, (char**)&p, 10);
369  if (errno) {
370  rb_raise(rb_eRangeError, "pack length too big");
371  }
372  }
373  else {
374  len = 1;
375  }
376 
377  switch (type) {
378  case 'U':
379  /* if encoding is US-ASCII, upgrade to UTF-8 */
380  if (enc_info == 1) enc_info = 2;
381  break;
382  case 'm': case 'M': case 'u':
383  /* keep US-ASCII (do nothing) */
384  break;
385  default:
386  /* fall back to BINARY */
387  enc_info = 0;
388  break;
389  }
390  switch (type) {
391  case 'A': case 'a': case 'Z':
392  case 'B': case 'b':
393  case 'H': case 'h':
394  from = NEXTFROM;
395  if (NIL_P(from)) {
396  ptr = "";
397  plen = 0;
398  }
399  else {
400  StringValue(from);
401  ptr = RSTRING_PTR(from);
402  plen = RSTRING_LEN(from);
403  OBJ_INFECT(res, from);
404  }
405 
406  if (p[-1] == '*')
407  len = plen;
408 
409  switch (type) {
410  case 'a': /* arbitrary binary string (null padded) */
411  case 'A': /* arbitrary binary string (ASCII space padded) */
412  case 'Z': /* null terminated string */
413  if (plen >= len) {
414  rb_str_buf_cat(res, ptr, len);
415  if (p[-1] == '*' && type == 'Z')
416  rb_str_buf_cat(res, nul10, 1);
417  }
418  else {
419  rb_str_buf_cat(res, ptr, plen);
420  len -= plen;
421  while (len >= 10) {
422  rb_str_buf_cat(res, (type == 'A')?spc10:nul10, 10);
423  len -= 10;
424  }
425  rb_str_buf_cat(res, (type == 'A')?spc10:nul10, len);
426  }
427  break;
428 
429 #define castchar(from) (char)((from) & 0xff)
430 
431  case 'b': /* bit string (ascending) */
432  {
433  int byte = 0;
434  long i, j = 0;
435 
436  if (len > plen) {
437  j = (len - plen + 1)/2;
438  len = plen;
439  }
440  for (i=0; i++ < len; ptr++) {
441  if (*ptr & 1)
442  byte |= 128;
443  if (i & 7)
444  byte >>= 1;
445  else {
446  char c = castchar(byte);
447  rb_str_buf_cat(res, &c, 1);
448  byte = 0;
449  }
450  }
451  if (len & 7) {
452  char c;
453  byte >>= 7 - (len & 7);
454  c = castchar(byte);
455  rb_str_buf_cat(res, &c, 1);
456  }
457  len = j;
458  goto grow;
459  }
460  break;
461 
462  case 'B': /* bit string (descending) */
463  {
464  int byte = 0;
465  long i, j = 0;
466 
467  if (len > plen) {
468  j = (len - plen + 1)/2;
469  len = plen;
470  }
471  for (i=0; i++ < len; ptr++) {
472  byte |= *ptr & 1;
473  if (i & 7)
474  byte <<= 1;
475  else {
476  char c = castchar(byte);
477  rb_str_buf_cat(res, &c, 1);
478  byte = 0;
479  }
480  }
481  if (len & 7) {
482  char c;
483  byte <<= 7 - (len & 7);
484  c = castchar(byte);
485  rb_str_buf_cat(res, &c, 1);
486  }
487  len = j;
488  goto grow;
489  }
490  break;
491 
492  case 'h': /* hex string (low nibble first) */
493  {
494  int byte = 0;
495  long i, j = 0;
496 
497  if (len > plen) {
498  j = (len + 1) / 2 - (plen + 1) / 2;
499  len = plen;
500  }
501  for (i=0; i++ < len; ptr++) {
502  if (ISALPHA(*ptr))
503  byte |= (((*ptr & 15) + 9) & 15) << 4;
504  else
505  byte |= (*ptr & 15) << 4;
506  if (i & 1)
507  byte >>= 4;
508  else {
509  char c = castchar(byte);
510  rb_str_buf_cat(res, &c, 1);
511  byte = 0;
512  }
513  }
514  if (len & 1) {
515  char c = castchar(byte);
516  rb_str_buf_cat(res, &c, 1);
517  }
518  len = j;
519  goto grow;
520  }
521  break;
522 
523  case 'H': /* hex string (high nibble first) */
524  {
525  int byte = 0;
526  long i, j = 0;
527 
528  if (len > plen) {
529  j = (len + 1) / 2 - (plen + 1) / 2;
530  len = plen;
531  }
532  for (i=0; i++ < len; ptr++) {
533  if (ISALPHA(*ptr))
534  byte |= ((*ptr & 15) + 9) & 15;
535  else
536  byte |= *ptr & 15;
537  if (i & 1)
538  byte <<= 4;
539  else {
540  char c = castchar(byte);
541  rb_str_buf_cat(res, &c, 1);
542  byte = 0;
543  }
544  }
545  if (len & 1) {
546  char c = castchar(byte);
547  rb_str_buf_cat(res, &c, 1);
548  }
549  len = j;
550  goto grow;
551  }
552  break;
553  }
554  break;
555 
556  case 'c': /* signed char */
557  case 'C': /* unsigned char */
558  integer_size = 1;
559  bigendian_p = BIGENDIAN_P(); /* not effective */
560  goto pack_integer;
561 
562  case 's': /* s for int16_t, s! for signed short */
563  integer_size = NATINT_LEN(short, 2);
564  bigendian_p = BIGENDIAN_P();
565  goto pack_integer;
566 
567  case 'S': /* S for uint16_t, S! for unsigned short */
568  integer_size = NATINT_LEN(short, 2);
569  bigendian_p = BIGENDIAN_P();
570  goto pack_integer;
571 
572  case 'i': /* i and i! for signed int */
573  integer_size = (int)sizeof(int);
574  bigendian_p = BIGENDIAN_P();
575  goto pack_integer;
576 
577  case 'I': /* I and I! for unsigned int */
578  integer_size = (int)sizeof(int);
579  bigendian_p = BIGENDIAN_P();
580  goto pack_integer;
581 
582  case 'l': /* l for int32_t, l! for signed long */
583  integer_size = NATINT_LEN(long, 4);
584  bigendian_p = BIGENDIAN_P();
585  goto pack_integer;
586 
587  case 'L': /* L for uint32_t, L! for unsigned long */
588  integer_size = NATINT_LEN(long, 4);
589  bigendian_p = BIGENDIAN_P();
590  goto pack_integer;
591 
592  case 'q': /* q for int64_t, q! for signed long long */
593  integer_size = NATINT_LEN_Q;
594  bigendian_p = BIGENDIAN_P();
595  goto pack_integer;
596 
597  case 'Q': /* Q for uint64_t, Q! for unsigned long long */
598  integer_size = NATINT_LEN_Q;
599  bigendian_p = BIGENDIAN_P();
600  goto pack_integer;
601 
602  case 'j': /* j for intptr_t */
603  integer_size = sizeof(intptr_t);
604  bigendian_p = BIGENDIAN_P();
605  goto pack_integer;
606 
607  case 'J': /* J for uintptr_t */
608  integer_size = sizeof(uintptr_t);
609  bigendian_p = BIGENDIAN_P();
610  goto pack_integer;
611 
612  case 'n': /* 16 bit (2 bytes) integer (network byte-order) */
613  integer_size = 2;
614  bigendian_p = 1;
615  goto pack_integer;
616 
617  case 'N': /* 32 bit (4 bytes) integer (network byte-order) */
618  integer_size = 4;
619  bigendian_p = 1;
620  goto pack_integer;
621 
622  case 'v': /* 16 bit (2 bytes) integer (VAX byte-order) */
623  integer_size = 2;
624  bigendian_p = 0;
625  goto pack_integer;
626 
627  case 'V': /* 32 bit (4 bytes) integer (VAX byte-order) */
628  integer_size = 4;
629  bigendian_p = 0;
630  goto pack_integer;
631 
632  pack_integer:
633  if (explicit_endian) {
634  bigendian_p = explicit_endian == '>';
635  }
636  if (integer_size > MAX_INTEGER_PACK_SIZE)
637  rb_bug("unexpected intger size for pack: %d", integer_size);
638  while (len-- > 0) {
639  char intbuf[MAX_INTEGER_PACK_SIZE];
640 
641  from = NEXTFROM;
642  rb_integer_pack(from, intbuf, integer_size, 1, 0,
645  rb_str_buf_cat(res, intbuf, integer_size);
646  }
647  break;
648 
649  case 'f': /* single precision float in native format */
650  case 'F': /* ditto */
651  while (len-- > 0) {
652  float f;
653 
654  from = NEXTFROM;
655  f = (float)RFLOAT_VALUE(rb_to_float(from));
656  rb_str_buf_cat(res, (char*)&f, sizeof(float));
657  }
658  break;
659 
660  case 'e': /* single precision float in VAX byte-order */
661  while (len-- > 0) {
662  FLOAT_CONVWITH(tmp);
663 
664  from = NEXTFROM;
665  tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
666  HTOVF(tmp);
667  rb_str_buf_cat(res, tmp.buf, sizeof(float));
668  }
669  break;
670 
671  case 'E': /* double precision float in VAX byte-order */
672  while (len-- > 0) {
673  DOUBLE_CONVWITH(tmp);
674  from = NEXTFROM;
675  tmp.d = RFLOAT_VALUE(rb_to_float(from));
676  HTOVD(tmp);
677  rb_str_buf_cat(res, tmp.buf, sizeof(double));
678  }
679  break;
680 
681  case 'd': /* double precision float in native format */
682  case 'D': /* ditto */
683  while (len-- > 0) {
684  double d;
685 
686  from = NEXTFROM;
687  d = RFLOAT_VALUE(rb_to_float(from));
688  rb_str_buf_cat(res, (char*)&d, sizeof(double));
689  }
690  break;
691 
692  case 'g': /* single precision float in network byte-order */
693  while (len-- > 0) {
694  FLOAT_CONVWITH(tmp);
695  from = NEXTFROM;
696  tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
697  HTONF(tmp);
698  rb_str_buf_cat(res, tmp.buf, sizeof(float));
699  }
700  break;
701 
702  case 'G': /* double precision float in network byte-order */
703  while (len-- > 0) {
704  DOUBLE_CONVWITH(tmp);
705 
706  from = NEXTFROM;
707  tmp.d = RFLOAT_VALUE(rb_to_float(from));
708  HTOND(tmp);
709  rb_str_buf_cat(res, tmp.buf, sizeof(double));
710  }
711  break;
712 
713  case 'x': /* null byte */
714  grow:
715  while (len >= 10) {
716  rb_str_buf_cat(res, nul10, 10);
717  len -= 10;
718  }
719  rb_str_buf_cat(res, nul10, len);
720  break;
721 
722  case 'X': /* back up byte */
723  shrink:
724  plen = RSTRING_LEN(res);
725  if (plen < len)
726  rb_raise(rb_eArgError, "X outside of string");
727  rb_str_set_len(res, plen - len);
728  break;
729 
730  case '@': /* null fill to absolute position */
731  len -= RSTRING_LEN(res);
732  if (len > 0) goto grow;
733  len = -len;
734  if (len > 0) goto shrink;
735  break;
736 
737  case '%':
738  rb_raise(rb_eArgError, "%% is not supported");
739  break;
740 
741  case 'U': /* Unicode character */
742  while (len-- > 0) {
743  SIGNED_VALUE l;
744  char buf[8];
745  int le;
746 
747  from = NEXTFROM;
748  from = rb_to_int(from);
749  l = NUM2LONG(from);
750  if (l < 0) {
751  rb_raise(rb_eRangeError, "pack(U): value out of range");
752  }
753  le = rb_uv_to_utf8(buf, l);
754  rb_str_buf_cat(res, (char*)buf, le);
755  }
756  break;
757 
758  case 'u': /* uuencoded string */
759  case 'm': /* base64 encoded string */
760  from = NEXTFROM;
761  StringValue(from);
762  ptr = RSTRING_PTR(from);
763  plen = RSTRING_LEN(from);
764 
765  if (len == 0 && type == 'm') {
766  encodes(res, ptr, plen, type, 0);
767  ptr += plen;
768  break;
769  }
770  if (len <= 2)
771  len = 45;
772  else if (len > 63 && type == 'u')
773  len = 63;
774  else
775  len = len / 3 * 3;
776  while (plen > 0) {
777  long todo;
778 
779  if (plen > len)
780  todo = len;
781  else
782  todo = plen;
783  encodes(res, ptr, todo, type, 1);
784  plen -= todo;
785  ptr += todo;
786  }
787  break;
788 
789  case 'M': /* quoted-printable encoded string */
790  from = rb_obj_as_string(NEXTFROM);
791  if (len <= 1)
792  len = 72;
793  qpencode(res, from, len);
794  break;
795 
796  case 'P': /* pointer to packed byte string */
797  from = THISFROM;
798  if (!NIL_P(from)) {
799  StringValue(from);
800  if (RSTRING_LEN(from) < len) {
801  rb_raise(rb_eArgError, "too short buffer for P(%ld for %ld)",
802  RSTRING_LEN(from), len);
803  }
804  }
805  len = 1;
806  /* FALL THROUGH */
807  case 'p': /* pointer to string */
808  while (len-- > 0) {
809  char *t;
810  from = NEXTFROM;
811  if (NIL_P(from)) {
812  t = 0;
813  }
814  else {
815  t = StringValuePtr(from);
816  rb_obj_taint(from);
817  }
818  if (!associates) {
819  associates = rb_ary_new();
820  }
821  rb_ary_push(associates, from);
822  rb_str_buf_cat(res, (char*)&t, sizeof(char*));
823  }
824  break;
825 
826  case 'w': /* BER compressed integer */
827  while (len-- > 0) {
828  VALUE buf = rb_str_new(0, 0);
829  size_t numbytes;
830  int sign;
831  char *cp;
832 
833  from = NEXTFROM;
834  from = rb_to_int(from);
835  numbytes = rb_absint_numwords(from, 7, NULL);
836  if (numbytes == 0)
837  numbytes = 1;
838  buf = rb_str_new(NULL, numbytes);
839 
840  sign = rb_integer_pack(from, RSTRING_PTR(buf), RSTRING_LEN(buf), 1, 1, INTEGER_PACK_BIG_ENDIAN);
841 
842  if (sign < 0)
843  rb_raise(rb_eArgError, "can't compress negative numbers");
844  if (sign == 2)
845  rb_bug("buffer size problem?");
846 
847  cp = RSTRING_PTR(buf);
848  while (1 < numbytes) {
849  *cp |= 0x80;
850  cp++;
851  numbytes--;
852  }
853 
854  rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
855  }
856  break;
857 
858  default: {
859  char unknown[5];
860  if (ISPRINT(type)) {
861  unknown[0] = type;
862  unknown[1] = '\0';
863  }
864  else {
865  snprintf(unknown, sizeof(unknown), "\\x%.2x", type & 0xff);
866  }
867  rb_warning("unknown pack directive '%s' in '% "PRIsVALUE"'",
868  unknown, fmt);
869  break;
870  }
871  }
872  }
873 
874  if (associates) {
875  str_associate(res, associates);
876  }
877  OBJ_INFECT(res, fmt);
878  switch (enc_info) {
879  case 1:
881  break;
882  case 2:
884  break;
885  default:
886  /* do nothing, keep ASCII-8BIT */
887  break;
888  }
889  return res;
890 }
891 
892 static const char uu_table[] =
893 "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
894 static const char b64_table[] =
895 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
896 
897 static void
898 encodes(VALUE str, const char *s0, long len, int type, int tail_lf)
899 {
900  enum {buff_size = 4096, encoded_unit = 4, input_unit = 3};
901  char buff[buff_size + 1]; /* +1 for tail_lf */
902  long i = 0;
903  const char *const trans = type == 'u' ? uu_table : b64_table;
904  char padding;
905  const unsigned char *s = (const unsigned char *)s0;
906 
907  if (type == 'u') {
908  buff[i++] = (char)len + ' ';
909  padding = '`';
910  }
911  else {
912  padding = '=';
913  }
914  while (len >= input_unit) {
915  while (len >= input_unit && buff_size-i >= encoded_unit) {
916  buff[i++] = trans[077 & (*s >> 2)];
917  buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
918  buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
919  buff[i++] = trans[077 & s[2]];
920  s += input_unit;
921  len -= input_unit;
922  }
923  if (buff_size-i < encoded_unit) {
924  rb_str_buf_cat(str, buff, i);
925  i = 0;
926  }
927  }
928 
929  if (len == 2) {
930  buff[i++] = trans[077 & (*s >> 2)];
931  buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
932  buff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))];
933  buff[i++] = padding;
934  }
935  else if (len == 1) {
936  buff[i++] = trans[077 & (*s >> 2)];
937  buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
938  buff[i++] = padding;
939  buff[i++] = padding;
940  }
941  if (tail_lf) buff[i++] = '\n';
942  rb_str_buf_cat(str, buff, i);
943  if ((size_t)i > sizeof(buff)) rb_bug("encodes() buffer overrun");
944 }
945 
946 static const char hex_table[] = "0123456789ABCDEF";
947 
948 static void
949 qpencode(VALUE str, VALUE from, long len)
950 {
951  char buff[1024];
952  long i = 0, n = 0, prev = EOF;
953  unsigned char *s = (unsigned char*)RSTRING_PTR(from);
954  unsigned char *send = s + RSTRING_LEN(from);
955 
956  while (s < send) {
957  if ((*s > 126) ||
958  (*s < 32 && *s != '\n' && *s != '\t') ||
959  (*s == '=')) {
960  buff[i++] = '=';
961  buff[i++] = hex_table[*s >> 4];
962  buff[i++] = hex_table[*s & 0x0f];
963  n += 3;
964  prev = EOF;
965  }
966  else if (*s == '\n') {
967  if (prev == ' ' || prev == '\t') {
968  buff[i++] = '=';
969  buff[i++] = *s;
970  }
971  buff[i++] = *s;
972  n = 0;
973  prev = *s;
974  }
975  else {
976  buff[i++] = *s;
977  n++;
978  prev = *s;
979  }
980  if (n > len) {
981  buff[i++] = '=';
982  buff[i++] = '\n';
983  n = 0;
984  prev = '\n';
985  }
986  if (i > 1024 - 5) {
987  rb_str_buf_cat(str, buff, i);
988  i = 0;
989  }
990  s++;
991  }
992  if (n > 0) {
993  buff[i++] = '=';
994  buff[i++] = '\n';
995  }
996  if (i > 0) {
997  rb_str_buf_cat(str, buff, i);
998  }
999 }
1000 
1001 static inline int
1002 hex2num(char c)
1003 {
1004  int n;
1005  n = ruby_digit36_to_number_table[(unsigned char)c];
1006  if (16 <= n)
1007  n = -1;
1008  return n;
1009 }
1010 
1011 #define PACK_LENGTH_ADJUST_SIZE(sz) do { \
1012  tmp_len = 0; \
1013  if (len > (long)((send-s)/(sz))) { \
1014  if (!star) { \
1015  tmp_len = len-(send-s)/(sz); \
1016  } \
1017  len = (send-s)/(sz); \
1018  } \
1019 } while (0)
1020 
1021 #define PACK_ITEM_ADJUST() do { \
1022  if (tmp_len > 0 && mode == UNPACK_ARRAY) \
1023  rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \
1024 } while (0)
1025 
1026 /* Workaround for Oracle Solaris Studio 12.4 C compiler optimization bug
1027  * with "-xO4" optimization option.
1028  */
1029 #if defined(__SUNPRO_C) && __SUNPRO_C == 0x5130
1030 # define AVOID_CC_BUG volatile
1031 #else
1032 # define AVOID_CC_BUG
1033 #endif
1034 
1035 static VALUE
1036 infected_str_new(const char *ptr, long len, VALUE str)
1037 {
1038  VALUE s = rb_str_new(ptr, len);
1039 
1040  OBJ_INFECT(s, str);
1041  return s;
1042 }
1043 
1044 /* unpack mode */
1045 #define UNPACK_ARRAY 0
1046 #define UNPACK_BLOCK 1
1047 #define UNPACK_1 2
1048 
1049 static VALUE
1050 pack_unpack_internal(VALUE str, VALUE fmt, int mode)
1051 {
1052 #define hexdigits ruby_hexdigits
1053  char *s, *send;
1054  char *p, *pend;
1055  VALUE ary;
1056  char type;
1057  long len;
1058  AVOID_CC_BUG long tmp_len;
1059  int star;
1060 #ifdef NATINT_PACK
1061  int natint; /* native integer */
1062 #endif
1063  int signed_p, integer_size, bigendian_p;
1064 #define UNPACK_PUSH(item) do {\
1065  VALUE item_val = (item);\
1066  if ((mode) == UNPACK_BLOCK) {\
1067  rb_yield(item_val);\
1068  }\
1069  else if ((mode) == UNPACK_ARRAY) {\
1070  rb_ary_push(ary, item_val);\
1071  }\
1072  else /* if ((mode) == UNPACK_1) { */ {\
1073  return item_val; \
1074  }\
1075  } while (0)
1076 
1077  StringValue(str);
1078  StringValue(fmt);
1079  s = RSTRING_PTR(str);
1080  send = s + RSTRING_LEN(str);
1081  p = RSTRING_PTR(fmt);
1082  pend = p + RSTRING_LEN(fmt);
1083 
1084  ary = mode == UNPACK_ARRAY ? rb_ary_new() : Qnil;
1085  while (p < pend) {
1086  int explicit_endian = 0;
1087  type = *p++;
1088 #ifdef NATINT_PACK
1089  natint = 0;
1090 #endif
1091 
1092  if (ISSPACE(type)) continue;
1093  if (type == '#') {
1094  while ((p < pend) && (*p != '\n')) {
1095  p++;
1096  }
1097  continue;
1098  }
1099 
1100  star = 0;
1101  {
1102  modifiers:
1103  switch (*p) {
1104  case '_':
1105  case '!':
1106 
1107  if (strchr(natstr, type)) {
1108 #ifdef NATINT_PACK
1109  natint = 1;
1110 #endif
1111  p++;
1112  }
1113  else {
1114  rb_raise(rb_eArgError, "'%c' allowed only after types %s", *p, natstr);
1115  }
1116  goto modifiers;
1117 
1118  case '<':
1119  case '>':
1120  if (!strchr(endstr, type)) {
1121  rb_raise(rb_eArgError, "'%c' allowed only after types %s", *p, endstr);
1122  }
1123  if (explicit_endian) {
1124  rb_raise(rb_eRangeError, "Can't use both '<' and '>'");
1125  }
1126  explicit_endian = *p++;
1127  goto modifiers;
1128  }
1129  }
1130 
1131  if (p >= pend)
1132  len = 1;
1133  else if (*p == '*') {
1134  star = 1;
1135  len = send - s;
1136  p++;
1137  }
1138  else if (ISDIGIT(*p)) {
1139  errno = 0;
1140  len = STRTOUL(p, (char**)&p, 10);
1141  if (errno) {
1142  rb_raise(rb_eRangeError, "pack length too big");
1143  }
1144  }
1145  else {
1146  len = (type != '@');
1147  }
1148 
1149  switch (type) {
1150  case '%':
1151  rb_raise(rb_eArgError, "%% is not supported");
1152  break;
1153 
1154  case 'A':
1155  if (len > send - s) len = send - s;
1156  {
1157  long end = len;
1158  char *t = s + len - 1;
1159 
1160  while (t >= s) {
1161  if (*t != ' ' && *t != '\0') break;
1162  t--; len--;
1163  }
1164  UNPACK_PUSH(infected_str_new(s, len, str));
1165  s += end;
1166  }
1167  break;
1168 
1169  case 'Z':
1170  {
1171  char *t = s;
1172 
1173  if (len > send-s) len = send-s;
1174  while (t < s+len && *t) t++;
1175  UNPACK_PUSH(infected_str_new(s, t-s, str));
1176  if (t < send) t++;
1177  s = star ? t : s+len;
1178  }
1179  break;
1180 
1181  case 'a':
1182  if (len > send - s) len = send - s;
1183  UNPACK_PUSH(infected_str_new(s, len, str));
1184  s += len;
1185  break;
1186 
1187  case 'b':
1188  {
1189  VALUE bitstr;
1190  char *t;
1191  int bits;
1192  long i;
1193 
1194  if (p[-1] == '*' || len > (send - s) * 8)
1195  len = (send - s) * 8;
1196  bits = 0;
1197  bitstr = rb_usascii_str_new(0, len);
1198  t = RSTRING_PTR(bitstr);
1199  for (i=0; i<len; i++) {
1200  if (i & 7) bits >>= 1;
1201  else bits = (unsigned char)*s++;
1202  *t++ = (bits & 1) ? '1' : '0';
1203  }
1204  UNPACK_PUSH(bitstr);
1205  }
1206  break;
1207 
1208  case 'B':
1209  {
1210  VALUE bitstr;
1211  char *t;
1212  int bits;
1213  long i;
1214 
1215  if (p[-1] == '*' || len > (send - s) * 8)
1216  len = (send - s) * 8;
1217  bits = 0;
1218  bitstr = rb_usascii_str_new(0, len);
1219  t = RSTRING_PTR(bitstr);
1220  for (i=0; i<len; i++) {
1221  if (i & 7) bits <<= 1;
1222  else bits = (unsigned char)*s++;
1223  *t++ = (bits & 128) ? '1' : '0';
1224  }
1225  UNPACK_PUSH(bitstr);
1226  }
1227  break;
1228 
1229  case 'h':
1230  {
1231  VALUE bitstr;
1232  char *t;
1233  int bits;
1234  long i;
1235 
1236  if (p[-1] == '*' || len > (send - s) * 2)
1237  len = (send - s) * 2;
1238  bits = 0;
1239  bitstr = rb_usascii_str_new(0, len);
1240  t = RSTRING_PTR(bitstr);
1241  for (i=0; i<len; i++) {
1242  if (i & 1)
1243  bits >>= 4;
1244  else
1245  bits = (unsigned char)*s++;
1246  *t++ = hexdigits[bits & 15];
1247  }
1248  UNPACK_PUSH(bitstr);
1249  }
1250  break;
1251 
1252  case 'H':
1253  {
1254  VALUE bitstr;
1255  char *t;
1256  int bits;
1257  long i;
1258 
1259  if (p[-1] == '*' || len > (send - s) * 2)
1260  len = (send - s) * 2;
1261  bits = 0;
1262  bitstr = rb_usascii_str_new(0, len);
1263  t = RSTRING_PTR(bitstr);
1264  for (i=0; i<len; i++) {
1265  if (i & 1)
1266  bits <<= 4;
1267  else
1268  bits = (unsigned char)*s++;
1269  *t++ = hexdigits[(bits >> 4) & 15];
1270  }
1271  UNPACK_PUSH(bitstr);
1272  }
1273  break;
1274 
1275  case 'c':
1276  signed_p = 1;
1277  integer_size = 1;
1278  bigendian_p = BIGENDIAN_P(); /* not effective */
1279  goto unpack_integer;
1280 
1281  case 'C':
1282  signed_p = 0;
1283  integer_size = 1;
1284  bigendian_p = BIGENDIAN_P(); /* not effective */
1285  goto unpack_integer;
1286 
1287  case 's':
1288  signed_p = 1;
1289  integer_size = NATINT_LEN(short, 2);
1290  bigendian_p = BIGENDIAN_P();
1291  goto unpack_integer;
1292 
1293  case 'S':
1294  signed_p = 0;
1295  integer_size = NATINT_LEN(short, 2);
1296  bigendian_p = BIGENDIAN_P();
1297  goto unpack_integer;
1298 
1299  case 'i':
1300  signed_p = 1;
1301  integer_size = (int)sizeof(int);
1302  bigendian_p = BIGENDIAN_P();
1303  goto unpack_integer;
1304 
1305  case 'I':
1306  signed_p = 0;
1307  integer_size = (int)sizeof(int);
1308  bigendian_p = BIGENDIAN_P();
1309  goto unpack_integer;
1310 
1311  case 'l':
1312  signed_p = 1;
1313  integer_size = NATINT_LEN(long, 4);
1314  bigendian_p = BIGENDIAN_P();
1315  goto unpack_integer;
1316 
1317  case 'L':
1318  signed_p = 0;
1319  integer_size = NATINT_LEN(long, 4);
1320  bigendian_p = BIGENDIAN_P();
1321  goto unpack_integer;
1322 
1323  case 'q':
1324  signed_p = 1;
1325  integer_size = NATINT_LEN_Q;
1326  bigendian_p = BIGENDIAN_P();
1327  goto unpack_integer;
1328 
1329  case 'Q':
1330  signed_p = 0;
1331  integer_size = NATINT_LEN_Q;
1332  bigendian_p = BIGENDIAN_P();
1333  goto unpack_integer;
1334 
1335  case 'j':
1336  signed_p = 1;
1337  integer_size = sizeof(intptr_t);
1338  bigendian_p = BIGENDIAN_P();
1339  goto unpack_integer;
1340 
1341  case 'J':
1342  signed_p = 0;
1343  integer_size = sizeof(uintptr_t);
1344  bigendian_p = BIGENDIAN_P();
1345  goto unpack_integer;
1346 
1347  case 'n':
1348  signed_p = 0;
1349  integer_size = 2;
1350  bigendian_p = 1;
1351  goto unpack_integer;
1352 
1353  case 'N':
1354  signed_p = 0;
1355  integer_size = 4;
1356  bigendian_p = 1;
1357  goto unpack_integer;
1358 
1359  case 'v':
1360  signed_p = 0;
1361  integer_size = 2;
1362  bigendian_p = 0;
1363  goto unpack_integer;
1364 
1365  case 'V':
1366  signed_p = 0;
1367  integer_size = 4;
1368  bigendian_p = 0;
1369  goto unpack_integer;
1370 
1371  unpack_integer:
1372  if (explicit_endian) {
1373  bigendian_p = explicit_endian == '>';
1374  }
1375  PACK_LENGTH_ADJUST_SIZE(integer_size);
1376  while (len-- > 0) {
1377  int flags = bigendian_p ? INTEGER_PACK_BIG_ENDIAN : INTEGER_PACK_LITTLE_ENDIAN;
1378  VALUE val;
1379  if (signed_p)
1380  flags |= INTEGER_PACK_2COMP;
1381  val = rb_integer_unpack(s, integer_size, 1, 0, flags);
1382  UNPACK_PUSH(val);
1383  s += integer_size;
1384  }
1385  PACK_ITEM_ADJUST();
1386  break;
1387 
1388  case 'f':
1389  case 'F':
1390  PACK_LENGTH_ADJUST_SIZE(sizeof(float));
1391  while (len-- > 0) {
1392  float tmp;
1393  memcpy(&tmp, s, sizeof(float));
1394  s += sizeof(float);
1395  UNPACK_PUSH(DBL2NUM((double)tmp));
1396  }
1397  PACK_ITEM_ADJUST();
1398  break;
1399 
1400  case 'e':
1401  PACK_LENGTH_ADJUST_SIZE(sizeof(float));
1402  while (len-- > 0) {
1403  FLOAT_CONVWITH(tmp);
1404  memcpy(tmp.buf, s, sizeof(float));
1405  s += sizeof(float);
1406  VTOHF(tmp);
1407  UNPACK_PUSH(DBL2NUM(tmp.f));
1408  }
1409  PACK_ITEM_ADJUST();
1410  break;
1411 
1412  case 'E':
1413  PACK_LENGTH_ADJUST_SIZE(sizeof(double));
1414  while (len-- > 0) {
1415  DOUBLE_CONVWITH(tmp);
1416  memcpy(tmp.buf, s, sizeof(double));
1417  s += sizeof(double);
1418  VTOHD(tmp);
1419  UNPACK_PUSH(DBL2NUM(tmp.d));
1420  }
1421  PACK_ITEM_ADJUST();
1422  break;
1423 
1424  case 'D':
1425  case 'd':
1426  PACK_LENGTH_ADJUST_SIZE(sizeof(double));
1427  while (len-- > 0) {
1428  double tmp;
1429  memcpy(&tmp, s, sizeof(double));
1430  s += sizeof(double);
1431  UNPACK_PUSH(DBL2NUM(tmp));
1432  }
1433  PACK_ITEM_ADJUST();
1434  break;
1435 
1436  case 'g':
1437  PACK_LENGTH_ADJUST_SIZE(sizeof(float));
1438  while (len-- > 0) {
1439  FLOAT_CONVWITH(tmp);
1440  memcpy(tmp.buf, s, sizeof(float));
1441  s += sizeof(float);
1442  NTOHF(tmp);
1443  UNPACK_PUSH(DBL2NUM(tmp.f));
1444  }
1445  PACK_ITEM_ADJUST();
1446  break;
1447 
1448  case 'G':
1449  PACK_LENGTH_ADJUST_SIZE(sizeof(double));
1450  while (len-- > 0) {
1451  DOUBLE_CONVWITH(tmp);
1452  memcpy(tmp.buf, s, sizeof(double));
1453  s += sizeof(double);
1454  NTOHD(tmp);
1455  UNPACK_PUSH(DBL2NUM(tmp.d));
1456  }
1457  PACK_ITEM_ADJUST();
1458  break;
1459 
1460  case 'U':
1461  if (len > send - s) len = send - s;
1462  while (len > 0 && s < send) {
1463  long alen = send - s;
1464  unsigned long l;
1465 
1466  l = utf8_to_uv(s, &alen);
1467  s += alen; len--;
1468  UNPACK_PUSH(ULONG2NUM(l));
1469  }
1470  break;
1471 
1472  case 'u':
1473  {
1474  VALUE buf = infected_str_new(0, (send - s)*3/4, str);
1475  char *ptr = RSTRING_PTR(buf);
1476  long total = 0;
1477 
1478  while (s < send && (unsigned char)*s > ' ' && (unsigned char)*s < 'a') {
1479  long a,b,c,d;
1480  char hunk[3];
1481 
1482  len = ((unsigned char)*s++ - ' ') & 077;
1483 
1484  total += len;
1485  if (total > RSTRING_LEN(buf)) {
1486  len -= total - RSTRING_LEN(buf);
1487  total = RSTRING_LEN(buf);
1488  }
1489 
1490  while (len > 0) {
1491  long mlen = len > 3 ? 3 : len;
1492 
1493  if (s < send && (unsigned char)*s >= ' ' && (unsigned char)*s < 'a')
1494  a = ((unsigned char)*s++ - ' ') & 077;
1495  else
1496  a = 0;
1497  if (s < send && (unsigned char)*s >= ' ' && (unsigned char)*s < 'a')
1498  b = ((unsigned char)*s++ - ' ') & 077;
1499  else
1500  b = 0;
1501  if (s < send && (unsigned char)*s >= ' ' && (unsigned char)*s < 'a')
1502  c = ((unsigned char)*s++ - ' ') & 077;
1503  else
1504  c = 0;
1505  if (s < send && (unsigned char)*s >= ' ' && (unsigned char)*s < 'a')
1506  d = ((unsigned char)*s++ - ' ') & 077;
1507  else
1508  d = 0;
1509  hunk[0] = (char)(a << 2 | b >> 4);
1510  hunk[1] = (char)(b << 4 | c >> 2);
1511  hunk[2] = (char)(c << 6 | d);
1512  memcpy(ptr, hunk, mlen);
1513  ptr += mlen;
1514  len -= mlen;
1515  }
1516  if (s < send && (unsigned char)*s != '\r' && *s != '\n')
1517  s++; /* possible checksum byte */
1518  if (s < send && *s == '\r') s++;
1519  if (s < send && *s == '\n') s++;
1520  }
1521 
1522  rb_str_set_len(buf, total);
1523  UNPACK_PUSH(buf);
1524  }
1525  break;
1526 
1527  case 'm':
1528  {
1529  VALUE buf = infected_str_new(0, (send - s + 3)*3/4, str); /* +3 is for skipping paddings */
1530  char *ptr = RSTRING_PTR(buf);
1531  int a = -1,b = -1,c = 0,d = 0;
1532  static signed char b64_xtable[256];
1533 
1534  if (b64_xtable['/'] <= 0) {
1535  int i;
1536 
1537  for (i = 0; i < 256; i++) {
1538  b64_xtable[i] = -1;
1539  }
1540  for (i = 0; i < 64; i++) {
1541  b64_xtable[(unsigned char)b64_table[i]] = (char)i;
1542  }
1543  }
1544  if (len == 0) {
1545  while (s < send) {
1546  a = b = c = d = -1;
1547  a = b64_xtable[(unsigned char)*s++];
1548  if (s >= send || a == -1) rb_raise(rb_eArgError, "invalid base64");
1549  b = b64_xtable[(unsigned char)*s++];
1550  if (s >= send || b == -1) rb_raise(rb_eArgError, "invalid base64");
1551  if (*s == '=') {
1552  if (s + 2 == send && *(s + 1) == '=') break;
1553  rb_raise(rb_eArgError, "invalid base64");
1554  }
1555  c = b64_xtable[(unsigned char)*s++];
1556  if (s >= send || c == -1) rb_raise(rb_eArgError, "invalid base64");
1557  if (s + 1 == send && *s == '=') break;
1558  d = b64_xtable[(unsigned char)*s++];
1559  if (d == -1) rb_raise(rb_eArgError, "invalid base64");
1560  *ptr++ = castchar(a << 2 | b >> 4);
1561  *ptr++ = castchar(b << 4 | c >> 2);
1562  *ptr++ = castchar(c << 6 | d);
1563  }
1564  if (c == -1) {
1565  *ptr++ = castchar(a << 2 | b >> 4);
1566  if (b & 0xf) rb_raise(rb_eArgError, "invalid base64");
1567  }
1568  else if (d == -1) {
1569  *ptr++ = castchar(a << 2 | b >> 4);
1570  *ptr++ = castchar(b << 4 | c >> 2);
1571  if (c & 0x3) rb_raise(rb_eArgError, "invalid base64");
1572  }
1573  }
1574  else {
1575  while (s < send) {
1576  a = b = c = d = -1;
1577  while ((a = b64_xtable[(unsigned char)*s]) == -1 && s < send) {s++;}
1578  if (s >= send) break;
1579  s++;
1580  while ((b = b64_xtable[(unsigned char)*s]) == -1 && s < send) {s++;}
1581  if (s >= send) break;
1582  s++;
1583  while ((c = b64_xtable[(unsigned char)*s]) == -1 && s < send) {if (*s == '=') break; s++;}
1584  if (*s == '=' || s >= send) break;
1585  s++;
1586  while ((d = b64_xtable[(unsigned char)*s]) == -1 && s < send) {if (*s == '=') break; s++;}
1587  if (*s == '=' || s >= send) break;
1588  s++;
1589  *ptr++ = castchar(a << 2 | b >> 4);
1590  *ptr++ = castchar(b << 4 | c >> 2);
1591  *ptr++ = castchar(c << 6 | d);
1592  a = -1;
1593  }
1594  if (a != -1 && b != -1) {
1595  if (c == -1)
1596  *ptr++ = castchar(a << 2 | b >> 4);
1597  else {
1598  *ptr++ = castchar(a << 2 | b >> 4);
1599  *ptr++ = castchar(b << 4 | c >> 2);
1600  }
1601  }
1602  }
1603  rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
1604  UNPACK_PUSH(buf);
1605  }
1606  break;
1607 
1608  case 'M':
1609  {
1610  VALUE buf = infected_str_new(0, send - s, str);
1611  char *ptr = RSTRING_PTR(buf), *ss = s;
1612  int c1, c2;
1613 
1614  while (s < send) {
1615  if (*s == '=') {
1616  if (++s == send) break;
1617  if (s+1 < send && *s == '\r' && *(s+1) == '\n')
1618  s++;
1619  if (*s != '\n') {
1620  if ((c1 = hex2num(*s)) == -1) break;
1621  if (++s == send) break;
1622  if ((c2 = hex2num(*s)) == -1) break;
1623  *ptr++ = castchar(c1 << 4 | c2);
1624  }
1625  }
1626  else {
1627  *ptr++ = *s;
1628  }
1629  s++;
1630  ss = s;
1631  }
1632  rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
1633  rb_str_buf_cat(buf, ss, send-ss);
1635  UNPACK_PUSH(buf);
1636  }
1637  break;
1638 
1639  case '@':
1640  if (len > RSTRING_LEN(str))
1641  rb_raise(rb_eArgError, "@ outside of string");
1642  s = RSTRING_PTR(str) + len;
1643  break;
1644 
1645  case 'X':
1646  if (len > s - RSTRING_PTR(str))
1647  rb_raise(rb_eArgError, "X outside of string");
1648  s -= len;
1649  break;
1650 
1651  case 'x':
1652  if (len > send - s)
1653  rb_raise(rb_eArgError, "x outside of string");
1654  s += len;
1655  break;
1656 
1657  case 'P':
1658  if (sizeof(char *) <= (size_t)(send - s)) {
1659  VALUE tmp = Qnil;
1660  char *t;
1661 
1662  memcpy(&t, s, sizeof(char *));
1663  s += sizeof(char *);
1664 
1665  if (t) {
1666  VALUE a;
1667  const VALUE *p, *pend;
1668 
1669  if (!(a = str_associated(str))) {
1670  rb_raise(rb_eArgError, "no associated pointer");
1671  }
1672  p = RARRAY_CONST_PTR(a);
1673  pend = p + RARRAY_LEN(a);
1674  while (p < pend) {
1675  if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
1676  if (len < RSTRING_LEN(*p)) {
1677  tmp = rb_tainted_str_new(t, len);
1678  str_associate(tmp, a);
1679  }
1680  else {
1681  tmp = *p;
1682  }
1683  break;
1684  }
1685  p++;
1686  }
1687  if (p == pend) {
1688  rb_raise(rb_eArgError, "non associated pointer");
1689  }
1690  }
1691  UNPACK_PUSH(tmp);
1692  }
1693  break;
1694 
1695  case 'p':
1696  if (len > (long)((send - s) / sizeof(char *)))
1697  len = (send - s) / sizeof(char *);
1698  while (len-- > 0) {
1699  if ((size_t)(send - s) < sizeof(char *))
1700  break;
1701  else {
1702  VALUE tmp = Qnil;
1703  char *t;
1704 
1705  memcpy(&t, s, sizeof(char *));
1706  s += sizeof(char *);
1707 
1708  if (t) {
1709  VALUE a;
1710  const VALUE *p, *pend;
1711 
1712  if (!(a = str_associated(str))) {
1713  rb_raise(rb_eArgError, "no associated pointer");
1714  }
1715  p = RARRAY_CONST_PTR(a);
1716  pend = p + RARRAY_LEN(a);
1717  while (p < pend) {
1718  if (RB_TYPE_P(*p, T_STRING) && RSTRING_PTR(*p) == t) {
1719  tmp = *p;
1720  break;
1721  }
1722  p++;
1723  }
1724  if (p == pend) {
1725  rb_raise(rb_eArgError, "non associated pointer");
1726  }
1727  }
1728  UNPACK_PUSH(tmp);
1729  }
1730  }
1731  break;
1732 
1733  case 'w':
1734  {
1735  char *s0 = s;
1736  while (len > 0 && s < send) {
1737  if (*s & 0x80) {
1738  s++;
1739  }
1740  else {
1741  s++;
1743  len--;
1744  s0 = s;
1745  }
1746  }
1747  }
1748  break;
1749 
1750  default:
1751  rb_warning("unknown unpack directive '%c' in '%s'",
1752  type, RSTRING_PTR(fmt));
1753  break;
1754  }
1755  }
1756 
1757  return ary;
1758 }
1759 
1760 /*
1761  * call-seq:
1762  * str.unpack(format) -> anArray
1763  *
1764  * Decodes <i>str</i> (which may contain binary data) according to the
1765  * format string, returning an array of each value extracted. The
1766  * format string consists of a sequence of single-character directives,
1767  * summarized in the table at the end of this entry.
1768  * Each directive may be followed
1769  * by a number, indicating the number of times to repeat with this
1770  * directive. An asterisk (``<code>*</code>'') will use up all
1771  * remaining elements. The directives <code>sSiIlL</code> may each be
1772  * followed by an underscore (``<code>_</code>'') or
1773  * exclamation mark (``<code>!</code>'') to use the underlying
1774  * platform's native size for the specified type; otherwise, it uses a
1775  * platform-independent consistent size. Spaces are ignored in the
1776  * format string. See also <code>String#unpack1</code>, <code>Array#pack</code>.
1777  *
1778  * "abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
1779  * "abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
1780  * "abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
1781  * "aa".unpack('b8B8') #=> ["10000110", "01100001"]
1782  * "aaa".unpack('h2H2c') #=> ["16", "61", 97]
1783  * "\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
1784  * "now=20is".unpack('M*') #=> ["now is"]
1785  * "whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]
1786  *
1787  * This table summarizes the various formats and the Ruby classes
1788  * returned by each.
1789  *
1790  * Integer | |
1791  * Directive | Returns | Meaning
1792  * ------------------------------------------------------------------
1793  * C | Integer | 8-bit unsigned (unsigned char)
1794  * S | Integer | 16-bit unsigned, native endian (uint16_t)
1795  * L | Integer | 32-bit unsigned, native endian (uint32_t)
1796  * Q | Integer | 64-bit unsigned, native endian (uint64_t)
1797  * J | Integer | pointer width unsigned, native endian (uintptr_t)
1798  * | |
1799  * c | Integer | 8-bit signed (signed char)
1800  * s | Integer | 16-bit signed, native endian (int16_t)
1801  * l | Integer | 32-bit signed, native endian (int32_t)
1802  * q | Integer | 64-bit signed, native endian (int64_t)
1803  * j | Integer | pointer width signed, native endian (intptr_t)
1804  * | |
1805  * S_ S! | Integer | unsigned short, native endian
1806  * I I_ I! | Integer | unsigned int, native endian
1807  * L_ L! | Integer | unsigned long, native endian
1808  * Q_ Q! | Integer | unsigned long long, native endian (ArgumentError
1809  * | | if the platform has no long long type.)
1810  * J! | Integer | uintptr_t, native endian (same with J)
1811  * | |
1812  * s_ s! | Integer | signed short, native endian
1813  * i i_ i! | Integer | signed int, native endian
1814  * l_ l! | Integer | signed long, native endian
1815  * q_ q! | Integer | signed long long, native endian (ArgumentError
1816  * | | if the platform has no long long type.)
1817  * j! | Integer | intptr_t, native endian (same with j)
1818  * | |
1819  * S> s> S!> s!> | Integer | same as the directives without ">" except
1820  * L> l> L!> l!> | | big endian
1821  * I!> i!> | |
1822  * Q> q> Q!> q!> | | "S>" is same as "n"
1823  * J> j> J!> j!> | | "L>" is same as "N"
1824  * | |
1825  * S< s< S!< s!< | Integer | same as the directives without "<" except
1826  * L< l< L!< l!< | | little endian
1827  * I!< i!< | |
1828  * Q< q< Q!< q!< | | "S<" is same as "v"
1829  * J< j< J!< j!< | | "L<" is same as "V"
1830  * | |
1831  * n | Integer | 16-bit unsigned, network (big-endian) byte order
1832  * N | Integer | 32-bit unsigned, network (big-endian) byte order
1833  * v | Integer | 16-bit unsigned, VAX (little-endian) byte order
1834  * V | Integer | 32-bit unsigned, VAX (little-endian) byte order
1835  * | |
1836  * U | Integer | UTF-8 character
1837  * w | Integer | BER-compressed integer (see Array.pack)
1838  *
1839  * Float | |
1840  * Directive | Returns | Meaning
1841  * -----------------------------------------------------------------
1842  * D d | Float | double-precision, native format
1843  * F f | Float | single-precision, native format
1844  * E | Float | double-precision, little-endian byte order
1845  * e | Float | single-precision, little-endian byte order
1846  * G | Float | double-precision, network (big-endian) byte order
1847  * g | Float | single-precision, network (big-endian) byte order
1848  *
1849  * String | |
1850  * Directive | Returns | Meaning
1851  * -----------------------------------------------------------------
1852  * A | String | arbitrary binary string (remove trailing nulls and ASCII spaces)
1853  * a | String | arbitrary binary string
1854  * Z | String | null-terminated string
1855  * B | String | bit string (MSB first)
1856  * b | String | bit string (LSB first)
1857  * H | String | hex string (high nibble first)
1858  * h | String | hex string (low nibble first)
1859  * u | String | UU-encoded string
1860  * M | String | quoted-printable, MIME encoding (see RFC2045)
1861  * m | String | base64 encoded string (RFC 2045) (default)
1862  * | | base64 encoded string (RFC 4648) if followed by 0
1863  * P | String | pointer to a structure (fixed-length string)
1864  * p | String | pointer to a null-terminated string
1865  *
1866  * Misc. | |
1867  * Directive | Returns | Meaning
1868  * -----------------------------------------------------------------
1869  * @ | --- | skip to the offset given by the length argument
1870  * X | --- | skip backward one byte
1871  * x | --- | skip forward one byte
1872  *
1873  * HISTORY
1874  *
1875  * * J, J! j, and j! are available since Ruby 2.3.
1876  * * Q_, Q!, q_, and q! are available since Ruby 2.1.
1877  * * I!<, i!<, I!>, and i!> are available since Ruby 1.9.3.
1878  */
1879 
1880 static VALUE
1882 {
1883  int mode = rb_block_given_p() ? UNPACK_BLOCK : UNPACK_ARRAY;
1884  return pack_unpack_internal(str, fmt, mode);
1885 }
1886 
1887 /*
1888  * call-seq:
1889  * str.unpack1(format) -> obj
1890  *
1891  * Decodes <i>str</i> (which may contain binary data) according to the
1892  * format string, returning the first value extracted.
1893  * See also <code>String#unpack</code>, <code>Array#pack</code>.
1894  */
1895 
1896 static VALUE
1898 {
1899  return pack_unpack_internal(str, fmt, UNPACK_1);
1900 }
1901 
1902 int
1903 rb_uv_to_utf8(char buf[6], unsigned long uv)
1904 {
1905  if (uv <= 0x7f) {
1906  buf[0] = (char)uv;
1907  return 1;
1908  }
1909  if (uv <= 0x7ff) {
1910  buf[0] = castchar(((uv>>6)&0xff)|0xc0);
1911  buf[1] = castchar((uv&0x3f)|0x80);
1912  return 2;
1913  }
1914  if (uv <= 0xffff) {
1915  buf[0] = castchar(((uv>>12)&0xff)|0xe0);
1916  buf[1] = castchar(((uv>>6)&0x3f)|0x80);
1917  buf[2] = castchar((uv&0x3f)|0x80);
1918  return 3;
1919  }
1920  if (uv <= 0x1fffff) {
1921  buf[0] = castchar(((uv>>18)&0xff)|0xf0);
1922  buf[1] = castchar(((uv>>12)&0x3f)|0x80);
1923  buf[2] = castchar(((uv>>6)&0x3f)|0x80);
1924  buf[3] = castchar((uv&0x3f)|0x80);
1925  return 4;
1926  }
1927  if (uv <= 0x3ffffff) {
1928  buf[0] = castchar(((uv>>24)&0xff)|0xf8);
1929  buf[1] = castchar(((uv>>18)&0x3f)|0x80);
1930  buf[2] = castchar(((uv>>12)&0x3f)|0x80);
1931  buf[3] = castchar(((uv>>6)&0x3f)|0x80);
1932  buf[4] = castchar((uv&0x3f)|0x80);
1933  return 5;
1934  }
1935  if (uv <= 0x7fffffff) {
1936  buf[0] = castchar(((uv>>30)&0xff)|0xfc);
1937  buf[1] = castchar(((uv>>24)&0x3f)|0x80);
1938  buf[2] = castchar(((uv>>18)&0x3f)|0x80);
1939  buf[3] = castchar(((uv>>12)&0x3f)|0x80);
1940  buf[4] = castchar(((uv>>6)&0x3f)|0x80);
1941  buf[5] = castchar((uv&0x3f)|0x80);
1942  return 6;
1943  }
1944  rb_raise(rb_eRangeError, "pack(U): value out of range");
1945 
1946  UNREACHABLE;
1947 }
1948 
1949 static const unsigned long utf8_limits[] = {
1950  0x0, /* 1 */
1951  0x80, /* 2 */
1952  0x800, /* 3 */
1953  0x10000, /* 4 */
1954  0x200000, /* 5 */
1955  0x4000000, /* 6 */
1956  0x80000000, /* 7 */
1957 };
1958 
1959 static unsigned long
1960 utf8_to_uv(const char *p, long *lenp)
1961 {
1962  int c = *p++ & 0xff;
1963  unsigned long uv = c;
1964  long n;
1965 
1966  if (!(uv & 0x80)) {
1967  *lenp = 1;
1968  return uv;
1969  }
1970  if (!(uv & 0x40)) {
1971  *lenp = 1;
1972  rb_raise(rb_eArgError, "malformed UTF-8 character");
1973  }
1974 
1975  if (!(uv & 0x20)) { n = 2; uv &= 0x1f; }
1976  else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }
1977  else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }
1978  else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }
1979  else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
1980  else {
1981  *lenp = 1;
1982  rb_raise(rb_eArgError, "malformed UTF-8 character");
1983  }
1984  if (n > *lenp) {
1985  rb_raise(rb_eArgError, "malformed UTF-8 character (expected %ld bytes, given %ld bytes)",
1986  n, *lenp);
1987  }
1988  *lenp = n--;
1989  if (n != 0) {
1990  while (n--) {
1991  c = *p++ & 0xff;
1992  if ((c & 0xc0) != 0x80) {
1993  *lenp -= n + 1;
1994  rb_raise(rb_eArgError, "malformed UTF-8 character");
1995  }
1996  else {
1997  c &= 0x3f;
1998  uv = uv << 6 | c;
1999  }
2000  }
2001  }
2002  n = *lenp - 1;
2003  if (uv < utf8_limits[n]) {
2004  rb_raise(rb_eArgError, "redundant UTF-8 sequence");
2005  }
2006  return uv;
2007 }
2008 
2009 void
2011 {
2012  rb_define_method(rb_cArray, "pack", pack_pack, -1);
2013  rb_define_method(rb_cString, "unpack", pack_unpack, 1);
2014  rb_define_method(rb_cString, "unpack1", pack_unpack1, 1);
2015 
2017 }
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:1906
void rb_str_associate(VALUE str, VALUE add)
Definition: pack.c:130
#define ISDIGIT(c)
Definition: ruby.h:2129
uint64_t u
Definition: pack.c:78
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3531
#define MAX_INTEGER_PACK_SIZE
Definition: pack.c:105
#define RARRAY_LEN(a)
Definition: ruby.h:1026
void rb_bug(const char *fmt,...)
Definition: error.c:482
#define BIGENDIAN_P()
Definition: pack.c:62
#define ENCODING_CODERANGE_SET(obj, encindex, cr)
Definition: encoding.h:109
static VALUE pack_unpack_internal(VALUE str, VALUE fmt, int mode)
Definition: pack.c:1050
#define FLOAT_CONVWITH(x)
Definition: pack.c:93
#define NATINT_LEN(type, len)
Definition: pack.c:66
#define THISFROM
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:1858
#define PACK_ITEM_ADJUST()
Definition: pack.c:1021
VALUE rb_eTypeError
Definition: error.c:762
#define UNREACHABLE
Definition: ruby.h:46
#define castchar(from)
#define ULONG2NUM(x)
Definition: ruby.h:1574
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:905
int rb_usascii_encindex(void)
Definition: encoding.c:1344
void rb_str_set_len(VALUE, long)
Definition: string.c:2545
static void str_associate(VALUE str, VALUE add)
Definition: pack.c:117
VALUE rb_to_int(VALUE)
Definition: object.c:2687
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
static const char uu_table[]
Definition: pack.c:892
static const char toofew[]
Definition: pack.c:107
#define NTOHD(x)
Definition: pack.c:102
#define NEXTFROM
VALUE rb_str_associated(VALUE str)
Definition: pack.c:136
#define NTOHF(x)
Definition: pack.c:96
#define INTEGER_PACK_2COMP
Definition: intern.h:143
static const char natstr[]
Definition: pack.c:28
#define ENC_CODERANGE_7BIT
Definition: encoding.h:100
VALUE rb_eRangeError
Definition: error.c:766
const char * rb_obj_classname(VALUE)
Definition: variable.c:458
VALUE rb_str_buf_cat(VALUE, const char *, long)
static ID id_associated
Definition: pack.c:114
#define ISALPHA(c)
Definition: ruby.h:2128
static VALUE pack_unpack(VALUE str, VALUE fmt)
Definition: pack.c:1881
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
#define le(x, y)
Definition: time.c:72
unsigned long long uint64_t
Definition: sha2.h:102
static void encodes(VALUE, const char *, long, int, int)
Definition: pack.c:898
int rb_block_given_p(void)
Definition: eval.c:797
VALUE rb_obj_taint(VALUE)
Definition: object.c:1008
#define HTOND(x)
Definition: pack.c:100
#define val
#define HTOVF(x)
Definition: pack.c:95
VALUE rb_eRuntimeError
Definition: error.c:761
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1364
static VALUE infected_str_new(const char *ptr, long len, VALUE str)
Definition: pack.c:1036
VALUE rb_ary_new(void)
Definition: array.c:493
int rb_ascii8bit_encindex(void)
Definition: encoding.c:1314
#define STRTOUL(str, endptr, base)
Definition: ruby.h:2141
#define snprintf
Definition: subst.h:6
#define NIL_P(v)
Definition: ruby.h:451
#define add(x, y)
Definition: date_strftime.c:23
static void qpencode(VALUE, VALUE, long)
Definition: pack.c:949
void rb_enc_set_index(VALUE obj, int idx)
Definition: encoding.c:818
static VALUE str_associated(VALUE str)
Definition: pack.c:124
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
#define HTOVD(x)
Definition: pack.c:101
#define ENC_CODERANGE_VALID
Definition: encoding.h:101
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3617
double d
Definition: pack.c:77
static const char hex_table[]
Definition: pack.c:946
#define EOF
Definition: vsnprintf.c:201
#define RSTRING_LEN(str)
Definition: ruby.h:978
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1028
int errno
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1364
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4309
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
unsigned int uintptr_t
Definition: win32.h:106
#define UNPACK_ARRAY
Definition: pack.c:1045
static int hex2num(char c)
Definition: pack.c:1002
unsigned long VALUE
Definition: ruby.h:85
char * strchr(char *, char)
int intptr_t
Definition: win32.h:90
int rb_utf8_encindex(void)
Definition: encoding.c:1329
#define INTEGER_PACK_LITTLE_ENDIAN
Definition: intern.h:149
#define INTEGER_PACK_BIG_ENDIAN
Definition: intern.h:152
#define VTOHF(x)
Definition: pack.c:97
static VALUE pack_pack(int argc, VALUE *argv, VALUE ary)
Definition: pack.c:271
unsigned int uint32_t
Definition: sha2.h:101
register unsigned int len
Definition: zonetab.h:51
#define UNPACK_1
Definition: pack.c:1047
#define DOUBLE_CONVWITH(x)
Definition: pack.c:99
#define RSTRING_PTR(str)
Definition: ruby.h:982
static unsigned long utf8_to_uv(const char *, long *)
Definition: pack.c:1960
static const unsigned long utf8_limits[]
Definition: pack.c:1949
#define RFLOAT_VALUE(v)
Definition: ruby.h:940
#define f
uint32_t u
Definition: pack.c:73
static const char endstr[]
Definition: pack.c:30
#define UNPACK_BLOCK
Definition: pack.c:1046
#define T_STRING
Definition: ruby.h:496
#define OBJ_INFECT(x, s)
Definition: ruby.h:1304
#define ONLY_FOR_INTERNAL_USE(func)
Definition: internal.h:1027
#define ISPRINT(c)
Definition: ruby.h:2122
#define NATINT_LEN_Q
Definition: pack.c:36
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
Definition: bignum.c:3366
VALUE rb_cArray
Definition: array.c:25
int rb_uv_to_utf8(char buf[6], unsigned long uv)
Definition: pack.c:1903
float f
Definition: pack.c:72
#define hexdigits
#define PACK_LENGTH_ADJUST_SIZE(sz)
Definition: pack.c:1011
#define StringValuePtr(v)
Definition: ruby.h:570
#define VTOHD(x)
Definition: pack.c:103
static const char b64_table[]
Definition: pack.c:894
void Init_pack(void)
Definition: pack.c:2010
void rb_warning(const char *fmt,...)
Definition: error.c:250
RUBY_EXTERN const signed char ruby_digit36_to_number_table[]
Definition: escape.c:6
#define CONST_ID(var, str)
Definition: ruby.h:1743
#define memcpy(d, s, n)
Definition: ffi_common.h:55
VALUE rb_tainted_str_new(const char *, long)
Definition: string.c:853
VALUE rb_str_buf_new(long)
Definition: string.c:1247
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:742
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
static VALUE pack_unpack1(VALUE str, VALUE fmt)
Definition: pack.c:1897
#define UNPACK_PUSH(item)
VALUE rb_eArgError
Definition: error.c:763
#define AVOID_CC_BUG
Definition: pack.c:1032
#define NUM2LONG(x)
Definition: ruby.h:648
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
Definition: variable.c:1225
ID rb_make_internal_id(void)
Definition: symbol.c:768
#define HTONF(x)
Definition: pack.c:94
char ** argv
Definition: ruby.c:184
#define DBL2NUM(dbl)
Definition: ruby.h:941
#define ISSPACE(c)
Definition: ruby.h:2124
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_to_float(VALUE)
Definition: object.c:3006
VALUE rb_str_new(const char *, long)
Definition: string.c:736
#define SIGNED_VALUE
Definition: ruby.h:87