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