diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index c45b480..82676b7 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -1032,6 +1032,53 @@ int main (int argc, char *argv[]) // service RPC mode else { + URI uri; + bool validURI = URI::parse(service, uri); + if (validURI) + { + if (uri.protocol != "pva") + { + std::cerr << "invalid URI scheme '" << uri.protocol << "', only 'pva' is supported" << std::endl; + // TODO + return 1; + } + + if (uri.path.length() <= 1) + { + std::cerr << "invalid URI, empty path" << std::endl; + // TODO + return 1; + } + + // skip trailing '/' + service = uri.path.substr(1); + + string::const_iterator end_i = uri.query.end(); + string::const_iterator begin_i = uri.query.begin(); + while (begin_i != end_i) + { + string::const_iterator pair_end_i = find(begin_i, end_i, '&'); + + string::const_iterator name_end_i = find(begin_i, pair_end_i, '='); + if (name_end_i != pair_end_i) + { + string name(begin_i, name_end_i); + string value(name_end_i+1, pair_end_i); + parameters.push_back(pair(name, value)); + } + else + { + fprintf(stderr, "Parameter not specified in name=value form. ('eget -h' for help.)\n"); + // TODO + return 1; + } + + begin_i = pair_end_i; + if (begin_i != end_i) + begin_i++; // skip '&' + } + } + /* std::cerr << "service : " << service << std::endl; std::cerr << "parameters : " << std::endl; @@ -1040,7 +1087,7 @@ int main (int argc, char *argv[]) for (; iter != parameters.end(); iter++) std::cerr << " " << iter->first << " = " << iter->second << std::endl; //std::cerr << "encoded URL request: '" << urlEncodedRequest << "'" << std::endl; - */ + */ // simply empty PVStructure::shared_pointer pvRequest = diff --git a/testApp/remote/pvutils.cpp b/testApp/remote/pvutils.cpp index a69edc6..5c5a9b7 100644 --- a/testApp/remote/pvutils.cpp +++ b/testApp/remote/pvutils.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std; using namespace std::tr1; @@ -283,3 +284,39 @@ epics::pvData::FieldConstPtr GetFieldRequesterImpl::getField() Lock lock(m_pointerMutex); return m_field; } + + + +// TODO invalid characters check, etc. +bool URI::parse(const string& uri, URI& result) +{ + const string prot_end("://"); + string::const_iterator prot_i = search(uri.begin(), uri.end(), + prot_end.begin(), prot_end.end()); + if( prot_i == uri.end() || prot_i == uri.begin() ) + return false; + + result.protocol.reserve(distance(uri.begin(), prot_i)); + transform(uri.begin(), prot_i, + back_inserter(result.protocol), + ::tolower); // protocol is icase + + advance(prot_i, prot_end.length()); + if ( prot_i == uri.end() ) + return false; + + string::const_iterator path_i = find(prot_i, uri.end(), '/'); + result.host.assign(prot_i, path_i); + + string::const_iterator fragment_i = find(path_i, uri.end(), '#'); + if ( fragment_i != uri.end() ) + result.fragment.assign(fragment_i+1, uri.end()); + + string::const_iterator query_i = find(path_i, fragment_i, '?'); + result.path.assign(path_i, query_i); + if( query_i != fragment_i ) + result.query.assign(++query_i, fragment_i); + + return true; +} + diff --git a/testApp/remote/pvutils.h b/testApp/remote/pvutils.h index 187041c..a71864e 100644 --- a/testApp/remote/pvutils.h +++ b/testApp/remote/pvutils.h @@ -25,6 +25,14 @@ char to_hex(char code); /* IMPORTANT: be sure to free() the returned string after use */ char *url_encode(const char *str); +#include + +struct URI { +public: + static bool parse(const std::string& uri, URI& result); +public: + std::string protocol, host, path, query, fragment; +}; class RequesterImpl : public epics::pvData::Requester