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";
40static const char natstr[] =
"sSiIlLjJ";
42static const char endstr[] =
"sSiIlLqQjJ";
44#ifdef HAVE_TRUE_LONG_LONG
46# define NATINT_LEN_Q NATINT_LEN(long long, 8)
48# define NATINT_LEN_Q 8
51#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
62 static int endian_value;
65 if (init)
return endian_value;
68 return endian_value = p[0]?0:1;
70# define BIGENDIAN_P() (is_bigendian())
71#elif defined(WORDS_BIGENDIAN)
72# define BIGENDIAN_P() 1
74# define BIGENDIAN_P() 0
78# define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len))
80# define NATINT_LEN(type,len) ((int)sizeof(type))
93#define swapf(x) swap32(x)
94#define swapd(x) swap64(x)
96#define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
97#define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
98#define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x))
99#define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x))
100#define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x))
101#define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x))
102#define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
103#define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))
105#define FLOAT_CONVWITH(x) FLOAT_SWAPPER x;
106#define HTONF(x) ((x).u = rb_htonf((x).u))
107#define HTOVF(x) ((x).u = rb_htovf((x).u))
108#define NTOHF(x) ((x).u = rb_ntohf((x).u))
109#define VTOHF(x) ((x).u = rb_vtohf((x).u))
111#define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x;
112#define HTOND(x) ((x).u = rb_htond((x).u))
113#define HTOVD(x) ((x).u = rb_htovd((x).u))
114#define NTOHD(x) ((x).u = rb_ntohd((x).u))
115#define VTOHD(x) ((x).u = rb_vtohd((x).u))
117#define MAX_INTEGER_PACK_SIZE 8
119static const char toofew[] =
"too few arguments";
121static void encodes(VALUE,
const char*,
long,
int,
int);
122static void qpencode(VALUE,VALUE,
long);
124static unsigned long utf8_to_uv(
const char*,
long*);
126static ID id_associated;
129str_associate(VALUE str, VALUE add)
136str_associated(VALUE str)
138 VALUE associates = rb_ivar_lookup(str, id_associated,
Qfalse);
140 rb_raise(rb_eArgError,
"no associated pointer");
145associated_pointer(VALUE associates,
const char *t)
148 const VALUE *pend = p +
RARRAY_LEN(associates);
149 for (; p < pend; p++) {
153 rb_raise(rb_eArgError,
"non associated pointer");
158unknown_directive(
const char *mode,
char type, VALUE fmt)
167 snprintf(unknown,
sizeof(unknown),
"\\x%.2x",
type & 0xff);
169 fmt = rb_str_quote_unprintable(fmt);
170 rb_warning(
"unknown %s directive '%s' in '%"PRIsVALUE
"'",
175VALUE_to_float(VALUE obj)
177 VALUE v = rb_to_float(obj);
183 else if (d < -FLT_MAX) {
186 else if (d <= FLT_MAX) {
197 static const char nul10[] =
"\0\0\0\0\0\0\0\0\0\0";
198 static const char spc10[] =
" ";
199 const char *p, *pend;
200 VALUE res, from, associates = 0;
208 int integer_size, bigendian_p;
226#define TOO_FEW (rb_raise(rb_eArgError, toofew), 0)
227#define MORE_ITEM (idx < RARRAY_LEN(ary))
228#define THISFROM (MORE_ITEM ? RARRAY_AREF(ary, idx) : TOO_FEW)
229#define NEXTFROM (MORE_ITEM ? RARRAY_AREF(ary, idx++) : TOO_FEW)
232 int explicit_endian = 0;
234 rb_raise(rb_eRuntimeError,
"format string modified");
243 while ((p < pend) && (*p !=
'\n')) {
254 if (strchr(natstr,
type)) {
261 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, natstr);
267 if (!strchr(endstr,
type)) {
268 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, endstr);
270 if (explicit_endian) {
271 rb_raise(rb_eRangeError,
"Can't use both '<' and '>'");
273 explicit_endian = *p++;
279 len = strchr(
"@Xxu",
type) ? 0
280 : strchr(
"PMm",
type) ? 1
286 len =
STRTOUL(p, (
char**)&p, 10);
288 rb_raise(rb_eRangeError,
"pack length too big");
298 if (enc_info == 1) enc_info = 2;
300 case 'm':
case 'M':
case 'u':
309 case 'A':
case 'a':
case 'Z':
332 if (p[-1] ==
'*' &&
type ==
'Z')
346#define castchar(from) (char)((from) & 0xff)
354 j = (len - plen + 1)/2;
357 for (i=0; i++ < len; ptr++) {
363 char c = castchar(
byte);
370 byte >>= 7 - (len & 7);
385 j = (len - plen + 1)/2;
388 for (i=0; i++ < len; ptr++) {
393 char c = castchar(
byte);
400 byte <<= 7 - (len & 7);
415 j = (len + 1) / 2 - (plen + 1) / 2;
418 for (i=0; i++ < len; ptr++) {
420 byte |= (((*ptr & 15) + 9) & 15) << 4;
422 byte |= (*ptr & 15) << 4;
426 char c = castchar(
byte);
432 char c = castchar(
byte);
446 j = (len + 1) / 2 - (plen + 1) / 2;
449 for (i=0; i++ < len; ptr++) {
451 byte |= ((*ptr & 15) + 9) & 15;
457 char c = castchar(
byte);
463 char c = castchar(
byte);
476 bigendian_p = BIGENDIAN_P();
480 integer_size = NATINT_LEN(
short, 2);
481 bigendian_p = BIGENDIAN_P();
485 integer_size = NATINT_LEN(
short, 2);
486 bigendian_p = BIGENDIAN_P();
490 integer_size = (int)
sizeof(
int);
491 bigendian_p = BIGENDIAN_P();
495 integer_size = (int)
sizeof(
int);
496 bigendian_p = BIGENDIAN_P();
500 integer_size = NATINT_LEN(
long, 4);
501 bigendian_p = BIGENDIAN_P();
505 integer_size = NATINT_LEN(
long, 4);
506 bigendian_p = BIGENDIAN_P();
510 integer_size = NATINT_LEN_Q;
511 bigendian_p = BIGENDIAN_P();
515 integer_size = NATINT_LEN_Q;
516 bigendian_p = BIGENDIAN_P();
520 integer_size =
sizeof(intptr_t);
521 bigendian_p = BIGENDIAN_P();
525 integer_size =
sizeof(uintptr_t);
526 bigendian_p = BIGENDIAN_P();
550 if (explicit_endian) {
551 bigendian_p = explicit_endian ==
'>';
553 if (integer_size > MAX_INTEGER_PACK_SIZE)
554 rb_bug(
"unexpected intger size for pack: %d", integer_size);
556 char intbuf[MAX_INTEGER_PACK_SIZE];
572 f = VALUE_to_float(from);
582 tmp.f = VALUE_to_float(from);
590 DOUBLE_CONVWITH(tmp);
613 tmp.f = VALUE_to_float(from);
621 DOUBLE_CONVWITH(tmp);
643 rb_raise(rb_eArgError,
"X outside of string");
649 if (len > 0)
goto grow;
651 if (len > 0)
goto shrink;
655 rb_raise(rb_eArgError,
"%% is not supported");
665 from = rb_to_int(from);
668 rb_raise(rb_eRangeError,
"pack(U): value out of range");
682 if (len == 0 &&
type ==
'm') {
683 encodes(res, ptr, plen,
type, 0);
689 else if (len > 63 &&
type ==
'u')
700 encodes(res, ptr, todo,
type, 1);
710 qpencode(res, from, len);
718 rb_raise(rb_eArgError,
"too short buffer for P(%ld for %ld)",
750 from = rb_to_int(from);
759 rb_raise(rb_eArgError,
"can't compress negative numbers");
761 rb_bug(
"buffer size problem?");
764 while (1 < numbytes) {
775 unknown_directive(
"pack",
type, fmt);
782 str_associate(res, associates);
798static const char uu_table[] =
799"`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
800static const char b64_table[] =
801"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
804encodes(VALUE str,
const char *s0,
long len,
int type,
int tail_lf)
806 enum {buff_size = 4096, encoded_unit = 4, input_unit = 3};
807 char buff[buff_size + 1];
809 const char *
const trans =
type ==
'u' ? uu_table : b64_table;
811 const unsigned char *s = (
const unsigned char *)s0;
814 buff[i++] = (char)len +
' ';
820 while (len >= input_unit) {
821 while (len >= input_unit && buff_size-i >= encoded_unit) {
822 buff[i++] = trans[077 & (*s >> 2)];
823 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
824 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
825 buff[i++] = trans[077 & s[2]];
829 if (buff_size-i < encoded_unit) {
836 buff[i++] = trans[077 & (*s >> 2)];
837 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
838 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((
'\0' >> 6) & 03))];
842 buff[i++] = trans[077 & (*s >> 2)];
843 buff[i++] = trans[077 & (((*s << 4) & 060) | ((
'\0' >> 4) & 017))];
847 if (tail_lf) buff[i++] =
'\n';
849 if ((
size_t)i >
sizeof(buff))
rb_bug(
"encodes() buffer overrun");
852static const char hex_table[] =
"0123456789ABCDEF";
855qpencode(VALUE str, VALUE from,
long len)
858 long i = 0, n = 0, prev = EOF;
859 unsigned char *s = (
unsigned char*)
RSTRING_PTR(from);
864 (*s < 32 && *s !=
'\n' && *s !=
'\t') ||
867 buff[i++] = hex_table[*s >> 4];
868 buff[i++] = hex_table[*s & 0x0f];
872 else if (*s ==
'\n') {
873 if (prev ==
' ' || prev ==
'\t') {
917#define PACK_LENGTH_ADJUST_SIZE(sz) do { \
919 if (len > (long)((send-s)/(sz))) { \
921 tmp_len = len-(send-s)/(sz); \
923 len = (send-s)/(sz); \
927#define PACK_ITEM_ADJUST() do { \
928 if (tmp_len > 0 && mode == UNPACK_ARRAY) \
929 rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \
936#if defined(__SUNPRO_C) && 0x5130 <= __SUNPRO_C && __SUNPRO_C <= 0x5150
937# define AVOID_CC_BUG volatile
943#define UNPACK_ARRAY 0
944#define UNPACK_BLOCK 1
948pack_unpack_internal(VALUE str, VALUE fmt,
int mode,
long offset)
950#define hexdigits ruby_hexdigits
953 VALUE ary, associates =
Qfalse;
956 AVOID_CC_BUG
long tmp_len;
961 int signed_p, integer_size, bigendian_p;
962#define UNPACK_PUSH(item) do {\
963 VALUE item_val = (item);\
964 if ((mode) == UNPACK_BLOCK) {\
967 else if ((mode) == UNPACK_ARRAY) {\
968 rb_ary_push(ary, item_val);\
978 if (offset < 0)
rb_raise(rb_eArgError,
"offset can't be negative");
980 if (offset > len)
rb_raise(rb_eArgError,
"offset outside of string");
989#define UNPACK_FETCH(var, type) (memcpy((var), s, sizeof(type)), s += sizeof(type))
993 int explicit_endian = 0;
1001 while ((p < pend) && (*p !=
'\n')) {
1014 if (strchr(natstr,
type)) {
1021 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, natstr);
1027 if (!strchr(endstr,
type)) {
1028 rb_raise(rb_eArgError,
"'%c' allowed only after types %s", *p, endstr);
1030 if (explicit_endian) {
1031 rb_raise(rb_eRangeError,
"Can't use both '<' and '>'");
1033 explicit_endian = *p++;
1040 else if (*p ==
'*') {
1047 len =
STRTOUL(p, (
char**)&p, 10);
1048 if (len < 0 || errno) {
1049 rb_raise(rb_eRangeError,
"pack length too big");
1053 len = (
type !=
'@');
1058 rb_raise(rb_eArgError,
"%% is not supported");
1062 if (len > send - s) len = send - s;
1065 char *t = s + len - 1;
1068 if (*t !=
' ' && *t !=
'\0')
break;
1080 if (len > send-s) len = send-s;
1081 while (t < s+len && *t) t++;
1084 s = star ? t : s+len;
1089 if (len > send - s) len = send - s;
1101 if (p[-1] ==
'*' || len > (send - s) * 8)
1102 len = (send - s) * 8;
1106 for (i=0; i<len; i++) {
1107 if (i & 7) bits >>= 1;
1108 else bits = (
unsigned char)*s++;
1109 *t++ = (bits & 1) ?
'1' :
'0';
1111 UNPACK_PUSH(bitstr);
1122 if (p[-1] ==
'*' || len > (send - s) * 8)
1123 len = (send - s) * 8;
1127 for (i=0; i<len; i++) {
1128 if (i & 7) bits <<= 1;
1129 else bits = (
unsigned char)*s++;
1130 *t++ = (bits & 128) ?
'1' :
'0';
1132 UNPACK_PUSH(bitstr);
1143 if (p[-1] ==
'*' || len > (send - s) * 2)
1144 len = (send - s) * 2;
1148 for (i=0; i<len; i++) {
1152 bits = (
unsigned char)*s++;
1153 *t++ = hexdigits[bits & 15];
1155 UNPACK_PUSH(bitstr);
1166 if (p[-1] ==
'*' || len > (send - s) * 2)
1167 len = (send - s) * 2;
1171 for (i=0; i<len; i++) {
1175 bits = (
unsigned char)*s++;
1176 *t++ = hexdigits[(bits >> 4) & 15];
1178 UNPACK_PUSH(bitstr);
1185 bigendian_p = BIGENDIAN_P();
1186 goto unpack_integer;
1191 bigendian_p = BIGENDIAN_P();
1192 goto unpack_integer;
1196 integer_size = NATINT_LEN(
short, 2);
1197 bigendian_p = BIGENDIAN_P();
1198 goto unpack_integer;
1202 integer_size = NATINT_LEN(
short, 2);
1203 bigendian_p = BIGENDIAN_P();
1204 goto unpack_integer;
1208 integer_size = (int)
sizeof(
int);
1209 bigendian_p = BIGENDIAN_P();
1210 goto unpack_integer;
1214 integer_size = (int)
sizeof(
int);
1215 bigendian_p = BIGENDIAN_P();
1216 goto unpack_integer;
1220 integer_size = NATINT_LEN(
long, 4);
1221 bigendian_p = BIGENDIAN_P();
1222 goto unpack_integer;
1226 integer_size = NATINT_LEN(
long, 4);
1227 bigendian_p = BIGENDIAN_P();
1228 goto unpack_integer;
1232 integer_size = NATINT_LEN_Q;
1233 bigendian_p = BIGENDIAN_P();
1234 goto unpack_integer;
1238 integer_size = NATINT_LEN_Q;
1239 bigendian_p = BIGENDIAN_P();
1240 goto unpack_integer;
1244 integer_size =
sizeof(intptr_t);
1245 bigendian_p = BIGENDIAN_P();
1246 goto unpack_integer;
1250 integer_size =
sizeof(uintptr_t);
1251 bigendian_p = BIGENDIAN_P();
1252 goto unpack_integer;
1258 goto unpack_integer;
1264 goto unpack_integer;
1270 goto unpack_integer;
1276 goto unpack_integer;
1279 if (explicit_endian) {
1280 bigendian_p = explicit_endian ==
'>';
1282 PACK_LENGTH_ADJUST_SIZE(integer_size);
1297 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1300 UNPACK_FETCH(&tmp,
float);
1301 UNPACK_PUSH(
DBL2NUM((
double)tmp));
1307 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1309 FLOAT_CONVWITH(tmp);
1310 UNPACK_FETCH(tmp.buf,
float);
1318 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1320 DOUBLE_CONVWITH(tmp);
1321 UNPACK_FETCH(tmp.buf,
double);
1330 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1333 UNPACK_FETCH(&tmp,
double);
1340 PACK_LENGTH_ADJUST_SIZE(
sizeof(
float));
1342 FLOAT_CONVWITH(tmp);
1343 UNPACK_FETCH(tmp.buf,
float);
1351 PACK_LENGTH_ADJUST_SIZE(
sizeof(
double));
1353 DOUBLE_CONVWITH(tmp);
1354 UNPACK_FETCH(tmp.buf,
double);
1362 if (len > send - s) len = send - s;
1363 while (len > 0 && s < send) {
1364 long alen = send - s;
1367 l = utf8_to_uv(s, &alen);
1379 while (s < send && (
unsigned char)*s >
' ' && (
unsigned char)*s <
'a') {
1383 len = ((
unsigned char)*s++ -
' ') & 077;
1392 long mlen = len > 3 ? 3 : len;
1394 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1395 a = ((
unsigned char)*s++ -
' ') & 077;
1398 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1399 b = ((
unsigned char)*s++ -
' ') & 077;
1402 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1403 c = ((
unsigned char)*s++ -
' ') & 077;
1406 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1407 d = ((
unsigned char)*s++ -
' ') & 077;
1410 hunk[0] = (char)(a << 2 | b >> 4);
1411 hunk[1] = (char)(b << 4 | c >> 2);
1412 hunk[2] = (char)(c << 6 | d);
1413 memcpy(ptr, hunk, mlen);
1417 if (s < send && (
unsigned char)*s !=
'\r' && *s !=
'\n')
1419 if (s < send && *s ==
'\r') s++;
1420 if (s < send && *s ==
'\n') s++;
1430 VALUE buf =
rb_str_new(0, (send - s + 3)*3/4);
1432 int a = -1,b = -1,c = 0,d = 0;
1433 static signed char b64_xtable[256];
1435 if (b64_xtable[
'/'] <= 0) {
1438 for (i = 0; i < 256; i++) {
1441 for (i = 0; i < 64; i++) {
1442 b64_xtable[(
unsigned char)b64_table[i]] = (
char)i;
1448 a = b64_xtable[(
unsigned char)*s++];
1449 if (s >= send || a == -1)
rb_raise(rb_eArgError,
"invalid base64");
1450 b = b64_xtable[(
unsigned char)*s++];
1451 if (s >= send || b == -1)
rb_raise(rb_eArgError,
"invalid base64");
1453 if (s + 2 == send && *(s + 1) ==
'=')
break;
1454 rb_raise(rb_eArgError,
"invalid base64");
1456 c = b64_xtable[(
unsigned char)*s++];
1457 if (s >= send || c == -1)
rb_raise(rb_eArgError,
"invalid base64");
1458 if (s + 1 == send && *s ==
'=')
break;
1459 d = b64_xtable[(
unsigned char)*s++];
1460 if (d == -1)
rb_raise(rb_eArgError,
"invalid base64");
1461 *ptr++ = castchar(a << 2 | b >> 4);
1462 *ptr++ = castchar(b << 4 | c >> 2);
1463 *ptr++ = castchar(c << 6 | d);
1466 *ptr++ = castchar(a << 2 | b >> 4);
1467 if (b & 0xf)
rb_raise(rb_eArgError,
"invalid base64");
1470 *ptr++ = castchar(a << 2 | b >> 4);
1471 *ptr++ = castchar(b << 4 | c >> 2);
1472 if (c & 0x3)
rb_raise(rb_eArgError,
"invalid base64");
1478 while ((a = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1479 if (s >= send)
break;
1481 while ((b = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1482 if (s >= send)
break;
1484 while ((c = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1485 if (*s ==
'=' || s >= send)
break;
1487 while ((d = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1488 if (*s ==
'=' || s >= send)
break;
1490 *ptr++ = castchar(a << 2 | b >> 4);
1491 *ptr++ = castchar(b << 4 | c >> 2);
1492 *ptr++ = castchar(c << 6 | d);
1495 if (a != -1 && b != -1) {
1497 *ptr++ = castchar(a << 2 | b >> 4);
1499 *ptr++ = castchar(a << 2 | b >> 4);
1500 *ptr++ = castchar(b << 4 | c >> 2);
1518 if (++s == send)
break;
1519 if (s+1 < send && *s ==
'\r' && *(s+1) ==
'\n')
1522 if ((c1 = hex2num(*s)) == -1)
break;
1523 if (++s == send)
break;
1524 if ((c2 = hex2num(*s)) == -1)
break;
1525 csum |= *ptr++ = castchar(c1 << 4 | c2);
1529 csum |= *ptr++ = *s;
1544 rb_raise(rb_eArgError,
"@ outside of string");
1550 rb_raise(rb_eArgError,
"X outside of string");
1556 rb_raise(rb_eArgError,
"x outside of string");
1561 if (
sizeof(
char *) <= (
size_t)(send - s)) {
1565 UNPACK_FETCH(&t,
char *);
1567 if (!associates) associates = str_associated(str);
1568 tmp = associated_pointer(associates, t);
1571 str_associate(tmp, associates);
1579 if (len > (
long)((send - s) /
sizeof(
char *)))
1580 len = (send - s) /
sizeof(
char *);
1582 if ((
size_t)(send - s) <
sizeof(
char *))
1588 UNPACK_FETCH(&t,
char *);
1590 if (!associates) associates = str_associated(str);
1591 tmp = associated_pointer(associates, t);
1601 while (len > 0 && s < send) {
1616 unknown_directive(
"unpack",
type, fmt);
1628 return pack_unpack_internal(str, fmt, mode,
RB_NUM2LONG(offset));
1634 return pack_unpack_internal(str, fmt, UNPACK_1,
RB_NUM2LONG(offset));
1645 buf[0] = castchar(((uv>>6)&0xff)|0xc0);
1646 buf[1] = castchar((uv&0x3f)|0x80);
1650 buf[0] = castchar(((uv>>12)&0xff)|0xe0);
1651 buf[1] = castchar(((uv>>6)&0x3f)|0x80);
1652 buf[2] = castchar((uv&0x3f)|0x80);
1655 if (uv <= 0x1fffff) {
1656 buf[0] = castchar(((uv>>18)&0xff)|0xf0);
1657 buf[1] = castchar(((uv>>12)&0x3f)|0x80);
1658 buf[2] = castchar(((uv>>6)&0x3f)|0x80);
1659 buf[3] = castchar((uv&0x3f)|0x80);
1662 if (uv <= 0x3ffffff) {
1663 buf[0] = castchar(((uv>>24)&0xff)|0xf8);
1664 buf[1] = castchar(((uv>>18)&0x3f)|0x80);
1665 buf[2] = castchar(((uv>>12)&0x3f)|0x80);
1666 buf[3] = castchar(((uv>>6)&0x3f)|0x80);
1667 buf[4] = castchar((uv&0x3f)|0x80);
1670 if (uv <= 0x7fffffff) {
1671 buf[0] = castchar(((uv>>30)&0xff)|0xfc);
1672 buf[1] = castchar(((uv>>24)&0x3f)|0x80);
1673 buf[2] = castchar(((uv>>18)&0x3f)|0x80);
1674 buf[3] = castchar(((uv>>12)&0x3f)|0x80);
1675 buf[4] = castchar(((uv>>6)&0x3f)|0x80);
1676 buf[5] = castchar((uv&0x3f)|0x80);
1679 rb_raise(rb_eRangeError,
"pack(U): value out of range");
1684static const unsigned long utf8_limits[] = {
1695utf8_to_uv(
const char *p,
long *lenp)
1697 int c = *p++ & 0xff;
1698 unsigned long uv = c;
1707 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1710 if (!(uv & 0x20)) { n = 2; uv &= 0x1f; }
1711 else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }
1712 else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }
1713 else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }
1714 else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
1717 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1720 rb_raise(rb_eArgError,
"malformed UTF-8 character (expected %ld bytes, given %ld bytes)",
1727 if ((c & 0xc0) != 0x80) {
1729 rb_raise(rb_eArgError,
"malformed UTF-8 character");
1738 if (uv < utf8_limits[n]) {
1739 rb_raise(rb_eArgError,
"redundant UTF-8 sequence");
1744#include "pack.rbinc"
1749 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.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
void rb_warning(const char *fmt,...)
Issues a warning.
int rb_utf8_encindex(void)
Identical to rb_utf8_encoding(), except it returns the encoding's index instead of the encoding itsel...
int rb_ascii8bit_encindex(void)
Identical to rb_ascii8bit_encoding(), except it returns the encoding's index instead of the encoding ...
void rb_enc_set_index(VALUE obj, int encindex)
Destructively assigns an encoding (via its index) to an object.
int rb_usascii_encindex(void)
Identical to rb_usascii_encoding(), except it returns the encoding's index instead of the encoding it...
Defines RBIMPL_HAS_BUILTIN.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Exports an integer into a buffer.
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
Calculates the number of words needed represent the absolute value of the passed integer.
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Import an integer from a buffer.
#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.
VALUE rb_str_buf_cat(VALUE, const char *, long)
Just another name of rb_str_cat.
void rb_str_modify(VALUE str)
Declares that the string is about to be modified.
VALUE rb_usascii_str_new(const char *ptr, long len)
Identical to rb_str_new(), except it generates a string of "US ASCII" encoding.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
VALUE rb_str_new(const char *ptr, long len)
Allocates an instance of rb_cString.
VALUE rb_str_buf_new(long capa)
Allocates a "string buffer".
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
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.
const signed char ruby_digit36_to_number_table[]
Character to number mapping like ‘'a’->10,'b'->11` etc.
#define RB_NUM2LONG
Just another name of rb_num2long_inline.
VALUE type(ANYARGS)
ANYARGS-ed function type.
#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*.
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
const char * rb_obj_classname(VALUE obj)
Queries the name of the class of the passed object.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.