13 #include <sys/types.h> 25 #ifdef HAVE_TRUE_LONG_LONG 26 static const char natstr[] =
"sSiIlLqQjJ";
28 static const char natstr[] =
"sSiIlLjJ";
30 static const char endstr[] =
"sSiIlLqQjJ";
32 #ifdef HAVE_TRUE_LONG_LONG 34 # define NATINT_LEN_Q NATINT_LEN(long long, 8) 36 # define NATINT_LEN_Q 8 39 #if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8) 50 static int endian_value;
53 if (init)
return endian_value;
56 return endian_value = p[0]?0:1;
58 # define BIGENDIAN_P() (is_bigendian()) 59 #elif defined(WORDS_BIGENDIAN) 60 # define BIGENDIAN_P() 1 62 # define BIGENDIAN_P() 0 66 # define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len)) 68 # define NATINT_LEN(type,len) ((int)sizeof(type)) 81 #define swapf(x) swap32(x) 82 #define swapd(x) swap64(x) 84 #define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x)) 85 #define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x)) 86 #define rb_htonf(x) (BIGENDIAN_P()?(x):swapf(x)) 87 #define rb_htond(x) (BIGENDIAN_P()?(x):swapd(x)) 88 #define rb_htovf(x) (BIGENDIAN_P()?swapf(x):(x)) 89 #define rb_htovd(x) (BIGENDIAN_P()?swapd(x):(x)) 90 #define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x)) 91 #define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x)) 93 #define FLOAT_CONVWITH(x) FLOAT_SWAPPER x; 94 #define HTONF(x) ((x).u = rb_htonf((x).u)) 95 #define HTOVF(x) ((x).u = rb_htovf((x).u)) 96 #define NTOHF(x) ((x).u = rb_ntohf((x).u)) 97 #define VTOHF(x) ((x).u = rb_vtohf((x).u)) 99 #define DOUBLE_CONVWITH(x) DOUBLE_SWAPPER x; 100 #define HTOND(x) ((x).u = rb_htond((x).u)) 101 #define HTOVD(x) ((x).u = rb_htovd((x).u)) 102 #define NTOHD(x) ((x).u = rb_ntohd((x).u)) 103 #define VTOHD(x) ((x).u = rb_vtohd((x).u)) 105 #define MAX_INTEGER_PACK_SIZE 8 107 static const char toofew[] =
"too few arguments";
112 static unsigned long utf8_to_uv(
const char*,
long*);
273 static const char nul10[] =
"\0\0\0\0\0\0\0\0\0\0";
274 static const char spc10[] =
" ";
275 const char *p, *pend;
276 VALUE fmt, opt =
Qnil, res, from, associates = 0, buffer = 0;
284 int integer_size, bigendian_p;
292 static ID keyword_ids[1];
308 #define TOO_FEW (rb_raise(rb_eArgError, toofew), 0) 309 #define MORE_ITEM (idx < RARRAY_LEN(ary)) 310 #define THISFROM (MORE_ITEM ? RARRAY_AREF(ary, idx) : TOO_FEW) 311 #define NEXTFROM (MORE_ITEM ? RARRAY_AREF(ary, idx++) : TOO_FEW) 314 int explicit_endian = 0;
325 while ((p < pend) && (*p !=
'\n')) {
352 if (explicit_endian) {
355 explicit_endian = *p++;
361 len =
strchr(
"@Xxu", type) ? 0
368 len =
STRTOUL(p, (
char**)&p, 10);
380 if (enc_info == 1) enc_info = 2;
382 case 'm':
case 'M':
case 'u':
391 case 'A':
case 'a':
case 'Z':
415 if (p[-1] ==
'*' && type ==
'Z')
429 #define castchar(from) (char)((from) & 0xff) 437 j = (len - plen + 1)/2;
440 for (i=0; i++ <
len; ptr++) {
453 byte >>= 7 - (len & 7);
468 j = (len - plen + 1)/2;
471 for (i=0; i++ <
len; ptr++) {
483 byte <<= 7 - (len & 7);
498 j = (len + 1) / 2 - (plen + 1) / 2;
501 for (i=0; i++ <
len; ptr++) {
503 byte |= (((*ptr & 15) + 9) & 15) << 4;
505 byte |= (*ptr & 15) << 4;
529 j = (len + 1) / 2 - (plen + 1) / 2;
532 for (i=0; i++ <
len; ptr++) {
534 byte |= ((*ptr & 15) + 9) & 15;
573 integer_size = (int)
sizeof(
int);
578 integer_size = (int)
sizeof(
int);
633 if (explicit_endian) {
634 bigendian_p = explicit_endian ==
'>';
637 rb_bug(
"unexpected intger size for pack: %d", integer_size);
732 if (len > 0)
goto grow;
734 if (len > 0)
goto shrink;
765 if (len == 0 && type ==
'm') {
766 encodes(res, ptr, plen, type, 0);
772 else if (len > 63 && type ==
'u')
783 encodes(res, ptr, todo, type, 1);
845 rb_bug(
"buffer size problem?");
848 while (1 < numbytes) {
865 snprintf(unknown,
sizeof(unknown),
"\\x%.2x", type & 0xff);
893 "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
895 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
900 enum {buff_size = 4096, encoded_unit = 4, input_unit = 3};
901 char buff[buff_size + 1];
905 const unsigned char *s = (
const unsigned char *)s0;
908 buff[i++] = (char)len +
' ';
914 while (len >= input_unit) {
915 while (len >= input_unit && buff_size-i >= encoded_unit) {
916 buff[i++] = trans[077 & (*s >> 2)];
917 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
918 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
919 buff[i++] = trans[077 & s[2]];
923 if (buff_size-i < encoded_unit) {
930 buff[i++] = trans[077 & (*s >> 2)];
931 buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
932 buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((
'\0' >> 6) & 03))];
936 buff[i++] = trans[077 & (*s >> 2)];
937 buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
941 if (tail_lf) buff[i++] =
'\n';
943 if ((
size_t)i >
sizeof(buff))
rb_bug(
"encodes() buffer overrun");
952 long i = 0, n = 0, prev =
EOF;
953 unsigned char *s = (
unsigned char*)
RSTRING_PTR(from);
958 (*s < 32 && *s !=
'\n' && *s !=
'\t') ||
966 else if (*s ==
'\n') {
967 if (prev ==
' ' || prev ==
'\t') {
1011 #define PACK_LENGTH_ADJUST_SIZE(sz) do { \ 1013 if (len > (long)((send-s)/(sz))) { \ 1015 tmp_len = len-(send-s)/(sz); \ 1017 len = (send-s)/(sz); \ 1021 #define PACK_ITEM_ADJUST() do { \ 1022 if (tmp_len > 0 && mode == UNPACK_ARRAY) \ 1023 rb_ary_store(ary, RARRAY_LEN(ary)+tmp_len-1, Qnil); \ 1029 #if defined(__SUNPRO_C) && __SUNPRO_C == 0x5130 1030 # define AVOID_CC_BUG volatile 1032 # define AVOID_CC_BUG 1045 #define UNPACK_ARRAY 0 1046 #define UNPACK_BLOCK 1 1052 #define hexdigits ruby_hexdigits 1063 int signed_p, integer_size, bigendian_p;
1064 #define UNPACK_PUSH(item) do {\ 1065 VALUE item_val = (item);\ 1066 if ((mode) == UNPACK_BLOCK) {\ 1067 rb_yield(item_val);\ 1069 else if ((mode) == UNPACK_ARRAY) {\ 1070 rb_ary_push(ary, item_val);\ 1086 int explicit_endian = 0;
1094 while ((p < pend) && (*p !=
'\n')) {
1123 if (explicit_endian) {
1126 explicit_endian = *p++;
1133 else if (*p ==
'*') {
1140 len =
STRTOUL(p, (
char**)&p, 10);
1146 len = (type !=
'@');
1155 if (len > send - s) len = send - s;
1158 char *t = s + len - 1;
1161 if (*t !=
' ' && *t !=
'\0')
break;
1173 if (len > send-s) len = send-s;
1174 while (t < s+len && *t) t++;
1177 s = star ? t : s+
len;
1182 if (len > send - s) len = send - s;
1194 if (p[-1] ==
'*' || len > (send - s) * 8)
1195 len = (send - s) * 8;
1199 for (i=0; i<
len; i++) {
1200 if (i & 7) bits >>= 1;
1201 else bits = (
unsigned char)*s++;
1202 *t++ = (bits & 1) ?
'1' :
'0';
1215 if (p[-1] ==
'*' || len > (send - s) * 8)
1216 len = (send - s) * 8;
1220 for (i=0; i<
len; i++) {
1221 if (i & 7) bits <<= 1;
1222 else bits = (
unsigned char)*s++;
1223 *t++ = (bits & 128) ?
'1' :
'0';
1236 if (p[-1] ==
'*' || len > (send - s) * 2)
1237 len = (send - s) * 2;
1241 for (i=0; i<
len; i++) {
1245 bits = (
unsigned char)*s++;
1259 if (p[-1] ==
'*' || len > (send - s) * 2)
1260 len = (send - s) * 2;
1264 for (i=0; i<
len; i++) {
1268 bits = (
unsigned char)*s++;
1279 goto unpack_integer;
1285 goto unpack_integer;
1291 goto unpack_integer;
1297 goto unpack_integer;
1301 integer_size = (int)
sizeof(
int);
1303 goto unpack_integer;
1307 integer_size = (int)
sizeof(
int);
1309 goto unpack_integer;
1315 goto unpack_integer;
1321 goto unpack_integer;
1327 goto unpack_integer;
1333 goto unpack_integer;
1339 goto unpack_integer;
1345 goto unpack_integer;
1351 goto unpack_integer;
1357 goto unpack_integer;
1363 goto unpack_integer;
1369 goto unpack_integer;
1372 if (explicit_endian) {
1373 bigendian_p = explicit_endian ==
'>';
1393 memcpy(&tmp, s,
sizeof(
float));
1404 memcpy(tmp.buf, s,
sizeof(
float));
1416 memcpy(tmp.buf, s,
sizeof(
double));
1417 s +=
sizeof(double);
1429 memcpy(&tmp, s,
sizeof(
double));
1430 s +=
sizeof(double);
1440 memcpy(tmp.buf, s,
sizeof(
float));
1452 memcpy(tmp.buf, s,
sizeof(
double));
1453 s +=
sizeof(double);
1461 if (len > send - s) len = send - s;
1462 while (len > 0 && s < send) {
1463 long alen = send - s;
1478 while (s < send && (
unsigned char)*s >
' ' && (
unsigned char)*s <
'a') {
1482 len = ((
unsigned char)*s++ -
' ') & 077;
1491 long mlen = len > 3 ? 3 :
len;
1493 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1494 a = ((
unsigned char)*s++ -
' ') & 077;
1497 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1498 b = ((
unsigned char)*s++ -
' ') & 077;
1501 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1502 c = ((
unsigned char)*s++ -
' ') & 077;
1505 if (s < send && (
unsigned char)*s >=
' ' && (
unsigned char)*s <
'a')
1506 d = ((
unsigned char)*s++ -
' ') & 077;
1509 hunk[0] = (char)(a << 2 | b >> 4);
1510 hunk[1] = (char)(b << 4 | c >> 2);
1511 hunk[2] = (char)(c << 6 | d);
1516 if (s < send && (
unsigned char)*s !=
'\r' && *s !=
'\n')
1518 if (s < send && *s ==
'\r') s++;
1519 if (s < send && *s ==
'\n') s++;
1531 int a = -1,b = -1,c = 0,d = 0;
1532 static signed char b64_xtable[256];
1534 if (b64_xtable[
'/'] <= 0) {
1537 for (i = 0; i < 256; i++) {
1540 for (i = 0; i < 64; i++) {
1541 b64_xtable[(
unsigned char)
b64_table[i]] = (
char)i;
1547 a = b64_xtable[(
unsigned char)*s++];
1549 b = b64_xtable[(
unsigned char)*s++];
1552 if (s + 2 == send && *(s + 1) ==
'=')
break;
1555 c = b64_xtable[(
unsigned char)*s++];
1557 if (s + 1 == send && *s ==
'=')
break;
1558 d = b64_xtable[(
unsigned char)*s++];
1560 *ptr++ =
castchar(a << 2 | b >> 4);
1561 *ptr++ =
castchar(b << 4 | c >> 2);
1565 *ptr++ =
castchar(a << 2 | b >> 4);
1569 *ptr++ =
castchar(a << 2 | b >> 4);
1570 *ptr++ =
castchar(b << 4 | c >> 2);
1577 while ((a = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1578 if (s >= send)
break;
1580 while ((b = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1581 if (s >= send)
break;
1583 while ((c = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1584 if (*s ==
'=' || s >= send)
break;
1586 while ((d = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1587 if (*s ==
'=' || s >= send)
break;
1589 *ptr++ =
castchar(a << 2 | b >> 4);
1590 *ptr++ =
castchar(b << 4 | c >> 2);
1594 if (a != -1 && b != -1) {
1596 *ptr++ =
castchar(a << 2 | b >> 4);
1598 *ptr++ =
castchar(a << 2 | b >> 4);
1599 *ptr++ =
castchar(b << 4 | c >> 2);
1616 if (++s == send)
break;
1617 if (s+1 < send && *s ==
'\r' && *(s+1) ==
'\n')
1620 if ((c1 =
hex2num(*s)) == -1)
break;
1621 if (++s == send)
break;
1622 if ((c2 =
hex2num(*s)) == -1)
break;
1658 if (
sizeof(
char *) <= (
size_t)(send - s)) {
1662 memcpy(&t, s,
sizeof(
char *));
1663 s +=
sizeof(
char *);
1667 const VALUE *p, *pend;
1696 if (len > (
long)((send - s) /
sizeof(
char *)))
1697 len = (send - s) /
sizeof(
char *);
1699 if ((
size_t)(send - s) <
sizeof(
char *))
1705 memcpy(&t, s,
sizeof(
char *));
1706 s +=
sizeof(
char *);
1710 const VALUE *p, *pend;
1736 while (len > 0 && s < send) {
1751 rb_warning(
"unknown unpack directive '%c' in '%s'",
1910 buf[0] =
castchar(((uv>>6)&0xff)|0xc0);
1915 buf[0] =
castchar(((uv>>12)&0xff)|0xe0);
1916 buf[1] =
castchar(((uv>>6)&0x3f)|0x80);
1920 if (uv <= 0x1fffff) {
1921 buf[0] =
castchar(((uv>>18)&0xff)|0xf0);
1922 buf[1] =
castchar(((uv>>12)&0x3f)|0x80);
1923 buf[2] =
castchar(((uv>>6)&0x3f)|0x80);
1927 if (uv <= 0x3ffffff) {
1928 buf[0] =
castchar(((uv>>24)&0xff)|0xf8);
1929 buf[1] =
castchar(((uv>>18)&0x3f)|0x80);
1930 buf[2] =
castchar(((uv>>12)&0x3f)|0x80);
1931 buf[3] =
castchar(((uv>>6)&0x3f)|0x80);
1935 if (uv <= 0x7fffffff) {
1936 buf[0] =
castchar(((uv>>30)&0xff)|0xfc);
1937 buf[1] =
castchar(((uv>>24)&0x3f)|0x80);
1938 buf[2] =
castchar(((uv>>18)&0x3f)|0x80);
1939 buf[3] =
castchar(((uv>>12)&0x3f)|0x80);
1940 buf[4] =
castchar(((uv>>6)&0x3f)|0x80);
1959 static unsigned long 1962 int c = *p++ & 0xff;
1963 unsigned long uv = c;
1975 if (!(uv & 0x20)) { n = 2; uv &= 0x1f; }
1976 else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }
1977 else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }
1978 else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }
1979 else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
1992 if ((c & 0xc0) != 0x80) {
RUBY_EXTERN VALUE rb_cString
void rb_str_associate(VALUE str, VALUE add)
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define MAX_INTEGER_PACK_SIZE
void rb_bug(const char *fmt,...)
#define ENCODING_CODERANGE_SET(obj, encindex, cr)
static VALUE pack_unpack_internal(VALUE str, VALUE fmt, int mode)
#define FLOAT_CONVWITH(x)
#define NATINT_LEN(type, len)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
#define PACK_ITEM_ADJUST()
VALUE rb_ary_push(VALUE ary, VALUE item)
int rb_usascii_encindex(void)
void rb_str_set_len(VALUE, long)
static void str_associate(VALUE str, VALUE add)
void rb_raise(VALUE exc, const char *fmt,...)
static const char uu_table[]
static const char toofew[]
VALUE rb_str_associated(VALUE str)
#define INTEGER_PACK_2COMP
static const char natstr[]
#define ENC_CODERANGE_7BIT
const char * rb_obj_classname(VALUE)
VALUE rb_str_buf_cat(VALUE, const char *, long)
static VALUE pack_unpack(VALUE str, VALUE fmt)
#define RB_TYPE_P(obj, type)
unsigned long long uint64_t
static void encodes(VALUE, const char *, long, int, int)
int rb_block_given_p(void)
VALUE rb_obj_taint(VALUE)
VALUE rb_obj_as_string(VALUE)
static VALUE infected_str_new(const char *ptr, long len, VALUE str)
int rb_ascii8bit_encindex(void)
#define STRTOUL(str, endptr, base)
static void qpencode(VALUE, VALUE, long)
void rb_enc_set_index(VALUE obj, int idx)
static VALUE str_associated(VALUE str)
#define ENC_CODERANGE_VALID
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
static const char hex_table[]
#define RARRAY_CONST_PTR(a)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
static int hex2num(char c)
char * strchr(char *, char)
int rb_utf8_encindex(void)
#define INTEGER_PACK_LITTLE_ENDIAN
#define INTEGER_PACK_BIG_ENDIAN
static VALUE pack_pack(int argc, VALUE *argv, VALUE ary)
register unsigned int len
#define DOUBLE_CONVWITH(x)
static unsigned long utf8_to_uv(const char *, long *)
static const unsigned long utf8_limits[]
static const char endstr[]
#define ONLY_FOR_INTERNAL_USE(func)
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
int rb_uv_to_utf8(char buf[6], unsigned long uv)
#define PACK_LENGTH_ADJUST_SIZE(sz)
#define StringValuePtr(v)
static const char b64_table[]
void rb_warning(const char *fmt,...)
RUBY_EXTERN const signed char ruby_digit36_to_number_table[]
#define CONST_ID(var, str)
VALUE rb_tainted_str_new(const char *, long)
VALUE rb_str_buf_new(long)
VALUE rb_usascii_str_new(const char *, long)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
static VALUE pack_unpack1(VALUE str, VALUE fmt)
#define UNPACK_PUSH(item)
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
ID rb_make_internal_id(void)
VALUE rb_str_new(const char *, long)