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