int buf_get(struct buffer *buf, void *dest, int size) { int count; if(size < 1 || !dest || !buf) return -EINVAL; if(size > buf_used(buf)) size = buf_used(buf); if(size == 0) return 0; count = buf->bs + buf->size - buf->get; if(size > count) { memcpy(dest, buf->get, count); memcpy(dest+count, buf->bs, size-count); buf->get = buf->bs + size-count; } else { memcpy(dest, buf->get, size); buf->get += size; } return size; }
/** * netplay_resize_socket_buffer * * Resize the given socket_buffer's buffer to the requested size. */ bool netplay_resize_socket_buffer(struct socket_buffer *sbuf, size_t newsize) { unsigned char *newdata = (unsigned char*)malloc(newsize); if (newdata == NULL) return false; /* Copy in the old data */ if (sbuf->end < sbuf->start) { memcpy(newdata, sbuf->data + sbuf->start, sbuf->bufsz - sbuf->start); memcpy(newdata + sbuf->bufsz - sbuf->start, sbuf->data, sbuf->end); } else if (sbuf->end > sbuf->start) { memcpy(newdata, sbuf->data + sbuf->start, sbuf->end - sbuf->start); } /* Adjust our read offset */ if (sbuf->read < sbuf->start) sbuf->read += sbuf->bufsz - sbuf->start; else sbuf->read -= sbuf->start; /* Adjust start and end */ sbuf->end = buf_used(sbuf); sbuf->start = 0; /* Free the old one and replace it with the new one */ free(sbuf->data); sbuf->data = newdata; sbuf->bufsz = newsize; return true; }
void buf_dbg(struct buffer *buf) { printf("used: %d free: %d get@%d put@%d\n", buf_used(buf), buf_space(buf), buf->get - buf->bs, buf->put - buf->bs); return; }
void render_proc(void *theCookie, void *buffer, size_t req, const media_raw_audio_format &format) { int amt; while ((amt = buf_used()) < req) snooze(100000); read_buffer((unsigned char *)buffer, req); }
void on_read(tcp_client *client) { conn_peer *peer = (conn_peer*)client->data; int ind = get_peer_ind(peer, client); tcp_client *rclient = peer->conn[ind^1]; if (peer->status[ind^1] == OFF) { return; } char tmp[65536]; while(buf_used(&client->rbuf)) { int n = buf_readall(&client->rbuf, tmp, 65536); tcp_send(rclient, tmp, n); } }
/* remove data from ringbuffer */ static int read_buffer(unsigned char *data, int len) { int first_len = buffer_len - buf_read_pos; int buffered = buf_used(); if (len > buffered) len = buffered; if (first_len > len) first_len = len; /* till end of buffer */ memcpy(data, buffer + buf_read_pos, first_len); if (len > first_len) { /* we have to wrap around */ /* remaining part from beginning of buffer */ memcpy(data + first_len, buffer, len - first_len); } buf_read_pos = (buf_read_pos + len) % buffer_len; return len; }
static int read_buffer(unsigned char* data,int len){ int first_len = BUFFSIZE - read_pos; int buffered = buf_used(); if (len > buffered) len = buffered; if (first_len > len) first_len = len; // till end of buffer #ifdef USE_SDL_INTERNAL_MIXER SDL_MixAudio (data, &buffer[read_pos], first_len, volume); #else memcpy (data, &buffer[read_pos], first_len); #endif if (len > first_len) { // we have to wrap around // remaining part from beginning of buffer #ifdef USE_SDL_INTERNAL_MIXER SDL_MixAudio (&data[first_len], buffer, len - first_len, volume); #else memcpy (&data[first_len], buffer, len - first_len); #endif } read_pos = (read_pos + len) % BUFFSIZE; return len; }
static size_t buf_remaining(struct socket_buffer *sbuf) { return sbuf->bufsz - buf_used(sbuf) - 1; }
/** * netplay_send_flush * * Flush unsent data in the given socket buffer, blocking to do so if * requested. * * Returns false only on socket failures, true otherwise. */ bool netplay_send_flush(struct socket_buffer *sbuf, int sockfd, bool block) { ssize_t sent; if (buf_used(sbuf) == 0) return true; if (sbuf->end > sbuf->start) { /* Usual case: Everything's in order */ if (block) { if (!socket_send_all_blocking(sockfd, sbuf->data + sbuf->start, buf_used(sbuf), false)) return false; sbuf->start = sbuf->end = 0; } else { sent = socket_send_all_nonblocking(sockfd, sbuf->data + sbuf->start, buf_used(sbuf), false); if (sent < 0) return false; sbuf->start += sent; if (sbuf->start == sbuf->end) sbuf->start = sbuf->end = 0; } } else { /* Unusual case: Buffer overlaps break */ if (block) { if (!socket_send_all_blocking(sockfd, sbuf->data + sbuf->start, sbuf->bufsz - sbuf->start, false)) return false; sbuf->start = 0; return netplay_send_flush(sbuf, sockfd, true); } else { sent = socket_send_all_nonblocking(sockfd, sbuf->data + sbuf->start, sbuf->bufsz - sbuf->start, false); if (sent < 0) return false; sbuf->start += sent; if (sbuf->start >= sbuf->bufsz) { sbuf->start = 0; return netplay_send_flush(sbuf, sockfd, false); } } } return true; }