\doxysubsection{tube.\+c}
\label{tube_8c_source}\index{tube.c@{tube.c}}
\mbox{\hyperlink{tube_8c}{Go to the documentation of this file.}}
\begin{DoxyCode}{0}
\DoxyCodeLine{00001 \textcolor{comment}{/*= -\/*-\/ c-\/basic-\/offset: 4; indent-\/tabs-\/mode: nil; -\/*-\/}}
\DoxyCodeLine{00002 \textcolor{comment}{ *}}
\DoxyCodeLine{00003 \textcolor{comment}{ * librsync -\/-\/ dynamic caching and delta update in HTTP}}
\DoxyCodeLine{00004 \textcolor{comment}{ *}}
\DoxyCodeLine{00005 \textcolor{comment}{ * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net>}}
\DoxyCodeLine{00006 \textcolor{comment}{ *}}
\DoxyCodeLine{00007 \textcolor{comment}{ * This program is free software; you can redistribute it and/or modify}}
\DoxyCodeLine{00008 \textcolor{comment}{ * it under the terms of the GNU Lesser General Public License as published by}}
\DoxyCodeLine{00009 \textcolor{comment}{ * the Free Software Foundation; either version 2.1 of the License, or}}
\DoxyCodeLine{00010 \textcolor{comment}{ * (at your option) any later version.}}
\DoxyCodeLine{00011 \textcolor{comment}{ *}}
\DoxyCodeLine{00012 \textcolor{comment}{ * This program is distributed in the hope that it will be useful,}}
\DoxyCodeLine{00013 \textcolor{comment}{ * but WITHOUT ANY WARRANTY; without even the implied warranty of}}
\DoxyCodeLine{00014 \textcolor{comment}{ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the}}
\DoxyCodeLine{00015 \textcolor{comment}{ * GNU Lesser General Public License for more details.}}
\DoxyCodeLine{00016 \textcolor{comment}{ *}}
\DoxyCodeLine{00017 \textcolor{comment}{ * You should have received a copy of the GNU Lesser General Public License}}
\DoxyCodeLine{00018 \textcolor{comment}{ * along with this program; if not, write to the Free Software}}
\DoxyCodeLine{00019 \textcolor{comment}{ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.}}
\DoxyCodeLine{00020 \textcolor{comment}{ */}}
\DoxyCodeLine{00021 }
\DoxyCodeLine{00022                               \textcolor{comment}{/*=}}
\DoxyCodeLine{00023 \textcolor{comment}{                               | Where a calculator on the ENIAC is}}
\DoxyCodeLine{00024 \textcolor{comment}{                               | equpped with 18,000 vaccuum tubes and}}
\DoxyCodeLine{00025 \textcolor{comment}{                               | weighs 30 tons, computers in the}}
\DoxyCodeLine{00026 \textcolor{comment}{                               | future may have only 1,000 vaccuum}}
\DoxyCodeLine{00027 \textcolor{comment}{                               | tubes and perhaps weigh 1 1/2}}
\DoxyCodeLine{00028 \textcolor{comment}{                               | tons.}}
\DoxyCodeLine{00029 \textcolor{comment}{                               |   -\/-\/ Popular Mechanics, March 1949}}
\DoxyCodeLine{00030 \textcolor{comment}{                               */}}
\DoxyCodeLine{00031 \textcolor{comment}{}}
\DoxyCodeLine{00032 \textcolor{comment}{/** \(\backslash\)file tube.c}}
\DoxyCodeLine{00033 \textcolor{comment}{ * A somewhat elastic but fairly small buffer for data passing through a}}
\DoxyCodeLine{00034 \textcolor{comment}{ * stream.}}
\DoxyCodeLine{00035 \textcolor{comment}{ *}}
\DoxyCodeLine{00036 \textcolor{comment}{ * In most cases the iter can adjust to send just as much data will fit. In}}
\DoxyCodeLine{00037 \textcolor{comment}{ * some cases that would be too complicated, because it has to transmit an}}
\DoxyCodeLine{00038 \textcolor{comment}{ * integer or something similar. So in that case we stick whatever won't fit}}
\DoxyCodeLine{00039 \textcolor{comment}{ * into a small buffer.}}
\DoxyCodeLine{00040 \textcolor{comment}{ *}}
\DoxyCodeLine{00041 \textcolor{comment}{ * A tube can contain some literal data to go out (typically command bytes),}}
\DoxyCodeLine{00042 \textcolor{comment}{ * and also an instruction to copy data from the stream's input or from some}}
\DoxyCodeLine{00043 \textcolor{comment}{ * other location. Both literal data and a copy command can be queued at the}}
\DoxyCodeLine{00044 \textcolor{comment}{ * same time, but only in that order and at most one of each.}}
\DoxyCodeLine{00045 \textcolor{comment}{ *}}
\DoxyCodeLine{00046 \textcolor{comment}{ * \(\backslash\)todo As an optimization, write it directly to the stream if possible. But}}
\DoxyCodeLine{00047 \textcolor{comment}{ * for simplicity don't do that yet.}}
\DoxyCodeLine{00048 \textcolor{comment}{ *}}
\DoxyCodeLine{00049 \textcolor{comment}{ * \(\backslash\)todo I think our current copy code will lock up if the application only}}
\DoxyCodeLine{00050 \textcolor{comment}{ * ever calls us with either input or output buffers, and not both. So I guess}}
\DoxyCodeLine{00051 \textcolor{comment}{ * in that case we might need to copy into some temporary buffer space, and}}
\DoxyCodeLine{00052 \textcolor{comment}{ * then back out again later. */}}
\DoxyCodeLine{00053 }
\DoxyCodeLine{00054 \textcolor{preprocessor}{\#include "{}config.h"{}}             \textcolor{comment}{/* IWYU pragma: keep */}}
\DoxyCodeLine{00055 \textcolor{preprocessor}{\#include <assert.h>}}
\DoxyCodeLine{00056 \textcolor{preprocessor}{\#include <stdlib.h>}}
\DoxyCodeLine{00057 \textcolor{preprocessor}{\#include <string.h>}}
\DoxyCodeLine{00058 \textcolor{preprocessor}{\#include "{}librsync.h"{}}}
\DoxyCodeLine{00059 \textcolor{preprocessor}{\#include "{}job.h"{}}}
\DoxyCodeLine{00060 \textcolor{preprocessor}{\#include "{}scoop.h"{}}}
\DoxyCodeLine{00061 \textcolor{preprocessor}{\#include "{}trace.h"{}}}
\DoxyCodeLine{00062 }
\DoxyCodeLine{00063 \textcolor{keyword}{static} \textcolor{keywordtype}{void} rs\_tube\_catchup\_write(rs\_job\_t *job)}
\DoxyCodeLine{00064 \{}
\DoxyCodeLine{00065     rs\_buffers\_t *stream = job-\/>stream;}
\DoxyCodeLine{00066     \textcolor{keywordtype}{size\_t} len = job-\/>write\_len;}
\DoxyCodeLine{00067 }
\DoxyCodeLine{00068     assert(len > 0);}
\DoxyCodeLine{00069     \textcolor{keywordflow}{if} (len > stream-\/>avail\_out)}
\DoxyCodeLine{00070         len = stream-\/>avail\_out;}
\DoxyCodeLine{00071     \textcolor{keywordflow}{if} (len) \{}
\DoxyCodeLine{00072         memcpy(stream-\/>next\_out, job-\/>write\_buf, len);}
\DoxyCodeLine{00073         stream-\/>next\_out += len;}
\DoxyCodeLine{00074         stream-\/>avail\_out -\/= len;}
\DoxyCodeLine{00075         job-\/>write\_len -\/= len;}
\DoxyCodeLine{00076         \textcolor{keywordflow}{if} (job-\/>write\_len > 0)}
\DoxyCodeLine{00077             \textcolor{comment}{/* Still something left in the tube, shuffle it to the front. */}}
\DoxyCodeLine{00078             memmove(job-\/>write\_buf, job-\/>write\_buf + len, job-\/>write\_len);}
\DoxyCodeLine{00079     \}}
\DoxyCodeLine{00080     rs\_trace(\textcolor{stringliteral}{"{}wrote "{}} FMT\_SIZE \textcolor{stringliteral}{"{} bytes from tube, "{}} FMT\_SIZE \textcolor{stringliteral}{"{} left to write"{}},}
\DoxyCodeLine{00081              len, job-\/>write\_len);}
\DoxyCodeLine{00082 \}}
\DoxyCodeLine{00083 \textcolor{comment}{}}
\DoxyCodeLine{00084 \textcolor{comment}{/** Catch up on an outstanding copy command.}}
\DoxyCodeLine{00085 \textcolor{comment}{ *}}
\DoxyCodeLine{00086 \textcolor{comment}{ * Takes data from the scoop and writes as much as will fit to the output, up}}
\DoxyCodeLine{00087 \textcolor{comment}{ * to the limit of the outstanding copy. */}}
\DoxyCodeLine{00088 \textcolor{keyword}{static} \textcolor{keywordtype}{void} rs\_tube\_catchup\_copy(rs\_job\_t *job)}
\DoxyCodeLine{00089 \{}
\DoxyCodeLine{00090     assert(job-\/>write\_len == 0);}
\DoxyCodeLine{00091     assert(job-\/>copy\_len > 0);}
\DoxyCodeLine{00092     rs\_buffers\_t *stream = job-\/>stream;}
\DoxyCodeLine{00093     \textcolor{keywordtype}{size\_t} copy\_len = job-\/>copy\_len;}
\DoxyCodeLine{00094     \textcolor{keywordtype}{size\_t} avail\_in = rs\_scoop\_avail(job);}
\DoxyCodeLine{00095     \textcolor{keywordtype}{size\_t} avail\_out = stream-\/>avail\_out;}
\DoxyCodeLine{00096     \textcolor{keywordtype}{size\_t} len, ilen;}
\DoxyCodeLine{00097     \textcolor{keywordtype}{void} *next;}
\DoxyCodeLine{00098 }
\DoxyCodeLine{00099     \textcolor{keywordflow}{if} (copy\_len > avail\_in)}
\DoxyCodeLine{00100         copy\_len = avail\_in;}
\DoxyCodeLine{00101     \textcolor{keywordflow}{if} (copy\_len > avail\_out)}
\DoxyCodeLine{00102         copy\_len = avail\_out;}
\DoxyCodeLine{00103     len = copy\_len;}
\DoxyCodeLine{00104     \textcolor{keywordflow}{for} (next = rs\_scoop\_iterbuf(job, \&len, \&ilen); ilen > 0;}
\DoxyCodeLine{00105          next = rs\_scoop\_nextbuf(job, \&len, \&ilen)) \{}
\DoxyCodeLine{00106         memcpy(stream-\/>next\_out, next, ilen);}
\DoxyCodeLine{00107         stream-\/>next\_out += ilen;}
\DoxyCodeLine{00108         stream-\/>avail\_out -\/= ilen;}
\DoxyCodeLine{00109         job-\/>copy\_len -\/= ilen;}
\DoxyCodeLine{00110     \}}
\DoxyCodeLine{00111     rs\_trace(\textcolor{stringliteral}{"{}copied "{}} FMT\_SIZE \textcolor{stringliteral}{"{} bytes from scoop, "{}} FMT\_SIZE}
\DoxyCodeLine{00112              \textcolor{stringliteral}{"{} left in scoop, "{}} FMT\_SIZE \textcolor{stringliteral}{"{} left to copy"{}}, copy\_len,}
\DoxyCodeLine{00113              rs\_scoop\_avail(job), job-\/>copy\_len);}
\DoxyCodeLine{00114 \}}
\DoxyCodeLine{00115 \textcolor{comment}{}}
\DoxyCodeLine{00116 \textcolor{comment}{/** Put whatever will fit from the tube into the output of the stream.}}
\DoxyCodeLine{00117 \textcolor{comment}{ *}}
\DoxyCodeLine{00118 \textcolor{comment}{ * \(\backslash\)return RS\_DONE if the tube is now empty and ready to accept another}}
\DoxyCodeLine{00119 \textcolor{comment}{ * command, RS\_BLOCKED if there is still stuff waiting to go out. */}}
\DoxyCodeLine{00120 rs\_result rs\_tube\_catchup(rs\_job\_t *job)}
\DoxyCodeLine{00121 \{}
\DoxyCodeLine{00122     \textcolor{keywordflow}{if} (job-\/>write\_len) \{}
\DoxyCodeLine{00123         rs\_tube\_catchup\_write(job);}
\DoxyCodeLine{00124         \textcolor{keywordflow}{if} (job-\/>write\_len)}
\DoxyCodeLine{00125             \textcolor{keywordflow}{return} RS\_BLOCKED;}
\DoxyCodeLine{00126     \}}
\DoxyCodeLine{00127 }
\DoxyCodeLine{00128     \textcolor{keywordflow}{if} (job-\/>copy\_len) \{}
\DoxyCodeLine{00129         rs\_tube\_catchup\_copy(job);}
\DoxyCodeLine{00130         \textcolor{keywordflow}{if} (job-\/>copy\_len) \{}
\DoxyCodeLine{00131             \textcolor{keywordflow}{if} (rs\_scoop\_eof(job)) \{}
\DoxyCodeLine{00132                 rs\_error(\textcolor{stringliteral}{"{}reached end of file while copying data"{}});}
\DoxyCodeLine{00133                 \textcolor{keywordflow}{return} RS\_INPUT\_ENDED;}
\DoxyCodeLine{00134             \}}
\DoxyCodeLine{00135             \textcolor{keywordflow}{return} RS\_BLOCKED;}
\DoxyCodeLine{00136         \}}
\DoxyCodeLine{00137     \}}
\DoxyCodeLine{00138     \textcolor{keywordflow}{return} RS\_DONE;}
\DoxyCodeLine{00139 \}}
\DoxyCodeLine{00140 }
\DoxyCodeLine{00141 \textcolor{comment}{/* Check whether there is data in the tube waiting to go out.}}
\DoxyCodeLine{00142 \textcolor{comment}{}}
\DoxyCodeLine{00143 \textcolor{comment}{   \(\backslash\)return true if the previous command has finished doing all its output. */}}
\DoxyCodeLine{00144 \textcolor{keywordtype}{int} rs\_tube\_is\_idle(rs\_job\_t \textcolor{keyword}{const} *job)}
\DoxyCodeLine{00145 \{}
\DoxyCodeLine{00146     \textcolor{keywordflow}{return} job-\/>write\_len == 0 \&\& job-\/>copy\_len == 0;}
\DoxyCodeLine{00147 \}}
\DoxyCodeLine{00148 \textcolor{comment}{}}
\DoxyCodeLine{00149 \textcolor{comment}{/** Queue up a request to copy through \(\backslash\)p len bytes from the input to the}}
\DoxyCodeLine{00150 \textcolor{comment}{ * output of the stream.}}
\DoxyCodeLine{00151 \textcolor{comment}{ *}}
\DoxyCodeLine{00152 \textcolor{comment}{ * The data is copied from the scoop (if there is anything there) or from the}}
\DoxyCodeLine{00153 \textcolor{comment}{ * input, on the next call to rs\_tube\_write().}}
\DoxyCodeLine{00154 \textcolor{comment}{ *}}
\DoxyCodeLine{00155 \textcolor{comment}{ * We can only accept this request if there is no copy command already pending.}}
\DoxyCodeLine{00156 \textcolor{comment}{ *}}
\DoxyCodeLine{00157 \textcolor{comment}{ * \(\backslash\)todo Try to do the copy immediately, and return a result. Then, people can}}
\DoxyCodeLine{00158 \textcolor{comment}{ * try to continue if possible. Is this really required? Callers can just go}}
\DoxyCodeLine{00159 \textcolor{comment}{ * out and back in again after flushing the tube. */}}
\DoxyCodeLine{00160 \textcolor{keywordtype}{void} rs\_tube\_copy(rs\_job\_t *job, \textcolor{keywordtype}{size\_t} len)}
\DoxyCodeLine{00161 \{}
\DoxyCodeLine{00162     assert(job-\/>copy\_len == 0);}
\DoxyCodeLine{00163 }
\DoxyCodeLine{00164     job-\/>copy\_len = len;}
\DoxyCodeLine{00165 \}}
\DoxyCodeLine{00166 \textcolor{comment}{}}
\DoxyCodeLine{00167 \textcolor{comment}{/** Push some data into the tube for storage.}}
\DoxyCodeLine{00168 \textcolor{comment}{ *}}
\DoxyCodeLine{00169 \textcolor{comment}{ * The tube's never supposed to get very big, so this will just pop loudly if}}
\DoxyCodeLine{00170 \textcolor{comment}{ * you do that.}}
\DoxyCodeLine{00171 \textcolor{comment}{ *}}
\DoxyCodeLine{00172 \textcolor{comment}{ * We can't accept write data if there's already a copy command in the tube,}}
\DoxyCodeLine{00173 \textcolor{comment}{ * because the write data comes out first. */}}
\DoxyCodeLine{00174 \textcolor{keywordtype}{void} rs\_tube\_write(rs\_job\_t *job, \textcolor{keyword}{const} \textcolor{keywordtype}{void} *buf, \textcolor{keywordtype}{size\_t} len)}
\DoxyCodeLine{00175 \{}
\DoxyCodeLine{00176     assert(job-\/>copy\_len == 0);}
\DoxyCodeLine{00177     assert(len <= \textcolor{keyword}{sizeof}(job-\/>write\_buf) -\/ job-\/>write\_len);}
\DoxyCodeLine{00178 }
\DoxyCodeLine{00179     memcpy(job-\/>write\_buf + job-\/>write\_len, buf, len);}
\DoxyCodeLine{00180     job-\/>write\_len += len;}
\DoxyCodeLine{00181 \}}

\end{DoxyCode}
