librsync  2.3.4
scoop.h
Go to the documentation of this file.
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- library for network deltas
4  *
5  * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22  /*=
23  | Two wars in a lifetime bear hard on the little places.
24  | In winter when storms come rushing out of the dark,
25  | And the bay boils like a cauldron of sharks,
26  | The old remember the trenches at Paschendale
27  | And sons who died on the Burma Railway.
28  */
29 
30 /** \file scoop.h
31  * Manage librsync streams of IO.
32  *
33  * See \sa scoop.c and \sa tube.c for related code for input and output
34  * respectively.
35  *
36  * OK, so I'll admit IO here is a little complex. The most important player
37  * here is the stream, which is an object for managing filter operations. It
38  * has both input and output sides, both of which is just a (pointer,len) pair
39  * into a buffer provided by the client. The code controlling the stream
40  * handles however much data it wants, and the client provides or accepts
41  * however much is convenient.
42  *
43  * At the same time as being friendly to the client, we also try to be very
44  * friendly to the internal code. It wants to be able to ask for arbitrary
45  * amounts of input or output and get it without having to keep track of
46  * partial completion. So there are functions which either complete, or queue
47  * whatever was not sent and return RS_BLOCKED.
48  *
49  * The output buffer is a little more clever than simply a data buffer. Instead
50  * it knows that we can send either literal data, or data copied through from
51  * the input of the stream.
52  *
53  * In buf.c you will find functions that then map buffers onto stdio files.
54  *
55  * On return from an encoding function, some input will have been consumed
56  * and/or some output produced, but either the input or the output or possibly
57  * both could have some remaining bytes available.
58  *
59  * librsync never does IO or memory allocation for stream input, but relies on
60  * the caller. This is very nice for integration, but means that we have to be
61  * fairly flexible as to when we can `read' or `write' stuff internally.
62  *
63  * librsync basically does two types of IO. It reads network integers of
64  * various lengths which encode command and control information such as
65  * versions and signatures. It also does bulk data transfer.
66  *
67  * IO of network integers is internally buffered, because higher levels of the
68  * code need to see them transmitted atomically: it's no good to read half of a
69  * uint32. So there is a small and fixed length internal buffer which
70  * accumulates these. Unlike previous versions of the library, we don't require
71  * that the caller hold the start until the whole thing has arrived, which
72  * guarantees that we can always make progress.
73  *
74  * On each call into a stream iterator, it should begin by trying to flush
75  * output. This may well use up all the remaining stream space, in which case
76  * nothing else can be done. */
77 #ifndef SCOOP_H
78 # define SCOOP_H
79 # include <stdbool.h>
80 # include <stddef.h>
81 # include "job.h"
82 # include "librsync.h"
83 
85 int rs_tube_is_idle(rs_job_t const *job);
86 void rs_tube_write(rs_job_t *job, void const *buf, size_t len);
87 void rs_tube_copy(rs_job_t *job, size_t len);
88 
89 void rs_scoop_advance(rs_job_t *job, size_t len);
90 rs_result rs_scoop_readahead(rs_job_t *job, size_t len, void **ptr);
91 rs_result rs_scoop_read(rs_job_t *job, size_t len, void **ptr);
92 rs_result rs_scoop_read_rest(rs_job_t *job, size_t *len, void **ptr);
93 
94 static inline size_t rs_scoop_avail(rs_job_t *job)
95 {
96  return job->scoop_avail + job->stream->avail_in;
97 }
98 
99 /** Test if the scoop has reached eof. */
100 static inline bool rs_scoop_eof(rs_job_t *job)
101 {
102  return !rs_scoop_avail(job) && job->stream->eof_in;
103 }
104 
105 /** Get a pointer to the next input in the scoop. */
106 static inline void *rs_scoop_buf(rs_job_t *job)
107 {
108  return job->scoop_avail ? (void *)job->scoop_next : (void *)job->
109  stream->next_in;
110 }
111 
112 /** Get the contiguous length of the next input in the scoop. */
113 static inline size_t rs_scoop_len(rs_job_t *job)
114 {
115  return job->scoop_avail ? job->scoop_avail : job->stream->avail_in;
116 }
117 
118 /** Get the next contiguous buffer of data available in the scoop.
119  *
120  * This will return a pointer to the data and reduce len to the amount of
121  * contiguous data available at that position.
122  *
123  * \param *job - the job instance to use.
124  *
125  * \param *len - the amount of data desired, updated to the amount available.
126  *
127  * \return A pointer to the data. */
128 static inline void *rs_scoop_getbuf(rs_job_t *job, size_t *len)
129 {
130  size_t max_len = rs_scoop_len(job);
131  if (*len > max_len)
132  *len = max_len;
133  return rs_scoop_buf(job);
134 }
135 
136 /** Iterate through and consume contiguous data buffers in the scoop.
137  *
138  * Example: \code
139  * size_t len=rs_scoop_avail(job);
140  * size_t ilen;
141  *
142  * for (buf = rs_scoop_iterbuf(job, &len, &ilen); ilen > 0;
143  * buf = rs_scoop_nextbuf(job, &len, &ilen))
144  * ilen = fwrite(buf, ilen, 1, f);
145  * \endcode
146  *
147  * At each iteration buf and ilen are the data and its length for the current
148  * iteration, and len is the remaining data to iterate through including the
149  * current iteration. During an iteration you can change ilen to indicate only
150  * part of the buffer was processed and the next iteration will take this into
151  * account. Setting ilen = 0 to indicate blocking or errors will terminate
152  * iteration.
153  *
154  * At the end of iteration buf will point at the next location in the scoop
155  * after the iterated data, len and ilen will be zero, or the remaining data
156  * and last ilen if iteration was terminated by setting ilen = 0.
157  *
158  * \param *job - the job instance to use.
159  *
160  * \param *len - the size_t amount of data to iterate over.
161  *
162  * \param *ilen - the size_t amount of data in the current iteration.
163  *
164  * \return A pointer to data in the current iteration. */
165 static inline void *rs_scoop_iterbuf(rs_job_t *job, size_t *len, size_t *ilen)
166 {
167  *ilen = *len;
168  return rs_scoop_getbuf(job, ilen);
169 }
170 
171 /** Get the next iteration of contiguous data buffers from the scoop.
172  *
173  * This advances the scoop for the previous iteration, and gets the next
174  * iteration. \sa rs_scoop_iterbuf */
175 static inline void *rs_scoop_nextbuf(rs_job_t *job, size_t *len, size_t *ilen)
176 {
177  if (*ilen == 0)
178  return rs_scoop_buf(job);
179  rs_scoop_advance(job, *ilen);
180  *len -= *ilen;
181  return rs_scoop_iterbuf(job, len, ilen);
182 }
183 
184 #endif /* !SCOOP_H */
void rs_tube_copy(rs_job_t *job, size_t len)
Queue up a request to copy through len bytes from the input to the output of the stream.
Definition: tube.c:160
void rs_tube_write(rs_job_t *job, void const *buf, size_t len)
Push some data into the tube for storage.
Definition: tube.c:174
void rs_scoop_advance(rs_job_t *job, size_t len)
Advance the input cursor forward len bytes.
Definition: scoop.c:117
size_t scoop_avail
The amount of data available.
Definition: job.h:100
size_t avail_in
Number of bytes available at next_in.
Definition: librsync.h:342
rs_byte_t * scoop_next
The next data pointer.
Definition: job.h:98
Public header for librsync.
static void * rs_scoop_nextbuf(rs_job_t *job, size_t *len, size_t *ilen)
Get the next iteration of contiguous data buffers from the scoop.
Definition: scoop.h:175
rs_result rs_tube_catchup(rs_job_t *job)
Put whatever will fit from the tube into the output of the stream.
Definition: tube.c:120
rs_result rs_scoop_read_rest(rs_job_t *job, size_t *len, void **ptr)
Read whatever data remains in the input stream.
Definition: scoop.c:212
static bool rs_scoop_eof(rs_job_t *job)
Test if the scoop has reached eof.
Definition: scoop.h:100
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:180
Generic state-machine interface.
rs_result rs_scoop_read(rs_job_t *job, size_t len, void **ptr)
Read LEN bytes if possible, and remove them from the input scoop.
Definition: scoop.c:192
static void * rs_scoop_buf(rs_job_t *job)
Get a pointer to the next input in the scoop.
Definition: scoop.h:106
static size_t rs_scoop_len(rs_job_t *job)
Get the contiguous length of the next input in the scoop.
Definition: scoop.h:113
static void * rs_scoop_iterbuf(rs_job_t *job, size_t *len, size_t *ilen)
Iterate through and consume contiguous data buffers in the scoop.
Definition: scoop.h:165
static void * rs_scoop_getbuf(rs_job_t *job, size_t *len)
Get the next contiguous buffer of data available in the scoop.
Definition: scoop.h:128
int eof_in
True if there is no more data after this.
Definition: librsync.h:345
rs_result rs_scoop_readahead(rs_job_t *job, size_t len, void **ptr)
Read from scoop without advancing.
Definition: scoop.c:148
The contents of this structure are private.
Definition: job.h:47