#pragma once #include //Unless specified otherwise, functions return -1 on error or socket closure. //If *bufsz==0 || *buf==NULL, allocates buf newly. //Returns line length; reallocates buf if needed. i64 tcp_read_line(int sock,char **buf,i64 *bufsz); i64 tcp_read_data(int sock,char *buf,i64 length); i64 tcp_send_data(int sock,const char *buf,i64 length); i64 tcp_send_str(int sock,const char *str); i64 tcp_send_line(int sock,const char *str); i64 tcp_send_line_f(int sock,const char *format,...) __attribute__((format (printf,2,3))); i64 tcp_send_list(int sock,const char *tag,const char *const *list,i64 len); i64 tcp_send_int(int sock,const char *tag,i64 value); i64 tcp_read_ok(int sock,const char *tag); typedef struct TcpList{ i64 nitems; char **items; } TcpList; //Returns NULL on error instead of -1. TcpList* tcp_read_list(int sock,const char *tag); void tcp_list_destroy(TcpList *list); typedef enum TcpResponseType{ TCP_OK, //- TCP_LIST, //lval TCP_INT, //ival TCP_ERROR, //eval TCP_PUSH_JOIN, //jval TCP_PUSH_LEAVE, //jval TCP_PUSH_MESSAGE, //mval } TcpResponseType; typedef struct TcpResponse{ TcpResponseType type; union { TcpList *lval; i64 ival; char *eval; struct { char *gameid,*roomid; i64 id; } jval; struct { char *gameid,*roomid; i64 id; char *message; } mval; }; } TcpResponse; //Returns NULL on error instead of -1. TcpResponse* tcp_read_response(int sock,const char *tag); void tcp_response_destroy(TcpResponse *res); //Returns the socket. int tcp_connect(const char *hostname,int port);