Botan 1.10.17

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