]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
Japanese manpage translation update
[apt.git] / apt-pkg / contrib / fileutl.cc
index de215a50bdd187a39837962fd2e5a7b6d21faa79..b7c7b231dba6bb5f3baacc5c11dc4ed811265732 100644 (file)
@@ -78,6 +78,9 @@
 
 using namespace std;
 
+/* Should be a multiple of the common page size (4096) */
+static constexpr unsigned long long APT_BUFFER_SIZE = 64 * 1024;
+
 // RunScripts - Run a set of scripts from a configuration subtree      /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -163,7 +166,7 @@ bool CopyFile(FileFd &From,FileFd &To)
       return false;
 
    // Buffered copy between fds
-   constexpr size_t BufSize = 64000;
+   constexpr size_t BufSize = APT_BUFFER_SIZE;
    std::unique_ptr<unsigned char[]> Buf(new unsigned char[BufSize]);
    unsigned long long ToRead = 0;
    do {
@@ -932,7 +935,7 @@ struct APT_HIDDEN simple_buffer {                                                   /*{{{*/
       reset(4096);
    }
    ~simple_buffer() {
-      delete buffer;
+      delete[] buffer;
    }
 
    const char *get() const { return buffer + bufferstart; }
@@ -965,9 +968,9 @@ struct APT_HIDDEN simple_buffer {                                                   /*{{{*/
    }
    ssize_t write(const void *from, unsigned long long requested_size) APT_MUSTCHECK
    {
-      if (buffersize_max - size() < requested_size)
-        requested_size = buffersize_max - size();
-      memcpy(buffer + bufferend, from, requested_size);
+      if (free() < requested_size)
+        requested_size = free();
+      memcpy(getend(), from, requested_size);
       bufferend += requested_size;
       if (bufferstart == bufferend)
         bufferstart = bufferend = 0;
@@ -1051,7 +1054,7 @@ public:
         {
            buffer.reset();
            unsigned long long actualread = 0;
-           if (filefd->Read(buffer.get(), buffer.buffersize_max, &actualread) == false)
+           if (filefd->Read(buffer.getend(), buffer.free(), &actualread) == false)
               return nullptr;
            buffer.bufferend = actualread;
            if (buffer.size() == 0)
@@ -1116,6 +1119,7 @@ public:
         return filefd->FileFdError("Seek on file %s because it couldn't be reopened", filefd->FileName.c_str());
 
       buffer.reset();
+      set_seekpos(0);
       if (To != 0)
         return filefd->Skip(To);
 
@@ -1247,7 +1251,7 @@ public:
         if (written < 0 && errno == EINTR)
            continue;
         if (written < 0)
-           return false;
+           return wrapped->InternalWriteError();
 
         writebuffer.bufferstart += written;
       }
@@ -1257,16 +1261,16 @@ public:
    }
    virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override
    {
-      size_t written = 0;
-
-      while (written < Size) {
-        auto buffered = writebuffer.write(static_cast<char const*>(From) + written, Size - written);
+      // Optimisation: If the buffer is empty and we have more to write than
+      // would fit in the buffer (or equal number of bytes), write directly.
+      if (writebuffer.empty() == true && Size >= writebuffer.free())
+        return wrapped->InternalWrite(From, Size);
 
-        written += buffered;
+      // Write as much into the buffer as possible and then flush if needed
+      auto written = writebuffer.write(From, Size);
 
-        if (writebuffer.full() && InternalFlush() == false)
-              return -1;
-      }
+      if (writebuffer.full() && InternalFlush() == false)
+        return -1;
 
       return written;
    }
@@ -1500,7 +1504,6 @@ public:
 };
                                                                        /*}}}*/
 class APT_HIDDEN Lz4FileFdPrivate: public FileFdPrivate {                              /*{{{*/
-   static constexpr unsigned long long BLK_SIZE = 64 * 1024;
    static constexpr unsigned long long LZ4_HEADER_SIZE = 19;
    static constexpr unsigned long long LZ4_FOOTER_SIZE = 4;
 #ifdef HAVE_LZ4
@@ -1510,7 +1513,7 @@ class APT_HIDDEN Lz4FileFdPrivate: public FileFdPrivate {                         /*{{{*/
    FileFd backend;
    simple_buffer lz4_buffer;
    // Count of bytes that the decompressor expects to read next, or buffer size.
-   size_t next_to_load = BLK_SIZE;
+   size_t next_to_load = APT_BUFFER_SIZE;
 public:
    virtual bool InternalOpen(int const iFd, unsigned int const Mode) override
    {
@@ -1519,11 +1522,11 @@ public:
 
       if ((Mode & FileFd::WriteOnly) == FileFd::WriteOnly) {
         res = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION);
-        lz4_buffer.reset(LZ4F_compressBound(BLK_SIZE, nullptr)
+        lz4_buffer.reset(LZ4F_compressBound(APT_BUFFER_SIZE, nullptr)
                          + LZ4_HEADER_SIZE + LZ4_FOOTER_SIZE);
       } else {
         res = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
-        lz4_buffer.reset(64 * 1024);
+        lz4_buffer.reset(APT_BUFFER_SIZE);
       }
 
       filefd->Flags |= FileFd::Compressed;
@@ -1591,7 +1594,7 @@ public:
    }
    virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override
    {
-      unsigned long long const towrite = std::min(BLK_SIZE, Size);
+      unsigned long long const towrite = std::min(APT_BUFFER_SIZE, Size);
 
       res = LZ4F_compressUpdate(cctx,
                                lz4_buffer.buffer, lz4_buffer.buffersize_max,
@@ -1619,7 +1622,7 @@ public:
    {
       /* Reset variables */
       res = 0;
-      next_to_load = BLK_SIZE;
+      next_to_load = APT_BUFFER_SIZE;
 
       if (cctx != nullptr)
       {
@@ -1813,6 +1816,7 @@ public:
    }
    virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override
    {
+      ssize_t Res;
       lzma->stream.next_in = (uint8_t *)From;
       lzma->stream.avail_in = Size;
       lzma->stream.next_out = lzma->buffer;
@@ -1823,9 +1827,21 @@ public:
       size_t const n = sizeof(lzma->buffer)/sizeof(lzma->buffer[0]) - lzma->stream.avail_out;
       size_t const m = (n == 0) ? 0 : fwrite(lzma->buffer, 1, n, lzma->file);
       if (m != n)
-        return -1;
+      {
+        Res = -1;
+        errno = 0;
+      }
       else
-        return Size - lzma->stream.avail_in;
+      {
+        Res = Size - lzma->stream.avail_in;
+        if (Res == 0)
+        {
+           // lzma run was okay, but produced no output…
+           Res = -1;
+           errno = EINTR;
+        }
+      }
+      return Res;
    }
    virtual bool InternalWriteError() override
    {
@@ -2422,10 +2438,18 @@ bool FileFd::Write(const void *From,unsigned long long Size)
    while (Res > 0 && Size > 0)
    {
       Res = d->InternalWrite(From, Size);
-      if (Res < 0 && errno == EINTR)
-        continue;
+
       if (Res < 0)
+      {
+        if (errno == EINTR)
+        {
+           // trick the while-loop into running again
+           Res = 1;
+           errno = 0;
+           continue;
+        }
         return d->InternalWriteError();
+      }
 
       From = (char const *)From + Res;
       Size -= Res;