1 ///###////////////////////////////////////////////////////////////////////////
2 //
3 // Burton Computer Corporation
4 // http://www.burton-computer.com
5 // http://www.cooldevtools.com
6 // $Id: MessageHeaderList.cc 272 2007-01-06 19:37:27Z brian $
7 //
8 // Copyright (C) 2007 Burton Computer Corporation
9 // ALL RIGHTS RESERVED
10 //
11 // This program is open source software; you can redistribute it
12 // and/or modify it under the terms of the Q Public License (QPL)
13 // version 1.0. Use of this software in whole or in part, including
14 // linking it (modified or unmodified) into other programs is
15 // subject to the terms of the QPL.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // Q Public License for more details.
21 //
22 // You should have received a copy of the Q Public License
23 // along with this program; see the file LICENSE.txt. If not, visit
24 // the Burton Computer Corporation or CoolDevTools web site
25 // QPL pages at:
26 //
27 // http://www.burton-computer.com/qpl.html
28 // http://www.cooldevtools.com/qpl.html
29 //
30
31 #include "RegularExpression.h"
32 #include "MultiLineSubString.h"
33 #include "MultiLineJoinedString.h"
34 #include "MessageHeader.h"
35 #include "MessageHeaderList.h"
36
37 static const string CONTENT_TYPE("content-type");
38
header(const string & name) const39 CRef<AbstractMultiLineString> MessageHeaderList::header(const string &name) const
40 {
41 MultiLineStringList values;
42 for (int i = 0; i < m_headers.size(); ++i) {
43 if (m_headers[i]->hasName(name)) {
44 values.push_back(m_headers[i]->lines());
45 }
46 }
47
48 if (values.size() == 0) {
49 return CRef<AbstractMultiLineString>();
50 }
51
52 if (values.size() == 1) {
53 return values[0];
54 }
55
56 return CRef<AbstractMultiLineString>(new MultiLineJoinedString(values));
57 }
58
getContentTypeString(string & buffer) const59 const string &MessageHeaderList::getContentTypeString(string &buffer) const
60 {
61 getHeaderString(CONTENT_TYPE, EMPTY_STRING, buffer);
62 buffer = to_lower(buffer);
63 return buffer;
64 }
65
getBoundaryString(string & buffer) const66 const string &MessageHeaderList::getBoundaryString(string &buffer) const
67 {
68 string header;
69 getHeaderString(CONTENT_TYPE, EMPTY_STRING, header);
70 return findParam(header, "boundary", EMPTY_STRING, buffer);
71 }
72
getCharsetString(string & buffer) const73 const string &MessageHeaderList::getCharsetString(string &buffer) const
74 {
75 string header;
76 getHeaderString(CONTENT_TYPE, EMPTY_STRING, header);
77 findParam(header, "charset", EMPTY_STRING, buffer);
78 buffer = to_lower(buffer);
79 return buffer;
80 }
81
getHeaderString(const string & header_name,const string & default_value,string & buffer) const82 const string &MessageHeaderList::getHeaderString(const string &header_name,
83 const string &default_value,
84 string &buffer) const
85 {
86 CRef<AbstractMultiLineString> header_strings(header(header_name));
87 if (header_strings.isNull()) {
88 buffer = default_value;
89 } else {
90 header_strings->join(buffer);
91 }
92 return buffer;
93 }
94
hasBoundaryString() const95 bool MessageHeaderList::hasBoundaryString() const
96 {
97 string boundary_string;
98 getBoundaryString(boundary_string);
99 return boundary_string.length() > 0;
100 }
101
isTextType() const102 bool MessageHeaderList::isTextType() const
103 {
104 string content_type;
105 getContentTypeString(content_type);
106 return content_type.length() == 0 || starts_with(content_type, "text");
107 }
108
hasType(const string & type_name) const109 bool MessageHeaderList::hasType(const string &type_name) const
110 {
111 string content_type;
112 getContentTypeString(content_type);
113 return starts_with(content_type, type_name);
114 }
115
isMessageType() const116 bool MessageHeaderList::isMessageType() const
117 {
118 return hasType("message/rfc822");
119 }
120
findParam(const string & header,const string & param,const string & defaultValue,string & buffer) const121 const string &MessageHeaderList::findParam(const string &header,
122 const string ¶m,
123 const string &defaultValue,
124 string &buffer) const
125 {
126 RegularExpression param_regex(string("[^a-z]") + param + "[ \t]*=[ \t]*\"([^\"]+)\"", 2, true);
127 if (param_regex.match(header)) {
128 return param_regex.getMatch(1, buffer);
129 }
130
131 param_regex.setExpression(string("[^a-z]") + param + "[ \t]*=[ \t]*([^ \t;\"]+)", 2, true);
132 if (param_regex.match(header)) {
133 return param_regex.getMatch(1, buffer);
134 }
135
136 buffer = defaultValue;
137 return buffer;
138 }
139
140