monotone

monotone Mtn Source Tree

Root/botan/secqueue.cpp

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

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status