Switch to side-by-side view

--- a
+++ b/mpd2src/fiforeader.cpp
@@ -0,0 +1,107 @@
+/* Copyright (C) 2015 J.F.Dockes
+ *   This program 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.
+ *
+ *   This program 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 more 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.,
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#include "fiforeader.h"
+
+#include <iostream>
+#include <string>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "log.h"
+#include "audioutil.h"
+
+using namespace std;
+
+FifoReader::FifoReader(const string& fn, int sampleRate, int bitsPerSample,
+                       int chans, bool needswap, bool blocking)
+    : m_fn(fn), m_needswap(needswap), m_blocking(blocking),
+      m_fd(-1), m_tmpbuf(0), m_tmpbufsize(0)
+{
+    setAudioParams(sampleRate, bitsPerSample, chans);
+}
+
+FifoReader::~FifoReader()
+{
+    if (m_fd >= 0)
+        ::close(m_fd);
+    
+    if (m_tmpbuf)
+        free(m_tmpbuf);
+}
+
+bool FifoReader::open()
+{
+    LOGDEB("FifoReader::open: blocking: " << m_blocking << endl);
+    
+    int flags = m_blocking ? O_RDONLY : O_RDONLY|O_NONBLOCK;
+    if ((m_fd = ::open(m_fn.c_str(), flags)) < 0) {
+        LOGERR("open() errno " << errno << " on " << m_fn << endl);
+        return false;
+    }
+    return true;
+}
+
+
+const unsigned char *FifoReader::data(size_t size)
+{
+    //LOGDEB("FifoReader: data " << size << " bytes. blocking " << m_blocking
+    // << endl);
+    if (m_tmpbufsize < size) {
+        m_tmpbuf = (unsigned char *)realloc(m_tmpbuf, size);
+        m_tmpbufsize = size;
+    }
+
+    if (m_blocking) {
+        size_t remaining = size;
+        while (remaining) {
+            ssize_t nread = read(m_fd, m_tmpbuf + size - remaining, remaining);
+            if (nread <= 0) {
+                LOGERR("FifoReader::read: ret " << nread << " errno " <<
+                       errno << " : " << strerror(errno) << endl);
+                return 0;
+            } else {
+                remaining -= nread;
+            }
+        }
+    } else {
+        ssize_t nread = read(m_fd, m_tmpbuf, size);
+        if (nread != ssize_t(size)) {
+            if (nread >= 0 || errno == EAGAIN) {
+                if (nread < 0)
+                    nread = 0;
+                //LOGDEB("FifoReader::data: inserting " << size - nread <<
+                //       " bytes\n");
+                memset(m_tmpbuf + nread, 0, size - nread);
+            } else {
+                LOGERR("FifoReader::read: ret " << nread << " errno " <<
+                       errno << " : " << strerror(errno) << endl);
+                return 0;
+            }
+        }
+    }
+    
+    if (m_needswap)
+        swapSamples(m_tmpbuf, bytesPerSample(), m_tmpbufsize / bytesPerSample());
+
+    //LOGDEB("FifoReader: data done" << endl);
+    return m_tmpbuf;
+}