Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

secqueue.cpp
Go to the documentation of this file.
1 /*
2 * SecureQueue
3 * (C) 1999-2007 Jack Lloyd
4 * 2012 Markus Wanner
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/secqueue.h>
10 #include <algorithm>
11
12 namespace Botan {
13
14 /**
15 * A node in a SecureQueue
16 */
17 class SecureQueueNode
18 {
19 public:
20 SecureQueueNode() : m_buffer(DEFAULT_BUFFERSIZE)
21 { m_next = nullptr; m_start = m_end = 0; }
22
23 ~SecureQueueNode() { m_next = nullptr; m_start = m_end = 0; }
24
25 size_t write(const uint8_t input[], size_t length)
26 {
27 size_t copied = std::min<size_t>(length, m_buffer.size() - m_end);
28 copy_mem(m_buffer.data() + m_end, input, copied);
29 m_end += copied;
30 return copied;
31 }
32
33 size_t read(uint8_t output[], size_t length)
34 {
35 size_t copied = std::min(length, m_end - m_start);
36 copy_mem(output, m_buffer.data() + m_start, copied);
37 m_start += copied;
38 return copied;
39 }
40
41 size_t peek(uint8_t output[], size_t length, size_t offset = 0)
42 {
43 const size_t left = m_end - m_start;
44 if(offset >= left) return 0;
45 size_t copied = std::min(length, left - offset);
46 copy_mem(output, m_buffer.data() + m_start + offset, copied);
47 return copied;
48 }
49
50 size_t size() const { return (m_end - m_start); }
51 private:
52 friend class SecureQueue;
53 SecureQueueNode* m_next;
54 secure_vector<uint8_t> m_buffer;
55 size_t m_start, m_end;
56 };
57
58 /*
59 * Create a SecureQueue
60 */
61 SecureQueue::SecureQueue()
62 {
63 m_bytes_read = 0;
64 set_next(nullptr, 0);
65 m_head = m_tail = new SecureQueueNode;
66 }
67
68 /*
69 * Copy a SecureQueue
70 */
71 SecureQueue::SecureQueue(const SecureQueue& input) :
72 Fanout_Filter(), DataSource()
73 {
74 m_bytes_read = 0;
75 set_next(nullptr, 0);
76
77 m_head = m_tail = new SecureQueueNode;
78 SecureQueueNode* temp = input.m_head;
79 while(temp)
80 {
81 write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start);
82 temp = temp->m_next;
83 }
84 }
85
86 /*
87 * Destroy this SecureQueue
88 */
89 void SecureQueue::destroy()
90 {
91 SecureQueueNode* temp = m_head;
92 while(temp)
93 {
94 SecureQueueNode* holder = temp->m_next;
95 delete temp;
96 temp = holder;
97 }
98 m_head = m_tail = nullptr;
99 }
100
101 /*
102 * Copy a SecureQueue
103 */
104 SecureQueue& SecureQueue::operator=(const SecureQueue& input)
105 {
106 destroy();
107 m_bytes_read = input.get_bytes_read();
108 m_head = m_tail = new SecureQueueNode;
109 SecureQueueNode* temp = input.m_head;
110 while(temp)
111 {
112 write(&temp->m_buffer[temp->m_start], temp->m_end - temp->m_start);
113 temp = temp->m_next;
114 }
115 return (*this);
116 }
117
118 /*
119 * Add some bytes to the queue
120 */
121 void SecureQueue::write(const uint8_t input[], size_t length)
122 {
123 if(!m_head)
124 m_head = m_tail = new SecureQueueNode;
125 while(length)
126 {
127 const size_t n = m_tail->write(input, length);
128 input += n;
129 length -= n;
130 if(length)
131 {
132 m_tail->m_next = new SecureQueueNode;
133 m_tail = m_tail->m_next;
134 }
135 }
136 }
137
138 /*
139 * Read some bytes from the queue
140 */
141 size_t SecureQueue::read(uint8_t output[], size_t length)
142 {
143 size_t got = 0;
144 while(length && m_head)
145 {
146 const size_t n = m_head->read(output, length);
147 output += n;
148 got += n;
149 length -= n;
150 if(m_head->size() == 0)
151 {
152 SecureQueueNode* holder = m_head->m_next;
153 delete m_head;
154 m_head = holder;
155 }
156 }
157 m_bytes_read += got;
158 return got;
159 }
160
161 /*
162 * Read data, but do not remove it from queue
163 */
164 size_t SecureQueue::peek(uint8_t output[], size_t length, size_t offset) const
165 {
166 SecureQueueNode* current = m_head;
167
168 while(offset && current)
169 {
170 if(offset >= current->size())
171 {
172 offset -= current->size();
173 current = current->m_next;
174 }
175 else
176 break;
177 }
178
179 size_t got = 0;
180 while(length && current)
181 {
182 const size_t n = current->peek(output, length, offset);
183 offset = 0;
184 output += n;
185 got += n;
186 length -= n;
187 current = current->m_next;
188 }
189 return got;
190 }
191
192 /**
193 * Return how many bytes have been read so far.
194 */
195 size_t SecureQueue::get_bytes_read() const
196 {
197 return m_bytes_read;
198 }
199
200 /*
201 * Return how many bytes the queue holds
202 */
203 size_t SecureQueue::size() const
204 {
205 SecureQueueNode* current = m_head;
206 size_t count = 0;
207
208 while(current)
209 {
210 count += current->size();
211 current = current->m_next;
212 }
213 return count;
214 }
215
216 /*
217 * Test if the queue has any data in it
218 */
219 bool SecureQueue::end_of_data() const
220 {
221 return (size() == 0);
222 }
223
224 bool SecureQueue::empty() const
225 {
226 return (size() == 0);
227 }
228
229 }
Botan::SecureQueue::read
size_t read(uint8_t[], size_t) override
Definition: secqueue.cpp:141
Botan::SecureQueue
Definition: secqueue.h:20
Botan::Fanout_Filter
Definition: filter.h:152
Botan::Fanout_Filter::set_next
void set_next(Filter *f[], size_t n)
Definition: filter.h:162
Botan::SecureQueue::operator=
SecureQueue & operator=(const SecureQueue &other)
Definition: secqueue.cpp:104
Botan::DataSource
Definition: data_src.h:21
Botan::SecureQueue::write
void write(const uint8_t[], size_t) override
Definition: secqueue.cpp:121
Botan::SecureQueue::empty
bool empty() const
Definition: secqueue.cpp:224
Botan::SecureQueue::peek
size_t peek(uint8_t[], size_t, size_t=0) const override
Definition: secqueue.cpp:164
Botan::SecureQueue::get_bytes_read
size_t get_bytes_read() const override
Definition: secqueue.cpp:195
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Botan
Definition: alg_id.cpp:13
Botan::SecureQueue::size
size_t size() const
Definition: secqueue.cpp:203
Botan::CT::min
T min(T a, T b)
Definition: ct_utils.h:180
Botan::SecureQueue::end_of_data
bool end_of_data() const override
Definition: secqueue.cpp:219
Botan::SecureQueue::SecureQueue
SecureQueue()
Definition: secqueue.cpp:61