"finished" message also when skipping configuration backup
[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=0;
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                 if (r < 0)
131                 {
132                         if (errno != EWOULDBLOCK && errno != EBUSY && errno != EINTR)
133                                 eDebug("couldn't read: %m");
134                 }
135                 else
136                 {
137                         len-=r;
138                         re+=r;
139                         if (r != tc)
140                                 break;
141                 }
142         }
143         return re;
144 }
145
146 int eIOBuffer::tofile(int fd, int len)
147 {
148         int written=0;
149         int w;
150         while (len && !buffer.empty())
151         {       
152                 if (buffer.begin() == buffer.end())
153                         break;
154                 int tc=buffer.front().len-ptr;
155                 if (tc > len)
156                         tc = len;
157         
158                 w=::write(fd, buffer.front().data+ptr, tc);
159                 if (w < 0)
160                 {
161                         if (errno != EWOULDBLOCK && errno != EBUSY && errno != EINTR)
162                                 eDebug("write: %m");
163                         w=0;
164                 }
165                 ptr+=w;
166                 if (ptr == buffer.front().len)
167                         removeblock();
168                 written+=w;     
169
170                 len-=w;
171                 if (tc != w)
172                         break;
173         }
174         return written;
175 }
176
177 int eIOBuffer::searchchr(char ch) const
178 {
179         std::list<eIOBufferData>::const_iterator i(buffer.begin());
180         int p=ptr;
181         int c=0;
182         while (1)
183         {       
184                 if (i == buffer.end())
185                         break;
186                 while (p < i->len)
187                 {
188                         if (i->data[p] == ch)
189                                 return c;
190                         else
191                                 c++, p++;
192                 }
193                 ++i;
194                 p=0;
195         }
196         return -1;
197 }
198