Switch to unified view

a b/src/bincimapmime/mime-printheader.cc
1
/* -*- Mode: c++; -*- */
2
/*  --------------------------------------------------------------------
3
 *  Filename:
4
 *    mime-printheader.cc
5
 *  
6
 *  Description:
7
 *    Implementation of main mime parser components
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
#ifdef HAVE_CONFIG_H
27
#include <config.h>
28
#endif
29
30
#include "mime.h"
31
#include "mime-utils.h"
32
#include "mime-inputsource.h"
33
#include "convert.h"
34
#include "iodevice.h"
35
#include "iofactory.h"
36
37
#include <string>
38
#include <vector>
39
#include <map>
40
#include <exception>
41
#include <iostream>
42
43
#include <string.h>
44
#include <ctype.h>
45
#include <stdio.h>
46
#include <errno.h>
47
48
using namespace ::std;
49
50
//------------------------------------------------------------------------
51
void Binc::MimePart::printHeader(int fd, IODevice &output,
52
               vector<string> headers, bool includeheaders, 
53
               unsigned int startoffset,
54
               unsigned int length, string &store) const
55
{
56
  if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
57
    delete mimeSource;
58
    mimeSource = new MimeInputSource(fd);
59
  }
60
61
  mimeSource->seek(headerstartoffsetcrlf);
62
63
  string name;
64
  string content;
65
  char cqueue[2];
66
  memset(cqueue, 0, sizeof(cqueue));
67
68
  bool quit = false;
69
  char c = '\0';
70
71
  unsigned int wrotebytes = 0;
72
  unsigned int processedbytes = 0;
73
  bool hasHeaderSeparator = false;
74
75
  while (!quit) {
76
    // read name
77
    while (1) {
78
      // allow EOF to end the header
79
      if (!mimeSource->getChar(&c)) {
80
  quit = true;
81
  break;
82
      }
83
84
      // assume this character is part of the header name.
85
      name += c;
86
      
87
      // break on the first colon
88
      if (c == ':')
89
  break;
90
91
      // break if a '\n' turned up.
92
      if (c == '\n') {
93
  // end of headers detected
94
  if (name == "\r\n") {
95
    hasHeaderSeparator = true;
96
    quit = true;
97
    break;
98
  }
99
  
100
  // put all data back in the buffer to the beginning of this
101
  // line.
102
  for (int i = name.length(); i >= 0; --i)
103
    mimeSource->ungetChar();
104
  
105
  // abort printing of header. note that in this case, the
106
  // headers will not end with a seperate \r\n.
107
  quit = true;
108
  name = "";
109
  break;
110
      }
111
    }
112
113
    if (quit) break;
114
115
    // at this point, we have a name, that is - the start of a
116
    // header. we'll read until the end of the header.
117
    while (!quit) {
118
      // allow EOF to end the header.
119
      if (!mimeSource->getChar(&c)) {
120
  quit = true;
121
  break;
122
      }
123
124
      if (c == '\n') ++nlines;
125
126
      // make a fifo queue of the last 4 characters.
127
      cqueue[0] = cqueue[1];
128
      cqueue[1] = c;
129
130
      // print header
131
      if (cqueue[0] == '\n' && cqueue[1] != '\t' && cqueue[1] != ' ') {
132
  // it wasn't a space, so put it back as it is most likely
133
  // the start of a header name. in any case it terminates the
134
  // content part of this header.
135
  mimeSource->ungetChar();
136
  
137
  string lowername = name;
138
  lowercase(lowername);
139
  trim(lowername, ": \t");
140
  bool foundMatch = false;
141
  for (vector<string>::const_iterator i = headers.begin();
142
       i != headers.end(); ++i) {
143
    string nametmp = *i;
144
    lowercase(nametmp);
145
    if (nametmp == lowername) {
146
      foundMatch = true;
147
      break;
148
    }
149
  }
150
151
  if (foundMatch == includeheaders || headers.size() == 0) {
152
    string out = name + content;
153
    for (string::const_iterator i = out.begin(); i != out.end(); ++i)
154
      if (processedbytes >= startoffset && wrotebytes < length) {
155
        if (processedbytes >= startoffset) {
156
      store += *i;
157
      ++wrotebytes;
158
        }
159
      } else
160
        ++processedbytes;
161
  }
162
163
  // move on to the next header
164
  content = "";
165
  name = "";
166
  break;
167
      }
168
169
      content += c;
170
    }
171
  }
172
173
  if (name != "") {
174
    string lowername = name;
175
    lowercase(lowername);
176
    trim(lowername, ": \t");
177
    bool foundMatch = false;
178
    for (vector<string>::const_iterator i = headers.begin();
179
   i != headers.end(); ++i) {
180
      string nametmp = *i;
181
      lowercase(nametmp);
182
      if (nametmp == lowername) {
183
  foundMatch = true;
184
  break;
185
      }
186
    }
187
    
188
    if (hasHeaderSeparator || foundMatch == includeheaders || headers.size() == 0) {
189
      string out = name + content;
190
      for (string::const_iterator i = out.begin(); i != out.end(); ++i)
191
  if (processedbytes >= startoffset && wrotebytes < length) {
192
    store += *i;
193
    ++wrotebytes;
194
  } else
195
    ++processedbytes;
196
    }
197
  }
198
}