Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00021
00022 #include "SchemeParser.h"
00023
00024 #include <boost/foreach.hpp>
00025
00026 namespace icl_core
00027 {
00028
00029 std::ostream &operator<<(std::ostream &stream, const Scheme &scheme)
00030 {
00031 stream << scheme.scheme_name << scheme.specifier;
00032
00033 bool first = true;
00034 BOOST_FOREACH(Query query, scheme.queries)
00035 {
00036 if ( first )
00037 {
00038 stream << "?";
00039 first = false;
00040 }
00041 else
00042 {
00043 stream << "&";
00044 }
00045 stream << query.name << "=" << query.value;
00046 }
00047
00048 if (scheme.anchor.size() > 0)
00049 {
00050 stream << "#" << scheme.anchor;
00051 }
00052
00053 return stream;
00054 }
00055
00056
00057 void SchemeFunction::operator () (char const* str, char const* end) const
00058 {
00059 std::string name(str, end);
00060 for (size_t i = 0; i < name.size(); ++i)
00061 {
00062 name[i] = tolower(name[i]);
00063 }
00064 if (name == "file://")
00065 {
00066 m_scheme_handler->scheme_type = FileScheme;
00067 }
00068 else if (name == "http://")
00069 {
00070 m_scheme_handler->scheme_type = HttpScheme;
00071 }
00072 else if (name == "camera://")
00073 {
00074 m_scheme_handler->scheme_type = CameraScheme;
00075 }
00076 else if (name == "gps://")
00077 {
00078 m_scheme_handler->scheme_type = GpsScheme;
00079 }
00080 else
00081 {
00082 m_scheme_handler->scheme_type = OtherScheme;
00083 }
00084 m_scheme_handler->scheme_name = name;
00085 }
00086
00087 void SpecifierFunction::operator () (char const* str, char const* end) const
00088 {
00089 std::string name(str, end);
00090 m_scheme_handler->specifier = name;
00091 }
00092
00093 void AnchorFunction::operator () (char const* str, char const* end) const
00094 {
00095 std::string name(str, end);
00096 m_scheme_handler->anchor = name;
00097 }
00098
00099 void QueryKeyFunction::operator () (char const* str, char const* end) const
00100 {
00101 std::string name(str, end);
00102 Query query;
00103 query.name = name;
00104 m_queries->push_back(query);
00105 }
00106
00107 void QueryValueFunction::operator () (char const* str, char const* end) const
00108 {
00109 std::string value(str, end);
00110 if (m_queries->empty())
00111 {
00112 Query query;
00113 query.name = "";
00114 m_queries->push_back(query);
00115 }
00116 QueryList::reverse_iterator rit = m_queries->rbegin();
00117 assert(rit != m_queries->rend());
00118 rit->value = value;
00119 }
00120
00121 SchemeParser::SchemeParser()
00122 {
00123 m_scheme.scheme_type = icl_core::OtherScheme;
00124 }
00125
00126 SchemeParser::~SchemeParser()
00127 {
00128 }
00129
00130 bool SchemeParser::parseScheme(const String &str)
00131 {
00132 return this->parseScheme(str, m_scheme, m_info);
00133 }
00134
00135 const BOOST_SPIRIT_NAMESPACE::parse_info<>& SchemeParser::getParseInfo() const
00136 {
00137 return m_info;
00138 }
00139
00140 const icl_core::Scheme& SchemeParser::getSchemeResult() const
00141 {
00142 return m_scheme;
00143 }
00144
00145 bool SchemeParser::parseScheme(const String &str, Scheme &scheme_handler,
00146 BOOST_SPIRIT_NAMESPACE::parse_info<> &info)
00147 {
00148 using BOOST_SPIRIT_NAMESPACE::rule;
00149 using BOOST_SPIRIT_NAMESPACE::alnum_p;
00150 using BOOST_SPIRIT_NAMESPACE::ch_p;
00151 using BOOST_SPIRIT_NAMESPACE::space_p;
00152 using BOOST_SPIRIT_NAMESPACE::str_p;
00153 using BOOST_SPIRIT_NAMESPACE::alpha_p;
00154 using BOOST_SPIRIT_NAMESPACE::anychar_p;
00155
00156 SchemeFunction addScheme;
00157 addScheme.m_scheme_handler = &scheme_handler;
00158
00159 SpecifierFunction addSpecifier;
00160 addSpecifier.m_scheme_handler = &scheme_handler;
00161
00162 AnchorFunction addAnchor;
00163 addAnchor.m_scheme_handler = &scheme_handler;
00164
00165 QueryKeyFunction addName;
00166 addName.m_queries = &scheme_handler.queries;
00167
00168 QueryValueFunction addValue;
00169 addValue.m_queries = &scheme_handler.queries;
00170
00171
00172 rule<> extword_p = +alnum_p >> *((ch_p('_') | ch_p('-') | ch_p('.') | space_p) >> +alnum_p);
00173 rule<> anchor_word = +alnum_p >> !(ch_p('-') >> +alnum_p);
00174
00175
00176 rule<> scheme_ch = str_p("://");
00177 rule<> anchor_ch = ch_p('#');
00178 rule<> querystart_ch = ch_p('?');
00179 rule<> querydelim_ch = ch_p('&');
00180
00181
00182 rule<> scheme_p = +alpha_p >> *((ch_p('+')) >> +alpha_p) >> scheme_ch;
00183 rule<> specifier_p = +(anychar_p - querystart_ch - anchor_ch);
00184
00185 rule<> anchor_p = anchor_ch >> anchor_word[addAnchor];
00186
00187
00188 rule<> query_key = +alnum_p >> *(alnum_p | (ch_p('_') >> alnum_p));
00189 rule<> query_value = +(anychar_p - (querystart_ch | querydelim_ch | space_p));
00190 rule<> query_pair = query_key[addName] >> ch_p('=') >> query_value[addValue];
00191 rule<> query_p = querystart_ch >> query_pair >> *(querydelim_ch >> query_pair);
00192
00193
00194 rule<> scheme_rule = !scheme_p[addScheme] >> specifier_p[addSpecifier] >> !anchor_p >> !query_p;
00195
00196 scheme_handler.queries.clear();
00197 info = parse(str.c_str(), scheme_rule);
00198
00199 return info.full;
00200 }
00201
00203 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00204
00205 bool SchemeParser::ParseScheme(const String &str)
00206 {
00207 return parseScheme(str);
00208 }
00209
00210 const BOOST_SPIRIT_NAMESPACE::parse_info<> &SchemeParser::GetParseInfo() const
00211 {
00212 return getParseInfo();
00213 }
00214
00215 const icl_core::Scheme &SchemeParser::GetSchemeResult() const
00216 {
00217 return getSchemeResult();
00218 }
00219
00220 bool SchemeParser::ParseScheme(const String &str, Scheme &scheme_handler, BOOST_SPIRIT_NAMESPACE::parse_info<> &info)
00221 {
00222 return parseScheme(str, scheme_handler, info);
00223 }
00224
00225 #endif
00226
00227 }