]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
FildFd: Introduce a Flush() function and call it from Close()
[apt.git] / apt-pkg / contrib / fileutl.cc
index 38ae0246ead05a1498c20f225a4f1b2cd6da636f..ecc8c83fd3b7a4ae5af660205bdf66fb280712b8 100644 (file)
@@ -928,6 +928,7 @@ struct APT_HIDDEN simple_buffer {                                                   /*{{{*/
    const char *get() const { return buffer + bufferstart; }
    char *get() { return buffer + bufferstart; }
    bool empty() const { return bufferend <= bufferstart; }
+   bool full() const { return bufferend == buffersize_max; }
    unsigned long long size() const { return bufferend-bufferstart; }
    void reset() { bufferend = bufferstart = 0; }
    ssize_t read(void *to, unsigned long long requested_size) APT_MUSTCHECK
@@ -940,6 +941,16 @@ struct APT_HIDDEN simple_buffer {                                                  /*{{{*/
         bufferstart = bufferend = 0;
       return requested_size;
    }
+   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);
+      bufferend += requested_size;
+      if (bufferstart == bufferend)
+        bufferstart = bufferend = 0;
+      return requested_size;
+   }
 };
                                                                        /*}}}*/
 
@@ -947,16 +958,49 @@ class APT_HIDDEN FileFdPrivate {                                                  /*{{{*/
 protected:
    FileFd * const filefd;
    simple_buffer buffer;
-public:
    int compressed_fd;
    pid_t compressor_pid;
    bool is_pipe;
    APT::Configuration::Compressor compressor;
    unsigned int openmode;
    unsigned long long seekpos;
+public:
+
    explicit FileFdPrivate(FileFd * const pfilefd) : filefd(pfilefd),
       compressed_fd(-1), compressor_pid(-1), is_pipe(false),
       openmode(0), seekpos(0) {};
+   virtual APT::Configuration::Compressor get_compressor() const
+   {
+      return compressor;
+   }
+   virtual void set_compressor(APT::Configuration::Compressor const &compressor)
+   {
+      this->compressor = compressor;
+   }
+   virtual unsigned int get_openmode() const
+   {
+      return openmode;
+   }
+   virtual void set_openmode(unsigned int openmode)
+   {
+      this->openmode = openmode;
+   }
+   virtual bool get_is_pipe() const
+   {
+      return is_pipe;
+   }
+   virtual void set_is_pipe(bool is_pipe)
+   {
+      this->is_pipe = is_pipe;
+   }
+   virtual unsigned long long get_seekpos() const
+   {
+      return seekpos;
+   }
+   virtual void set_seekpos(unsigned long long seekpos)
+   {
+      this->seekpos = seekpos;
+   }
 
    virtual bool InternalOpen(int const iFd, unsigned int const Mode) = 0;
    ssize_t InternalRead(void * To, unsigned long long Size)
@@ -1011,6 +1055,10 @@ public:
       *To = '\0';
       return InitialTo;
    }
+   virtual bool InternalFlush()
+   {
+      return true;
+   }
    virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) = 0;
    virtual bool InternalWriteError() { return filefd->FileFdErrno("write",_("Write error")); }
    virtual bool InternalSeek(unsigned long long const To)
@@ -1515,7 +1563,7 @@ public:
         SetCloseExec(Pipe[J],true);
 
       compressed_fd = filefd->iFd;
-      is_pipe = true;
+      set_is_pipe(true);
 
       if (Comp == true)
         filefd->iFd = Pipe[1];
@@ -1937,8 +1985,8 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
       else
         d = new PipedFileFdPrivate(this);
 
-      d->openmode = Mode;
-      d->compressor = compressor;
+      d->set_openmode(Mode);
+      d->set_compressor(compressor);
       if ((Flags & AutoClose) != AutoClose && d->InternalAlwaysAutoClose())
       {
         // Need to duplicate fd here or gz/bz2 close for cleanup will close the fd as well
@@ -1996,7 +2044,7 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
       To = (char *)To + Res;
       Size -= Res;
       if (d != NULL)
-        d->seekpos += Res;
+        d->set_seekpos(d->get_seekpos() + Res);
       if (Actual != 0)
         *Actual += Res;
    }
@@ -2026,6 +2074,15 @@ char* FileFd::ReadLine(char *To, unsigned long long const Size)
    return d->InternalReadLine(To, Size);
 }
                                                                        /*}}}*/
+// FileFd::Flush - Flush the file                                      /*{{{*/
+bool FileFd::Flush()
+{
+   if (d == nullptr)
+      return true;
+
+   return d->InternalFlush();
+}
+                                                                       /*}}}*/
 // FileFd::Write - Write to the file                                   /*{{{*/
 bool FileFd::Write(const void *From,unsigned long long Size)
 {
@@ -2044,7 +2101,7 @@ bool FileFd::Write(const void *From,unsigned long long Size)
       From = (char const *)From + Res;
       Size -= Res;
       if (d != NULL)
-        d->seekpos += Res;
+        d->set_seekpos(d->get_seekpos() + Res);
    }
 
    if (Size == 0)
@@ -2112,13 +2169,13 @@ unsigned long long FileFd::Tell()
    off_t const Res = d->InternalTell();
    if (Res == (off_t)-1)
       FileFdErrno("lseek","Failed to determine the current file position");
-   d->seekpos = Res;
+   d->set_seekpos(Res);
    return Res;
 }
                                                                        /*}}}*/
 static bool StatFileFd(char const * const msg, int const iFd, std::string const &FileName, struct stat &Buf, FileFdPrivate * const d) /*{{{*/
 {
-   bool ispipe = (d != NULL && d->is_pipe == true);
+   bool ispipe = (d != NULL && d->get_is_pipe() == true);
    if (ispipe == false)
    {
       if (fstat(iFd,&Buf) != 0)
@@ -2135,7 +2192,7 @@ static bool StatFileFd(char const * const msg, int const iFd, std::string const
       // we set it here, too, as we get the info here for free
       // in theory the Open-methods should take care of it already
       if (d != NULL)
-        d->is_pipe = true;
+        d->set_is_pipe(true);
       if (stat(FileName.c_str(), &Buf) != 0)
         return _error->Errno("fstat", "Unable to determine %s for file %s", msg, FileName.c_str());
    }
@@ -2179,6 +2236,8 @@ unsigned long long FileFd::Size()
 /* */
 bool FileFd::Close()
 {
+   if (Flush() == false)
+      return false;
    if (iFd == -1)
       return true;