Botan  1.10.9
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 */
61  {
62  set_next(0, 0);
63  head = tail = new SecureQueueNode;
64  }
65 
66 /*
67 * Copy a SecureQueue
68 */
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 */
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 */
207  {
208  return (size() == 0);
209  }
210 
211 }
size_t read(byte[], size_t)
Definition: secqueue.cpp:137
BigInt n
Definition: numthry.cpp:26
void set_next(Filter *f[], size_t n)
Definition: filter.h:144
SecureQueue & operator=(const SecureQueue &other)
Definition: secqueue.cpp:101
size_t peek(byte[], size_t, size_t=0) const
Definition: secqueue.cpp:159
unsigned char byte
Definition: types.h:22
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
void write(const byte[], size_t)
Definition: secqueue.cpp:117
size_t size() const
Definition: secqueue.cpp:190
bool end_of_data() const
Definition: secqueue.cpp:206