Method: Addrinfo#marshal_load
- Defined in:
- raddrinfo.c
#marshal_load(ary) ⇒ Object
:nodoc:
2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 |
# File 'raddrinfo.c', line 2068
static VALUE
addrinfo_mload(VALUE self, VALUE ary)
{
VALUE v;
VALUE canonname, inspectname;
int afamily, pfamily, socktype, protocol;
union_sockaddr ss;
socklen_t len;
rb_addrinfo_t *rai;
if (check_addrinfo(self))
rb_raise(rb_eTypeError, "already initialized socket address");
ary = rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
v = rb_ary_entry(ary, 0);
StringValue(v);
if (rsock_family_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &afamily) == -1)
rb_raise(rb_eTypeError, "unexpected address family");
v = rb_ary_entry(ary, 2);
StringValue(v);
if (rsock_family_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &pfamily) == -1)
rb_raise(rb_eTypeError, "unexpected protocol family");
v = rb_ary_entry(ary, 3);
if (v == INT2FIX(0))
socktype = 0;
else {
StringValue(v);
if (rsock_socktype_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &socktype) == -1)
rb_raise(rb_eTypeError, "unexpected socktype");
}
v = rb_ary_entry(ary, 4);
if (v == INT2FIX(0))
protocol = 0;
else {
StringValue(v);
if (IS_IP_FAMILY(afamily)) {
if (rsock_ipproto_to_int(RSTRING_PTR(v), RSTRING_LEN(v), &protocol) == -1)
rb_raise(rb_eTypeError, "unexpected protocol");
}
else {
rb_raise(rb_eTypeError, "unexpected protocol");
}
}
v = rb_ary_entry(ary, 5);
if (NIL_P(v))
canonname = Qnil;
else {
StringValue(v);
canonname = v;
}
v = rb_ary_entry(ary, 6);
if (NIL_P(v))
inspectname = Qnil;
else {
StringValue(v);
inspectname = v;
}
v = rb_ary_entry(ary, 1);
switch(afamily) {
#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN
case AF_UNIX:
{
struct sockaddr_un uaddr;
INIT_SOCKADDR_UN(&uaddr, sizeof(struct sockaddr_un));
StringValue(v);
if (sizeof(uaddr.sun_path) < (size_t)RSTRING_LEN(v))
rb_raise(rb_eSocket,
"too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)",
(size_t)RSTRING_LEN(v), sizeof(uaddr.sun_path));
memcpy(uaddr.sun_path, RSTRING_PTR(v), RSTRING_LEN(v));
len = (socklen_t)sizeof(uaddr);
memcpy(&ss, &uaddr, len);
break;
}
#endif
default:
{
VALUE pair = rb_convert_type(v, T_ARRAY, "Array", "to_ary");
struct rb_addrinfo *res;
int flags = AI_NUMERICHOST;
#ifdef AI_NUMERICSERV
flags |= AI_NUMERICSERV;
#endif
res = call_getaddrinfo(rb_ary_entry(pair, 0), rb_ary_entry(pair, 1),
INT2NUM(pfamily), INT2NUM(socktype), INT2NUM(protocol),
INT2NUM(flags), 1, Qnil);
len = res->ai->ai_addrlen;
memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen);
rb_freeaddrinfo(res);
break;
}
}
DATA_PTR(self) = rai = alloc_addrinfo();
init_addrinfo(rai, &ss.addr, len,
pfamily, socktype, protocol,
canonname, inspectname);
return self;
}
|