diff options
author | Damien Miller <djm@mindrot.org> | 1999-10-27 13:42:43 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-10-27 13:42:43 +1000 |
commit | d4a8b7e34dd619a4debf9a206c81db26d1402ea6 (patch) | |
tree | a47d770a2f790f40d18b0982d4e55fa7cfb1fa3b /buffer.c |
Initial revision
Diffstat (limited to 'buffer.c')
-rw-r--r-- | buffer.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/buffer.c b/buffer.c new file mode 100644 index 000000000..e183d1017 --- /dev/null +++ b/buffer.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | |||
3 | buffer.c | ||
4 | |||
5 | Author: Tatu Ylonen <ylo@cs.hut.fi> | ||
6 | |||
7 | Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
8 | All rights reserved | ||
9 | |||
10 | Created: Sat Mar 18 04:15:33 1995 ylo | ||
11 | |||
12 | Functions for manipulating fifo buffers (that can grow if needed). | ||
13 | |||
14 | */ | ||
15 | |||
16 | #include "includes.h" | ||
17 | RCSID("$Id: buffer.c,v 1.1 1999/10/27 03:42:43 damien Exp $"); | ||
18 | |||
19 | #include "xmalloc.h" | ||
20 | #include "buffer.h" | ||
21 | #include "ssh.h" | ||
22 | |||
23 | /* Initializes the buffer structure. */ | ||
24 | |||
25 | void buffer_init(Buffer *buffer) | ||
26 | { | ||
27 | buffer->alloc = 4096; | ||
28 | buffer->buf = xmalloc(buffer->alloc); | ||
29 | buffer->offset = 0; | ||
30 | buffer->end = 0; | ||
31 | } | ||
32 | |||
33 | /* Frees any memory used for the buffer. */ | ||
34 | |||
35 | void buffer_free(Buffer *buffer) | ||
36 | { | ||
37 | memset(buffer->buf, 0, buffer->alloc); | ||
38 | xfree(buffer->buf); | ||
39 | } | ||
40 | |||
41 | /* Clears any data from the buffer, making it empty. This does not actually | ||
42 | zero the memory. */ | ||
43 | |||
44 | void buffer_clear(Buffer *buffer) | ||
45 | { | ||
46 | buffer->offset = 0; | ||
47 | buffer->end = 0; | ||
48 | } | ||
49 | |||
50 | /* Appends data to the buffer, expanding it if necessary. */ | ||
51 | |||
52 | void buffer_append(Buffer *buffer, const char *data, unsigned int len) | ||
53 | { | ||
54 | char *cp; | ||
55 | buffer_append_space(buffer, &cp, len); | ||
56 | memcpy(cp, data, len); | ||
57 | } | ||
58 | |||
59 | /* Appends space to the buffer, expanding the buffer if necessary. | ||
60 | This does not actually copy the data into the buffer, but instead | ||
61 | returns a pointer to the allocated region. */ | ||
62 | |||
63 | void buffer_append_space(Buffer *buffer, char **datap, unsigned int len) | ||
64 | { | ||
65 | /* If the buffer is empty, start using it from the beginning. */ | ||
66 | if (buffer->offset == buffer->end) | ||
67 | { | ||
68 | buffer->offset = 0; | ||
69 | buffer->end = 0; | ||
70 | } | ||
71 | |||
72 | restart: | ||
73 | /* If there is enough space to store all data, store it now. */ | ||
74 | if (buffer->end + len < buffer->alloc) | ||
75 | { | ||
76 | *datap = buffer->buf + buffer->end; | ||
77 | buffer->end += len; | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | /* If the buffer is quite empty, but all data is at the end, move the | ||
82 | data to the beginning and retry. */ | ||
83 | if (buffer->offset > buffer->alloc / 2) | ||
84 | { | ||
85 | memmove(buffer->buf, buffer->buf + buffer->offset, | ||
86 | buffer->end - buffer->offset); | ||
87 | buffer->end -= buffer->offset; | ||
88 | buffer->offset = 0; | ||
89 | goto restart; | ||
90 | } | ||
91 | |||
92 | /* Increase the size of the buffer and retry. */ | ||
93 | buffer->alloc += len + 32768; | ||
94 | buffer->buf = xrealloc(buffer->buf, buffer->alloc); | ||
95 | goto restart; | ||
96 | } | ||
97 | |||
98 | /* Returns the number of bytes of data in the buffer. */ | ||
99 | |||
100 | unsigned int buffer_len(Buffer *buffer) | ||
101 | { | ||
102 | return buffer->end - buffer->offset; | ||
103 | } | ||
104 | |||
105 | /* Gets data from the beginning of the buffer. */ | ||
106 | |||
107 | void buffer_get(Buffer *buffer, char *buf, unsigned int len) | ||
108 | { | ||
109 | if (len > buffer->end - buffer->offset) | ||
110 | fatal("buffer_get trying to get more bytes than in buffer"); | ||
111 | memcpy(buf, buffer->buf + buffer->offset, len); | ||
112 | buffer->offset += len; | ||
113 | } | ||
114 | |||
115 | /* Consumes the given number of bytes from the beginning of the buffer. */ | ||
116 | |||
117 | void buffer_consume(Buffer *buffer, unsigned int bytes) | ||
118 | { | ||
119 | if (bytes > buffer->end - buffer->offset) | ||
120 | fatal("buffer_get trying to get more bytes than in buffer"); | ||
121 | buffer->offset += bytes; | ||
122 | } | ||
123 | |||
124 | /* Consumes the given number of bytes from the end of the buffer. */ | ||
125 | |||
126 | void buffer_consume_end(Buffer *buffer, unsigned int bytes) | ||
127 | { | ||
128 | if (bytes > buffer->end - buffer->offset) | ||
129 | fatal("buffer_get trying to get more bytes than in buffer"); | ||
130 | buffer->end -= bytes; | ||
131 | } | ||
132 | |||
133 | /* Returns a pointer to the first used byte in the buffer. */ | ||
134 | |||
135 | char *buffer_ptr(Buffer *buffer) | ||
136 | { | ||
137 | return buffer->buf + buffer->offset; | ||
138 | } | ||
139 | |||
140 | /* Dumps the contents of the buffer to stderr. */ | ||
141 | |||
142 | void buffer_dump(Buffer *buffer) | ||
143 | { | ||
144 | int i; | ||
145 | unsigned char *ucp = (unsigned char *)buffer->buf; | ||
146 | |||
147 | for (i = buffer->offset; i < buffer->end; i++) | ||
148 | fprintf(stderr, " %02x", ucp[i]); | ||
149 | fprintf(stderr, "\n"); | ||
150 | } | ||