update python
[enigma2.git] / lib / base / buffer.cpp
1 #include <lib/base/buffer.h>
2 #include <lib/base/eerror.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 void eIOBuffer::removeblock()
8 {
9         ASSERT(!buffer.empty());
10         eIOBufferData &b=buffer.front();
11         delete[] b.data;
12         buffer.pop_front();
13         ptr=0;
14 }
15
16 eIOBuffer::eIOBufferData &eIOBuffer::addblock()
17 {
18         eIOBufferData s;
19         s.data=new __u8[allocationsize];
20         s.len=0;
21         buffer.push_back(s);
22         return buffer.back();
23 }
24
25 eIOBuffer::~eIOBuffer()
26 {
27         clear();
28 }
29
30 void eIOBuffer::clear()
31 {
32         while (!buffer.empty())
33                 removeblock();
34 }
35
36 int eIOBuffer::size() const
37 {
38         int total=0;
39         for (std::list<eIOBufferData>::const_iterator i(buffer.begin()); i != buffer.end(); ++i)
40                 total+=i->len;
41         total-=ptr;
42         return total;
43 }
44
45 int eIOBuffer::empty() const
46 {
47         return buffer.empty();
48 }
49
50 int eIOBuffer::peek(void *dest, int len) const
51 {
52         __u8 *dst=(__u8*)dest;
53         std::list<eIOBufferData>::const_iterator i(buffer.begin());
54         int p=ptr;
55         int written=0;
56         while (len)
57         {       
58                 if (i == buffer.end())
59                         break;
60                 int tc=i->len-p;
61                 if (tc > len)
62                         tc = len;
63         
64                 memcpy(dst, i->data+p, tc);
65                 dst+=tc;
66                 written+=tc;
67         
68                 ++i;
69                 p=0;
70                         
71                 len-=tc;
72         }
73         return written;
74 }
75
76 void eIOBuffer::skip(int len)
77 {
78         while (len)
79         {
80                 ASSERT(! buffer.empty());
81                 int tn=len;
82                 if (tn > (buffer.front().len-ptr))
83                         tn=buffer.front().len-ptr;
84
85                 ptr+=tn;
86                 if (ptr == buffer.front().len)
87                         removeblock();
88                 len-=tn;
89         }
90 }
91
92 int eIOBuffer::read(void *dest, int len)
93 {
94         __u8 *dst=(__u8*)dest;
95         len=peek(dst, len);
96         skip(len);
97         return len;
98 }
99
100 void eIOBuffer::write(const void *source, int len)
101 {
102         const __u8 *src=(const __u8*)source;
103         while (len)
104         {
105                 int tc=len;
106                 if (buffer.empty() || (allocationsize == buffer.back().len))
107                         addblock();
108                 if (tc > allocationsize-buffer.back().len)
109                         tc=allocationsize-buffer.back().len;
110                 memcpy(buffer.back().data+buffer.back().len, src, tc);
111                 src+=tc;
112                 buffer.back().len+=tc;
113                 len-=tc;
114         }
115 }
116
117 int eIOBuffer::fromfile(int fd, int len)
118 {
119         int re=0;
120         while (len)
121         {
122                 int tc=len;
123                 int r;
124                 if (buffer.empty() || (allocationsize == buffer.back().len))
125                         addblock();
126                 if (tc > allocationsize-buffer.back().len)
127                         tc=allocationsize-buffer.back().len;
128                 r=::read(fd, buffer.back().data+buffer.back().len, tc);
129                 buffer.back().len+=r;
130                 len-=r;
131                 if (r < 0)
132                 {
133                         if (errno != EWOULDBLOCK)
134                                 eDebug("read: %m");
135                         r=0;
136                 }
137                 re+=r;
138                 if (r != tc)
139                         break;
140         }
141         return re;
142 }
143
144 int eIOBuffer::tofile(int fd, int len)
145 {
146         int written=0;
147         int w;
148         while (len && !buffer.empty())
149         {       
150                 if (buffer.begin() == buffer.end())
151                         break;
152                 int tc=buffer.front().len-ptr;
153                 if (tc > len)
154                         tc = len;
155         
156                 w=::write(fd, buffer.front().data+ptr, tc);
157                 if (w < 0)
158                 {
159                         if (errno != EWOULDBLOCK)
160                                 eDebug("write: %m");
161                         w=0;
162                 }
163                 ptr+=w;
164                 if (ptr == buffer.front().len)
165                         removeblock();
166                 written+=w;     
167
168                 len-=w;
169                 if (tc != w)
170                         break;
171         }
172         return written;
173 }
174
175 int eIOBuffer::searchchr(char ch) const
176 {
177         std::list<eIOBufferData>::const_iterator i(buffer.begin());
178         int p=ptr;
179         int c=0;
180         while (1)
181         {       
182                 if (i == buffer.end())
183                         break;
184                 while (p < i->len)
185                 {
186                         if (i->data[p] == ch)
187                                 return c;
188                         else
189                                 c++, p++;
190                 }
191                 ++i;
192                 p=0;
193         }
194         return -1;
195 }
196