]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/stringbuf.c
Add FileMoveChunked(); which can read and write with offsets.
[citadel.git] / libcitadel / lib / stringbuf.c
index 0d88f7ca14f9c2e9925b744300194791c3334f7f..3e81aac65efa992a96496250c6668201e848e391 100644 (file)
@@ -1345,6 +1345,23 @@ int StrBufRemove_token(StrBuf *Source, int parmnum, char separator)
        return ReducedBy;
 }
 
+int StrBufExtract_tokenFromStr(StrBuf *dest, const char *Source, long SourceLen, int parmnum, char separator)
+{
+       const StrBuf Temp = {
+               (char*)Source,
+               SourceLen,
+               SourceLen,
+               1
+#ifdef SIZE_DEBUG
+               ,
+               0,
+               "",
+               ""
+#endif
+       };
+
+       return StrBufExtract_token(dest, &Temp, parmnum, separator);
+}
 
 /**
  * @ingroup StrBuf_Tokenizer
@@ -3892,18 +3909,38 @@ void FDIOBufferDelete(FDIOBuffer *FDB)
 
 int FileSendChunked(FDIOBuffer *FDB, const char **Err)
 {
-
+       ssize_t sent, pipesize;
 #ifdef LINUX_SPLICE
-       ssize_t sent;
-       sent = sendfile(FDB->IOB->fd, FDB->OtherFD, &FDB->TotalSentAlready, FDB->ChunkSendRemain);
+       if (FDB->PipeSize == 0)
+       {
+               pipesize = splice(FDB->OtherFD,
+                                 &FDB->TotalSentAlready, 
+                                 FDB->SplicePipe[1],
+                                 NULL, 
+                                 FDB->ChunkSendRemain, 
+                                 SPLICE_F_MOVE);
+       
+               if (pipesize == -1)
+               {
+                       *Err = strerror(errno);
+                       return pipesize;
+               }
+               FDB->PipeSize = pipesize;
+       }
+       sent =  splice(FDB->SplicePipe[0],
+                      NULL, 
+                      FDB->IOB->fd,
+                      NULL, 
+                      FDB->PipeSize,
+                      SPLICE_F_MORE | SPLICE_F_MOVE | SPLICE_F_NONBLOCK);
        if (sent == -1)
        {
                *Err = strerror(errno);
                return sent;
        }
+       FDB->PipeSize -= sent;
        FDB->ChunkSendRemain -= sent;
-       FDB->TotalSentAlready += sent;
-       return FDB->ChunkSendRemain;
+       return sent;
 #else
 
        char *pRead;
@@ -3940,25 +3977,105 @@ int FileRecvChunked(FDIOBuffer *FDB, const char **Err)
        ssize_t sent, pipesize;
 
 #ifdef LINUX_SPLICE
+       if (FDB->PipeSize == 0)
+       {
+               pipesize = splice(FDB->IOB->fd,
+                                 NULL, 
+                                 FDB->SplicePipe[1],
+                                 NULL, 
+                                 FDB->ChunkSendRemain, 
+                                 SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
+
+               if (pipesize == -1)
+               {
+                       *Err = strerror(errno);
+                       return pipesize;
+               }
+               FDB->PipeSize = pipesize;
+       }
+       
+       sent = splice(FDB->SplicePipe[0],
+                     NULL, 
+                     FDB->OtherFD,
+                     &FDB->TotalSentAlready, 
+                     FDB->PipeSize,
+                     SPLICE_F_MORE | SPLICE_F_MOVE);
 
-       pipesize = splice(FDB->IOB->fd, NULL, 
-                         FDB->SplicePipe[1], NULL, 
-                         FDB->ChunkSendRemain, 
-                         SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
-       if (pipesize == -1)
+       if (sent == -1)
        {
                *Err = strerror(errno);
-               return pipesize;
+               return sent;
+       }
+       FDB->PipeSize -= sent;
+       FDB->ChunkSendRemain -= sent;
+       return sent;
+#else
+       
+       sent = read(FDB->IOB->fd, FDB->ChunkBuffer->buf, FDB->ChunkSendRemain);
+       if (sent > 0) {
+               int nWritten = 0;
+               int rc; 
+               
+               FDB->ChunkBuffer->BufUsed = sent;
+
+               while (nWritten < FDB->ChunkBuffer->BufUsed) {
+                       rc =  write(FDB->OtherFD, FDB->ChunkBuffer->buf + nWritten, FDB->ChunkBuffer->BufUsed - nWritten);
+                       if (rc < 0) {
+                               *Err = strerror(errno);
+                               return rc;
+                       }
+                       nWritten += rc;
+
+               }
+               FDB->ChunkBuffer->BufUsed = 0;
+               FDB->TotalSentAlready += sent;
+               FDB->ChunkSendRemain -= sent;
+               return FDB->ChunkSendRemain;
+       }
+       else if (sent < 0) {
+               *Err = strerror(errno);
+               return sent;
+       }
+
+#endif
+       return 0;
+}
+
+int FileMoveChunked(FDIOBuffer *FDB, const char **Err)
+{
+       ssize_t sent, pipesize;
+
+#ifdef LINUX_SPLICE
+       if (FDB->PipeSize == 0)
+       {
+               pipesize = splice(FDB->IOB->fd,
+                                 &FDB->TotalReadAlready, 
+                                 FDB->SplicePipe[1],
+                                 NULL, 
+                                 FDB->ChunkSendRemain, 
+                                 SPLICE_F_MORE | SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
+
+               if (pipesize == -1)
+               {
+                       *Err = strerror(errno);
+                       return pipesize;
+               }
+               FDB->PipeSize = pipesize;
        }
        
-       sent = splice(FDB->SplicePipe[0], NULL, 
-                     FDB->OtherFD, &FDB->TotalSentAlready, 
-                     pipesize, SPLICE_F_MORE | SPLICE_F_MOVE);
+       sent = splice(FDB->SplicePipe[0],
+                     NULL, 
+                     FDB->OtherFD,
+                     &FDB->TotalSentAlready, 
+                     FDB->PipeSize,
+                     SPLICE_F_MORE | SPLICE_F_MOVE);
+
        if (sent == -1)
        {
                *Err = strerror(errno);
                return sent;
        }
+       FDB->PipeSize -= sent;
        FDB->ChunkSendRemain -= sent;
        return sent;
 #else