+ return InternalUnbufferedRead(To, Size) + tmp;
+ }
+ virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) = 0;
+ virtual bool InternalReadError() { return filefd->FileFdErrno("read",_("Read error")); }
+ virtual char * InternalReadLine(char * To, unsigned long long Size)
+ {
+ if (unlikely(Size == 0))
+ return nullptr;
+ --Size;
+ To[0] = '\0';
+ if (unlikely(Size == 0))
+ return To;
+ char * const InitialTo = To;
+
+ do {
+ if (buffersize == 0)
+ {
+ unsigned long long actualread = 0;
+ if (filefd->Read(buffer, buffersize_max, &actualread) == false)
+ return nullptr;
+ buffersize = actualread;
+ if (buffersize == 0)
+ {
+ if (To == InitialTo)
+ return nullptr;
+ break;
+ }
+ filefd->Flags &= ~FileFd::HitEof;
+ }
+
+ unsigned long long const OutputSize = std::min(Size, buffersize);
+ char const * const newline = static_cast<char const * const>(memchr(buffer, '\n', OutputSize));
+ if (newline != nullptr)
+ {
+ size_t length = (newline - buffer);
+ ++length;
+ memcpy(To, buffer, length);
+ To += length;
+ if (length < buffersize)
+ {
+ buffersize -= length;
+ memmove(buffer, buffer + length, buffersize);
+ }
+ else
+ buffersize = 0;
+ break;
+ }
+ else
+ {
+ memcpy(To, buffer, OutputSize);
+ To += OutputSize;
+ Size -= OutputSize;
+ buffersize -= OutputSize;
+ memmove(buffer, buffer + OutputSize, buffersize);
+ }
+ } while (Size > 0);
+ *To = '\0';
+ return InitialTo;