]> git.vomp.tv Git - vompclient.git/blob - stream.cc
Initial import
[vompclient.git] / stream.cc
1 /*
2     Copyright 2005 Mark Calderbank
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "stream.h"
22
23 Stream::Stream()
24 {
25   initted = 0;
26 }
27
28 Stream::~Stream()
29 {
30   shutdown();
31 }
32
33 void Stream::shutdown()
34 {
35   if (initted) {
36     free(outbuf);
37   }
38   initted = 0;
39 }
40
41 int Stream::init(int bufsize)
42 {
43   outbuf = (UCHAR*) malloc(bufsize);
44   if (!outbuf) return 1;
45   bufferSize = bufsize;
46   bufferHead = bufferTail = 0;
47   full = 0;
48   initted = 1;
49   return 0;
50 }
51
52 void Stream::flush()
53 {
54   bufferHead = bufferTail = 0;
55   full = 0;
56 }
57
58 int Stream::put(UCHAR* inbuf, int len)
59 {
60   int ret = 0;
61   int localTail = bufferTail;
62   if (len == 0 || (full)) return ret;
63
64   if (bufferHead >= localTail)
65   {
66     // We have free rein to the end of the buffer
67     if (len < (bufferSize - bufferHead))
68     {
69       // We won't reach the end of the buffer.
70       memcpy(outbuf + bufferHead, inbuf, len);
71       bufferHead += len;
72       ret += len; return ret;
73     } else
74     {
75       // We'll reach the end of the buffer and loop round.
76       memcpy(outbuf + bufferHead, inbuf, (bufferSize - bufferHead));
77       inbuf += (bufferSize - bufferHead);
78       ret += (bufferSize - bufferHead);
79       len -= (bufferSize - bufferHead);
80       bufferHead = 0;
81       if (localTail == 0) full = 1;
82       if (len == 0 || (full)) return ret;
83     }
84   }
85   // We can advance the head up to the tail
86   // If we reach it, we are full.
87   if (len < (localTail - bufferHead))
88   {
89     // We'll fall short of the tail.
90     memcpy(outbuf + bufferHead, inbuf, len);
91     bufferHead += len;
92     ret += len; return ret;
93   } else
94   {
95     // We'll hit the tail.
96     memcpy(outbuf + bufferHead, inbuf, (localTail - bufferHead));
97     ret += (localTail - bufferHead);
98     bufferHead = localTail; full = 1;
99     return ret;
100   }
101 }
102
103 int Stream::drain(int fd)
104 {
105   int ret = 0;
106   int localHead = bufferHead;
107   int written;
108   if (localHead == bufferTail && (!full)) return ret;
109
110   if (localHead <= bufferTail)
111   {
112     // Drain to the end of the buffer
113     written = write(fd, outbuf + bufferTail, (bufferSize - bufferTail));
114     if (written < 0) return ret;
115     full = 0;
116     ret += written;
117     if (written == (bufferSize - bufferTail))
118       bufferTail = 0;
119     else
120       bufferTail += written;
121     if (localHead == 0) return ret;
122   }
123   written = write(fd, outbuf + bufferTail, (localHead - bufferTail));
124   if (written < 0) return ret;
125   ret += written;
126   bufferTail += written;
127   return ret;
128 }