diff --git a/src/tawashi_implem/mime_split.cpp b/src/tawashi_implem/mime_split.cpp index c86a59f..83692b7 100644 --- a/src/tawashi_implem/mime_split.cpp +++ b/src/tawashi_implem/mime_split.cpp @@ -28,9 +28,21 @@ #include #include #include -#include #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include + #include #include #include @@ -39,7 +51,10 @@ #include #include #include + #include +#include +#include // The Internet Media Type [9 <#ref-9>] of the attached entity. The syntax is // the same as the HTTP Content-Type header. @@ -96,6 +111,7 @@ namespace tawashi { m_master_string(parString), m_begin(m_master_string->cbegin()) { + namespace px = boost::phoenix; using boost::spirit::ascii::space; using boost::spirit::qi::char_; using boost::spirit::qi::lit; @@ -105,7 +121,6 @@ namespace tawashi { using boost::spirit::qi::lexeme; using boost::string_ref; using boost::spirit::_1; - namespace px = boost::phoenix; content_type = -media_type; media_type = type >> "/" >> subtype >> *(lit(";") >> parameter); @@ -115,7 +130,13 @@ namespace tawashi { attribute = token.alias(); value = token | quoted_string; - token = raw[+(alnum | char_("-_."))][_val = px::bind(&string_ref::substr, px::construct(px::ref(*m_master_string)), px::begin(_1) - px::ref(m_begin), px::size(_1))]; + token = raw[+(alnum | char_("_.-"))][ + _val = px::bind( + &string_ref::substr, px::construct(px::ref(*m_master_string)), + px::begin(_1) - px::ref(m_begin), + px::size(_1) + ) + ]; quoted_string = raw[ lexeme[ lit('"') >> @@ -128,9 +149,26 @@ namespace tawashi { px::size(_1) - 2 )]; } + + struct simple_token_checker { + typedef bool result_type; + + template + bool operator() (const V& parIn) const { + std::cout << "simple_token_checker returning "; + if (std::find(std::begin(parIn), std::end(parIn), ' ') == std::end(parIn)) { + std::cout << "true\n"; + return true; + } + else { + std::cout << "false\n"; + return false; + } + } + }; } //unnamed namespace - SplitMime split_mime (const std::string* parMime, bool& parParseOk, int& parParsedCharCount) { + SplitMime string_to_mime (const std::string* parMime, bool& parParseOk, int& parParsedCharCount) { using boost::spirit::qi::blank; using boost::spirit::qi::blank_type; @@ -154,4 +192,41 @@ namespace tawashi { assert(parParsedCharCount >= 0); return result; } + + std::string mime_to_string (const SplitMime& parMime, bool& parWriteOk) { + namespace px = boost::phoenix; + using boost::string_ref; + using boost::spirit::karma::generate; + using boost::spirit::karma::char_; + using boost::spirit::karma::string; + using boost::spirit::karma::rule; + using boost::spirit::karma::alnum; + using boost::spirit::karma::eps; + using boost::spirit::_val; + + if (parMime.type.empty() or parMime.subtype.empty()) { + parWriteOk = false; + return std::string(); + } + + px::function is_simple_token; + std::string retval; + std::back_insert_iterator out_iter(retval); + rule, string_ref()> token; + rule, string_ref()> quoted_string; + rule, string_ref()> param_value; + + token %= eps(is_simple_token(_val)) << *(alnum | char_("._-")); + quoted_string %= '"' << string << '"'; + param_value %= token | quoted_string; + + parWriteOk = generate( + out_iter, + string << "/" << string << *( + "; " << string << "=" << param_value + ), + parMime + ); + return retval; + } } //namespace tawashi diff --git a/src/tawashi_implem/mime_split.hpp b/src/tawashi_implem/mime_split.hpp index a767c9a..98d1ccf 100644 --- a/src/tawashi_implem/mime_split.hpp +++ b/src/tawashi_implem/mime_split.hpp @@ -30,5 +30,6 @@ namespace tawashi { MimeParametersMapType parameters; }; - SplitMime split_mime (const std::string* parMime, bool& parParseOk, int& parParsedCharCount); + SplitMime string_to_mime (const std::string* parMime, bool& parParseOk, int& parParsedCharCount); + std::string mime_to_string (const SplitMime& parMime, bool& parWriteOk); } //namespace tawashi diff --git a/test/unit/test_mime_split.cpp b/test/unit/test_mime_split.cpp index c626d4c..5647f32 100644 --- a/test/unit/test_mime_split.cpp +++ b/test/unit/test_mime_split.cpp @@ -24,16 +24,16 @@ namespace { } } //unnamed namespace -TEST_CASE ("Test the Mime-type splitter", "[mime][parser]") { +TEST_CASE ("Test the string_to_mime parser", "[mime][parser]") { using tawashi::SplitMime; - using tawashi::split_mime; + using tawashi::string_to_mime; bool ok; int parsed_count; { std::string test("application/x-javascript; charset=UTF-8"); std::string curr_val; - SplitMime split = split_mime(&test, ok, parsed_count); + SplitMime split = string_to_mime(&test, ok, parsed_count); REQUIRE(ok); CHECK(test.size() == parsed_count); @@ -49,7 +49,7 @@ TEST_CASE ("Test the Mime-type splitter", "[mime][parser]") { { std::string test("image/jpeg; filename=genome.jpeg; modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\""); std::string curr_val; - SplitMime split = split_mime(&test, ok, parsed_count); + SplitMime split = string_to_mime(&test, ok, parsed_count); REQUIRE(ok); CHECK(test.size() == parsed_count); @@ -66,3 +66,40 @@ TEST_CASE ("Test the Mime-type splitter", "[mime][parser]") { CHECK(curr_val == "Wed, 12 Feb 1997 16:29:51 -0500"); } } + +TEST_CASE ("Test the mime_to_string parser", "[mime][parser]") { + using tawashi::SplitMime; + using tawashi::mime_to_string; + + std::string type = "image"; + std::string subtype = "jpeg"; + bool ok; + + { + SplitMime test; + test.type = type; + test.subtype = subtype; + std::string result = mime_to_string(test, ok); + REQUIRE(ok); + CHECK(result == "image/jpeg"); + } + { + SplitMime test; + test.type = type; + test.subtype = subtype; + test.parameters["filename"] = "genome.jpeg"; + std::string result = mime_to_string(test, ok); + REQUIRE(ok); + CHECK(result == "image/jpeg; filename=genome.jpeg"); + } + { + SplitMime test; + test.type = type; + test.subtype = subtype; + test.parameters["modification-date"] = "Wed, 12 Feb 1997 16:29:51 -0500"; + test.parameters["filename"] = "genome.jpeg"; + std::string result = mime_to_string(test, ok); + REQUIRE(ok); + CHECK(result == "image/jpeg; filename=genome.jpeg; modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\""); + } +}