Switch to unified view

a b/src/bincimapmime/mime-inputsource.h
1
/* -*- Mode: c++; -*- */
2
/*  --------------------------------------------------------------------
3
 *  Filename:
4
 *    src/mime-inputsource.h
5
 *  
6
 *  Description:
7
 *    The base class of the MIME input source
8
 *  --------------------------------------------------------------------
9
 *  Copyright 2002-2004 Andreas Aardal Hanssen
10
 *
11
 *  This program is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  This program is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this program; if not, write to the Free Software
23
 *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
24
 *  --------------------------------------------------------------------
25
 */
26
#ifndef mime_inputsource_h_included
27
#define mime_inputsource_h_included
28
29
#ifdef HAVE_CONFIG_H
30
#include <config.h>
31
#endif
32
33
#include <string.h>
34
#include <unistd.h>
35
36
namespace Binc {
37
38
  class MimeInputSource {
39
  public:
40
    inline MimeInputSource(int fd, unsigned int start = 0);
41
    virtual inline ~MimeInputSource(void);
42
43
    virtual inline bool fillInputBuffer(void);
44
    virtual inline void reset(void);
45
46
    inline void seek(unsigned int offset);
47
    inline bool getChar(char *c);
48
    inline void ungetChar(void);
49
    inline int getFileDescriptor(void) const;
50
51
    inline unsigned int getOffset(void) const;
52
53
  private:
54
    int fd;
55
    char data[16384];
56
    unsigned int offset;
57
    unsigned int tail;
58
    unsigned int head;
59
    unsigned int start;
60
    char lastChar;
61
  };
62
63
  inline MimeInputSource::MimeInputSource(int fd, unsigned int start)
64
  {
65
    this->fd = fd;
66
    this->start = start;
67
    offset = 0;
68
    tail = 0;
69
    head = 0;
70
    lastChar = '\0';
71
    memset(data, '\0', sizeof(data));
72
73
    seek(start);
74
  }
75
76
  inline MimeInputSource::~MimeInputSource(void)
77
  {
78
  }
79
80
  inline bool MimeInputSource::fillInputBuffer(void)
81
  {
82
    char raw[4096];
83
    ssize_t nbytes = read(fd, raw, sizeof(raw));
84
    if (nbytes <= 0) {
85
      // FIXME: If ferror(crlffile) we should log this.
86
      return false;
87
    }
88
89
    for (ssize_t i = 0; i < nbytes; ++i) {
90
      const char c = raw[i];
91
      if (c == '\r') {
92
  if (lastChar == '\r') {
93
    data[tail++ & (0x4000-1)] = '\r';
94
    data[tail++ & (0x4000-1)] = '\n';
95
  }
96
      } else if (c == '\n') {
97
  data[tail++ & (0x4000-1)] = '\r';
98
  data[tail++ & (0x4000-1)] = '\n';
99
      } else {
100
  if (lastChar == '\r') {
101
    data[tail++ & (0x4000-1)] = '\r';
102
    data[tail++ & (0x4000-1)] = '\n';
103
  }
104
105
  data[tail++ & (0x4000-1)] = c;
106
      }
107
      
108
      lastChar = c;
109
    }
110
111
    return true;
112
  }
113
114
  inline void MimeInputSource::reset(void)
115
  {
116
    offset = head = tail = 0;
117
    lastChar = '\0';
118
119
    if (fd != -1)
120
      lseek(fd, 0, SEEK_SET);
121
  }
122
123
  inline void MimeInputSource::seek(unsigned int seekToOffset)
124
  {
125
    if (offset > seekToOffset)
126
      reset();
127
   
128
    char c;
129
    int n = 0;
130
    while (seekToOffset > offset) {
131
      if (!getChar(&c))
132
  break;
133
      ++n;
134
    }
135
  }
136
137
  inline bool MimeInputSource::getChar(char *c)
138
  {
139
    if (head == tail && !fillInputBuffer())
140
      return false;
141
142
    *c = data[head++ & (0x4000-1)];
143
    ++offset;
144
    return true;
145
  }
146
147
  inline void MimeInputSource::ungetChar()
148
  {
149
    --head;
150
    --offset;
151
  }
152
153
  inline int MimeInputSource::getFileDescriptor(void) const
154
  {
155
    return fd;
156
  }
157
158
  inline unsigned int MimeInputSource::getOffset(void) const
159
  {
160
    return offset;
161
  }
162
}
163
164
extern Binc::MimeInputSource *mimeSource;
165
166
#endif