// get the value of a parameter bool MimeField::GetParameter(const char* pszAttr, AnsiString& strValue) const { strValue = ""; bool encodedParameter = false; vector<AnsiString> parameters = StringParser::SplitString(AnsiString(m_strValue), ";"); for (unsigned int i = 1; i < parameters.size(); i++) { AnsiString value = parameters[i]; value.TrimLeft(); // Locate end of parameter name. int nameEndPos = 0; for (nameEndPos = 0; nameEndPos < value.GetLength(); nameEndPos++) { char c = value[nameEndPos]; if (c == ' ' || c == '*' || c == '=') break; } // If we haven't found any value for this parameter, bail out. if (nameEndPos == 0 && strValue.IsEmpty()) return false; AnsiString parameterName = value.Mid(0, nameEndPos); if (parameterName.CompareNoCase(pszAttr) != 0) continue; // Locate start of parameter value. int valuePos = 0; for (valuePos = nameEndPos; valuePos < value.GetLength(); valuePos++) { char c = value[valuePos]; if (c == '=') break; } // We want the char before = NOT char after param name // to detect encoding per RFC 2231 4.1 // http://www.hmailserver.com/forum/viewtopic.php?f=10&t=21417 char characterBeforeEquals = value[valuePos - 1]; if (characterBeforeEquals == '*') encodedParameter = true; // Skip past the equal sign. valuePos++; // Locate the start of the actual value. May be enclosed with quotes. // // For instance, this is perfectly valid // Content-Type: text/plain; charset = "iso-8859-1" // for (; valuePos < value.GetLength(); valuePos++) { char c = value[valuePos]; if (c == ' ' || c == '"') continue; else break; } // Locate the end of the value. The value may contain // pretty much any character, including space. int valueEndPos = valuePos; for (; valueEndPos < value.GetLength(); valueEndPos++) { char c = value[valueEndPos]; if (c == ';' || c == '"') break; else continue; } int valueLength = valueEndPos - valuePos; value = value.Mid(valuePos, valueLength); // If the value is // Content-Type: text/plain; charset = "iso-8859-1" // it needs to be trimmed. value.TrimRight(); strValue.append(value); } if (strValue.IsEmpty()) return false; /* (2) MIME headers, like the RFC 822 headers they often appear in, are limited to 7bit US-ASCII, and the encoded-word mechanisms of RFC 2047 are not available to parameter values. This makes it impossible to have parameter values in character sets other than US-ASCII without specifying some sort of private per-parameter encoding. http://tools.ietf.org/html/draft-freed-pvcsc-03 Examples: Input: ISO-8859-1''%E9%2E%70%6E%67 Output: =?ISO-8859-1?Q?=E9=2Epng?= */ if (encodedParameter) { MimeParameterRFC2184Decoder decoder; strValue.assign(decoder.Decode(strValue)); } strValue.TrimLeft(); return true; }