--- a
+++ b/src/mediaserver/cdplugins/abuffer.h
@@ -0,0 +1,82 @@
+#ifndef _ABUFFER_H_INCLUDED_
+#define _ABUFFER_H_INCLUDED_
+
+#include <stdlib.h>
+#include <string.h>
+
+/// Data buffer used on the queue.
+///
+/// The implementation details are public because this may be used
+/// externally when inserting an intermediary queue to process the
+/// data.
+///
+/// This is a very raw structure and it is never shared. Either
+/// the data producer or consumer has exclusive use until the
+/// buffer is passed on.
+///
+/// The producer possibly allocates a buffer (or retrieves a
+/// recycled one from somewhere), copies data to it, setting the
+/// 'bytes' value, then passes it on.
+///
+/// The consumer gets the buffer from a queue, then does what it
+/// needs with the data, possibly in several chunks, using the
+/// curoffs field to keep track. curoffs is private to the
+/// consumer (nornally set to zero when getting the buffer).
+struct ABuffer {
+ ABuffer(size_t bufsize)
+ : buf((char*)malloc(bufsize)), allocbytes(bufsize),
+ bytes(0), curoffs(0) { }
+
+ // @param buf is is a malloced buffer, and we take ownership. The
+ // caller MUST NOT free it.
+ // @param bufsize buffer allocated size in bytes.
+ // @param bytes data contents size.
+ ABuffer(char *buf, size_t bufsize, size_t bytes)
+ : buf(buf), allocbytes(bufsize), bytes(bytes), curoffs(0) { }
+
+ ~ABuffer() {
+ if (buf)
+ free(buf);
+ }
+
+ bool setminalloc(size_t minbytes) {
+ if (allocbytes >= minbytes) {
+ return true;
+ }
+ if ((buf = (char *)realloc(buf, minbytes)) == nullptr) {
+ return false;
+ }
+ allocbytes = minbytes;
+ return true;
+ }
+
+ // Append data. This should not be used casually as we don't take
+ // much care to make the reallocation efficient. Typically, this
+ // is only used to buffer a bit of data at the beginning of the
+ // stream for header forensics.
+ bool append(const char *data, int cnt) {
+ if (!setminalloc(2*(cnt+bytes))) {
+ return false;
+ }
+ memcpy(buf + bytes, data, cnt);
+ bytes += cnt;
+ return true;
+ }
+
+ ABuffer *dup() {
+ ABuffer *n = new ABuffer(bytes);
+ if (nullptr == n || nullptr == n->buf) {
+ return nullptr;
+ }
+ memcpy(n->buf, buf, bytes);
+ n->bytes = bytes;
+ return n;
+ }
+
+ char *buf;
+ unsigned int allocbytes; // buffer size
+ unsigned int bytes; // Useful bytes, set by producer.
+ unsigned int curoffs; // Current offset in data, used by the consumer
+};
+
+#endif /* _ABUFFER_H_INCLUDED_ */