crypto/
buffer.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use std::cmp;
8
9use cryptoutil;
10
11#[derive(Clone,Copy)]
12pub enum BufferResult {
13    BufferUnderflow,
14    BufferOverflow
15}
16
17pub trait ReadBuffer {
18    fn is_empty(&self) -> bool;
19    fn is_full(&self) -> bool;
20    fn remaining(&self) -> usize;
21    fn capacity(&self) -> usize;
22    fn position(&self) -> usize { self.capacity() - self.remaining() }
23
24    fn rewind(&mut self, distance: usize);
25    fn truncate(&mut self, amount: usize);
26    fn reset(&mut self);
27
28    fn peek_next(&self, count: usize) -> &[u8];
29    fn peek_remaining(&self) -> &[u8] {
30        self.peek_next(self.remaining())
31    }
32
33    fn take_next(&mut self, count: usize) -> &[u8];
34    fn take_remaining(&mut self) -> &[u8] {
35        let rem = self.remaining();
36        self.take_next(rem)
37    }
38
39    fn push_to<W: WriteBuffer>(&mut self, output: &mut W) {
40        let count = cmp::min(output.remaining(), self.remaining());
41        cryptoutil::copy_memory(self.take_next(count), output.take_next(count));
42    }
43}
44
45pub trait WriteBuffer {
46    fn is_empty(&self) -> bool;
47    fn is_full(&self) -> bool;
48    fn remaining(&self) -> usize;
49    fn capacity(&self) -> usize;
50    fn position(&self) -> usize { self.capacity() - self.remaining() }
51
52    fn rewind(&mut self, distance: usize);
53    fn reset(&mut self);
54
55    // FIXME - Shouldn't need mut self
56    fn peek_read_buffer(&mut self) -> RefReadBuffer;
57
58    fn take_next(&mut self, count: usize) -> &mut [u8];
59    fn take_remaining(&mut self) -> &mut [u8] {
60        let rem = self.remaining();
61        self.take_next(rem)
62    }
63    fn take_read_buffer(&mut self) -> RefReadBuffer;
64}
65
66pub struct RefReadBuffer<'a> {
67    buff: &'a [u8],
68    pos: usize
69}
70
71impl <'a> RefReadBuffer<'a> {
72    pub fn new(buff: &[u8]) -> RefReadBuffer {
73        RefReadBuffer {
74            buff: buff,
75            pos: 0
76        }
77    }
78}
79
80impl <'a> ReadBuffer for RefReadBuffer<'a> {
81    fn is_empty(&self) -> bool { self.pos == self.buff.len() }
82    fn is_full(&self) -> bool { self.pos == 0 }
83    fn remaining(&self) -> usize { self.buff.len() - self.pos }
84    fn capacity(&self) -> usize { self.buff.len() }
85
86    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
87    fn truncate(&mut self, amount: usize) {
88        self.buff = &self.buff[..self.buff.len() - amount];
89    }
90    fn reset(&mut self) { self.pos = 0; }
91
92    fn peek_next(&self, count: usize) -> &[u8] { &self.buff[self.pos..count] }
93
94    fn take_next(&mut self, count: usize) -> &[u8] {
95        let r = &self.buff[self.pos..self.pos + count];
96        self.pos += count;
97        r
98    }
99}
100
101pub struct OwnedReadBuffer {
102    buff: Vec<u8>,
103    len: usize,
104    pos: usize
105}
106
107impl OwnedReadBuffer {
108    pub fn new(buff: Vec<u8>) -> OwnedReadBuffer {
109        let len = buff.len();
110        OwnedReadBuffer {
111            buff: buff,
112            len: len,
113            pos: 0
114        }
115    }
116    pub fn new_with_len<'a>(buff: Vec<u8>, len: usize) -> OwnedReadBuffer {
117        OwnedReadBuffer {
118            buff: buff,
119            len: len,
120            pos: 0
121        }
122    }
123    pub fn into_write_buffer(self) -> OwnedWriteBuffer {
124        OwnedWriteBuffer::new(self.buff)
125    }
126    pub fn borrow_write_buffer(&mut self) -> BorrowedWriteBuffer {
127        self.pos = 0;
128        self.len = 0;
129        BorrowedWriteBuffer::new(self)
130    }
131}
132
133impl ReadBuffer for OwnedReadBuffer {
134    fn is_empty(&self) -> bool { self.pos == self.len }
135    fn is_full(&self) -> bool { self.pos == 0 }
136    fn remaining(&self) -> usize { self.len - self.pos }
137    fn capacity(&self) -> usize { self.len }
138
139    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
140    fn truncate(&mut self, amount: usize) { self.len -= amount; }
141    fn reset(&mut self) { self.pos = 0; }
142
143    fn peek_next(&self, count: usize) -> &[u8] { &self.buff[self.pos..count] }
144
145    fn take_next(&mut self, count: usize) -> &[u8] {
146        let r = &self.buff[self.pos..self.pos + count];
147        self.pos += count;
148        r
149    }
150}
151
152pub struct RefWriteBuffer<'a> {
153    buff: &'a mut [u8],
154    len: usize,
155    pos: usize
156}
157
158impl <'a> RefWriteBuffer<'a> {
159    pub fn new(buff: &mut [u8]) -> RefWriteBuffer {
160        let len = buff.len();
161        RefWriteBuffer {
162            buff: buff,
163            len: len,
164            pos: 0
165        }
166    }
167}
168
169impl <'a> WriteBuffer for RefWriteBuffer<'a> {
170    fn is_empty(&self) -> bool { self.pos == 0 }
171    fn is_full(&self) -> bool { self.pos == self.len }
172    fn remaining(&self) -> usize { self.len - self.pos }
173    fn capacity(&self) -> usize { self.len }
174
175    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
176    fn reset(&mut self) { self.pos = 0; }
177
178    fn peek_read_buffer(&mut self) -> RefReadBuffer {
179        RefReadBuffer::new(&mut self.buff[..self.pos])
180    }
181
182    fn take_next(&mut self, count: usize) -> &mut [u8] {
183        let r = &mut self.buff[self.pos..self.pos + count];
184        self.pos += count;
185        r
186    }
187    fn take_read_buffer(&mut self) -> RefReadBuffer {
188        let r = RefReadBuffer::new(&mut self.buff[..self.pos]);
189        self.pos = 0;
190        r
191    }
192}
193
194pub struct BorrowedWriteBuffer<'a> {
195    parent: &'a mut OwnedReadBuffer,
196    pos: usize,
197    len: usize
198}
199
200impl <'a> BorrowedWriteBuffer<'a> {
201    fn new(parent: &mut OwnedReadBuffer) -> BorrowedWriteBuffer {
202        let buff_len = parent.buff.len();
203        BorrowedWriteBuffer {
204            parent: parent,
205            pos: 0,
206            len: buff_len
207        }
208    }
209}
210
211impl <'a> WriteBuffer for BorrowedWriteBuffer<'a> {
212    fn is_empty(&self) -> bool { self.pos == 0 }
213    fn is_full(&self) -> bool { self.pos == self.len }
214    fn remaining(&self) -> usize { self.len - self.pos }
215    fn capacity(&self) -> usize { self.len }
216
217    fn rewind(&mut self, distance: usize) {
218        self.pos -= distance;
219        self.parent.len -= distance;
220    }
221    fn reset(&mut self) {
222        self.pos = 0;
223        self.parent.len = 0;
224    }
225
226    fn peek_read_buffer(&mut self) -> RefReadBuffer {
227        RefReadBuffer::new(&self.parent.buff[..self.pos])
228    }
229
230    fn take_next<>(&mut self, count: usize) -> &mut [u8] {
231        let r = &mut self.parent.buff[self.pos..self.pos + count];
232        self.pos += count;
233        self.parent.len += count;
234        r
235    }
236    fn take_read_buffer(&mut self) -> RefReadBuffer {
237        let r = RefReadBuffer::new(&self.parent.buff[..self.pos]);
238        self.pos = 0;
239        self.parent.len = 0;
240        r
241    }
242}
243
244pub struct OwnedWriteBuffer {
245    buff: Vec<u8>,
246    len: usize,
247    pos: usize
248}
249
250impl OwnedWriteBuffer {
251    pub fn new(buff: Vec<u8>) -> OwnedWriteBuffer {
252        let len = buff.len();
253        OwnedWriteBuffer {
254            buff: buff,
255            len: len,
256            pos: 0
257        }
258    }
259    pub fn into_read_buffer(self) -> OwnedReadBuffer {
260        let pos = self.pos;
261        OwnedReadBuffer::new_with_len(self.buff, pos)
262    }
263}
264
265impl WriteBuffer for OwnedWriteBuffer {
266    fn is_empty(&self) -> bool { self.pos == 0 }
267    fn is_full(&self) -> bool { self.pos == self.len }
268    fn remaining(&self) -> usize { self.len - self.pos }
269    fn capacity(&self) -> usize { self.len }
270
271    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
272    fn reset(&mut self) { self.pos = 0; }
273
274    fn peek_read_buffer<'a>(&'a mut self) -> RefReadBuffer<'a> {
275        RefReadBuffer::new(&self.buff[..self.pos])
276    }
277
278    fn take_next<'a>(&'a mut self, count: usize) -> &'a mut [u8] {
279        let r = &mut self.buff[self.pos..self.pos + count];
280        self.pos += count;
281        r
282    }
283    fn take_read_buffer<'a>(&'a mut self) -> RefReadBuffer<'a> {
284        let r = RefReadBuffer::new(&self.buff[..self.pos]);
285        self.pos = 0;
286        r
287    }
288}