/*=========================================================================*\ * Unix domain socket dgram submodule * LuaSocket toolkit \*=========================================================================*/ #include "luasocket.h" #include "auxiliar.h" #include "socket.h" #include "options.h" #include "unix.h" #include #include #include #define UNIXDGRAM_DATAGRAMSIZE 8192 // provide a SUN_LEN macro if sys/un.h doesn't (e.g. Android) #ifndef SUN_LEN #define SUN_LEN(ptr) \ ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + strlen ((ptr)->sun_path)) #endif /*=========================================================================*\ * Internal function prototypes \*=========================================================================*/ static int global_create(lua_State *L); static int meth_connect(lua_State *L); static int meth_bind(lua_State *L); static int meth_send(lua_State *L); static int meth_receive(lua_State *L); static int meth_close(lua_State *L); static int meth_setoption(lua_State *L); static int meth_settimeout(lua_State *L); static int meth_gettimeout(lua_State *L); static int meth_getfd(lua_State *L); static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); static int meth_receivefrom(lua_State *L); static int meth_sendto(lua_State *L); static int meth_getsockname(lua_State *L); static const char *unixdgram_tryconnect(p_unix un, const char *path); static const char *unixdgram_trybind(p_unix un, const char *path); /* unixdgram object methods */ static luaL_Reg unixdgram_methods[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"bind", meth_bind}, {"close", meth_close}, {"connect", meth_connect}, {"dirty", meth_dirty}, {"getfd", meth_getfd}, {"send", meth_send}, {"sendto", meth_sendto}, {"receive", meth_receive}, {"receivefrom", meth_receivefrom}, {"setfd", meth_setfd}, {"setoption", meth_setoption}, {"setpeername", meth_connect}, {"setsockname", meth_bind}, {"getsockname", meth_getsockname}, {"settimeout", meth_settimeout}, {"gettimeout", meth_gettimeout}, {NULL, NULL} }; /* socket option handlers */ static t_opt optset[] = { {"reuseaddr", opt_set_reuseaddr}, {NULL, NULL} }; /* functions in library namespace */ static luaL_Reg func[] = { {"dgram", global_create}, {NULL, NULL} }; /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ int unixdgram_open(lua_State *L) { /* create classes */ auxiliar_newclass(L, "unixdgram{connected}", unixdgram_methods); auxiliar_newclass(L, "unixdgram{unconnected}", unixdgram_methods); /* create class groups */ auxiliar_add2group(L, "unixdgram{connected}", "unixdgram{any}"); auxiliar_add2group(L, "unixdgram{unconnected}", "unixdgram{any}"); auxiliar_add2group(L, "unixdgram{connected}", "select{able}"); auxiliar_add2group(L, "unixdgram{unconnected}", "select{able}"); luaL_setfuncs(L, func, 0); return 0; } /*=========================================================================*\ * Lua methods \*=========================================================================*/ static const char *unixdgram_strerror(int err) { /* a 'closed' error on an unconnected means the target address was not * accepted by the transport layer */ if (err == IO_CLOSED) return "refused"; else return socket_strerror(err); } static int meth_send(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{connected}", 1); p_timeout tm = &un->tm; size_t count, sent = 0; int err; const char *data = luaL_checklstring(L, 2, &count); timeout_markstart(tm); err = socket_send(&un->sock, data, count, &sent, tm); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, unixdgram_strerror(err)); return 2; } lua_pushnumber(L, (lua_Number) sent); return 1; } /*-------------------------------------------------------------------------*\ * Send data through unconnected unixdgram socket \*-------------------------------------------------------------------------*/ static int meth_sendto(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1); size_t count, sent = 0; const char *data = luaL_checklstring(L, 2, &count); const char *path = luaL_checkstring(L, 3); p_timeout tm = &un->tm; int err; struct sockaddr_un remote; size_t len = strlen(path); if (len >= sizeof(remote.sun_path)) { lua_pushnil(L); lua_pushstring(L, "path too long"); return 2; } memset(&remote, 0, sizeof(remote)); strcpy(remote.sun_path, path); remote.sun_family = AF_UNIX; timeout_markstart(tm); #ifdef UNIX_HAS_SUN_LEN remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + len + 1; err = socket_sendto(&un->sock, data, count, &sent, (SA *) &remote, remote.sun_len, tm); #else err = socket_sendto(&un->sock, data, count, &sent, (S
#import "/template.typ": *
#show: A => apply(A)
#set raw(lang: "java-new")
#set par(leading: 0.7em)

#assignment(8, pad: true)[
  Write a program to find a number from an array of number objects.
]

#scos("FindNumberInArray")

#v(1em)

=== Discussion

#skind[Classes, interfaces and methods used from Java standard library]

- `java.util.Scanner` class:
  - `int nextInt()`: Scan an `int` value from the input stream.
  - `double nextDouble()`: Scan a `double` value from the input stream.
- `java.util.InputMismatchException` is thrown by the methods of `Scanner` class when encountering invalid input.

#skind[Classes and methods implemented in the program]

- The `Number` class objects represent a `double` value and provide methods for equality comparison.
  - Constructor `Number(double)`: Create a number object for the provided value.
  - `double valueOf()`: Returns the underlying number.
  - `boolean equals(Object)`: Compares the equality of the number with another object.
- The `NumberArray` class manages an array of `Number` objects.
  - Constructor `NumberArray(double[])`: Create a `NumberArray` object from an array of `double` values.
  - `int find(Number)`: Find the position of a given `Number` in the array, or return -1 if not found.
  - `void display()`: Display the elements of the array.
- The `FindNumberInArray` class contains the main program for finding a number in an array:
  - `public static void main(String[])`: Takes user input for the length and elements of an array, creates a `NumberArray`, and finds a specified number in the array.
  
#signature()
=======*\ * Library functions \*=========================================================================*/ /*-------------------------------------------------------------------------*\ * Creates a master unixdgram object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { t_socket sock; int err = socket_create(&sock, AF_UNIX, SOCK_DGRAM, 0); /* try to allocate a system socket */ if (err == IO_DONE) { /* allocate unixdgram object */ p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); /* set its type as master object */ auxiliar_setclass(L, "unixdgram{unconnected}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); un->sock = sock; io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &un->sock); timeout_init(&un->tm, -1, -1); buffer_init(&un->buf, &un->io, &un->tm); return 1; } else { lua_pushnil(L); lua_pushstring(L, socket_strerror(err)); return 2; } }