summaryrefslogtreecommitdiff
path: root/rsync/stream.c
Unidiff
Diffstat (limited to 'rsync/stream.c') (more/less context) (ignore whitespace changes)
-rw-r--r--rsync/stream.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/rsync/stream.c b/rsync/stream.c
new file mode 100644
index 0000000..d20d866
--- a/dev/null
+++ b/rsync/stream.c
@@ -0,0 +1,155 @@
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- dynamic caching and delta update in HTTP
4 * $Id$
5 *
6 * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /*
24 * Programming languages should be designed not
25 * by piling feature on top of feature, but by
26 * removing the weaknesses and restrictions that
27 * make additional features appear necessary.
28 * -- Revised^5 Report on Scheme
29 */
30
31
32/*
33 * OK, so I'll admit IO here is a little complex. The most important
34 * player here is the stream, which is an object for managing filter
35 * operations. It has both input and output sides, both of which is
36 * just a (pointer,len) pair into a buffer provided by the client.
37 * The code controlling the stream handles however much data it wants,
38 * and the client provides or accepts however much is convenient.
39 *
40 * At the same time as being friendly to the client, we also try to be
41 * very friendly to the internal code. It wants to be able to ask for
42 * arbitrary amounts of input or output and get it without having to
43 * keep track of partial completion. So there are functions which
44 * either complete, or queue whatever was not sent and return
45 * RS_BLOCKED.
46 *
47 * The output buffer is a little more clever than simply a data
48 * buffer. Instead it knows that we can send either literal data, or
49 * data copied through from the input of the stream.
50 *
51 * In buf.c you will find functions that then map buffers onto stdio
52 * files.
53 *
54 * So on return from an encoding function, either the input or the
55 * output or possibly both will have no more bytes available.
56 */
57
58/*
59 * Manage librsync streams of IO. See scoop.c and tube.c for related
60 * code for input and output respectively.
61 *
62 * librsync never does IO or memory allocation, but relies on the
63 * caller. This is very nice for integration, but means that we have
64 * to be fairly flexible as to when we can `read' or `write' stuff
65 * internally.
66 *
67 * librsync basically does two types of IO. It reads network integers
68 * of various lengths which encode command and control information
69 * such as versions and signatures. It also does bulk data transfer.
70 *
71 * IO of network integers is internally buffered, because higher
72 * levels of the code need to see them transmitted atomically: it's no
73 * good to read half of a uint32. So there is a small and fixed
74 * length internal buffer which accumulates these. Unlike previous
75 * versions of the library, we don't require that the caller hold the
76 * start until the whole thing has arrived, which guarantees that we
77 * can always make progress.
78 *
79 * On each call into a stream iterator, it should begin by trying to
80 * flush output. This may well use up all the remaining stream space,
81 * in which case nothing else can be done.
82 */
83
84/* TODO: Return errors rather than aborting if something goes wrong. */
85
86
87#include <config_rsync.h>
88
89#include <assert.h>
90#include <stdlib.h>
91#include <string.h>
92#include <stdio.h>
93
94#include "rsync.h"
95#include "stream.h"
96#include "util.h"
97#include "trace.h"
98
99static const int RS_STREAM_DOGTAG = 2001125;
100
101
102/**
103 * \brief Copy up to \p max_len bytes from input of \b stream to its output.
104 *
105 * Return the number of bytes actually copied, which may be less than
106 * LEN if there is not enough space in one or the other stream.
107 *
108 * This always does the copy immediately. Most functions should call
109 * rs_tube_copy() to cause the copy to happen gradually as space
110 * becomes available.
111 */
112int rs_buffers_copy(rs_buffers_t *stream, int max_len)
113{
114 int len = max_len;
115
116 assert(len > 0);
117
118 if ((unsigned) len > stream->avail_in) {
119 rs_trace("copy limited to %d available input bytes",
120 stream->avail_in);
121 len = stream->avail_in;
122 }
123
124
125 if ((unsigned) len > stream->avail_out) {
126 rs_trace("copy limited to %d available output bytes",
127 stream->avail_out);
128 len = stream->avail_out;
129 }
130
131 if (!len)
132 return 0;
133/* rs_trace("stream copied chunk of %d bytes", len); */
134
135 memcpy(stream->next_out, stream->next_in, len);
136
137 stream->next_out += len;
138 stream->avail_out -= len;
139
140 stream->next_in += len;
141 stream->avail_in -= len;
142
143 return len;
144}
145
146
147/**
148 * Whenever a stream processing function exits, it should have done so
149 * because it has either consumed all the input or has filled the
150 * output buffer. This function checks that simple postcondition.
151 */
152void rs_buffers_check_exit(rs_buffers_t const *stream)
153{
154 assert(stream->avail_in == 0 || stream->avail_out == 0);
155}