/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
// A ring buffer to hold arbitrary data. Provides no thread safety. Unless // otherwise specified, functions return 0 on success and -1 on error.
// 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) {
if (self == NULL) { return 0;
} if (data == NULL) { return 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) { return 0;
} if (!data) { return 0;
}
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) { return 0;
}
{ // 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;
}
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.