| 106 | }; |
| 107 | |
| 108 | void xs_tcp_constructor(xsMachine *the) |
| 109 | { |
| 110 | TCP tcp = C_NULL; |
| 111 | uint8_t create = xsmcArgc > 0; |
| 112 | uint8_t connect = 0, triggerable = 0, triggered = 0, nodelay = 0, format = kIOFormatBuffer; |
| 113 | xsSlot *onReadable, *onWritable, *onError; |
| 114 | struct net_context *context = C_NULL;; |
| 115 | struct sockaddr_in remote; |
| 116 | int result; |
| 117 | |
| 118 | xsmcVars(1); |
| 119 | |
| 120 | if (create) { |
| 121 | format = builtinInitializeFormat(the, format); |
| 122 | if ((kIOFormatNumber != format) && (kIOFormatBuffer != format)) |
| 123 | xsRangeError("unimplemented"); |
| 124 | |
| 125 | onReadable = builtinGetCallback(the, xsID_onReadable); |
| 126 | if (onReadable) |
| 127 | triggerable |= kTCPReadable; |
| 128 | |
| 129 | onWritable = builtinGetCallback(the, xsID_onWritable); |
| 130 | if (onWritable) |
| 131 | triggerable |= kTCPWritable; |
| 132 | |
| 133 | onError = builtinGetCallback(the, xsID_onError); |
| 134 | if (onError) |
| 135 | triggerable |= kTCPError; |
| 136 | |
| 137 | if (xsmcGet(xsVar(0), xsArg(0), xsID_nodelay)) |
| 138 | nodelay = xsmcToBoolean(xsVar(0)) ? 2 : 1; |
| 139 | |
| 140 | if (xsmcGet(xsVar(0), xsArg(0), xsID_from)) { |
| 141 | tcp = xsmcGetHostDataValidate(xsVar(0), (void *)&xsTCPHooks); |
| 142 | context = tcp->context; |
| 143 | if (!context) |
| 144 | xsUnknownError("invalid from"); |
| 145 | |
| 146 | if ((triggerable & kTCPWritable) && (tcp->sendBufferSize > tcp->sendBytesInFlight)) |
| 147 | triggered |= kTCPWritable; |
| 148 | if ((triggerable & kTCPReadable) && tcp->buffers) |
| 149 | triggered |= kTCPReadable; |
| 150 | |
| 151 | xsForget(tcp->obj); |
| 152 | xsmcSetHostData(xsVar(0), NULL); |
| 153 | xsmcSetHostDestructor(xsVar(0), NULL); |
| 154 | } |
| 155 | else { |
| 156 | xsmcGet(xsVar(0), xsArg(0), xsID_port); |
| 157 | int port = builtinGetSignedInteger(the, &xsVar(0)); |
| 158 | if ((port < 0) || (port > 65535)) |
| 159 | xsRangeError("invalid port"); |
| 160 | |
| 161 | xsmcGet(xsVar(0), xsArg(0), xsID_address); |
| 162 | remote.sin_family = AF_INET; |
| 163 | remote.sin_port = htons(port); |
| 164 | if (net_addr_pton(AF_INET, xsmcToString(xsVar(0)), &remote.sin_addr) < 0) |
| 165 | xsRangeError("invalid address"); |
nothing calls this directly
no test coverage detected