@@ -94,9 +94,8 @@ void Source::drainInto(Sink & sink)
9494{
9595 std::array<char , 8192 > buf;
9696 while (true ) {
97- size_t n;
9897 try {
99- n = read (buf.data (), buf.size ());
98+ auto n = read (buf.data (), buf.size ());
10099 sink ({buf.data (), n});
101100 } catch (EndOfFile &) {
102101 break ;
@@ -111,6 +110,16 @@ std::string Source::drain()
111110 return std::move (s.s );
112111}
113112
113+ void Source::skip (size_t len)
114+ {
115+ std::array<char , 8192 > buf;
116+ while (len) {
117+ auto n = read (buf.data (), std::min (len, buf.size ()));
118+ assert (n <= len);
119+ len -= n;
120+ }
121+ }
122+
114123size_t BufferedSource::read (char * data, size_t len)
115124{
116125 if (!buffer)
@@ -120,7 +129,7 @@ size_t BufferedSource::read(char * data, size_t len)
120129 bufPosIn = readUnbuffered (buffer.get (), bufSize);
121130
122131 /* Copy out the data in the buffer. */
123- size_t n = len > bufPosIn - bufPosOut ? bufPosIn - bufPosOut : len ;
132+ auto n = std::min ( len, bufPosIn - bufPosOut) ;
124133 memcpy (data, buffer.get () + bufPosOut, n);
125134 bufPosOut += n;
126135 if (bufPosIn == bufPosOut)
@@ -191,6 +200,39 @@ bool FdSource::hasData()
191200 }
192201}
193202
203+ void FdSource::skip (size_t len)
204+ {
205+ /* Discard data in the buffer. */
206+ if (len && buffer && bufPosIn - bufPosOut) {
207+ if (len >= bufPosIn - bufPosOut) {
208+ len -= bufPosIn - bufPosOut;
209+ bufPosIn = bufPosOut = 0 ;
210+ } else {
211+ bufPosOut += len;
212+ len = 0 ;
213+ }
214+ }
215+
216+ #ifndef _WIN32
217+ /* If we can, seek forward in the file to skip the rest. */
218+ if (isSeekable && len) {
219+ if (lseek (fd, len, SEEK_CUR) == -1 ) {
220+ if (errno == ESPIPE)
221+ isSeekable = false ;
222+ else
223+ throw SysError (" seeking forward in file" );
224+ } else {
225+ read += len;
226+ return ;
227+ }
228+ }
229+ #endif
230+
231+ /* Otherwise, skip by reading. */
232+ if (len)
233+ BufferedSource::skip (len);
234+ }
235+
194236size_t StringSource::read (char * data, size_t len)
195237{
196238 if (pos == s.size ())
0 commit comments