diff options
Diffstat (limited to 'src/include/mime-inputsource.h')
-rw-r--r-- | src/include/mime-inputsource.h | 141 |
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 |