]> git.vomp.tv Git - vompclient.git/blob - stream.cc
Connection failure detection
[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 0;
45   bufferSize = bufsize;
46   bufferHead = 0;
47   bufferTail = 0;
48   bufferMark = -1;
49   initted = 1;
50   return 1;
51 }
52
53 void Stream::flush()
54 {
55   bufferHead = 0;
56   bufferTail = 0;
57   bufferMark = -1;
58 }
59
60 int Stream::put(UCHAR* inbuf, int len)
61 {
62   int ret = 0;
63   int tail = bufferTail;
64   int head = bufferHead;
65   if (tail == 0) tail = bufferSize;
66
67   if (head < tail)
68   {
69     // The free space is in one continuous chunk.
70     if (len < tail - head)
71     {
72       memcpy(outbuf + head, inbuf, len);
73       bufferHead += len;
74       ret = len;
75     }
76   }
77   else if (len <= bufferSize - head)
78   {
79     // There is enough space above the Head.
80     memcpy(outbuf + head, inbuf, len);
81     if (head + len == bufferSize)
82       bufferHead = 0;
83     else
84       bufferHead += len;
85     ret = len;
86   }
87   else if (len < tail)
88   {
89     bufferMark = head;
90     memcpy(outbuf, inbuf, len);
91     bufferHead = len;
92     ret = len;
93   }
94   return ret;
95 }
96   
97 int Stream::drain(int fd)
98 {
99   int ret = 0;
100   int head = bufferHead;
101   int tail = bufferTail;
102   int mark = bufferMark;
103   int written;
104
105   if (mark == -1 && tail > head) mark = bufferSize;
106
107   if (mark >= 0)
108   {
109     // Drain up to the marker.
110     written = write(fd, outbuf + tail, (mark - tail));
111     if (written < 0) return ret;
112     ret += written;
113     if (written == (mark - tail))
114     {
115       bufferMark = -1;
116       bufferTail = tail = 0;
117     }
118     else
119     {
120       bufferTail += written;
121       return ret;
122     }
123   }
124
125   if (tail == head) return ret; // Empty
126
127   written = write(fd, outbuf + tail, (head - tail));
128   if (written < 0) return ret;
129   ret += written;
130   bufferTail = tail + written;
131   return ret;
132 }