Skip to content

Commit dff97a3

Browse files
authored
Implemented mocked roDataGramSocket and extracted common interfaces into ifSocket (#466)
1 parent 44e7a09 commit dff97a3

File tree

3 files changed

+935
-417
lines changed

3 files changed

+935
-417
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
import {
2+
Callable,
3+
ValueKind,
4+
StdlibArgument,
5+
BrsBoolean,
6+
BrsType,
7+
BrsComponent,
8+
BrsValue,
9+
Int32,
10+
RoSocketAddress,
11+
BrsInvalid,
12+
} from "..";
13+
import { Interpreter } from "../../interpreter";
14+
import {
15+
BrsSocket,
16+
IfSocket,
17+
IfSocketAsync,
18+
IfSocketOption,
19+
IfSocketStatus,
20+
} from "../interfaces/IfSocket";
21+
import { IfGetMessagePort, IfSetMessagePort } from "../interfaces/IfMessagePort";
22+
import * as net from "net";
23+
24+
export class RoDataGramSocket extends BrsComponent implements BrsValue, BrsSocket {
25+
readonly kind = ValueKind.Object;
26+
readonly socket?: net.Socket;
27+
readonly identity: number;
28+
private readonly interpreter: Interpreter;
29+
private broadcast: boolean;
30+
private multicastLoop: boolean;
31+
private multicastTTL: number;
32+
address?: RoSocketAddress;
33+
sendToAddress?: RoSocketAddress;
34+
ttl: number;
35+
reuseAddr: boolean;
36+
inline: boolean;
37+
sendBufferSize: number;
38+
recvBufferSize: number;
39+
sendTimeout: number;
40+
recvTimeout: number;
41+
errorCode: number;
42+
43+
constructor(interpreter: Interpreter) {
44+
super("roDataGramSocket");
45+
this.interpreter = interpreter;
46+
this.errorCode = 0;
47+
this.broadcast = false;
48+
this.multicastLoop = false;
49+
this.multicastTTL = 0;
50+
this.ttl = 0;
51+
this.reuseAddr = false;
52+
this.inline = false;
53+
this.sendBufferSize = 0;
54+
this.recvBufferSize = 0;
55+
this.sendTimeout = 0;
56+
this.recvTimeout = 0;
57+
try {
58+
this.socket = new net.Socket();
59+
} catch (err: any) {
60+
interpreter.stderr.write(
61+
`warning,[roDataGramSocket] Sockets are not supported in this environment.`
62+
);
63+
this.errorCode = 3474;
64+
}
65+
this.identity = generateUniqueId();
66+
const ifSocket = new IfSocket(this);
67+
const ifSocketAsync = new IfSocketAsync(this);
68+
const ifSocketStatus = new IfSocketStatus(this);
69+
const ifSocketOption = new IfSocketOption(this);
70+
const setPortIface = new IfSetMessagePort(this);
71+
const getPortIface = new IfGetMessagePort(this);
72+
this.registerMethods({
73+
ifSocketCastOption: [
74+
this.getBroadcast,
75+
this.setBroadcast,
76+
this.joinGroup,
77+
this.dropGroup,
78+
this.getMulticastLoop,
79+
this.setMulticastLoop,
80+
this.getMulticastTTL,
81+
this.setMulticastTTL,
82+
],
83+
ifSocket: [
84+
ifSocket.send,
85+
ifSocket.sendStr,
86+
ifSocket.receive,
87+
ifSocket.receiveStr,
88+
ifSocket.close,
89+
ifSocket.setAddress,
90+
ifSocket.getAddress,
91+
ifSocket.setSendToAddress,
92+
ifSocket.getSendToAddress,
93+
ifSocket.getReceivedFromAddress,
94+
ifSocket.getCountRcvBuf,
95+
ifSocket.getCountSendBuf,
96+
ifSocket.status,
97+
],
98+
ifSocketAsync: [
99+
ifSocketAsync.isReadable,
100+
ifSocketAsync.isWritable,
101+
ifSocketAsync.isException,
102+
ifSocketAsync.notifyReadable,
103+
ifSocketAsync.notifyWritable,
104+
ifSocketAsync.notifyException,
105+
ifSocketAsync.getID,
106+
],
107+
ifSocketStatus: [
108+
ifSocketStatus.eAgain,
109+
ifSocketStatus.eAlready,
110+
ifSocketStatus.eBadAddr,
111+
ifSocketStatus.eDestAddrReq,
112+
ifSocketStatus.eHostUnreach,
113+
ifSocketStatus.eInvalid,
114+
ifSocketStatus.eInProgress,
115+
ifSocketStatus.eWouldBlock,
116+
ifSocketStatus.eSuccess,
117+
ifSocketStatus.eOK,
118+
],
119+
ifSocketOption: [
120+
ifSocketOption.getTTL,
121+
ifSocketOption.setTTL,
122+
ifSocketOption.getReuseAddr,
123+
ifSocketOption.setReuseAddr,
124+
ifSocketOption.getOOBInline,
125+
ifSocketOption.setOOBInline,
126+
ifSocketOption.getSendBuf,
127+
ifSocketOption.setSendBuf,
128+
ifSocketOption.getRcvBuf,
129+
ifSocketOption.setRcvBuf,
130+
ifSocketOption.getSendTimeout,
131+
ifSocketOption.setSendTimeout,
132+
ifSocketOption.getReceiveTimeout,
133+
ifSocketOption.setReceiveTimeout,
134+
],
135+
ifSetMessagePort: [setPortIface.setMessagePort],
136+
ifGetMessagePort: [getPortIface.getMessagePort],
137+
});
138+
}
139+
140+
toString(parent?: BrsType): string {
141+
return "<Component: roDataGramSocket>";
142+
}
143+
144+
equalTo(other: BrsType): BrsBoolean {
145+
return BrsBoolean.False;
146+
}
147+
148+
/** Checks whether broadcast messages may be sent or received. */
149+
private readonly getBroadcast = new Callable("getBroadcast", {
150+
signature: { args: [], returns: ValueKind.Boolean },
151+
impl: (_: Interpreter) => {
152+
return BrsBoolean.from(this.broadcast);
153+
},
154+
});
155+
156+
/** Enables broadcast messages to be sent or received. */
157+
private readonly setBroadcast = new Callable("setBroadcast", {
158+
signature: {
159+
args: [new StdlibArgument("enable", ValueKind.Boolean)],
160+
returns: ValueKind.Boolean,
161+
},
162+
impl: (_: Interpreter, enable: BrsBoolean) => {
163+
this.broadcast = enable.toBoolean();
164+
return BrsBoolean.True;
165+
},
166+
});
167+
168+
/** Joins a specific multicast group. */
169+
private readonly joinGroup = new Callable("joinGroup", {
170+
signature: {
171+
args: [new StdlibArgument("ipAddress", ValueKind.Object)],
172+
returns: ValueKind.Boolean,
173+
},
174+
impl: (_: Interpreter, ipAddress: RoSocketAddress) => {
175+
this.address = ipAddress;
176+
return BrsBoolean.True;
177+
},
178+
});
179+
180+
/** Drops out of a specific multicast group. */
181+
private readonly dropGroup = new Callable("dropGroup", {
182+
signature: {
183+
args: [new StdlibArgument("ipAddress", ValueKind.Object)],
184+
returns: ValueKind.Object,
185+
},
186+
impl: (_: Interpreter, ipAddress: RoSocketAddress) => {
187+
// Implementation of dropGroup method
188+
return BrsInvalid.Instance;
189+
},
190+
});
191+
192+
/** Checks whether multicast messages are enabled for local loopback. */
193+
private readonly getMulticastLoop = new Callable("getMulticastLoop", {
194+
signature: {
195+
args: [],
196+
returns: ValueKind.Boolean,
197+
},
198+
impl: (_: Interpreter) => {
199+
return BrsBoolean.from(this.multicastLoop);
200+
},
201+
});
202+
203+
/** Enables local loopback of multicast messages. */
204+
private readonly setMulticastLoop = new Callable("setMulticastLoop", {
205+
signature: {
206+
args: [new StdlibArgument("enable", ValueKind.Boolean)],
207+
returns: ValueKind.Boolean,
208+
},
209+
impl: (_: Interpreter, enable: BrsBoolean) => {
210+
this.multicastLoop = enable.toBoolean();
211+
return BrsBoolean.True;
212+
},
213+
});
214+
215+
/** Returns the TTL integer value for multicast messages. */
216+
private readonly getMulticastTTL = new Callable("getMulticastTTL", {
217+
signature: {
218+
args: [],
219+
returns: ValueKind.Int32,
220+
},
221+
impl: (_: Interpreter) => {
222+
return new Int32(this.multicastTTL);
223+
},
224+
});
225+
226+
/** Enables local loopback of multicast messages. */
227+
private readonly setMulticastTTL = new Callable("setMulticastTTL", {
228+
signature: {
229+
args: [new StdlibArgument("ttl", ValueKind.Int32)],
230+
returns: ValueKind.Boolean,
231+
},
232+
impl: (_: Interpreter, ttl: Int32) => {
233+
this.multicastTTL = ttl.getValue();
234+
return BrsBoolean.True;
235+
},
236+
});
237+
}
238+
239+
function generateUniqueId(): number {
240+
const min = 10000000;
241+
const max = 99999999;
242+
return Math.floor(Math.random() * (max - min + 1)) + min;
243+
}

0 commit comments

Comments
 (0)