summaryrefslogtreecommitdiff
path: root/tools/source.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source.c')
-rw-r--r--tools/source.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/source.c b/tools/source.c
new file mode 100644
index 0000000..91c36c8
--- /dev/null
+++ b/tools/source.c
@@ -0,0 +1,195 @@
+#include "tools/source.h"
+#include "tools/select.h"
+#include "common.h"
+
+#include <vdr/tools.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+cTBSource::cTBSource(void) {
+ m_BytesRead = 0;
+ m_BytesWritten = 0;
+ m_Filed = -1;
+}
+
+bool cTBSource::Open(int Filed, bool IsUnixFd) {
+ if (IsOpen())
+ Close();
+
+ m_Filed = Filed;
+ if (IsUnixFd && ::fcntl(m_Filed, F_SETFL, O_NONBLOCK) == -1)
+ return false;
+
+ return true;
+}
+
+cTBSource::~cTBSource() {
+}
+
+bool cTBSource::Close(void) {
+ if (!IsOpen()) {
+ errno = EBADF;
+ return false;
+ }
+
+ m_Filed = -1;
+ return true;
+}
+
+ssize_t cTBSource::Read(void *Buffer, size_t Length) {
+ ssize_t res;
+ while ((res = SysRead(Buffer, Length)) < 0 && errno == EINTR)
+ errno = 0;
+ if (res > 0) m_BytesRead += res;
+ return res;
+}
+
+ssize_t cTBSource::Write(const void *Buffer, size_t Length) {
+ ssize_t res;
+ while ((res = SysWrite(Buffer, Length)) < 0 && errno == EINTR)
+ errno = 0;
+ if (res > 0) m_BytesWritten += res;
+ return res;
+}
+
+bool cTBSource::TimedWrite(const void *Buffer, size_t Length, uint TimeoutMs) {
+ cTBSelect sel;
+ time_t st;
+ int ms, offs;
+
+ st = time_ms();
+ ms = TimeoutMs;
+ offs = 0;
+ while (Length > 0) {
+ int b;
+
+ sel.Clear();
+ sel.Add(m_Filed, true);
+ if (sel.Select(ms) == -1)
+ return false;
+
+ if (sel.CanWrite(m_Filed)) {
+ if ((b = Write((char*)Buffer + offs, Length)) == -1)
+ return false;
+ offs += b;
+ Length -= b;
+ }
+
+ ms -= time_ms() - st;
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return false;
+ }
+ }
+ return true;
+}
+
+ssize_t cTBSource::ReadUntil(void *Buffer, size_t Length, const char *Seq,
+ uint TimeoutMs) {
+ char *offs;
+ time_t st;
+ int seqlen, ms;
+ size_t olen;
+ cTBSelect sel;
+
+ seqlen = strlen(Seq);
+ if ((offs = (char*)memmem(m_LineBuffer, m_LineBuffer.Length(), Seq, seqlen))){
+ olen = offs - m_LineBuffer;
+ if (olen >= Length) {
+ errno = ENOBUFS;
+ return -1;
+ }
+ memcpy(Buffer, m_LineBuffer, olen);
+ m_LineBuffer = m_LineBuffer.Mid(olen + seqlen);
+ Dprintf("ReadUntil: Served from Linebuffer: %d, |%.*s|\n", olen, olen - 1,
+ (char*)Buffer);
+ return olen;
+ }
+
+ st = time_ms();
+ ms = TimeoutMs;
+ while (m_LineBuffer.Length() < BUFSIZ) {
+ int b;
+
+ sel.Clear();
+ sel.Add(m_Filed, false);
+
+ if (sel.Select(ms) == -1)
+ return -1;
+
+ if (sel.CanRead(m_Filed)) {
+ offs = m_LineBuffer.Buffer(BUFSIZ);
+ if ((b = Read(offs + m_LineBuffer.Length(), BUFSIZ
+ - m_LineBuffer.Length())) == -1)
+ return -1;
+
+ m_LineBuffer.Release(m_LineBuffer.Length() + b);
+ if ((offs = (char*)memmem(m_LineBuffer, m_LineBuffer.Length(), Seq,
+ seqlen))) {
+ olen = offs - m_LineBuffer;
+ if (olen >= Length) {
+ errno = ENOBUFS;
+ return -1;
+ }
+ memcpy(Buffer, m_LineBuffer, olen);
+ m_LineBuffer = m_LineBuffer.Mid(olen + seqlen, m_LineBuffer.Length()
+ - olen - seqlen);
+ Dprintf("ReadUntil: Served after Read: %d, |%.*s|\n", olen, olen-1,
+ (char*)Buffer);
+ return olen;
+ }
+ }
+
+ ms -= time_ms() - st;
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ errno = ENOBUFS;
+ return -1;
+
+
+
+/*
+ cTBSelect sel;
+ time_t st, et;
+ int ms, seqlen, offs;
+
+ seqlen = strlen(Seq);
+ st = time_ms();
+ ms = TimeoutMs;
+ offs = 0;
+ while (Length > 0) {
+ int b;
+
+ sel.Clear();
+ sel.Add(m_Filed, false);
+ if (sel.Select(ms) == -1)
+ return -1;
+
+ if (sel.CanRead(m_Filed)) {
+ if ((b = Read((char*)Buffer + offs, Length)) == -1)
+ return -1;
+
+ offs += b;
+ Length -= b;
+
+ if (memmem(Buffer, offs, Seq, seqlen) != NULL)
+ return offs;
+ }
+
+ et = time_ms();
+ ms -= et - st;
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ errno = ENOBUFS;
+ return -1;
+*/
+}
+