// $Id: RparseUrl.cpp 492 2013-02-24 22:14:47Z mueller $
|
// $Id: RparseUrl.cpp 516 2013-05-05 21:24:52Z mueller $
|
//
|
//
|
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
//
|
//
|
// This program is free software; you may redistribute and/or modify it under
|
// This program is free software; you may redistribute and/or modify it under
|
// the terms of the GNU General Public License as published by the Free
|
// the terms of the GNU General Public License as published by the Free
|
// Software Foundation, either version 2, or at your option any later version.
|
// Software Foundation, either version 2, or at your option any later version.
|
//
|
//
|
// This program is distributed in the hope that it will be useful, but
|
// This program is distributed in the hope that it will be useful, but
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for complete details.
|
// for complete details.
|
//
|
//
|
// Revision History:
|
// Revision History:
|
// Date Rev Version Comment
|
// Date Rev Version Comment
|
// 2013-02-23 492 1.0.1 add static FindScheme(); allow no or empty scheme
|
// 2013-02-23 492 1.0.1 add static FindScheme(); allow no or empty scheme
|
// 2013-02-03 481 1.0 Initial version, extracted from RlinkPort
|
// 2013-02-03 481 1.0 Initial version, extracted from RlinkPort
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: RparseUrl.cpp 492 2013-02-24 22:14:47Z mueller $
|
\version $Id: RparseUrl.cpp 516 2013-05-05 21:24:52Z mueller $
|
\brief Implemenation of RparseUrl.
|
\brief Implemenation of RparseUrl.
|
*/
|
*/
|
|
|
#include <iostream>
|
#include <iostream>
|
|
|
#include "RparseUrl.hpp"
|
#include "RparseUrl.hpp"
|
|
|
#include "RosFill.hpp"
|
#include "RosFill.hpp"
|
#include "RosPrintf.hpp"
|
#include "RosPrintf.hpp"
|
|
|
using namespace std;
|
using namespace std;
|
|
|
/*!
|
/*!
|
\class Retro::RparseUrl
|
\class Retro::RparseUrl
|
\brief FIXME_docs
|
\brief FIXME_docs
|
*/
|
*/
|
|
|
// all method definitions in namespace Retro
|
// all method definitions in namespace Retro
|
namespace Retro {
|
namespace Retro {
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Default constructor
|
//! Default constructor
|
|
|
RparseUrl::RparseUrl()
|
RparseUrl::RparseUrl()
|
: fUrl(),
|
: fUrl(),
|
fScheme(),
|
fScheme(),
|
fPath(),
|
fPath(),
|
fOptMap()
|
fOptMap()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! Destructor
|
//! Destructor
|
|
|
RparseUrl::~RparseUrl()
|
RparseUrl::~RparseUrl()
|
{}
|
{}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RparseUrl::Set(const std::string& url, const std::string& optlist,
|
bool RparseUrl::Set(const std::string& url, const std::string& optlist,
|
RerrMsg& emsg)
|
RerrMsg& emsg)
|
{
|
{
|
fUrl = url;
|
fUrl = url;
|
fScheme = FindScheme(url);
|
fScheme = FindScheme(url);
|
fPath.clear();
|
fPath.clear();
|
fOptMap.clear();
|
fOptMap.clear();
|
|
|
size_t pdel = fScheme.length();
|
size_t pdel = fScheme.length();
|
if (pdel == 0 && url.length()>0 && url[0] != ':') pdel = -1;
|
if (pdel == 0 && url.length()>0 && url[0] != ':') pdel = -1;
|
size_t odel = url.find_first_of('?', fScheme.length());
|
size_t odel = url.find_first_of('?', fScheme.length());
|
|
|
if (odel == string::npos) { // no options
|
if (odel == string::npos) { // no options
|
if (url.length() > pdel+1) fPath = url.substr(pdel+1);
|
if (url.length() > pdel+1) fPath = url.substr(pdel+1);
|
|
|
} else { // options to process
|
} else { // options to process
|
fPath = url.substr(pdel+1,odel-(pdel+1));
|
fPath = url.substr(pdel+1,odel-(pdel+1));
|
string key;
|
string key;
|
string val;
|
string val;
|
bool hasval = false;
|
bool hasval = false;
|
|
|
for (size_t i=odel+1; i<url.length(); i++) {
|
for (size_t i=odel+1; i<url.length(); i++) {
|
char c = url[i];
|
char c = url[i];
|
if (c == ';') {
|
if (c == ';') {
|
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
key.clear();
|
key.clear();
|
val.clear();
|
val.clear();
|
hasval = false;
|
hasval = false;
|
} else {
|
} else {
|
if (!hasval) {
|
if (!hasval) {
|
if (c == '=') {
|
if (c == '=') {
|
hasval = true;
|
hasval = true;
|
} else
|
} else
|
key.push_back(c);
|
key.push_back(c);
|
} else {
|
} else {
|
if (c == '\\') {
|
if (c == '\\') {
|
if (i+1 >= url.length()) {
|
if (i+1 >= url.length()) {
|
emsg.Init("RparseUrl::ParseUrl()",
|
emsg.Init("RparseUrl::ParseUrl()",
|
string("invalid trailing \\ in url '") + url +
|
string("invalid trailing \\ in url '") + url + "'");
|
string("'"));
|
|
return false;
|
return false;
|
}
|
}
|
i += 1;
|
i += 1;
|
switch (url[i]) {
|
switch (url[i]) {
|
case '\\' : c = '\\'; break;
|
case '\\' : c = '\\'; break;
|
case ';' : c = ';'; break;
|
case ';' : c = ';'; break;
|
default : emsg.Init("RparseUrl::ParseUrl()",
|
default : emsg.Init("RparseUrl::ParseUrl()",
|
string("invalid \\ escape in url '") +
|
string("invalid \\ escape in url '") +
|
url + string("'"));
|
url + "'");
|
return false;
|
return false;
|
}
|
}
|
}
|
}
|
val.push_back(c);
|
val.push_back(c);
|
}
|
}
|
}
|
}
|
}
|
}
|
if (key.length() || hasval) {
|
if (key.length() || hasval) {
|
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
if (!AddOpt(key, val, hasval, optlist, emsg)) return false;
|
}
|
}
|
}
|
}
|
|
|
return true;
|
return true;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RparseUrl::Clear()
|
void RparseUrl::Clear()
|
{
|
{
|
fUrl.clear();
|
fUrl.clear();
|
fScheme.clear();
|
fScheme.clear();
|
fPath.clear();
|
fPath.clear();
|
fOptMap.clear();
|
fOptMap.clear();
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RparseUrl::FindOpt(const std::string& name) const
|
bool RparseUrl::FindOpt(const std::string& name) const
|
{
|
{
|
omap_cit_t it = fOptMap.find(name);
|
omap_cit_t it = fOptMap.find(name);
|
if (it == fOptMap.end()) return false;
|
if (it == fOptMap.end()) return false;
|
return true;
|
return true;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RparseUrl::FindOpt(const std::string& name, std::string& value) const
|
bool RparseUrl::FindOpt(const std::string& name, std::string& value) const
|
{
|
{
|
omap_cit_t it = fOptMap.find(name);
|
omap_cit_t it = fOptMap.find(name);
|
if (it == fOptMap.end()) return false;
|
if (it == fOptMap.end()) return false;
|
|
|
value = it->second;
|
value = it->second;
|
|
|
return true;
|
return true;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RparseUrl::Dump(std::ostream& os, int ind, const char* text) const
|
void RparseUrl::Dump(std::ostream& os, int ind, const char* text) const
|
{
|
{
|
RosFill bl(ind);
|
RosFill bl(ind);
|
os << bl << (text?text:"--") << "RparseUrl @ " << this << endl;
|
os << bl << (text?text:"--") << "RparseUrl @ " << this << endl;
|
|
|
os << bl << " fUrl: " << fUrl << endl;
|
os << bl << " fUrl: " << fUrl << endl;
|
os << bl << " fScheme: " << fScheme << endl;
|
os << bl << " fScheme: " << fScheme << endl;
|
os << bl << " fPath: " << fPath << endl;
|
os << bl << " fPath: " << fPath << endl;
|
os << bl << " fOptMap: " << endl;
|
os << bl << " fOptMap: " << endl;
|
for (omap_cit_t it=fOptMap.begin(); it!=fOptMap.end(); it++) {
|
for (omap_cit_t it=fOptMap.begin(); it!=fOptMap.end(); it++) {
|
os << bl << " " << RosPrintf((it->first).c_str(), "-s",8)
|
os << bl << " " << RosPrintf((it->first).c_str(), "-s",8)
|
<< " : " << it->second << endl;
|
<< " : " << it->second << endl;
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
std::string RparseUrl::FindScheme(const std::string& url,
|
std::string RparseUrl::FindScheme(const std::string& url,
|
const std::string& def)
|
const std::string& def)
|
{
|
{
|
size_t pdel = url.find_first_of(':');
|
size_t pdel = url.find_first_of(':');
|
if (pdel == string::npos) { // no : found
|
if (pdel == string::npos) { // no : found
|
return def;
|
return def;
|
}
|
}
|
|
|
size_t odel = url.find_first_of('?');
|
size_t odel = url.find_first_of('?');
|
if (odel != string::npos && odel < pdel) { // : after ?
|
if (odel != string::npos && odel < pdel) { // : after ?
|
return def;
|
return def;
|
}
|
}
|
|
|
return url.substr(0, pdel);
|
return url.substr(0, pdel);
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
bool RparseUrl::AddOpt(const std::string& key, const std::string& val,
|
bool RparseUrl::AddOpt(const std::string& key, const std::string& val,
|
bool hasval, const std::string& optlist, RerrMsg& emsg)
|
bool hasval, const std::string& optlist, RerrMsg& emsg)
|
{
|
{
|
string lkey = "|";
|
string lkey = "|";
|
lkey += key;
|
lkey += key;
|
if (hasval) lkey += "=";
|
if (hasval) lkey += "=";
|
lkey += "|";
|
lkey += "|";
|
if (optlist.find(lkey) == string::npos) {
|
if (optlist.find(lkey) == string::npos) {
|
emsg.Init("RparseUrl::AddOpt()",
|
emsg.Init("RparseUrl::AddOpt()",
|
string("invalid field name '") + lkey + string("'"));
|
string("invalid field name '") + lkey + "'; allowed: '" +
|
|
optlist + "'");
|
return false;
|
return false;
|
}
|
}
|
|
|
fOptMap.insert(omap_val_t(key, hasval ? val : "1"));
|
fOptMap.insert(omap_val_t(key, hasval ? val : "1"));
|
return true;
|
return true;
|
}
|
}
|
|
|
} // end namespace Retro
|
} // end namespace Retro
|
|
|