terom@1: terom@1: #include "sock_internal.h" terom@2: #include "sock_gnutls.h" terom@2: terom@3: #include terom@3: terom@9: // global sock_stream_ctx instance terom@9: struct sock_stream_ctx _sock_stream_ctx; terom@9: terom@9: err_t sock_init (struct event_base *ev_base, struct error_info *err) terom@2: { terom@9: // store ev_base terom@9: _sock_stream_ctx.ev_base = ev_base; terom@9: terom@4: // XXX: just call these all directly for now terom@5: if (sock_gnutls_global_init(err)) terom@4: return ERROR_CODE(err); terom@3: terom@4: // done terom@4: return SUCCESS; terom@2: } terom@1: terom@139: void sock_stream_init (struct sock_stream *sock, struct sock_stream_type *type, sock_stream_connect_cb cb_func, void *cb_arg) terom@3: { terom@3: // be strict terom@3: assert(sock->type == NULL); terom@3: terom@139: // store terom@3: sock->type = type; terom@139: sock->conn_cb_func = cb_func; terom@139: sock->conn_cb_arg = cb_arg; terom@3: } terom@3: terom@10: int sock_stream_read (struct sock_stream *sock, void *buf, size_t len) terom@10: { terom@118: struct error_info *err = SOCK_ERR(sock); terom@118: terom@118: // XXX: not readable terom@118: if (!sock->type->methods.read) terom@118: return -1; terom@10: terom@10: // proxy off to method handler terom@118: if (sock->type->methods.read(sock, buf, &len, err)) terom@118: return -ERROR_CODE(err); terom@10: terom@10: // return updated bytes-read len terom@10: return len; terom@10: } terom@10: terom@10: int sock_stream_write (struct sock_stream *sock, const void *buf, size_t len) terom@10: { terom@118: struct error_info *err = SOCK_ERR(sock); terom@118: terom@118: // XXX: not writeable terom@118: if (!sock->type->methods.write) terom@118: return -1; terom@10: terom@10: // proxy off to method handler terom@118: if (sock->type->methods.write(sock, buf, &len, err)) terom@118: return -ERROR_CODE(err); terom@10: terom@10: // return updated bytes-written len terom@10: return len; terom@10: } terom@10: terom@10: err_t sock_stream_event_init (struct sock_stream *sock, const struct sock_stream_callbacks *callbacks, void *arg) terom@9: { terom@9: // store terom@9: sock->cb_info = callbacks; terom@9: sock->cb_arg = arg; terom@10: terom@10: // run method terom@10: return sock->type->methods.event_init(sock); terom@9: } terom@9: terom@10: err_t sock_stream_event_enable (struct sock_stream *sock, short mask) terom@1: { terom@10: // run method terom@10: return sock->type->methods.event_enable(sock, mask); terom@1: } terom@1: terom@8: const struct error_info* sock_stream_error (struct sock_stream *sock) terom@3: { terom@8: // return pointer terom@8: return SOCK_ERR(sock); terom@3: } terom@12: terom@12: void sock_stream_invoke_callbacks (struct sock_stream *sock, short what) terom@12: { terom@12: if (what & EV_READ && sock->cb_info->on_read) terom@12: sock->cb_info->on_read(sock, sock->cb_arg); terom@12: terom@12: if (what & EV_WRITE && sock->cb_info->on_write) terom@12: sock->cb_info->on_read(sock, sock->cb_arg); terom@12: } terom@28: terom@139: void sock_stream_invoke_conn_cb (struct sock_stream *sock, struct error_info *err, bool direct) terom@139: { terom@139: if (!direct && sock->type->methods._conn_cb) { terom@139: // invoke indirectly terom@139: sock->type->methods._conn_cb(sock, err); terom@139: terom@139: } else { terom@139: sock_stream_connect_cb cb_func = sock->conn_cb_func; terom@139: terom@139: // invoke directly terom@139: sock->conn_cb_func = NULL; terom@139: cb_func(sock, err, sock->conn_cb_arg); terom@139: sock->conn_cb_arg = NULL; terom@139: } terom@139: } terom@139: terom@28: void sock_stream_release (struct sock_stream *sock) terom@28: { terom@28: sock->type->methods.release(sock); terom@28: } terom@28: