forked from jruby/jruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOption.java
More file actions
211 lines (176 loc) · 6.38 KB
/
Copy pathOption.java
File metadata and controls
211 lines (176 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package org.jruby.ext.socket;
import jnr.constants.platform.Errno;
import jnr.constants.platform.ProtocolFamily;
import jnr.constants.platform.Sock;
import jnr.constants.platform.SocketLevel;
import jnr.constants.platform.SocketOption;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyObject;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.Pack;
import org.jruby.util.Sprintf;
import java.nio.ByteBuffer;
import java.text.NumberFormat;
import java.util.Locale;
public class Option extends RubyObject {
public static void createOption(Ruby runtime) {
RubyClass addrinfo = runtime.getClass("Socket").defineClassUnder(
"Option",
runtime.getObject(),
new ObjectAllocator() {
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new Option(runtime, klazz);
}
});
addrinfo.defineAnnotatedMethods(Option.class);
}
public Option(Ruby runtime, RubyClass klass) {
super(runtime, klass);
}
public Option(Ruby runtime, ProtocolFamily family, SocketLevel level, SocketOption option, int data) {
this(runtime, (RubyClass)runtime.getClassFromPath("Socket::Option"), family, level, option, data);
}
public Option(Ruby runtime, RubyClass klass, ProtocolFamily family, SocketLevel level, SocketOption option, int data) {
super(runtime, klass);
this.family = family;
this.level = level;
this.option = option;
this.intData = data;
ByteList result = new ByteList(4);
this.data = Pack.packInt_i(result, data);
}
@JRubyMethod(required = 4)
public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
family = ProtocolFamily.valueOf(args[0].convertToInteger().getLongValue());
level = SocketLevel.valueOf(args[1].convertToInteger().getLongValue());
option = SocketOption.valueOf(args[2].convertToInteger().getLongValue());
data = args[3].convertToString().getByteList();
intData = Pack.unpackInt_i(ByteBuffer.wrap(data.bytes()));
return context.nil;
}
@JRubyMethod
public IRubyObject family(ThreadContext context) {
return context.runtime.newFixnum(family.longValue());
}
@JRubyMethod
public IRubyObject level(ThreadContext context) {
return context.runtime.newFixnum(level.longValue());
}
@JRubyMethod
public IRubyObject optname(ThreadContext context) {
return context.runtime.newFixnum(option.longValue());
}
@JRubyMethod
public IRubyObject data(ThreadContext context) {
return RubyString.newString(context.runtime, data).freeze(context);
}
// rb_sockopt_inspect
@JRubyMethod
public IRubyObject inspect(ThreadContext context) {
StringBuffer buf = new StringBuffer("#<");
buf
.append(metaClass.getRealClass().getName())
.append(" ")
.append(noPrefix(family));
if (level == SocketLevel.SOL_SOCKET) {
buf
.append(" SOCKET ")
.append(noPrefix(option));
} else if (family == ProtocolFamily.PF_UNIX) {
buf
.append(" level:")
.append(level.longValue())
.append(" ")
.append(noPrefix(option));
} else {
buf
.append(" level:")
.append(level.description())
.append(" ")
.append(noPrefix(option));
}
buf
.append(" ")
.append(optionValue())
.append(">");
return context.runtime.newString(buf.toString());
}
private String noPrefix(ProtocolFamily family) {
return family.description().substring("PF_".length());
}
private String noPrefix(SocketOption option) {
return option.description().substring("SO_".length());
}
// from rb_sockopt_inspect
private String optionValue() {
switch (option) {
case SO_DEBUG:
case SO_ACCEPTCONN:
case SO_BROADCAST:
case SO_REUSEADDR:
case SO_KEEPALIVE:
case SO_OOBINLINE:
case SO_SNDBUF:
case SO_RCVBUF:
case SO_DONTROUTE:
case SO_RCVLOWAT:
case SO_SNDLOWAT:
return String.valueOf(intData);
case SO_LINGER:
return intData == -1 ? "off" :
intData == 0 ? "on" :
"on(" + intData + ")";
case SO_RCVTIMEO:
case SO_SNDTIMEO:
return Sprintf.getNumberFormat(Locale.getDefault()).format(intData / 1000.0);
case SO_ERROR:
return Errno.valueOf(intData).description();
case SO_TYPE:
return Sock.valueOf(intData).description();
}
return "";
}
@JRubyMethod(meta = true)
public IRubyObject rb_int(ThreadContext context, IRubyObject self) {
return context.nil;
}
@JRubyMethod
public IRubyObject rb_int(ThreadContext context) {
return context.nil;
}
@JRubyMethod(meta = true)
public IRubyObject bool(ThreadContext context, IRubyObject self) {
return context.nil;
}
@JRubyMethod
public IRubyObject bool(ThreadContext context) {
return context.nil;
}
@JRubyMethod(meta = true)
public IRubyObject linger(ThreadContext context, IRubyObject self) {
return context.nil;
}
@JRubyMethod
public IRubyObject linger(ThreadContext context) {
return context.nil;
}
@JRubyMethod
public IRubyObject unpack(ThreadContext context, IRubyObject arg0) {
return Pack.unpack(context.runtime, data, arg0.convertToString().getByteList());
}
@JRubyMethod
public IRubyObject to_s(ThreadContext context) {
return RubyString.newString(context.runtime, data);
}
private ProtocolFamily family;
private SocketLevel level;
private SocketOption option;
private ByteList data;
private long intData;
}