// Get address of region(s) from which we can read data. // If the region is contiguous, `data_ptr_bytes_2` will be zero. // If non-contiguous, `data_ptr_bytes_2` will be the size in bytes of the second // region. Returns room available to be read or `element_count`, whichever is // smaller. static size_t GetBufferReadRegions(RingBuffer* buf,
size_t element_count, void** data_ptr_1,
size_t* data_ptr_bytes_1, void** data_ptr_2,
size_t* data_ptr_bytes_2) { const size_t readable_elements = WebRtc_available_read(buf); const size_t read_elements =
(readable_elements < element_count ? readable_elements : element_count); const size_t margin = buf->element_count - buf->read_pos;
// Check to see if read is not contiguous. if (read_elements > margin) { // Write data in two blocks that wrap the buffer.
*data_ptr_1 = buf->data + buf->read_pos * buf->element_size;
*data_ptr_bytes_1 = margin * buf->element_size;
*data_ptr_2 = buf->data;
*data_ptr_bytes_2 = (read_elements - margin) * buf->element_size;
} else {
*data_ptr_1 = buf->data + buf->read_pos * buf->element_size;
*data_ptr_bytes_1 = read_elements * buf->element_size;
*data_ptr_2 = NULL;
*data_ptr_bytes_2 = 0;
}
{ void* buf_ptr_1 = NULL; void* buf_ptr_2 = NULL;
size_t buf_ptr_bytes_1 = 0;
size_t buf_ptr_bytes_2 = 0; const size_t read_count =
GetBufferReadRegions(self, element_count, &buf_ptr_1, &buf_ptr_bytes_1,
&buf_ptr_2, &buf_ptr_bytes_2); if (buf_ptr_bytes_2 > 0) { // We have a wrap around when reading the buffer. Copy the buffer data to // `data` and point to it.
memcpy(data, buf_ptr_1, buf_ptr_bytes_1);
memcpy(((char*)data) + buf_ptr_bytes_1, buf_ptr_2, buf_ptr_bytes_2);
buf_ptr_1 = data;
} elseif (!data_ptr) { // No wrap, but a memcpy was requested.
memcpy(data, buf_ptr_1, buf_ptr_bytes_1);
} if (data_ptr) { // `buf_ptr_1` == `data` in the case of a wrap.
*data_ptr = read_count == 0 ? NULL : buf_ptr_1;
}
// Update read position
WebRtc_MoveReadPtr(self, (int)read_count);
return read_count;
}
}
size_t WebRtc_WriteBuffer(RingBuffer* self, constvoid* data,
size_t element_count) { if (!self) { return0;
} if (!data) { return0;
}
if (write_elements > margin) { // Buffer wrap around when writing.
memcpy(self->data + self->write_pos * self->element_size, data,
margin * self->element_size);
self->write_pos = 0;
n -= margin;
self->rw_wrap = DIFF_WRAP;
}
memcpy(self->data + self->write_pos * self->element_size,
((constchar*)data) + ((write_elements - n) * self->element_size),
n * self->element_size);
self->write_pos += n;
return write_elements;
}
}
int WebRtc_MoveReadPtr(RingBuffer* self, int element_count) { if (!self) { return0;
}
{ // We need to be able to take care of negative changes, hence use "int" // instead of "size_t". constint free_elements = (int)WebRtc_available_write(self); constint readable_elements = (int)WebRtc_available_read(self); int read_pos = (int)self->read_pos;
if (element_count > readable_elements) {
element_count = readable_elements;
} if (element_count < -free_elements) {
element_count = -free_elements;
}
read_pos += element_count; if (read_pos > (int)self->element_count) { // Buffer wrap around. Restart read position and wrap indicator.
read_pos -= (int)self->element_count;
self->rw_wrap = SAME_WRAP;
} if (read_pos < 0) { // Buffer wrap around. Restart read position and wrap indicator.
read_pos += (int)self->element_count;
self->rw_wrap = DIFF_WRAP;
}
self->read_pos = (size_t)read_pos;
return element_count;
}
}
size_t WebRtc_available_read(const RingBuffer* self) { if (!self) { return0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.