15 #include <sys/types.h> 27 #ifdef HAVE_TRUE_LONG_LONG 28 static const char natstr[] =
"sSiIlLqQ";
30 static const char natstr[] =
"sSiIlL";
32 static const char endstr[] =
"sSiIlLqQ";
34 #ifdef HAVE_TRUE_LONG_LONG 36 # define NATINT_LEN_Q NATINT_LEN(long long, 8) 38 # define NATINT_LEN_Q 8 41 #if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG != 8) 52 static int endian_value;
55 if (init)
return endian_value;
58 return endian_value = p[0]?0:1;
60 # define BIGENDIAN_P() (is_bigendian()) 61 #elif defined(WORDS_BIGENDIAN) 62 # define BIGENDIAN_P() 1 64 # define BIGENDIAN_P() 0 68 # define NATINT_LEN(type,len) (natint?(int)sizeof(type):(int)(len)) 70 # define NATINT_LEN(type,len) ((int)sizeof(type)) 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) 81 #define define_swapx(x, xtype) \ 83 TOKEN_PASTE(swap,x)(xtype z) \ 87 unsigned char *s, *t; \ 90 zp = xmalloc(sizeof(xtype)); \ 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]; \ 103 #if SIZEOF_SHORT == 2 104 # define swaps(x) swap16(x) 105 #elif SIZEOF_SHORT == 4 106 # define swaps(x) swap32(x) 112 # define swapi(x) swap16(x) 113 #elif SIZEOF_INT == 4 114 # define swapi(x) swap32(x) 120 # define swapl(x) swap32(x) 121 #elif SIZEOF_LONG == 8 122 # define swapl(x) swap64(x) 127 #ifdef HAVE_LONG_LONG 128 # if SIZEOF_LONG_LONG == 8 129 # define swapll(x) swap64(x) 135 #if SIZEOF_FLOAT == 4 && defined(HAVE_INT32_T) 136 # define swapf(x) swap32(x) 137 # define FLOAT_SWAPPER uint32_t 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) 147 swapd(
const double d)
153 utmp[0] = 0; utmp[1] = 0;
154 memcpy(utmp,&dtmp,
sizeof(
double));
156 utmp[0] =
swap32(utmp[1]);
158 memcpy(&dtmp,utmp,
sizeof(
double));
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)) 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)), \ 182 # define HTOVF(x,y) (memcpy(&(y),&(x),sizeof(float)), \ 183 (y) = rb_htovf((FLOAT_SWAPPER)(y)), \ 184 memcpy(&(x),&(y),sizeof(float)), \ 186 # define NTOHF(x,y) (memcpy(&(y),&(x),sizeof(float)), \ 187 (y) = rb_ntohf((FLOAT_SWAPPER)(y)), \ 188 memcpy(&(x),&(y),sizeof(float)), \ 190 # define VTOHF(x,y) (memcpy(&(y),&(x),sizeof(float)), \ 191 (y) = rb_vtohf((FLOAT_SWAPPER)(y)), \ 192 memcpy(&(x),&(y),sizeof(float)), \ 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) 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)), \ 208 # define HTOVD(x,y) (memcpy(&(y),&(x),sizeof(double)), \ 209 (y) = rb_htovd((DOUBLE_SWAPPER)(y)), \ 210 memcpy(&(x),&(y),sizeof(double)), \ 212 # define NTOHD(x,y) (memcpy(&(y),&(x),sizeof(double)), \ 213 (y) = rb_ntohd((DOUBLE_SWAPPER)(y)), \ 214 memcpy(&(x),&(y),sizeof(double)), \ 216 # define VTOHD(x,y) (memcpy(&(y),&(x),sizeof(double)), \ 217 (y) = rb_vtohd((DOUBLE_SWAPPER)(y)), \ 218 memcpy(&(x),&(y),sizeof(double)), \ 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) 228 #define MAX_INTEGER_PACK_SIZE 8 230 static const char toofew[] =
"too few arguments";
235 static unsigned long utf8_to_uv(
const char*,
long*);
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;
355 long items, len, idx, plen;
361 int integer_size, bigendian_p;
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) 376 int explicit_endian = 0;
387 while ((p < pend) && (*p !=
'\n')) {
414 if (explicit_endian) {
417 explicit_endian = *p++;
430 len =
STRTOUL(p, (
char**)&p, 10);
442 if (enc_info == 1) enc_info = 2;
444 case 'm':
case 'M':
case 'u':
453 case 'A':
case 'a':
case 'Z':
477 if (p[-1] ==
'*' &&
type ==
'Z')
491 #define castchar(from) (char)((from) & 0xff) 499 j = (len - plen + 1)/2;
502 for (i=0; i++ < len; ptr++) {
515 byte >>= 7 - (len & 7);
530 j = (len - plen + 1)/2;
533 for (i=0; i++ < len; ptr++) {
545 byte <<= 7 - (len & 7);
560 j = (len + 1) / 2 - (plen + 1) / 2;
563 for (i=0; i++ < len; ptr++) {
565 byte |= (((*ptr & 15) + 9) & 15) << 4;
567 byte |= (*ptr & 15) << 4;
591 j = (len + 1) / 2 - (plen + 1) / 2;
594 for (i=0; i++ < len; ptr++) {
596 byte |= ((*ptr & 15) + 9) & 15;
635 integer_size = (int)
sizeof(
int);
640 integer_size = (int)
sizeof(
int);
685 if (explicit_endian) {
686 bigendian_p = explicit_endian ==
'>';
689 rb_bug(
"unexpected intger size for pack: %d", integer_size);
790 if (len > 0)
goto grow;
792 if (len > 0)
goto shrink;
823 if (len == 0 &&
type ==
'm') {
830 else if (len > 63 &&
type ==
'u')
903 rb_bug(
"buffer size problem?");
906 while (1 < numbytes) {
917 rb_warning(
"unknown pack directive '%c' in '%s'",
942 "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
944 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
949 enum {buff_size = 4096, encoded_unit = 4};
950 char buff[buff_size + 1];
956 buff[i++] = (char)len +
' ';
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]];
971 if (buff_size-i < encoded_unit) {
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))];
984 buff[i++] = trans[077 & (*s >> 2)];
985 buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
989 if (tail_lf) buff[i++] =
'\n';
991 if ((
size_t)i >
sizeof(buff))
rb_bug(
"encodes() buffer overrun");
1000 long i = 0, n = 0, prev =
EOF;
1001 unsigned char *s = (
unsigned char*)
RSTRING_PTR(from);
1006 (*s < 32 && *s !=
'\n' && *s !=
'\t') ||
1014 else if (*s ==
'\n') {
1015 if (prev ==
' ' || prev ==
'\t') {
1059 #define PACK_LENGTH_ADJUST_SIZE(sz) do { \ 1061 if (len > (long)((send-s)/(sz))) { \ 1063 tmp_len = len-(send-s)/(sz); \ 1065 len = (send-s)/(sz); \ 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); \ 1200 static const char hexdigits[] =
"0123456789abcdef";
1211 int signed_p, integer_size, bigendian_p;
1212 #define UNPACK_PUSH(item) do {\ 1213 VALUE item_val = (item);\ 1215 rb_yield(item_val);\ 1218 rb_ary_push(ary, item_val);\ 1231 int explicit_endian = 0;
1239 while ((p < pend) && (*p !=
'\n')) {
1268 if (explicit_endian) {
1271 explicit_endian = *p++;
1278 else if (*p ==
'*') {
1285 len =
STRTOUL(p, (
char**)&p, 10);
1291 len = (
type !=
'@');
1300 if (len > send - s) len = send - s;
1303 char *
t = s + len - 1;
1306 if (*
t !=
' ' && *
t !=
'\0')
break;
1318 if (len > send-s) len = send-s;
1319 while (
t < s+len && *
t)
t++;
1322 s = star ?
t : s+len;
1327 if (len > send - s) len = send - s;
1339 if (p[-1] ==
'*' || len > (send - s) * 8)
1340 len = (send - s) * 8;
1344 for (i=0; i<len; i++) {
1345 if (i & 7) bits >>= 1;
1347 *
t++ = (bits & 1) ?
'1' :
'0';
1359 if (p[-1] ==
'*' || len > (send - s) * 8)
1360 len = (send - s) * 8;
1364 for (i=0; i<len; i++) {
1365 if (i & 7) bits <<= 1;
1367 *
t++ = (bits & 128) ?
'1' :
'0';
1379 if (p[-1] ==
'*' || len > (send - s) * 2)
1380 len = (send - s) * 2;
1384 for (i=0; i<len; i++) {
1389 *
t++ = hexdigits[bits & 15];
1401 if (p[-1] ==
'*' || len > (send - s) * 2)
1402 len = (send - s) * 2;
1406 for (i=0; i<len; i++) {
1411 *
t++ = hexdigits[(bits >> 4) & 15];
1420 goto unpack_integer;
1426 goto unpack_integer;
1432 goto unpack_integer;
1438 goto unpack_integer;
1442 integer_size = (int)
sizeof(
int);
1444 goto unpack_integer;
1448 integer_size = (int)
sizeof(
int);
1450 goto unpack_integer;
1456 goto unpack_integer;
1462 goto unpack_integer;
1468 goto unpack_integer;
1474 goto unpack_integer;
1480 goto unpack_integer;
1486 goto unpack_integer;
1492 goto unpack_integer;
1498 goto unpack_integer;
1501 if (explicit_endian) {
1502 bigendian_p = explicit_endian ==
'>';
1522 memcpy(&tmp, s,
sizeof(
float));
1535 memcpy(&tmp, s,
sizeof(
float));
1537 tmp =
VTOHF(tmp,ftmp);
1549 memcpy(&tmp, s,
sizeof(
double));
1550 s +=
sizeof(double);
1551 tmp =
VTOHD(tmp,dtmp);
1562 memcpy(&tmp, s,
sizeof(
double));
1563 s +=
sizeof(double);
1575 memcpy(&tmp, s,
sizeof(
float));
1577 tmp =
NTOHF(tmp,ftmp);
1589 memcpy(&tmp, s,
sizeof(
double));
1590 s +=
sizeof(double);
1591 tmp =
NTOHD(tmp,dtmp);
1598 if (len > send - s) len = send - s;
1599 while (len > 0 && s < send) {
1600 long alen = send - s;
1615 while (s < send && *s >
' ' && *s <
'a') {
1620 len = (*s++ -
' ') & 077;
1628 long mlen = len > 3 ? 3 : len;
1630 if (s < send && *s >=
' ')
1631 a = (*s++ -
' ') & 077;
1634 if (s < send && *s >=
' ')
1635 b = (*s++ -
' ') & 077;
1638 if (s < send && *s >=
' ')
1639 c = (*s++ -
' ') & 077;
1642 if (s < send && *s >=
' ')
1643 d = (*s++ -
' ') & 077;
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);
1653 if (*s ==
'\r') s++;
1654 if (*s ==
'\n') s++;
1655 else if (s < send && (s+1 == send || s[1] ==
'\n'))
1668 int a = -1,b = -1,c = 0,d = 0;
1669 static signed char b64_xtable[256];
1671 if (b64_xtable[
'/'] <= 0) {
1674 for (i = 0; i < 256; i++) {
1677 for (i = 0; i < 64; i++) {
1678 b64_xtable[(
unsigned char)
b64_table[i]] = (
char)i;
1684 a = b64_xtable[(
unsigned char)*s++];
1686 b = b64_xtable[(
unsigned char)*s++];
1689 if (s + 2 == send && *(s + 1) ==
'=')
break;
1692 c = b64_xtable[(
unsigned char)*s++];
1694 if (s + 1 == send && *s ==
'=')
break;
1695 d = b64_xtable[(
unsigned char)*s++];
1697 *ptr++ =
castchar(a << 2 | b >> 4);
1698 *ptr++ =
castchar(b << 4 | c >> 2);
1702 *ptr++ =
castchar(a << 2 | b >> 4);
1706 *ptr++ =
castchar(a << 2 | b >> 4);
1707 *ptr++ =
castchar(b << 4 | c >> 2);
1714 while ((a = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1715 if (s >= send)
break;
1717 while ((b = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {s++;}
1718 if (s >= send)
break;
1720 while ((c = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1721 if (*s ==
'=' || s >= send)
break;
1723 while ((d = b64_xtable[(
unsigned char)*s]) == -1 && s < send) {
if (*s ==
'=')
break; s++;}
1724 if (*s ==
'=' || s >= send)
break;
1726 *ptr++ =
castchar(a << 2 | b >> 4);
1727 *ptr++ =
castchar(b << 4 | c >> 2);
1731 if (a != -1 && b != -1) {
1733 *ptr++ =
castchar(a << 2 | b >> 4);
1735 *ptr++ =
castchar(a << 2 | b >> 4);
1736 *ptr++ =
castchar(b << 4 | c >> 2);
1753 if (++s == send)
break;
1754 if (s+1 < send && *s ==
'\r' && *(s+1) ==
'\n')
1757 if ((c1 =
hex2num(*s)) == -1)
break;
1758 if (++s == send)
break;
1759 if ((c2 =
hex2num(*s)) == -1)
break;
1795 if (
sizeof(
char *) <= (
size_t)(send - s)) {
1799 memcpy(&
t, s,
sizeof(
char *));
1800 s +=
sizeof(
char *);
1804 const VALUE *p, *pend;
1833 if (len > (
long)((send - s) /
sizeof(
char *)))
1834 len = (send - s) /
sizeof(
char *);
1836 if ((
size_t)(send - s) <
sizeof(
char *))
1842 memcpy(&
t, s,
sizeof(
char *));
1843 s +=
sizeof(
char *);
1847 const VALUE *p, *pend;
1873 while (len > 0 && s < send) {
1888 rb_warning(
"unknown unpack directive '%c' in '%s'",
1917 if (uv <= 0x1fffff) {
1924 if (uv <= 0x3ffffff) {
1932 if (uv <= 0x7fffffff) {
1956 static unsigned long 1959 int c = *p++ & 0xff;
1960 unsigned long uv = c;
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; }
1989 if ((c & 0xc0) != 0x80) {
RUBY_EXTERN VALUE rb_cString
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)
#define NATINT_LEN(type, len)
#define PACK_ITEM_ADJUST()
VALUE rb_ary_push(VALUE ary, VALUE item)
void rb_str_set_len(VALUE, long)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_str_associated(VALUE)
static const char uu_table[]
#define rb_utf8_encindex()
#define DOUBLE_CONVWITH(y)
#define INTEGER_PACK_2COMP
static const char natstr[]
#define ENC_CODERANGE_7BIT
VALUE rb_str_buf_cat(VALUE, const char *, long)
static VALUE pack_unpack(VALUE str, VALUE fmt)
#define RB_TYPE_P(obj, type)
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)
#define STRTOUL(str, endptr, base)
#define define_swapx(x, xtype)
void rb_enc_set_index(VALUE obj, int idx)
void rb_str_associate(VALUE, VALUE)
#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)
unsigned char buf[MIME_BUF_SIZE]
const signed char ruby_digit36_to_number_table[]
static int hex2num(char c)
static void qpencode(VALUE str, VALUE from, long len)
char * strchr(char *, char)
#define rb_usascii_encindex()
#define INTEGER_PACK_LITTLE_ENDIAN
#define INTEGER_PACK_BIG_ENDIAN
#define FLOAT_CONVWITH(y)
static const unsigned long utf8_limits[]
static const char endstr[]
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,...)
static unsigned long utf8_to_uv(const char *p, long *lenp)
VALUE rb_tainted_str_new(const char *, long)
static void encodes(VALUE str, const char *s, long len, int type, int tail_lf)
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)
#define rb_ascii8bit_encindex()
#define UNPACK_PUSH(item)
VALUE rb_str_new(const char *, long)