diff options
author | Vincent Richard <[email protected]> | 2005-04-12 18:42:54 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2005-04-12 18:42:54 +0000 |
commit | f879a9794c4908df8e7484250b56b13342a66038 (patch) | |
tree | 83f91b9f743eb70d5398c6ce543596b434274c16 /src/parameterizedHeaderField.cpp | |
parent | Added attachMDNRequest(). (diff) | |
download | vmime-f879a9794c4908df8e7484250b56b13342a66038.tar.gz vmime-f879a9794c4908df8e7484250b56b13342a66038.zip |
Added support for RFC-2231.
Diffstat (limited to 'src/parameterizedHeaderField.cpp')
-rw-r--r-- | src/parameterizedHeaderField.cpp | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp index 92631d9d..d3c8f67c 100644 --- a/src/parameterizedHeaderField.cpp +++ b/src/parameterizedHeaderField.cpp @@ -55,6 +55,20 @@ parameterizedHeaderField::parameterizedHeaderField() ; to use within parameter values */ + +#ifndef VMIME_BUILDING_DOC + +struct paramInfo +{ + bool extended; + std::vector <parameter::valueChunk> value; + string::size_type start; + string::size_type end; +}; + +#endif // VMIME_BUILDING_DOC + + void parameterizedHeaderField::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { @@ -73,6 +87,8 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty // If there is one or more parameters following... if (p < pend) { + std::map <string, paramInfo> params; + while (*p == ';') { // Skip ';' @@ -183,20 +199,99 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty // Don't allow ill-formed parameters if (attrStart != attrEnd && value.length()) { - // Append this parameter to the list - parameter* param = parameterFactory::getInstance()-> - create(string(buffer.begin() + attrStart, - buffer.begin() + attrEnd), value); + string name(buffer.begin() + attrStart, buffer.begin() + attrEnd); - param->setParsedBounds(attrStart, position + (p - pstart)); + // Check for RFC-2231 extended parameters + bool extended = false; + bool encoded = false; - appendParameter(param); + if (name[name.length() - 1] == '*') + { + name.erase(name.end() - 1, name.end()); + + extended = true; + encoded = true; + } + + // Check for RFC-2231 multi-section parameters + const string::size_type star = name.find_last_of('*'); + + if (star != string::npos) + { + bool allDigits = true; + + for (string::size_type i = star + 1 ; allDigits && (i < name.length()) ; ++i) + allDigits = parserHelpers::isDigit(name[i]); + + if (allDigits) + { + name.erase(name.begin() + star, name.end()); + extended = true; + } + + // NOTE: we ignore section number, and we suppose that + // the sequence is correct (ie. the sections appear + // in order: param*0, param*1...) + } + + // Add/replace/modify the parameter + const std::map <string, paramInfo>::iterator it = params.find(name); + + if (it != params.end()) + { + paramInfo& info = (*it).second; + + // An extended parameter replaces a normal one + if (!info.extended) + { + info.extended = extended; + info.value.clear(); + info.start = attrStart; + } + + // Append a new section for a multi-section parameter + parameter::valueChunk chunk; + chunk.encoded = encoded; + chunk.data = value; + + info.value.push_back(chunk); + info.end = position + (p - pstart); + } + else + { + parameter::valueChunk chunk; + chunk.encoded = encoded; + chunk.data = value; + + paramInfo info; + info.extended = extended; + info.value.push_back(chunk); + info.start = attrStart; + info.end = position + (p - pstart); + + // Insert a new parameter + params.insert(std::map <string, paramInfo>::value_type(name, info)); + } } // Skip white-spaces after this parameter while (p < pend && parserHelpers::isSpace(*p)) ++p; } } + + for (std::map <string, paramInfo>::const_iterator it = params.begin() ; + it != params.end() ; ++it) + { + const paramInfo& info = (*it).second; + + // Append this parameter to the list + parameter* param = parameterFactory::getInstance()->create((*it).first); + + param->parse(info.value); + param->setParsedBounds(info.start, info.end); + + appendParameter(param); + } } if (newPosition) |