12#include "ruby/internal/config.h"
20#include "internal/array.h"
21#include "internal/bits.h"
22#include "internal/string.h"
23#include "internal/symbol.h"
24#include "internal/variable.h"
37#ifdef HAVE_TRUE_LONG_LONG
38static const char natstr[] =
"sSiIlLqQjJ";
41static const char natstr[] =
"sSiIlLjJ";
42static const char endstr[] =
"sSiIlLqQjJ";
45#ifdef HAVE_TRUE_LONG_LONG
47# define NATINT_LEN_Q NATINT_LEN(long long, 8)
49# define NATINT_LEN_Q 8
52#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
63 static int endian_value;
66 if (init)
return endian_value;
69 return endian_value = p[0]?0:1;
71# define BIGENDIAN_P() (is_bigendian())
72#elif defined(WORDS_BIGENDIAN)
73# define BIGENDIAN_P() 1
75# define BIGENDIAN_P() 0
79# define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len))
81# define NATINT_LEN(type,len) ((int)sizeof(type))
94#define swapf(x) swap32(x)
95#define swapd(x) swap64(x)
97#define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
98#define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
99#define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x))
100#define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x))
101#define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x))
102#define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x))
103#define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
104#define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))
106#define FLOAT_CONVWITH(x) FLOAT_SWAPPER x;
107#define HTONF(x) ((x).u = rb_htonf((x).u))
108#define HTOVF(x) ((x).u = rb_htovf((x).u))
109#define NTOHF(x) ((x).u = rb_ntohf((x).u))
110#define VTOHF(x) ((x).u = rb_vtohf((x).u))
112#define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x;
113#define HTOND(x) ((x).u = rb_htond((x).u))
114#define HTOVD(x) ((x).u = rb_htovd((x).u))
115#define NTOHD(x) ((x).u = rb_ntohd((x).u))
116#define VTOHD(x) ((x).u = rb_vtohd((x).u))
118#define MAX_INTEGER_PACK_SIZE 8
120static const char toofew[] =
"too few arguments";
122static void encodes(
VALUE,
const char*,
long,
int,
int);
125static unsigned long utf8_to_uv(
const char*,
long*);
127static ID id_associated;
137str_associated(
VALUE str)
139 VALUE associates = rb_ivar_lookup(str, id_associated,
Qfalse);
141 rb_raise(rb_eArgError,
"no associated pointer");
146associated_pointer(
VALUE associates,
const char *t)
150 for (; p < pend; p++) {
152 if (RB_TYPE_P(tmp,
T_STRING) && RSTRING_PTR(tmp) == t)
return tmp;
154 rb_raise(rb_eArgError,
"non associated pointer");
160unknown_directive(const
char *mode,
char type,
VALUE fmt)
169 snprintf(unknown,
sizeof(unknown),
"\\x%.2x",
type & 0xff);
171 fmt = rb_str_quote_unprintable(fmt);
172 rb_raise(rb_eArgError,
"unknown %s directive '%s' in '%"PRIsVALUE
"'",
177VALUE_to_float(
VALUE obj)
185 else if (d < -FLT_MAX) {
188 else if (d <= FLT_MAX) {
199 static const char nul10[] =
"\0\0\0\0\0\0\0\0\0\0";
200 static const char spc10[] =
" ";
201 const char *p, *pend;
202 VALUE res, from, associates = 0;
210 int integer_size, bigendian_p;
214 p = RSTRING_PTR(fmt);
215 pend = p + RSTRING_LEN(fmt);
218 res = rb_str_buf_new(0);
223 rb_str_modify(buffer);
229#define TOO_FEW (rb_raise(rb_eArgError, toofew), 0)
230#define MORE_ITEM (idx < RARRAY_LEN(ary))
231#define THISFROM (MORE_ITEM ? RARRAY_AREF(ary, idx) : TOO_FEW)
232#define NEXTFROM (MORE_ITEM ? RARRAY_AREF(ary, idx++) : TOO_FEW)
235 int explicit_endian = 0;
236 if (RSTRING_PTR(fmt) + RSTRING_LEN(fmt) != pend) {
246 while ((p < pend) && (*p !=
'\n')) {
257 if (strchr(natstr,
type)) {
264 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, natstr);
270 if (!strchr(endstr,
type)) {
271 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, endstr);
273 if (explicit_endian) {
276 explicit_endian = *p++;
283 : strchr(
"PMm",
type) ? 1
301 if (enc_info == 1) enc_info = 2;
303 case 'm':
case 'M':
case 'u':
312 case 'A':
case 'a':
case 'Z':
322 ptr = RSTRING_PTR(from);
323 plen = RSTRING_LEN(from);
335 if (p[-1] ==
'*' &&
type ==
'Z')
349#define castchar(from) (char)((from) & 0xff)
357 j = (
len - plen + 1)/2;
360 for (i=0; i++ <
len; ptr++) {
366 char c = castchar(
byte);
373 byte >>= 7 - (
len & 7);
388 j = (
len - plen + 1)/2;
391 for (i=0; i++ <
len; ptr++) {
396 char c = castchar(
byte);
403 byte <<= 7 - (
len & 7);
418 j = (
len + 1) / 2 - (plen + 1) / 2;
421 for (i=0; i++ <
len; ptr++) {
423 byte |= (((*ptr & 15) + 9) & 15) << 4;
425 byte |= (*ptr & 15) << 4;
429 char c = castchar(
byte);
435 char c = castchar(
byte);
449 j = (
len + 1) / 2 - (plen + 1) / 2;
452 for (i=0; i++ <
len; ptr++) {
454 byte |= ((*ptr & 15) + 9) & 15;
460 char c = castchar(
byte);
466 char c = castchar(
byte);
479 bigendian_p = BIGENDIAN_P();
484 integer_size = NATINT_LEN(
short, 2);
485 bigendian_p = BIGENDIAN_P();
490 integer_size = (int)
sizeof(
int);
491 bigendian_p = BIGENDIAN_P();
496 integer_size = NATINT_LEN(
long, 4);
497 bigendian_p = BIGENDIAN_P();
502 integer_size = NATINT_LEN_Q;
503 bigendian_p = BIGENDIAN_P();
507 integer_size =
sizeof(intptr_t);
508 bigendian_p = BIGENDIAN_P();
512 integer_size =
sizeof(uintptr_t);
513 bigendian_p = BIGENDIAN_P();
537 if (explicit_endian) {
538 bigendian_p = explicit_endian ==
'>';
540 if (integer_size > MAX_INTEGER_PACK_SIZE)
541 rb_bug(
"unexpected integer size for pack: %d", integer_size);
543 char intbuf[MAX_INTEGER_PACK_SIZE];
546 rb_integer_pack(from, intbuf, integer_size, 1, 0,
559 f = VALUE_to_float(from);
569 tmp.f = VALUE_to_float(from);
577 DOUBLE_CONVWITH(tmp);
600 tmp.f = VALUE_to_float(from);
608 DOUBLE_CONVWITH(tmp);
628 plen = RSTRING_LEN(res);
630 rb_raise(rb_eArgError,
"X outside of string");
631 rb_str_set_len(res, plen -
len);
635 len -= RSTRING_LEN(res);
636 if (
len > 0)
goto grow;
638 if (
len > 0)
goto shrink;
642 rb_raise(rb_eArgError,
"%% is not supported");
666 ptr = RSTRING_PTR(from);
667 plen = RSTRING_LEN(from);
670 encodes(res, ptr, plen,
type, 0);
676 else if (
len > 63 &&
type ==
'u')
687 encodes(res, ptr, todo,
type, 1);
694 from = rb_obj_as_string(NEXTFROM);
697 qpencode(res, from,
len);
704 if (RSTRING_LEN(from) <
len) {
705 rb_raise(rb_eArgError,
"too short buffer for P(%ld for %ld)",
706 RSTRING_LEN(from),
len);
722 associates = rb_ary_new();
724 rb_ary_push(associates, from);
738 numbytes = rb_absint_numwords(from, 7, NULL);
746 rb_raise(rb_eArgError,
"can't compress negative numbers");
748 rb_bug(
"buffer size problem?");
750 cp = RSTRING_PTR(buf);
751 while (1 < numbytes) {
762 unknown_directive(
"pack",
type, fmt);
769 str_associate(res, associates);
776 rb_enc_set_index(res, rb_utf8_encindex());
785static const char uu_table[] =
786"`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
787static const char b64_table[] =
788"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
791encodes(
VALUE str,
const char *s0,
long len,
int type,
int tail_lf)
793 enum {buff_size = 4096, encoded_unit = 4, input_unit = 3};
794 char buff[buff_size + 1];
796 const char *
const trans =
type ==
'u' ? uu_table : b64_table;
798 const unsigned char *s = (
const unsigned char *)s0;
801 buff[i++] = (char)
len +
' ';
807 while (
len >= input_unit) {
808 while (
len >= input_unit && buff_size-i >= encoded_unit) {
809 buff[i++] = trans[077 & (*s >> 2)];
810 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
811 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
812 buff[i++] = trans[077 & s[2]];
816 if (buff_size-i < encoded_unit) {
823 buff[i++] = trans[077 & (*s >> 2)];
824 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
825 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((
'\0' >> 6) & 03))];
829 buff[i++] = trans[077 & (*s >> 2)];
830 buff[i++] = trans[077 & (((*s << 4) & 060) | ((
'\0' >> 4) & 017))];
834 if (tail_lf) buff[i++] =
'\n';
836 if ((
size_t)i >
sizeof(buff)) rb_bug(
"encodes() buffer overrun");
839static const char hex_table[] =
"0123456789ABCDEF";
845 long i = 0, n = 0, prev = EOF;
846 unsigned char *s = (
unsigned char*)RSTRING_PTR(from);
847 unsigned char *send = s + RSTRING_LEN(from);
851 (*s < 32 && *s !=
'\n' && *s !=
'\t') ||
854 buff[i++] = hex_table[*s >> 4];
855 buff[i++] = hex_table[*s & 0x0f];
859 else if (*s ==
'\n') {
860 if (prev ==
' ' || prev ==
'\t') {
904#define PACK_LENGTH_ADJUST_SIZE(sz) do { \
906 if (len > (long)((send-s)/(sz))) { \
908 tmp_len = len-(send-s)/(sz); \
910 len = (send-s)/(sz); \
914#define PACK_ITEM_ADJUST() do { \
915 if (tmp_len > 0 && mode == UNPACK_ARRAY) \
916 rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \
923#if defined(__SUNPRO_C) && 0x5130 <= __SUNPRO_C && __SUNPRO_C <= 0x5150
924# define AVOID_CC_BUG volatile
936pack_unpack_internal(
VALUE str,
VALUE fmt,
enum unpack_mode mode,
long offset)
938#define hexdigits ruby_hexdigits
944 AVOID_CC_BUG
long tmp_len;
949 int signed_p, integer_size, bigendian_p;
950#define UNPACK_PUSH(item) do {\
951 VALUE item_val = (item);\
952 if ((mode) == UNPACK_BLOCK) {\
955 else if ((mode) == UNPACK_ARRAY) {\
956 rb_ary_push(ary, item_val);\
967 if (offset < 0) rb_raise(rb_eArgError,
"offset can't be negative");
968 len = RSTRING_LEN(str);
969 if (offset >
len) rb_raise(rb_eArgError,
"offset outside of string");
971 s = RSTRING_PTR(str);
975 p = RSTRING_PTR(fmt);
976 pend = p + RSTRING_LEN(fmt);
978#define UNPACK_FETCH(var, type) (memcpy((var), s, sizeof(type)), s += sizeof(type))
980 ary = mode == UNPACK_ARRAY ? rb_ary_new() :
Qnil;
982 int explicit_endian = 0;
990 while ((p < pend) && (*p !=
'\n')) {
1003 if (strchr(natstr,
type)) {
1010 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, natstr);
1016 if (!strchr(endstr,
type)) {
1017 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, endstr);
1019 if (explicit_endian) {
1022 explicit_endian = *p++;
1029 else if (*p ==
'*') {
1047 rb_raise(rb_eArgError,
"%% is not supported");
1051 if (
len > send - s)
len = send - s;
1054 char *t = s +
len - 1;
1057 if (*t !=
' ' && *t !=
'\0')
break;
1069 if (
len > send-s)
len = send-s;
1070 while (t < s+
len && *t) t++;
1073 s = star ? t : s+
len;
1078 if (
len > send - s)
len = send - s;
1090 if (p[-1] ==
'*' ||
len > (send - s) * 8)
1091 len = (send - s) * 8;
1094 t = RSTRING_PTR(bitstr);
1095 for (i=0; i<
len; i++) {
1096 if (i & 7) bits >>= 1;
1097 else bits = (
unsigned char)*s++;
1098 *t++ = (bits & 1) ?
'1' :
'0';
1100 UNPACK_PUSH(bitstr);
1111 if (p[-1] ==
'*' ||
len > (send - s) * 8)
1112 len = (send - s) * 8;
1115 t = RSTRING_PTR(bitstr);
1116 for (i=0; i<
len; i++) {
1117 if (i & 7) bits <<= 1;
1118 else bits = (
unsigned char)*s++;
1119 *t++ = (bits & 128) ?
'1' :
'0';
1121 UNPACK_PUSH(bitstr);
1132 if (p[-1] ==
'*' ||
len > (send - s) * 2)
1133 len = (send - s) * 2;
1136 t = RSTRING_PTR(bitstr);
1137 for (i=0; i<
len; i++) {
1141 bits = (
unsigned char)*s++;
1142 *t++ = hexdigits[bits & 15];
1144 UNPACK_PUSH(bitstr);
1155 if (p[-1] ==
'*' ||
len > (send - s) * 2)
1156 len = (send - s) * 2;
1159 t = RSTRING_PTR(bitstr);
1160 for (i=0; i<
len; i++) {
1164 bits = (
unsigned char)*s++;
1165 *t++ = hexdigits[(bits >> 4) & 15];
1167 UNPACK_PUSH(bitstr);
1174 bigendian_p = BIGENDIAN_P();
1175 goto unpack_integer;
1180 bigendian_p = BIGENDIAN_P();
1181 goto unpack_integer;
1185 integer_size = NATINT_LEN(
short, 2);
1186 bigendian_p = BIGENDIAN_P();
1187 goto unpack_integer;
1191 integer_size = NATINT_LEN(
short, 2);
1192 bigendian_p = BIGENDIAN_P();
1193 goto unpack_integer;
1197 integer_size = (int)
sizeof(
int);
1198 bigendian_p = BIGENDIAN_P();
1199 goto unpack_integer;
1203 integer_size = (int)
sizeof(
int);
1204 bigendian_p = BIGENDIAN_P();
1205 goto unpack_integer;
1209 integer_size = NATINT_LEN(
long, 4);
1210 bigendian_p = BIGENDIAN_P();
1211 goto unpack_integer;
1215 integer_size = NATINT_LEN(
long, 4);
1216 bigendian_p = BIGENDIAN_P();
1217 goto unpack_integer;
1221 integer_size = NATINT_LEN_Q;
1222 bigendian_p = BIGENDIAN_P();
1223 goto unpack_integer;
1227 integer_size = NATINT_LEN_Q;
1228 bigendian_p = BIGENDIAN_P();
1229 goto unpack_integer;
1233 integer_size =
sizeof(intptr_t);
1234 bigendian_p = BIGENDIAN_P();
1235 goto unpack_integer;
1239 integer_size =
sizeof(uintptr_t);
1240 bigendian_p = BIGENDIAN_P();
1241 goto unpack_integer;
1247 goto unpack_integer;
1253 goto unpack_integer;
1259 goto unpack_integer;
1265 goto unpack_integer;
1268 if (explicit_endian) {
1269 bigendian_p = explicit_endian ==
'>';
1271 PACK_LENGTH_ADJUST_SIZE(integer_size);
1277 val = rb_integer_unpack(s, integer_size, 1, 0, flags);
1286 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1289 UNPACK_FETCH(&tmp,
float);
1290 UNPACK_PUSH(
DBL2NUM((
double)tmp));
1296 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1298 FLOAT_CONVWITH(tmp);
1299 UNPACK_FETCH(tmp.buf,
float);
1307 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1309 DOUBLE_CONVWITH(tmp);
1310 UNPACK_FETCH(tmp.buf,
double);
1319 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1322 UNPACK_FETCH(&tmp,
double);
1329 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1331 FLOAT_CONVWITH(tmp);
1332 UNPACK_FETCH(tmp.buf,
float);
1340 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1342 DOUBLE_CONVWITH(tmp);
1343 UNPACK_FETCH(tmp.buf,
double);
1351 if (
len > send - s)
len = send - s;
1352 while (
len > 0 && s < send) {
1353 long alen = send - s;
1356 l = utf8_to_uv(s, &alen);
1365 char *ptr = RSTRING_PTR(buf);
1368 while (s < send && (
unsigned char)*s >
' ' && (
unsigned char)*s <
'a') {
1372 len = ((
unsigned char)*s++ -
' ') & 077;
1375 if (total > RSTRING_LEN(buf)) {
1376 len -= total - RSTRING_LEN(buf);
1377 total = RSTRING_LEN(buf);
1381 long mlen =
len > 3 ? 3 :
len;
1383 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1384 a = ((
unsigned char)*s++ -
' ') & 077;
1387 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1388 b = ((
unsigned char)*s++ -
' ') & 077;
1391 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1392 c = ((
unsigned char)*s++ -
' ') & 077;
1395 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1396 d = ((
unsigned char)*s++ -
' ') & 077;
1399 hunk[0] = (char)(a << 2 | b >> 4);
1400 hunk[1] = (char)(b << 4 | c >> 2);
1401 hunk[2] = (char)(c << 6 | d);
1402 memcpy(ptr, hunk, mlen);
1406 if (s < send && (
unsigned char)*s !=
'\r' && *s !=
'\n')
1408 if (s < send && *s ==
'\r') s++;
1409 if (s < send && *s ==
'\n') s++;
1412 rb_str_set_len(buf, total);
1420 char *ptr = RSTRING_PTR(buf);
1421 int a = -1,b = -1,c = 0,d = 0;
1422 static signed char b64_xtable[256];
1424 if (b64_xtable[
'/'] <= 0) {
1427 for (i = 0; i < 256; i++) {
1430 for (i = 0; i < 64; i++) {
1431 b64_xtable[(
unsigned char)b64_table[i]] = (
char)i;
1437 a = b64_xtable[(
unsigned char)*s++];
1438 if (s >= send || a == -1) rb_raise(rb_eArgError,
"invalid base64");
1439 b = b64_xtable[(
unsigned char)*s++];
1440 if (s >= send || b == -1) rb_raise(rb_eArgError,
"invalid base64");
1442 if (s + 2 == send && *(s + 1) ==
'=')
break;
1443 rb_raise(rb_eArgError,
"invalid base64");
1445 c = b64_xtable[(
unsigned char)*s++];
1446 if (s >= send || c == -1) rb_raise(rb_eArgError,
"invalid base64");
1447 if (s + 1 == send && *s ==
'=')
break;
1448 d = b64_xtable[(
unsigned char)*s++];
1449 if (d == -1) rb_raise(rb_eArgError,
"invalid base64");
1450 *ptr++ = castchar(a << 2 | b >> 4);
1451 *ptr++ = castchar(b << 4 | c >> 2);
1452 *ptr++ = castchar(c << 6 | d);
1455 *ptr++ = castchar(a << 2 | b >> 4);
1456 if (b & 0xf) rb_raise(rb_eArgError,
"invalid base64");
1459 *ptr++ = castchar(a << 2 | b >> 4);
1460 *ptr++ = castchar(b << 4 | c >> 2);
1461 if (c & 0x3) rb_raise(rb_eArgError,
"invalid base64");
1467 while ((a = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1468 if (s >= send)
break;
1470 while ((b = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1471 if (s >= send)
break;
1473 while ((c = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1474 if (*s ==
'=' || s >= send)
break;
1476 while ((d = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1477 if (*s ==
'=' || s >= send)
break;
1479 *ptr++ = castchar(a << 2 | b >> 4);
1480 *ptr++ = castchar(b << 4 | c >> 2);
1481 *ptr++ = castchar(c << 6 | d);
1484 if (a != -1 && b != -1) {
1486 *ptr++ = castchar(a << 2 | b >> 4);
1488 *ptr++ = castchar(a << 2 | b >> 4);
1489 *ptr++ = castchar(b << 4 | c >> 2);
1493 rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
1501 char *ptr = RSTRING_PTR(buf), *ss = s;
1507 if (++s == send)
break;
1508 if (s+1 < send && *s ==
'\r' && *(s+1) ==
'\n')
1511 if ((c1 = hex2num(*s)) == -1)
break;
1512 if (++s == send)
break;
1513 if ((c2 = hex2num(*s)) == -1)
break;
1514 csum |= *ptr++ = castchar(c1 << 4 | c2);
1518 csum |= *ptr++ = *s;
1523 rb_str_set_len(buf, ptr - RSTRING_PTR(buf));
1532 if (
len > RSTRING_LEN(str))
1533 rb_raise(rb_eArgError,
"@ outside of string");
1534 s = RSTRING_PTR(str) +
len;
1538 if (
len > s - RSTRING_PTR(str))
1539 rb_raise(rb_eArgError,
"X outside of string");
1545 rb_raise(rb_eArgError,
"x outside of string");
1550 if (
sizeof(
char *) <= (
size_t)(send - s)) {
1554 UNPACK_FETCH(&t,
char *);
1556 if (!associates) associates = str_associated(str);
1557 tmp = associated_pointer(associates, t);
1558 if (
len < RSTRING_LEN(tmp)) {
1560 str_associate(tmp, associates);
1568 if (
len > (
long)((send - s) /
sizeof(
char *)))
1569 len = (send - s) /
sizeof(
char *);
1571 if ((
size_t)(send - s) <
sizeof(
char *))
1577 UNPACK_FETCH(&t,
char *);
1579 if (!associates) associates = str_associated(str);
1580 tmp = associated_pointer(associates, t);
1590 while (
len > 0 && s < send) {
1605 unknown_directive(
"unpack",
type, fmt);
1617 return pack_unpack_internal(str, fmt, mode,
RB_NUM2LONG(offset));
1623 return pack_unpack_internal(str, fmt, UNPACK_1,
RB_NUM2LONG(offset));
1634 buf[0] = castchar(((uv>>6)&0xff)|0xc0);
1635 buf[1] = castchar((uv&0x3f)|0x80);
1639 buf[0] = castchar(((uv>>12)&0xff)|0xe0);
1640 buf[1] = castchar(((uv>>6)&0x3f)|0x80);
1641 buf[2] = castchar((uv&0x3f)|0x80);
1644 if (uv <= 0x1fffff) {
1645 buf[0] = castchar(((uv>>18)&0xff)|0xf0);
1646 buf[1] = castchar(((uv>>12)&0x3f)|0x80);
1647 buf[2] = castchar(((uv>>6)&0x3f)|0x80);
1648 buf[3] = castchar((uv&0x3f)|0x80);
1651 if (uv <= 0x3ffffff) {
1652 buf[0] = castchar(((uv>>24)&0xff)|0xf8);
1653 buf[1] = castchar(((uv>>18)&0x3f)|0x80);
1654 buf[2] = castchar(((uv>>12)&0x3f)|0x80);
1655 buf[3] = castchar(((uv>>6)&0x3f)|0x80);
1656 buf[4] = castchar((uv&0x3f)|0x80);
1659 if (uv <= 0x7fffffff) {
1660 buf[0] = castchar(((uv>>30)&0xff)|0xfc);
1661 buf[1] = castchar(((uv>>24)&0x3f)|0x80);
1662 buf[2] = castchar(((uv>>18)&0x3f)|0x80);
1663 buf[3] = castchar(((uv>>12)&0x3f)|0x80);
1664 buf[4] = castchar(((uv>>6)&0x3f)|0x80);
1665 buf[5] = castchar((uv&0x3f)|0x80);
1673static const unsigned long utf8_limits[] = {
1684utf8_to_uv(
const char *p,
long *lenp)
1686 int c = *p++ & 0xff;
1687 unsigned long uv = c;
1696 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1699 if (!(uv & 0x20)) { n = 2; uv &= 0x1f; }
1700 else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }
1701 else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }
1702 else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }
1703 else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
1706 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1709 rb_raise(rb_eArgError,
"malformed UTF-8 character (expected %ld bytes, given %ld bytes)",
1716 if ((c & 0xc0) != 0x80) {
1718 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1727 if (uv < utf8_limits[n]) {
1728 rb_raise(rb_eArgError,
"redundant UTF-8 sequence");
1733#include "pack.rbinc"
1738 id_associated = rb_make_internal_id();
int rb_block_given_p(void)
Determines if the current method is given a block.
#define ENC_CODERANGE_7BIT
Old name of RUBY_ENC_CODERANGE_7BIT.
#define ENC_CODERANGE_VALID
Old name of RUBY_ENC_CODERANGE_VALID.
#define ISSPACE
Old name of rb_isspace.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define T_STRING
Old name of RUBY_T_STRING.
#define ULONG2NUM
Old name of RB_ULONG2NUM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define STRTOUL
Old name of ruby_strtoul.
#define ISDIGIT
Old name of rb_isdigit.
#define ISALPHA
Old name of rb_isalpha.
#define ISASCII
Old name of rb_isascii.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define NIL_P
Old name of RB_NIL_P.
#define DBL2NUM
Old name of rb_float_new.
#define ISPRINT
Old name of rb_isprint.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define ENCODING_CODERANGE_SET(obj, encindex, cr)
Old name of RB_ENCODING_CODERANGE_SET.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_to_float(VALUE val)
Identical to rb_check_to_float(), except it raises on error.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
#define INTEGER_PACK_LITTLE_ENDIAN
Little endian combination.
#define INTEGER_PACK_BIG_ENDIAN
Big endian combination.
int rb_uv_to_utf8(char buf[6], unsigned long uv)
Encodes a Unicode codepoint into its UTF-8 representation.
#define INTEGER_PACK_2COMP
Uses 2's complement representation.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#define rb_str_buf_cat
Just another name of rb_str_cat
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
void rb_must_asciicompat(VALUE obj)
Asserts that the given string's encoding is (Ruby's definition of) ASCII compatible.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
int len
Length of the buffer.
const signed char ruby_digit36_to_number_table[]
Character to number mapping like ‘'a’->10,'b'->11etc.
#define RB_NUM2LONG
Just another name of rb_num2long_inline
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RBIMPL_ATTR_NORETURN()
Wraps (or simulates) [[noreturn]]
#define RARRAY_LEN
Just another name of rb_array_len
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr
#define StringValue(v)
Ensures that the parameter object is a String.
#define StringValuePtr(v)
Identical to StringValue, except it returns a char*.
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
#define errno
Ractor-aware version of errno.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.