summaryrefslogtreecommitdiff
path: root/src/include/mime-inputsource.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/mime-inputsource.h')
-rw-r--r--src/include/mime-inputsource.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/include/mime-inputsource.h b/src/include/mime-inputsource.h
new file mode 100644
index 0000000..e37d508
--- /dev/null
+++ b/src/include/mime-inputsource.h
@@ -0,0 +1,141 @@
+/** --------------------------------------------------------------------
+ * @file mime-inputsource.h
+ * @brief The base class of the MIME input source
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef mime_inputsource_h_included
+#define mime_inputsource_h_included
+
+#include <string.h>
+#include <unistd.h>
+
+namespace Binc {
+
+ class MimeInputSource {
+ public:
+ inline MimeInputSource(int fd, unsigned int start = 0);
+ virtual inline ~MimeInputSource(void);
+
+ virtual inline bool fillInputBuffer(void);
+ virtual inline void reset(void);
+
+ inline void seek(unsigned int offset);
+ inline bool getChar(char *c);
+ inline void ungetChar(void);
+ inline int getFileDescriptor(void) const;
+
+ inline unsigned int getOffset(void) const;
+
+ private:
+ int fd;
+ char data[16384];
+ unsigned int offset;
+ unsigned int tail;
+ unsigned int head;
+ unsigned int start;
+ char lastChar;
+ };
+
+ inline MimeInputSource::MimeInputSource(int fd, unsigned int start)
+ {
+ this->fd = fd;
+ this->start = start;
+ offset = 0;
+ tail = 0;
+ head = 0;
+ lastChar = '\0';
+ memset(data, '\0', sizeof(data));
+
+ seek(start);
+ }
+
+ inline MimeInputSource::~MimeInputSource(void)
+ {
+ }
+
+ inline bool MimeInputSource::fillInputBuffer(void)
+ {
+ char raw[4096];
+ ssize_t nbytes = read(fd, raw, sizeof(raw));
+ if (nbytes <= 0) {
+ // FIXME: If ferror(crlffile) we should log this.
+ return false;
+ }
+
+ for (ssize_t i = 0; i < nbytes; ++i) {
+ const char c = raw[i];
+ if (c == '\r') {
+ if (lastChar == '\r') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ }
+ } else if (c == '\n') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ } else {
+ if (lastChar == '\r') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ }
+ data[tail++ & (0x4000-1)] = c;
+ }
+
+ lastChar = c;
+ }
+
+ return true;
+ }
+
+ inline void MimeInputSource::reset(void)
+ {
+ offset = head = tail = 0;
+ lastChar = '\0';
+
+ if (fd != -1)
+ lseek(fd, 0, SEEK_SET);
+ }
+
+ inline void MimeInputSource::seek(unsigned int seekToOffset)
+ {
+ if (offset > seekToOffset)
+ reset();
+
+ char c;
+ int n = 0;
+ while (seekToOffset > offset) {
+ if (!getChar(&c)) break;
+ ++n;
+ }
+ }
+
+ inline bool MimeInputSource::getChar(char *c)
+ {
+ if (head == tail && !fillInputBuffer())
+ return false;
+
+ *c = data[head++ & (0x4000-1)];
+ ++offset;
+ return true;
+ }
+
+ inline void MimeInputSource::ungetChar()
+ {
+ --head;
+ --offset;
+ }
+
+ inline int MimeInputSource::getFileDescriptor(void) const
+ {
+ return fd;
+ }
+
+ inline unsigned int MimeInputSource::getOffset(void) const
+ {
+ return offset;
+ }
+}
+
+extern Binc::MimeInputSource *mimeSource;
+
+#endif