librsync  2.0.1
stream.c
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- dynamic caching and delta update in HTTP
4  *
5  * Copyright (C) 2000, 2001 by Martin Pool <[email protected]>
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  * Programming languages should be designed not
24  * by piling feature on top of feature, but by
25  * removing the weaknesses and restrictions that
26  * make additional features appear necessary.
27  * -- Revised^5 Report on Scheme
28  */
29 
30 
31 /*
32  * OK, so I'll admit IO here is a little complex. The most important
33  * player here is the stream, which is an object for managing filter
34  * operations. It has both input and output sides, both of which is
35  * just a (pointer,len) pair into a buffer provided by the client.
36  * The code controlling the stream handles however much data it wants,
37  * and the client provides or accepts however much is convenient.
38  *
39  * At the same time as being friendly to the client, we also try to be
40  * very friendly to the internal code. It wants to be able to ask for
41  * arbitrary amounts of input or output and get it without having to
42  * keep track of partial completion. So there are functions which
43  * either complete, or queue whatever was not sent and return
44  * RS_BLOCKED.
45  *
46  * The output buffer is a little more clever than simply a data
47  * buffer. Instead it knows that we can send either literal data, or
48  * data copied through from the input of the stream.
49  *
50  * In buf.c you will find functions that then map buffers onto stdio
51  * files.
52  *
53  * So on return from an encoding function, either the input or the
54  * output or possibly both will have no more bytes available.
55  */
56 
57 /*
58  * Manage librsync streams of IO. See scoop.c and tube.c for related
59  * code for input and output respectively.
60  *
61  * librsync never does IO or memory allocation, but relies on the
62  * caller. This is very nice for integration, but means that we have
63  * to be fairly flexible as to when we can `read' or `write' stuff
64  * internally.
65  *
66  * librsync basically does two types of IO. It reads network integers
67  * of various lengths which encode command and control information
68  * such as versions and signatures. It also does bulk data transfer.
69  *
70  * IO of network integers is internally buffered, because higher
71  * levels of the code need to see them transmitted atomically: it's no
72  * good to read half of a uint32. So there is a small and fixed
73  * length internal buffer which accumulates these. Unlike previous
74  * versions of the library, we don't require that the caller hold the
75  * start until the whole thing has arrived, which guarantees that we
76  * can always make progress.
77  *
78  * On each call into a stream iterator, it should begin by trying to
79  * flush output. This may well use up all the remaining stream space,
80  * in which case nothing else can be done.
81  */
82 
83 /* TODO: Return errors rather than aborting if something goes wrong. */
84 
85 
86 #include "config.h"
87 
88 #include <assert.h>
89 #include <stdlib.h>
90 #include <string.h>
91 #include <stdio.h>
92 
93 #include "librsync.h"
94 #include "stream.h"
95 #include "util.h"
96 #include "trace.h"
97 
98 
99 /**
100  * \brief Copy up to \p max_len bytes from input of \b stream to its output.
101  *
102  * Return the number of bytes actually copied, which may be less than
103  * LEN if there is not enough space in one or the other stream.
104  *
105  * This always does the copy immediately. Most functions should call
106  * rs_tube_copy() to cause the copy to happen gradually as space
107  * becomes available.
108  */
109 int rs_buffers_copy(rs_buffers_t *stream, int max_len)
110 {
111  int len = max_len;
112 
113  assert(len > 0);
114 
115  if ((unsigned) len > stream->avail_in) {
116  rs_trace("copy limited to %ld available input bytes",
117  (long) stream->avail_in);
118  len = stream->avail_in;
119  }
120 
121 
122  if ((unsigned) len > stream->avail_out) {
123  rs_trace("copy limited to %ld available output bytes",
124  (long) stream->avail_out);
125  len = stream->avail_out;
126  }
127 
128  if (!len)
129  return 0;
130 /* rs_trace("stream copied chunk of %d bytes", len); */
131 
132  memcpy(stream->next_out, stream->next_in, len);
133 
134  stream->next_out += len;
135  stream->avail_out -= len;
136 
137  stream->next_in += len;
138  stream->avail_in -= len;
139 
140  return len;
141 }
142 
143 
144 /**
145  * Whenever a stream processing function exits, it should have done so
146  * because it has either consumed all the input or has filled the
147  * output buffer. This function checks that simple postcondition.
148  */
149 void rs_buffers_check_exit(rs_buffers_t const *stream)
150 {
151  assert(stream->avail_in == 0 || stream->avail_out == 0);
152 }
Description of input and output buffers.
Definition: librsync.h:360
size_t avail_out
Remaining free space at next_out.
Definition: librsync.h:396
char * next_out
Next output byte should be put there References a pointer which on entry points to the start of the o...
Definition: librsync.h:388
size_t avail_in
Number of bytes available at next_in References the length of available input.
Definition: librsync.h:375
Public header for librsync.
char * next_in
Next input byte.
Definition: librsync.h:366