Fix my name :)
[ardour.git] / libs / evoral / evoral / EventRingBuffer.hpp
index 05ec9217b878dffe79a8914a356390ed4dd3efc9..cc58d27bed67008108bf07f3be42de6fd8370c00 100644 (file)
@@ -1,15 +1,15 @@
 /* This file is part of Evoral.
- * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
- * 
+ * Copyright (C) 2008 David Robillard <http://drobilla.net>
+ *
  * Evoral is free software; you can redistribute it and/or modify it under the
  * terms of the GNU General Public License as published by the Free Software
  * Foundation; either version 2 of the License, or (at your option) any later
  * version.
- * 
+ *
  * Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
- * 
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 #ifndef EVORAL_EVENT_RING_BUFFER_HPP
 #define EVORAL_EVENT_RING_BUFFER_HPP
 
-#include <glib.h>
-#include <evoral/RingBuffer.hpp>
-#include <evoral/EventSink.hpp>
-#include <evoral/types.hpp>
-
 #include <iostream>
+
+#include "pbd/ringbufferNPT.h"
+
+#include "evoral/EventSink.hpp"
+#include "evoral/types.hpp"
+
 using namespace std;
 
 namespace Evoral {
 
-
 /** A RingBuffer of events (generic time-stamped binary "blobs").
  *
  * This packs a timestamp, size, and size bytes of data flat into the buffer.
  * Useful for MIDI events, OSC messages, etc.
+ *
+ * Note: the uint8_t template argument to RingBufferNPT<> indicates "byte
+ * oriented data", not anything particular linked to MIDI or any other
+ * possible interpretation of uint8_t.
  */
-class EventRingBuffer : public Evoral::RingBuffer<uint8_t>, public Evoral::EventSink {
+template<typename Time>
+class EventRingBuffer : public PBD::RingBufferNPT<uint8_t>, public Evoral::EventSink<Time> {
 public:
 
        /** @param capacity Ringbuffer capacity in bytes.
         */
-       EventRingBuffer(size_t capacity) : RingBuffer<uint8_t>(capacity)
+        EventRingBuffer(size_t capacity) : PBD::RingBufferNPT<uint8_t>(capacity)
        {}
 
-       size_t capacity() const { return _size; }
-       
-       bool peek_time(EventTime* time);
+        size_t capacity() const { return bufsize(); }
 
-       uint32_t write(EventTime  time, EventType  type, uint32_t  size, const uint8_t* buf);
-       bool     read (EventTime* time, EventType* type, uint32_t* size,       uint8_t* buf);
-};
+       /** Peek at the ringbuffer (read w/o advancing read pointer).
+        * @return how much has been peeked (wraps around if read exceeds
+        * the end of the buffer):
+        * <pre>
+        * |===========--------------R=============================|
+        *            read-pointer---^
+        * </pre>
+        */
+        bool peek (uint8_t*, size_t size);
 
+       uint32_t write(Time  time, EventType  type, uint32_t  size, const uint8_t* buf);
+       bool     read (Time* time, EventType* type, uint32_t* size,       uint8_t* buf);
+};
 
+template<typename Time>
 inline bool
-EventRingBuffer::peek_time(EventTime* time)
+EventRingBuffer<Time>::peek (uint8_t* buf, size_t size)
 {
-       bool success = RingBuffer<uint8_t>::full_peek(sizeof(EventTime), (uint8_t*)time);
-       return success;
-}
+        PBD::RingBufferNPT<uint8_t>::rw_vector vec;
+
+        get_read_vector (&vec);
 
+        if (vec.len[0] + vec.len[1] < size) {
+                return false;
+        }
 
+        if (vec.len[0] > 0) {
+                memcpy (buf, vec.buf[0], min (vec.len[0], size));
+        }
+
+        if (vec.len[0] < size) {
+                if (vec.len[1]) {
+                        memcpy (buf + vec.len[0], vec.buf[1], size - vec.len[0]);
+                }
+        }
+
+        return true;
+}
+
+template<typename Time>
 inline bool
-EventRingBuffer::read(EventTime* time, EventType* type, uint32_t* size, uint8_t* buf)
+EventRingBuffer<Time>::read(Time* time, EventType* type, uint32_t* size, uint8_t* buf)
 {
-       bool success = RingBuffer<uint8_t>::full_read(sizeof(EventTime), (uint8_t*)time);
-       if (success)
-               success = RingBuffer<uint8_t>::full_read(sizeof(EventType), (uint8_t*)type);
-       if (success)
-               success = RingBuffer<uint8_t>::full_read(sizeof(uint32_t), (uint8_t*)size);
-       if (success)
-               success = RingBuffer<uint8_t>::full_read(*size, buf);
-       
-       return success;
+       if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)time, sizeof (Time)) != sizeof (Time)) {
+                return false;
+        }
+
+        if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)type, sizeof(EventType)) != sizeof (EventType)) {
+                return false;
+        }
+
+        if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)size, sizeof(uint32_t)) != sizeof (uint32_t)) {
+                return false;
+        }
+
+        if (PBD::RingBufferNPT<uint8_t>::read (buf, *size) != *size) {
+                return false;
+        }
+
+       return true;
 }
 
 
+template<typename Time>
 inline uint32_t
-EventRingBuffer::write(EventTime time, EventType type, uint32_t size, const uint8_t* buf)
+EventRingBuffer<Time>::write(Time time, EventType type, uint32_t size, const uint8_t* buf)
 {
-       if (write_space() < (sizeof(EventTime) + sizeof(EventType) + sizeof(uint32_t) + size)) {
+       if (write_space() < (sizeof(Time) + sizeof(EventType) + sizeof(uint32_t) + size)) {
                return 0;
        } else {
-               RingBuffer<uint8_t>::write(sizeof(EventTime), (uint8_t*)&time);
-               RingBuffer<uint8_t>::write(sizeof(EventType), (uint8_t*)&type);
-               RingBuffer<uint8_t>::write(sizeof(uint32_t), (uint8_t*)&size);
-               RingBuffer<uint8_t>::write(size, buf);
+                PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&time, sizeof(Time));
+                PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&type, sizeof(EventType));
+                PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&size, sizeof(uint32_t));
+                PBD::RingBufferNPT<uint8_t>::write (buf, size);
                return size;
        }
 }