| 94 | }; |
| 95 | |
| 96 | void xs_tcp_constructor(xsMachine *the) |
| 97 | { |
| 98 | TCP tcp; |
| 99 | uint8_t create = xsmcArgc > 0; |
| 100 | uint8_t connect = 0, triggerable = 0, triggered = 0, nodelay = 0, format = kIOFormatBuffer, ready = 0; |
| 101 | xsSlot *onReadable, *onWritable, *onError; |
| 102 | int port; |
| 103 | struct tcp_pcb *skt; |
| 104 | TCPBuffer buffers = NULL; |
| 105 | ip_addr_t address; |
| 106 | |
| 107 | xsmcVars(1); |
| 108 | |
| 109 | if (create) { |
| 110 | CHECK_NETWORK_SAFE(); |
| 111 | |
| 112 | builtinInitIO(); |
| 113 | |
| 114 | format = builtinInitializeFormat(the, format); |
| 115 | if ((kIOFormatNumber != format) && (kIOFormatBuffer != format)) |
| 116 | xsRangeError("unimplemented"); |
| 117 | |
| 118 | onReadable = builtinGetCallback(the, xsID_onReadable); |
| 119 | if (onReadable) |
| 120 | triggerable |= kTCPReadable; |
| 121 | |
| 122 | onWritable = builtinGetCallback(the, xsID_onWritable); |
| 123 | if (onWritable) |
| 124 | triggerable |= kTCPWritable; |
| 125 | |
| 126 | onError = builtinGetCallback(the, xsID_onError); |
| 127 | if (onError) |
| 128 | triggerable |= kTCPError; |
| 129 | |
| 130 | if (xsmcGet(xsVar(0), xsArg(0), xsID_nodelay)) |
| 131 | nodelay = xsmcToBoolean(xsVar(0)) ? 2 : 1; |
| 132 | |
| 133 | if (xsmcGet(xsVar(0), xsArg(0), xsID_from)) { |
| 134 | TCP from; |
| 135 | |
| 136 | from = xsmcGetHostDataValidate(xsVar(0), (void *)&xsTCPHooks); |
| 137 | if (!from->skt) |
| 138 | xsUnknownError("invalid from"); |
| 139 | |
| 140 | skt = from->skt; |
| 141 | buffers = from->buffers; |
| 142 | triggered = from->triggered; |
| 143 | ready = from->ready; |
| 144 | if ((triggerable & kTCPWritable) && tcp_sndbuf(skt)) |
| 145 | triggered |= kTCPWritable; |
| 146 | if ((triggerable & kTCPReadable) && buffers) |
| 147 | triggered |= kTCPReadable; |
| 148 | from->skt = NULL; |
| 149 | from->buffers = NULL; |
| 150 | from->triggered = 0; |
| 151 | doClose(the, &xsVar(0)); |
| 152 | } |
| 153 | else { |
nothing calls this directly
no test coverage detected