]> git.vomp.tv Git - vompclient.git/blob - stream.cc
Fix some demuxer bugs
[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   initted = 1;
48   return 0;
49 }
50
51 void Stream::flush()
52 {
53   bufferHead = bufferTail = 0;
54 }
55
56 int Stream::put(UCHAR* inbuf, int len)
57 {
58   int ret = 0;
59   int localTail = bufferTail;
60   if (localTail == 0) localTail = bufferSize;
61   if (len == 0) return ret;
62
63   if (bufferHead >= localTail)
64   {
65     // We have free rein to the end of the buffer
66     if (len < (bufferSize - bufferHead))
67     {
68       // We won't reach the end of the buffer.
69       memcpy(outbuf + bufferHead, inbuf, len);
70       bufferHead += len;
71       ret += len; return ret;
72     } else
73     {
74       // We'll reach the end of the buffer and loop round.
75       memcpy(outbuf + bufferHead, inbuf, (bufferSize - bufferHead));
76       inbuf += (bufferSize - bufferHead);
77       ret += (bufferSize - bufferHead);
78       len -= (bufferSize - bufferHead);
79       bufferHead = 0;
80       if (len == 0) return ret;
81     }
82   }
83
84   if (localTail - bufferHead == 1) return ret; // Full
85
86   // We can advance the head up to the tail
87   // If we reach it, we are full.
88   if (len < (localTail - bufferHead - 1))
89   {
90     // We'll fall short of the tail.
91     memcpy(outbuf + bufferHead, inbuf, len);
92     bufferHead += len;
93     ret += len; return ret;
94   } else
95   {
96     // We'll hit the tail.
97     memcpy(outbuf + bufferHead, inbuf, (localTail - bufferHead - 1));
98     ret += (localTail - bufferHead - 1);
99     bufferHead = localTail - 1;
100     return ret;
101   }
102 }
103
104 int Stream::drain(int fd)
105 {
106   int ret = 0;
107   int localHead = bufferHead;
108   int written;
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     ret += written;
116     if (written == (bufferSize - bufferTail))
117       bufferTail = 0;
118     else
119     {
120       bufferTail += written;
121       return ret;
122     }
123   }
124
125   if (localHead == bufferTail) return ret; // Empty
126
127   written = write(fd, outbuf + bufferTail, (localHead - bufferTail));
128   if (written < 0) return ret;
129   ret += written;
130   bufferTail += written;
131   return ret;
132 }