/** * Try to read message from transport into msg. * * @returns TRUE if message is fully read. */ bool xmms_ipc_msg_read_transport (xmms_ipc_msg_t *msg, xmms_ipc_transport_t *transport, bool *disconnected) { char buf[512]; unsigned int ret, len, rlen; x_return_val_if_fail (msg, false); x_return_val_if_fail (transport, false); while (true) { len = XMMS_IPC_MSG_HEAD_LEN; if (msg->xfered >= XMMS_IPC_MSG_HEAD_LEN) { len += xmms_ipc_msg_get_length (msg); if (msg->xfered == len) { return true; } } x_return_val_if_fail (msg->xfered < len, false); rlen = len - msg->xfered; if (rlen > sizeof (buf)) rlen = sizeof (buf); ret = xmms_ipc_transport_read (transport, buf, rlen); if (ret == SOCKET_ERROR) { if (xmms_socket_error_recoverable ()) { return false; } if (disconnected) { *disconnected = true; } return false; } else if (ret == 0) { if (disconnected) { *disconnected = true; } return false; } else { xmmsv_bitbuffer_goto (msg->bb, msg->xfered * 8); xmmsv_bitbuffer_put_data (msg->bb, (unsigned char *) buf, ret); msg->xfered += ret; xmmsv_bitbuffer_goto (msg->bb, XMMS_IPC_MSG_HEAD_LEN * 8); } } }
/** * Try to write message to transport. If full message isn't written * the message will keep track of the amount of data written and not * write already written data next time. * * @returns TRUE if full message was written, FALSE otherwise. * disconnected is set if transport was disconnected */ bool xmms_ipc_msg_write_transport (xmms_ipc_msg_t *msg, xmms_ipc_transport_t *transport, bool *disconnected) { char *buf; unsigned int ret, len; x_return_val_if_fail (msg, false); x_return_val_if_fail (transport, false); xmmsv_bitbuffer_align (msg->bb); len = xmmsv_bitbuffer_len (msg->bb) / 8; x_return_val_if_fail (len > msg->xfered, true); buf = (char *) (xmmsv_bitbuffer_buffer (msg->bb) + msg->xfered); ret = xmms_ipc_transport_write (transport, buf, len - msg->xfered); if (ret == SOCKET_ERROR) { if (xmms_socket_error_recoverable ()) { return false; } if (disconnected) { *disconnected = true; } return false; } else if (!ret) { if (disconnected) { *disconnected = true; } } else { msg->xfered += ret; } return (len == msg->xfered); }
int read_do_udp (xmmsc_vis_udp_t *t, xmmsc_visualization_t *v, short *buffer, int drawtime, unsigned int blocking) { int old; int ret; int i, size; xmmsc_vis_udp_data_t packet_d; char* packet = packet_init_data (&packet_d); xmmsc_vischunk_t data; if (blocking) { wait_for_socket (t, blocking); } ret = recv (t->socket[0], packet, packet_d.size, 0); if ((ret > 0) && (*packet_d.__unaligned_type == 'V')) { uint16_t grace; struct timeval rtv; XMMSC_VIS_UNALIGNED_READ (data, packet_d.__unaligned_data, xmmsc_vischunk_t); /* resync connection */ XMMSC_VIS_UNALIGNED_READ (grace, packet_d.__unaligned_grace, uint16_t); grace = ntohs (grace); if (grace < 1000) { if (t->grace != 0) { t->grace = 0; /* use second socket here, so vis packets don't get lost */ t->timediff = udp_timediff (v->id, t->socket[1]); } } else { t->grace = grace; } /* include the measured time difference */ rtv.tv_sec = ntohl (data.timestamp[0]); rtv.tv_usec = ntohl (data.timestamp[1]); double interim = tv2ts (&rtv); interim -= t->timediff; ts2net (data.timestamp, interim); ret = 1; } else { if (ret == 1 && *packet_d.__unaligned_type == 'K') { ret = -1; } else if (ret > -1 || xmms_socket_error_recoverable ()) { ret = 0; } else { ret = -1; } free (packet); return ret; } old = check_drawtime (net2ts (data.timestamp), drawtime); if (!old) { size = ntohs (data.size); for (i = 0; i < size; ++i) { buffer[i] = (int16_t)ntohs (data.data[i]); } } free (packet); if (!old) { return size; } return 0; }