Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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