FIFO works.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 22 Jan 2014 07:14:04 +0000 (07:14 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 22 Jan 2014 07:14:04 +0000 (07:14 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1391 01035d8c-6547-0410-b346-abe4f91aad63

freedv-server/CMakeLists.txt
freedv-server/source/drivers.h
freedv-server/source/fifo.cpp
freedv-server/source/test/fifo.cpp [new file with mode: 0644]

index fac3274d47188fa0fe056a401b9d923a9e29ff4f..a5d03cb11da5355a70384aad2c990d6af4d316d7 100644 (file)
@@ -140,6 +140,7 @@ set(Test.sources
   source/test/audio_sink.cpp
   source/test/base.cpp
   source/test/blank_panel.cpp
+  source/test/fifo.cpp
   source/test/keying_sink.cpp
   source/test/ptt_constant.cpp
   source/test/text_constant.cpp
index 98cb614af1c50edd5aa20a1e3667278bc408bc0d..ca672972085e291238a4ae202fe22b389f6074ea 100644 (file)
@@ -41,6 +41,12 @@ namespace FreeDV {
 
                        ~FIFO();
 
+    /// Returns the amount of space available for incoming data.
+    /// \return The amount of space, in bytes, available for incoming data.
+    inline std::size_t incoming_available() const {
+                         return buffer_end - in + out - buffer;
+                       }
+
     /// Return the address of an incoming data buffer of the requested size.
     /// Throws an error if we run the buffer out of space. Well-behaved code
     /// won't allocate a size that can't be drained before it is further
@@ -53,7 +59,7 @@ namespace FreeDV {
     inline char *      incoming_buffer(std::size_t io_length) {
                          const char * io_end = in + io_length;
 
-                         if ( io_end >= buffer_end )
+                         if ( io_end > buffer_end )
                             return reorder(io_length);
                          else
                            return in;
@@ -66,12 +72,6 @@ namespace FreeDV {
                          in += length;
                        }
 
-    /// Returns the amount of space available for incoming data.
-    /// \return The amount of space, in bytes, available for incoming data.
-    inline std::size_t incoming_space() const {
-                         return buffer_end - in + out - buffer;
-                       }
-
     /// Returns the amount of data available to read.
     /// \return The amount of data, in bytes, available to read.
     inline std::size_t outgoing_available() const {
index 5d094dd2ef751ea8edb50ab889eddd8175af7517..b4df8ea05f9d6c56d6675e563d6acf6534193a07 100644 (file)
@@ -4,17 +4,22 @@
 
 namespace FreeDV {
   FIFO::FIFO(std::size_t size)
-  : buffer(new char[size]), buffer_end(buffer + size)
+  : buffer(new char[size]), buffer_end(buffer + size), in(buffer), out(buffer)
   {
     
   }
 
+  FIFO::~FIFO()
+  {
+    delete buffer;
+  }
+
   char *
   FIFO::reorder(std::size_t size)
   {
     const std::size_t bytes = in - out;
 
-    if ( bytes > 0 ) {
+    if ( bytes > 0 && out > buffer ) {
 
       // memmove() is specified to handle overlap properly.
       memmove(buffer, out, bytes);
diff --git a/freedv-server/source/test/fifo.cpp b/freedv-server/source/test/fifo.cpp
new file mode 100644 (file)
index 0000000..da7a6ae
--- /dev/null
@@ -0,0 +1,70 @@
+// Tests for the Base class.
+#include <drivers.h>
+#include <gtest/gtest.h>
+#include <stdexcept>
+
+using namespace FreeDV;
+
+class FIFOTest : public ::testing::Test {
+protected:
+       FIFO *  f;
+
+       FIFOTest()
+       : f(0)
+       {
+       }
+
+  void SetUp() {
+    f = new FIFO(100);
+  }
+
+  void TearDown() {
+    delete f;
+  }
+};
+
+TEST_F(FIFOTest, CanFillAndDrain) {
+  ASSERT_EQ(100, f->incoming_available());
+  memset(f->incoming_buffer(100), 255, 100);
+  ASSERT_EQ(0, f->outgoing_available());
+  f->incoming_done(100);
+  ASSERT_EQ(100, f->outgoing_available());
+  ASSERT_EQ(0, f->incoming_available());
+  EXPECT_THROW(f->incoming_buffer(1), std::runtime_error);
+  ASSERT_EQ(100, f->outgoing_available());
+  ASSERT_NE((char *)0, f->outgoing_buffer(100));
+  f->outgoing_done(100);
+  ASSERT_EQ(0, f->outgoing_available());
+  ASSERT_EQ(100, f->incoming_available());
+  ASSERT_EQ(100, f->incoming_available());
+  memset(f->incoming_buffer(100), 255, 100);
+  ASSERT_EQ(0, f->outgoing_available());
+  f->incoming_done(100);
+  ASSERT_EQ(100, f->outgoing_available());
+  ASSERT_EQ(0, f->incoming_available());
+}
+
+TEST_F(FIFOTest, Reorder) {
+  char * b;
+  const char * r;
+
+  ASSERT_EQ(100, f->incoming_available());
+  ASSERT_NE((char *)0, b = f->incoming_buffer(99));
+  memset(b, 0, 98);
+  b[98] = 'b';
+  f->incoming_done(99);
+  ASSERT_EQ(1, f->incoming_available());
+  ASSERT_EQ(99, f->outgoing_available());
+  ASSERT_NE((char *)0, f->outgoing_buffer(98));
+  f->outgoing_done(98);
+  ASSERT_EQ(1, f->outgoing_available());
+  ASSERT_EQ(99, f->incoming_available());
+  // This should cause reorder().
+  ASSERT_NE((char *)0, b = f->incoming_buffer(2));
+  f->incoming_done(0);
+  ASSERT_EQ(99, f->incoming_available());
+  ASSERT_EQ(1, f->outgoing_available());
+  ASSERT_NE((char *)0, r = f->outgoing_buffer(1));
+  ASSERT_EQ('b', *r);
+  f->outgoing_done(1);
+}