20#include <freerdp/config.h> 
   22#include <freerdp/utils/ringbuffer.h> 
   26#include <winpr/assert.h> 
   29#include <freerdp/log.h> 
   31#ifdef WITH_DEBUG_RINGBUFFER 
   32#define TAG FREERDP_TAG("utils.ringbuffer") 
   34#define DEBUG_RINGBUFFER(...) WLog_DBG(TAG, __VA_ARGS__) 
   36#define DEBUG_RINGBUFFER(...) \ 
   42BOOL ringbuffer_init(
RingBuffer* rb, 
size_t initialSize)
 
   45  rb->buffer = malloc(initialSize);
 
   50  rb->readPtr = rb->writePtr = 0;
 
   51  rb->initialSize = rb->size = rb->freeSize = initialSize;
 
   52  DEBUG_RINGBUFFER(
"ringbuffer_init(%p)", (
void*)rb);
 
   59  return rb->size - rb->freeSize;
 
   62size_t ringbuffer_capacity(
const RingBuffer* rb)
 
   70  DEBUG_RINGBUFFER(
"ringbuffer_destroy(%p)", (
void*)rb);
 
   78static BOOL ringbuffer_realloc(
RingBuffer* rb, 
size_t targetSize)
 
   82  DEBUG_RINGBUFFER(
"ringbuffer_realloc(%p): targetSize: %" PRIdz 
"", (
void*)rb, targetSize);
 
   84  if (rb->writePtr == rb->readPtr)
 
   89    newData = (BYTE*)realloc(rb->buffer, targetSize);
 
   94    rb->readPtr = rb->writePtr = 0;
 
   97  else if ((rb->writePtr >= rb->readPtr) && (rb->writePtr < targetSize))
 
  107    newData = (BYTE*)realloc(rb->buffer, targetSize);
 
  112    rb->buffer = newData;
 
  119    newData = (BYTE*)malloc(targetSize);
 
  124    if (rb->readPtr < rb->writePtr)
 
  131      memcpy(newData, rb->buffer + rb->readPtr, ringbuffer_used(rb));
 
  141      memcpy(dst, rb->buffer + rb->readPtr, rb->size - rb->readPtr);
 
  142      dst += (rb->size - rb->readPtr);
 
  145        memcpy(dst, rb->buffer, rb->writePtr);
 
  148    rb->writePtr = rb->size - rb->freeSize;
 
  151    rb->buffer = newData;
 
  154  rb->freeSize += (targetSize - rb->size);
 
  155  rb->size = targetSize;
 
  168BOOL ringbuffer_write(
RingBuffer* rb, 
const BYTE* ptr, 
size_t sz)
 
  171  size_t remaining = 0;
 
  174  DEBUG_RINGBUFFER(
"ringbuffer_write(%p): sz: %" PRIdz 
"", (
void*)rb, sz);
 
  176  if ((rb->freeSize <= sz) && !ringbuffer_realloc(rb, rb->size + sz))
 
  188  if (rb->size - rb->writePtr < sz)
 
  189    toWrite = rb->size - rb->writePtr;
 
  193    memcpy(rb->buffer + rb->writePtr, ptr, toWrite);
 
  194    remaining -= toWrite;
 
  199    memcpy(rb->buffer, ptr, remaining);
 
  201  rb->writePtr = (rb->writePtr + sz) % rb->size;
 
  206BYTE* ringbuffer_ensure_linear_write(
RingBuffer* rb, 
size_t sz)
 
  208  DEBUG_RINGBUFFER(
"ringbuffer_ensure_linear_write(%p): sz: %" PRIdz 
"", (
void*)rb, sz);
 
  211  if (rb->freeSize < sz)
 
  213    if (!ringbuffer_realloc(rb, rb->size + sz - rb->freeSize + 32))
 
  217  if (rb->writePtr == rb->readPtr)
 
  219    rb->writePtr = rb->readPtr = 0;
 
  222  if (rb->writePtr + sz < rb->size)
 
  223    return rb->buffer + rb->writePtr;
 
  232  memmove(rb->buffer, rb->buffer + rb->readPtr, rb->writePtr - rb->readPtr);
 
  234  rb->writePtr = rb->size - rb->freeSize;
 
  235  return rb->buffer + rb->writePtr;
 
  238BOOL ringbuffer_commit_written_bytes(
RingBuffer* rb, 
size_t sz)
 
  240  DEBUG_RINGBUFFER(
"ringbuffer_commit_written_bytes(%p): sz: %" PRIdz 
"", (
void*)rb, sz);
 
  246  if (rb->writePtr + sz > rb->size)
 
  249  rb->writePtr = (rb->writePtr + sz) % rb->size;
 
  256  size_t remaining = sz;
 
  260  DEBUG_RINGBUFFER(
"ringbuffer_peek(%p): sz: %" PRIdz 
"", (
const void*)rb, sz);
 
  266  if ((rb->size - rb->freeSize) < sz)
 
  267    remaining = rb->size - rb->freeSize;
 
  271  if ((rb->readPtr + remaining) > rb->size)
 
  272    toRead = rb->size - rb->readPtr;
 
  276    chunks[0].data = rb->buffer + rb->readPtr;
 
  277    chunks[0].size = toRead;
 
  285    chunks[chunkIndex].data = rb->buffer;
 
  286    chunks[chunkIndex].size = remaining;
 
  293void ringbuffer_commit_read_bytes(
RingBuffer* rb, 
size_t sz)
 
  295  DEBUG_RINGBUFFER(
"ringbuffer_commit_read_bytes(%p): sz: %" PRIdz 
"", (
void*)rb, sz);
 
  301  WINPR_ASSERT(rb->size - rb->freeSize >= sz);
 
  302  rb->readPtr = (rb->readPtr + sz) % rb->size;
 
  306  if ((rb->size != rb->initialSize) && (ringbuffer_used(rb) < rb->initialSize / 2))
 
  307    ringbuffer_realloc(rb, rb->initialSize);
 
a piece of data in the ring buffer, exactly like a glibc iovec