2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "NGBufferedDescriptor.h"
28 // returns the number of bytes which where read from the buffer
29 #define numberOfConsumedReadBufferBytes(self) \
30 ((self->readBufferSize == 0) ? 0 : (self->readBufferPos - self->readBuffer))
32 // returns the number of bytes which can be read from buffer (without source access)
33 #define numberOfAvailableReadBufferBytes(self) \
34 (self->readBufferFillSize - numberOfConsumedReadBufferBytes(self))
36 // look whether all bytes in the buffer where consumed, if so, reset the buffer
37 #define checkReadBufferFillState(self) \
38 if (numberOfAvailableReadBufferBytes(self) == 0) { \
39 self->readBufferPos = self->readBuffer; \
40 self->readBufferFillSize = 0; \
45 NGBufferedDescriptor *
46 NGBufferedDescriptor_newWithDescriptorAndSize(int _fd, int _size)
48 NGBufferedDescriptor *self = malloc(sizeof(NGBufferedDescriptor));
51 self->readBuffer = malloc(_size);
52 self->writeBuffer = malloc(_size);
53 self->readBufferPos = self->readBuffer;
54 self->readBufferSize = _size;
55 self->readBufferFillSize = 0; // no bytes are read from source
56 self->writeBufferFillSize = 0;
57 self->writeBufferSize = _size;
63 NGBufferedDescriptor *NGBufferedDescriptor_newWithDescriptor(int _fd) {
64 return NGBufferedDescriptor_newWithDescriptorAndSize(_fd, 1024);
66 NGBufferedDescriptor *
67 NGBufferedDescriptor_newWithOwnedDescriptorAndSize(int _fd, int _size) {
68 NGBufferedDescriptor *self = NULL;
70 if ((self = NGBufferedDescriptor_newWithDescriptorAndSize(_fd, _size)))
77 void NGBufferedDescriptor_free(NGBufferedDescriptor *self) {
79 NGBufferedDescriptor_flush(self);
81 if (self->ownsFd && self->fd != -1) {
86 if (self->readBuffer) {
87 free(self->readBuffer);
88 self->readBuffer = NULL;
89 self->readBufferPos = NULL;
91 self->readBufferFillSize = 0;
92 self->readBufferSize = 0;
94 if (self->writeBuffer) {
95 free(self->writeBuffer);
96 self->writeBuffer = NULL;
98 self->writeBufferFillSize = 0;
99 self->writeBufferSize = 0;
105 int NGBufferedDescriptor_getReadBufferSize(NGBufferedDescriptor *self) {
106 if (self == NULL) return 0;
107 return self->readBufferSize;
109 int NGBufferedDescriptor_getWriteBufferSize(NGBufferedDescriptor *self) {
110 if (self == NULL) return 0;
111 return self->writeBufferSize;
114 int NGBufferedDescriptor_read(NGBufferedDescriptor *self,
115 void *_buf, int _len)
117 register int availBytes;
119 if (self == NULL) return 0;
121 if (self->readBufferSize == 0) // no read buffering is done (buffersize==0)
122 return read(self->fd, _buf, _len);
124 availBytes = numberOfAvailableReadBufferBytes(self);
125 if (availBytes >= _len) {
126 // there are enough bytes in the buffer to fulfill the request
128 *(unsigned char *)_buf = *(unsigned char *)self->readBufferPos;
129 self->readBufferPos++;
132 memcpy(_buf, self->readBufferPos, _len);
133 self->readBufferPos += _len; // update read position (consumed-size)
135 checkReadBufferFillState(self); // check whether all bytes where consumed
138 else if (availBytes > 0) {
139 // there are some bytes in the buffer, these are returned
141 memcpy(_buf, self->readBufferPos, availBytes); // copy all bytes from buffer
142 self->readBufferPos = self->readBuffer; // reset position
143 self->readBufferFillSize = 0; // no bytes available in buffer anymore
146 else if (_len > self->readBufferSize) {
147 // requested _len is bigger than the buffersize, so we can bypass the
148 // buffer (which is empty, as guaranteed by the previous 'ifs'
149 return read(self->fd, _buf, _len);
152 // no bytes are available and the requested _len is smaller than the possible
153 // buffer size, we have to read the next block of input from the source
155 self->readBufferFillSize = read(self->fd,
156 self->readBuffer, self->readBufferSize);
158 // no comes a section which is roughly the same like the first to conditionals
160 if (self->readBufferFillSize >= _len) {
161 // there are enough bytes in the buffer to fulfill the request
163 memcpy(_buf, self->readBufferPos, _len);
164 self->readBufferPos += _len; // update read position (consumed-size)
165 checkReadBufferFillState(self); // check whether all bytes where consumed
168 else { // (readBufferFillSize > 0) (this is ensured by the above assert)
169 // there are some bytes in the buffer, these are returned
171 availBytes = self->readBufferFillSize;
172 memcpy(_buf, self->readBufferPos, self->readBufferFillSize); // copy all bytes from buffer
173 self->readBufferPos = self->readBuffer; // reset position
174 self->readBufferFillSize = 0; // no bytes available in buffer anymore
180 int NGBufferedDescriptor_write(NGBufferedDescriptor *self,
181 const void *_buf, int _len)
183 register int tmp = 0;
184 register int remaining = _len;
185 register void *track = (void *)_buf;
187 if (self == NULL) return 0;
189 while (remaining > 0) {
190 // how much bytes available in buffer ?
191 tmp = self->writeBufferSize - self->writeBufferFillSize;
192 tmp = (tmp > remaining) ? remaining : tmp;
194 memcpy((self->writeBuffer + self->writeBufferFillSize), track, tmp);
197 self->writeBufferFillSize += tmp;
199 if (self->writeBufferFillSize == self->writeBufferSize) {
200 void *pos = self->writeBuffer;
202 while (self->writeBufferFillSize > 0) {
205 result = write(self->fd, pos, self->writeBufferFillSize);
207 if ((result == 0) || (result < 0)) { // socket closed || error
208 self->writeBufferFillSize = 0; // content is lost ..
211 self->writeBufferFillSize -= result;
218 if (self->flags._flushOnNewline == 1) {
219 // scan buffer for newlines, if one is found, flush buffer
221 for (tmp = 0; tmp < _len; tmp++) {
223 NGBufferedDescriptor_flush(self);
232 track = NULL; // clean up for GC
238 char NGBufferedDescriptor_flush(NGBufferedDescriptor *self) {
239 if (self == NULL) return 0;
241 if (self->writeBufferFillSize > 0) {
242 int toGo = self->writeBufferFillSize;
243 void *pos = self->writeBuffer;
246 int result = write(self->fd, pos, toGo);
248 if (result == 0) // socket was closed
250 else if (result < 1) // socket error
256 self->writeBufferFillSize = 0;
261 unsigned char NGBufferedDescriptor_safeRead(NGBufferedDescriptor *self,
262 void *_buffer, int _len) {
263 if (self == NULL) return 0;
267 int result = NGBufferedDescriptor_read(self, _buffer, _len);
269 if (result == 0) // socket was closed
271 else if (result < 1) // socket error
280 char NGBufferedDescriptor_safeWrite(NGBufferedDescriptor *self,
281 const void *_buffer, int _len) {
282 if (self == NULL) return 0;
288 result = NGBufferedDescriptor_write(self, _buffer, _len);
290 if (result == 0) // socket was closed
292 else if (result < 1) // socket error
302 int NGBufferedDescriptor_readChar(NGBufferedDescriptor *self) {
304 return (NGBufferedDescriptor_safeRead(self, &c, 1)) ? c : -1;
307 char NGBufferedDescriptor_writeHttpHeader(NGBufferedDescriptor *self,
309 const unsigned char *_value)
311 register unsigned int len;
313 if (!NGBufferedDescriptor_safeWrite(self, _key, strlen((char *)_key)))
316 if (!NGBufferedDescriptor_safeWrite(self, ": ", 2))
319 len = strlen((char *)_value);
322 Required for deliverying certificates, we encode \n and \r as %10 and %13
323 assuming that the certficiate is in base64. To safeguard, we also encode
326 if (len > 0 && (index((char *)_value, '\n') != NULL ||
327 index((char *)_value, '\r') !=NULL)) {
328 for (len = 0; _value[len] != '\0'; len++) {
329 switch (_value[len]) {
334 sprintf(buf, "%%%02i", _value[len]);
335 if (NGBufferedDescriptor_write(self, buf, 3) <= 0)
340 if (NGBufferedDescriptor_write(self, &(_value[len]), 1) <= 0)
347 if (!NGBufferedDescriptor_safeWrite(self, _value, len))
351 if (!NGBufferedDescriptor_safeWrite(self, "\r\n", 2))