Ruby
2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
|
Go to the documentation of this file.
14 #include <sys/types.h>
28 #ifdef HAVE_TRUE_LONG_LONG
29 static const char natstr[] =
"sSiIlLqQjJ";
31 static const char natstr[] =
"sSiIlLjJ";
33 static const char endstr[] =
"sSiIlLqQjJ";
35 #ifdef HAVE_TRUE_LONG_LONG
37 # define NATINT_LEN_Q NATINT_LEN(long long, 8)
39 # define NATINT_LEN_Q 8
42 #if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
53 static int endian_value;
56 if (init)
return endian_value;
59 return endian_value = p[0]?0:1;
61 # define BIGENDIAN_P() (is_bigendian())
62 #elif defined(WORDS_BIGENDIAN)
63 # define BIGENDIAN_P() 1
65 # define BIGENDIAN_P() 0
69 # define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len))
71 # define NATINT_LEN(type,len) ((int)sizeof(type))
84 #define swapf(x) swap32(x)
85 #define swapd(x) swap64(x)
87 #define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
88 #define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
89 #define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x))
90 #define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x))
91 #define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x))
92 #define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x))
93 #define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
94 #define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))
96 #define FLOAT_CONVWITH(x) FLOAT_SWAPPER x;
97 #define HTONF(x) ((x).u = rb_htonf((x).u))
98 #define HTOVF(x) ((x).u = rb_htovf((x).u))
99 #define NTOHF(x) ((x).u = rb_ntohf((x).u))
100 #define VTOHF(x) ((x).u = rb_vtohf((x).u))
102 #define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x;
103 #define HTOND(x) ((x).u = rb_htond((x).u))
104 #define HTOVD(x) ((x).u = rb_htovd((x).u))
105 #define NTOHD(x) ((x).u = rb_ntohd((x).u))
106 #define VTOHD(x) ((x).u = rb_vtohd((x).u))
108 #define MAX_INTEGER_PACK_SIZE 8
110 static const char toofew[] =
"too few arguments";
112 static void encodes(
VALUE,
const char*,
long,
int,
int);
115 static unsigned long utf8_to_uv(
const char*,
long*);
117 static ID id_associated;
133 unknown_directive(
const char *mode,
char type,
VALUE fmt)
143 snprintf(unknown,
sizeof(unknown),
"\\x%.2x",
type & 0xff);
162 else if (d < -FLT_MAX) {
165 else if (d <= FLT_MAX) {
176 static const char nul10[] =
"\0\0\0\0\0\0\0\0\0\0";
177 static const char spc10[] =
" ";
178 const char *p, *pend;
179 VALUE res, from, associates = 0;
187 int integer_size, bigendian_p;
204 #define TOO_FEW (rb_raise(rb_eArgError, toofew), 0)
205 #define MORE_ITEM (idx < RARRAY_LEN(ary))
206 #define THISFROM (MORE_ITEM ? RARRAY_AREF(ary, idx) : TOO_FEW)
207 #define NEXTFROM (MORE_ITEM ? RARRAY_AREF(ary, idx++) : TOO_FEW)
210 int explicit_endian = 0;
221 while ((p < pend) && (*p !=
'\n')) {
248 if (explicit_endian) {
251 explicit_endian = *p++;
276 if (enc_info == 1) enc_info = 2;
278 case 'm':
case 'M':
case 'u':
287 case 'A':
case 'a':
case 'Z':
310 if (p[-1] ==
'*' &&
type ==
'Z')
324 #define castchar(from) (char)((from) & 0xff)
332 j = (
len - plen + 1)/2;
348 byte >>= 7 - (
len & 7);
363 j = (
len - plen + 1)/2;
378 byte <<= 7 - (
len & 7);
393 j = (
len + 1) / 2 - (plen + 1) / 2;
398 byte |= (((*
ptr & 15) + 9) & 15) << 4;
400 byte |= (*
ptr & 15) << 4;
424 j = (
len + 1) / 2 - (plen + 1) / 2;
429 byte |= ((*
ptr & 15) + 9) & 15;
468 integer_size = (
int)
sizeof(
int);
473 integer_size = (
int)
sizeof(
int);
528 if (explicit_endian) {
529 bigendian_p = explicit_endian ==
'>';
532 rb_bug(
"unexpected intger size for pack: %d", integer_size);
550 f = VALUE_to_float(from);
560 tmp.f = VALUE_to_float(from);
591 tmp.f = VALUE_to_float(from);
627 if (
len > 0)
goto grow;
629 if (
len > 0)
goto shrink;
661 encodes(res,
ptr, plen,
type, 0);
667 else if (
len > 63 &&
type ==
'u')
678 encodes(res,
ptr, todo,
type, 1);
688 qpencode(res, from,
len);
739 rb_bug(
"buffer size problem?");
742 while (1 < numbytes) {
753 unknown_directive(
"pack",
type,
fmt);
760 str_associate(res, associates);
776 static const char uu_table[] =
777 "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
778 static const char b64_table[] =
779 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
784 enum {buff_size = 4096, encoded_unit = 4, input_unit = 3};
785 char buff[buff_size + 1];
787 const char *
const trans =
type ==
'u' ? uu_table : b64_table;
789 const unsigned char *s = (
const unsigned char *)s0;
798 while (
len >= input_unit) {
799 while (
len >= input_unit && buff_size-
i >= encoded_unit) {
800 buff[
i++] = trans[077 & (*s >> 2)];
801 buff[
i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
802 buff[
i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
803 buff[
i++] = trans[077 & s[2]];
807 if (buff_size-
i < encoded_unit) {
814 buff[
i++] = trans[077 & (*s >> 2)];
815 buff[
i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
816 buff[
i++] = trans[077 & (((s[1] << 2) & 074) | ((
'\0' >> 6) & 03))];
820 buff[
i++] = trans[077 & (*s >> 2)];
821 buff[
i++] = trans[077 & (((*s << 4) & 060) | ((
'\0' >> 4) & 017))];
825 if (tail_lf) buff[
i++] =
'\n';
827 if ((
size_t)
i >
sizeof(buff))
rb_bug(
"encodes() buffer overrun");
830 static const char hex_table[] =
"0123456789ABCDEF";
836 long i = 0,
n = 0, prev =
EOF;
837 unsigned char *s = (
unsigned char*)
RSTRING_PTR(from);
842 (*s < 32 && *s !=
'\n' && *s !=
'\t') ||
845 buff[
i++] = hex_table[*s >> 4];
846 buff[
i++] = hex_table[*s & 0x0f];
850 else if (*s ==
'\n') {
851 if (prev ==
' ' || prev ==
'\t') {
895 #define PACK_LENGTH_ADJUST_SIZE(sz) do { \
897 if (len > (long)((send-s)/(sz))) { \
899 tmp_len = len-(send-s)/(sz); \
901 len = (send-s)/(sz); \
905 #define PACK_ITEM_ADJUST() do { \
906 if (tmp_len > 0 && mode == UNPACK_ARRAY) \
907 rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \
914 #if defined(__SUNPRO_C) && 0x5130 <= __SUNPRO_C && __SUNPRO_C <= 0x5150
915 # define AVOID_CC_BUG volatile
917 # define AVOID_CC_BUG
921 #define UNPACK_ARRAY 0
922 #define UNPACK_BLOCK 1
928 #define hexdigits ruby_hexdigits
939 int signed_p, integer_size, bigendian_p;
940 #define UNPACK_PUSH(item) do {\
941 VALUE item_val = (item);\
942 if ((mode) == UNPACK_BLOCK) {\
945 else if ((mode) == UNPACK_ARRAY) {\
946 rb_ary_push(ary, item_val);\
962 int explicit_endian = 0;
970 while ((p < pend) && (*p !=
'\n')) {
999 if (explicit_endian) {
1002 explicit_endian = *p++;
1009 else if (*p ==
'*') {
1031 if (
len > send - s)
len = send - s;
1034 char *t = s +
len - 1;
1037 if (*t !=
' ' && *t !=
'\0')
break;
1049 if (
len > send-s)
len = send-s;
1050 while (t < s+
len && *t) t++;
1053 s = star ? t : s+
len;
1058 if (
len > send - s)
len = send - s;
1070 if (p[-1] ==
'*' ||
len > (send - s) * 8)
1071 len = (send - s) * 8;
1076 if (
i & 7) bits >>= 1;
1077 else bits = (
unsigned char)*s++;
1078 *t++ = (bits & 1) ?
'1' :
'0';
1091 if (p[-1] ==
'*' ||
len > (send - s) * 8)
1092 len = (send - s) * 8;
1097 if (
i & 7) bits <<= 1;
1098 else bits = (
unsigned char)*s++;
1099 *t++ = (bits & 128) ?
'1' :
'0';
1112 if (p[-1] ==
'*' ||
len > (send - s) * 2)
1113 len = (send - s) * 2;
1121 bits = (
unsigned char)*s++;
1135 if (p[-1] ==
'*' ||
len > (send - s) * 2)
1136 len = (send - s) * 2;
1144 bits = (
unsigned char)*s++;
1155 goto unpack_integer;
1161 goto unpack_integer;
1167 goto unpack_integer;
1173 goto unpack_integer;
1177 integer_size = (
int)
sizeof(
int);
1179 goto unpack_integer;
1183 integer_size = (
int)
sizeof(
int);
1185 goto unpack_integer;
1191 goto unpack_integer;
1197 goto unpack_integer;
1203 goto unpack_integer;
1209 goto unpack_integer;
1215 goto unpack_integer;
1221 goto unpack_integer;
1227 goto unpack_integer;
1233 goto unpack_integer;
1239 goto unpack_integer;
1245 goto unpack_integer;
1248 if (explicit_endian) {
1249 bigendian_p = explicit_endian ==
'>';
1269 memcpy(&tmp, s,
sizeof(
float));
1280 memcpy(tmp.buf, s,
sizeof(
float));
1292 memcpy(tmp.buf, s,
sizeof(
double));
1305 memcpy(&tmp, s,
sizeof(
double));
1316 memcpy(tmp.buf, s,
sizeof(
float));
1328 memcpy(tmp.buf, s,
sizeof(
double));
1337 if (
len > send - s)
len = send - s;
1338 while (
len > 0 && s < send) {
1339 long alen = send - s;
1342 l = utf8_to_uv(s, &alen);
1354 while (s < send && (
unsigned char)*s >
' ' && (
unsigned char)*s <
'a') {
1358 len = ((
unsigned char)*s++ -
' ') & 077;
1367 long mlen =
len > 3 ? 3 :
len;
1369 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1370 a = ((
unsigned char)*s++ -
' ') & 077;
1373 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1374 b = ((
unsigned char)*s++ -
' ') & 077;
1377 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1378 c = ((
unsigned char)*s++ -
' ') & 077;
1381 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1382 d = ((
unsigned char)*s++ -
' ') & 077;
1385 hunk[0] = (
char)(a << 2 | b >> 4);
1386 hunk[1] = (
char)(b << 4 | c >> 2);
1387 hunk[2] = (
char)(c << 6 | d);
1392 if (s < send && (
unsigned char)*s !=
'\r' && *s !=
'\n')
1394 if (s < send && *s ==
'\r') s++;
1395 if (s < send && *s ==
'\n') s++;
1407 int a = -1,b = -1,c = 0,d = 0;
1408 static signed char b64_xtable[256];
1410 if (b64_xtable[
'/'] <= 0) {
1413 for (
i = 0;
i < 256;
i++) {
1416 for (
i = 0;
i < 64;
i++) {
1417 b64_xtable[(
unsigned char)b64_table[
i]] = (
char)
i;
1423 a = b64_xtable[(
unsigned char)*s++];
1425 b = b64_xtable[(
unsigned char)*s++];
1428 if (s + 2 == send && *(s + 1) ==
'=')
break;
1431 c = b64_xtable[(
unsigned char)*s++];
1433 if (s + 1 == send && *s ==
'=')
break;
1434 d = b64_xtable[(
unsigned char)*s++];
1453 while ((a = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1454 if (s >= send)
break;
1456 while ((b = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1457 if (s >= send)
break;
1459 while ((c = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1460 if (*s ==
'=' || s >= send)
break;
1462 while ((d = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1463 if (*s ==
'=' || s >= send)
break;
1470 if (a != -1 && b != -1) {
1493 if (++s == send)
break;
1494 if (s+1 < send && *s ==
'\r' && *(s+1) ==
'\n')
1497 if ((c1 = hex2num(*s)) == -1)
break;
1498 if (++s == send)
break;
1499 if ((c2 = hex2num(*s)) == -1)
break;
1504 csum |= *
ptr++ = *s;
1536 if (
sizeof(
char *) <= (
size_t)(send - s)) {
1540 memcpy(&t, s,
sizeof(
char *));
1541 s +=
sizeof(
char *);
1545 const VALUE *p, *pend;
1547 if (!(a = str_associated(
str))) {
1556 str_associate(tmp, a);
1574 if (
len > (
long)((send - s) /
sizeof(
char *)))
1575 len = (send - s) /
sizeof(
char *);
1577 if ((
size_t)(send - s) <
sizeof(
char *))
1583 memcpy(&t, s,
sizeof(
char *));
1584 s +=
sizeof(
char *);
1588 const VALUE *p, *pend;
1590 if (!(a = str_associated(
str))) {
1614 while (
len > 0 && s < send) {
1629 unknown_directive(
"unpack",
type,
fmt);
1641 return pack_unpack_internal(
str,
fmt, mode);
1668 if (uv <= 0x1fffff) {
1675 if (uv <= 0x3ffffff) {
1683 if (uv <= 0x7fffffff) {
1697 static const unsigned long utf8_limits[] = {
1707 static unsigned long
1708 utf8_to_uv(
const char *p,
long *lenp)
1710 int c = *p++ & 0xff;
1711 unsigned long uv = c;
1723 if (!(uv & 0x20)) {
n = 2; uv &= 0x1f; }
1724 else if (!(uv & 0x10)) {
n = 3; uv &= 0x0f; }
1725 else if (!(uv & 0x08)) {
n = 4; uv &= 0x07; }
1726 else if (!(uv & 0x04)) {
n = 5; uv &= 0x03; }
1727 else if (!(uv & 0x02)) {
n = 6; uv &= 0x01; }
1740 if ((c & 0xc0) != 0x80) {
1751 if (uv < utf8_limits[
n]) {
1757 #include "pack.rbinc"
#define ENC_CODERANGE_VALID
VALUE rb_str_buf_new(long)
int rb_block_given_p(void)
Determines if the current method is given a block.
void rb_warning(const char *fmt,...)
ID rb_make_internal_id(void)
char * strchr(char *, char)
int rb_utf8_encindex(void)
VALUE rb_obj_as_string(VALUE)
#define RB_TYPE_P(obj, type)
#define INTEGER_PACK_LITTLE_ENDIAN
unsigned long long uint64_t
int rb_uv_to_utf8(char buf[6], unsigned long uv)
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
#define DOUBLE_CONVWITH(x)
int rb_ascii8bit_encindex(void)
#define INTEGER_PACK_BIG_ENDIAN
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_to_float(VALUE)
Converts a Numeric object into Float.
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
VALUE rb_ary_push(VALUE ary, VALUE item)
#define PACK_ITEM_ADJUST()
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define ENCODING_CODERANGE_SET(obj, encindex, cr)
#define UNPACK_PUSH(item)
#define PACK_LENGTH_ADJUST_SIZE(sz)
void rb_enc_set_index(VALUE obj, int idx)
#define StringValuePtr(v)
void rb_str_set_len(VALUE, long)
#define STRTOUL(str, endptr, base)
VALUE rb_to_int(VALUE)
Converts val into Integer.
unsigned char buf[MIME_BUF_SIZE]
int rb_usascii_encindex(void)
void rb_bug(const char *fmt,...)
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
VALUE rb_str_subseq(VALUE, long, long)
char str[HTML_ESCAPE_MAX_LEN+1]
#define RARRAY_CONST_PTR(s)
#define ENC_CODERANGE_7BIT
const char * rb_obj_classname(VALUE)
#define FLOAT_CONVWITH(x)
#define NATINT_LEN(type, len)
RUBY_EXTERN const signed char ruby_digit36_to_number_table[]
#define INTEGER_PACK_2COMP
VALUE rb_ivar_set(VALUE, ID, VALUE)
#define MAX_INTEGER_PACK_SIZE
#define UNREACHABLE_RETURN(val)
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_str_quote_unprintable(VALUE)