blob: fff3e9823d1fc7520168b3cbfda15b105eddb6f1 [file] [log] [blame]
/* $Id$
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "util/EtchURL.h"
#include "capu/os/StringUtils.h"
EtchURL::EtchURL()
: terms(ETCH_DEFAULT_URL_TERMS_HASH_BIT_SIZE) {
}
EtchURL::EtchURL(const char* urlStr) {
if (urlStr == NULL) {
//already initialized
} else if (strlen(urlStr) > 0) {
EtchString str(urlStr);
if (parse(&str) != ETCH_OK) {
fragment.set("");
host.set("");
password.set("");
port = 0;
scheme.set("");
uri.set("");
user.set("");
}
}
}
EtchURL::EtchURL(const EtchString& urlStr) {
if (urlStr.c_str() == NULL) {
//already initialized
} else if (urlStr.length() > 0) {
if (parse(&urlStr) != ETCH_OK) {
fragment.set("");
host.set("");
password.set("");
port = 0;
scheme.set("");
uri.set("");
user.set("");
}
}
}
EtchURL::~EtchURL() {
params.clear();
terms.clear();
}
status_t EtchURL::parse(const EtchString* s) {
if (s == NULL)
return ETCH_EINVAL;
// s is scheme:[//[user[:password]@]host[:port]/]uri[;params][?terms][#fragment]
capu::int32_t result = s->leftFind(':');
status_t error_result;
if (result == -1)
return ETCH_ERROR;
//parsing of scheme
EtchString x[2];
//x[0] contains scheme
error_result = s->substring(0, result, &x[0]);
if (error_result != ETCH_OK)
return error_result;
//x[1] will contain rest of url [//[user[:password]@]host[:port]/]uri[;params][?terms][#fragment]
error_result = s->substring(result + 1, s->length()-(result + 1), &x[1]);
if (error_result != ETCH_OK)
return error_result;
setScheme(x[0]);
EtchString _s(x[1]);
// _s is [//[user[:password]@]host[:port]/]uri[;params][?terms][#fragment]
result = _s.leftFind('#');
if (result != -1) {
//parse the fragments
//x[0] will contain the rest of url [//[user[:password]@]host[:port]/]uri[;params][?terms]
error_result = _s.substring(0, result, &x[0]);
if (error_result != ETCH_OK)
return error_result;
//x[1] will contain the fragments
error_result = _s.substring(result + 1, _s.length()-(result + 1), &x[1]);
if (error_result != ETCH_OK)
return error_result;
//set the fragments
setFragment(x[1]);
_s = x[0];
}
// s is [//[user[:password]@]host[:port]/]uri[;params][?terms]
result = _s.leftFind('?');
if (result != -1) {
//parse terms
//x[0] will contain rest of url [//[user[:password]@]host[:port]/]uri[;params]
error_result = _s.substring(0, result, &x[0]);
if (error_result != ETCH_OK)
return error_result;
//x[1] will contain the terms
error_result = _s.substring(result + 1, _s.length()-(result + 1), &x[1]);
if (error_result != ETCH_OK)
return error_result;
//parse and sets the terms
error_result = parseTerms(&x[1]);
if (error_result != ETCH_OK)
return error_result;
_s = x[0];
}
// s is [//[user[:password]@]host[:port]/]uri[;params]
result = _s.leftFind(';');
if (result != -1) {
//parse terms
//x[0] will contain rest of url [//[user[:password]@]host[:port]/]uri
error_result = _s.substring(0, result, &x[0]);
if (error_result != ETCH_OK)
return error_result;
error_result = _s.substring(result + 1, _s.length()-(result + 1), &x[1]);
if (error_result != ETCH_OK)
return error_result;
//x[1] will contain the params
error_result = parseParams(&x[1]);
if (error_result != ETCH_OK)
return error_result;
_s = x[0];
}
// s is [//[user[:password]@]host[:port]/]uri
char *str = new char [_s.length() + 1];
etch_strcpy_s(str, _s.length() + 1, _s.c_str());
if ((str[0] == '/') && (str[1] == '/')) {
//eleminate "//"
_s.set(&str[2]);
// s is [user[:password]@]host[:port]/uri
//parse uri
result = _s.leftFind('/');
if (result != -1) {
//x[0] contains rest of uri [user[:password]@]host[:port]
error_result = _s.substring(0, result, &x[0]);
if (error_result != ETCH_OK)
return error_result;
//x[1] will contain the uri
error_result = _s.substring(result + 1, _s.length()-(result + 1), &x[1]);
if (error_result != ETCH_OK)
return error_result;
// parse [user[:password]@]host[:port]
error_result = parseHost(&x[0]);
if (error_result != ETCH_OK)
return error_result;
//now s contains the uri
_s = x[1];
} else {
// s is [user[:password]@]host[:port]
error_result = parseHost(&_s);
if (error_result != ETCH_OK)
return error_result;
//uri is not given
_s.set("");
}
}
setUri(_s);
delete [] str;
return ETCH_OK;
}
status_t EtchURL::parseHost(const EtchString* s) {
if (s == NULL) {
return ETCH_EINVAL;
}
// s is [user[:password]@]host[:port]
capu::int32_t result = s->leftFind('@');
EtchString x[2];
if (result != -1) {
if (s->substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (s->substring(result + 1, s->length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
parseUserPassword(&x[0]);
parseHostPort(&x[1]);
} else {
parseHostPort(s);
}
return ETCH_OK;
}
status_t EtchURL::parseUserPassword(const EtchString* s) {
if (s == NULL) {
return ETCH_EINVAL;
}
// s is user[:password]
capu::int32_t result = s->leftFind(':');
EtchString x[2];
if (result != -1) {
if (s->substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (s->substring(result + 1, s->length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
setUser(x[0]);
setPassword(x[1]);
} else {
setUser(*s);
}
return ETCH_OK;
}
status_t EtchURL::parseHostPort(const EtchString* s) {
if (s == NULL) {
return ETCH_EINVAL;
}
capu::int32_t result = s->leftFind(':');
EtchString x[2];
if (x != NULL) {
if (s->substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (s->substring(result + 1, s->length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
setHost(x[0]);
EtchString *p = &x[1];
capu::int32_t _port = atoi(p->c_str());
setPort(_port);
} else {
setHost(*s);
}
return ETCH_OK;
}
status_t EtchURL::parseParams(const EtchString* s) {
// s is param[;param]*
if (s == NULL) {
return ETCH_EINVAL;
}
if (s->length() == 0)
return ETCH_OK; //THERE IS NOTHING TO PARSE
EtchString _s = *s;
EtchString x[2];
capu::int32_t result = _s.leftFind(';');
while (result != -1) {
if (_s.substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (_s.substring(result + 1, _s.length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
addParam(x[0]);
_s.set(x[1].c_str());
result = _s.leftFind(';');
}
addParam(_s);
return ETCH_OK;
}
status_t EtchURL::parseTerms(const EtchString* s) {
if (s == NULL) {
return ETCH_EINVAL;
}
if (s->length() == 0)
return ETCH_OK; //THERE IS NOTHING TO PARSE
EtchString _s = *s;
EtchString x[2];
capu::int32_t result = _s.leftFind('&');
while (result != -1) {
if (_s.substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (_s.substring(result + 1, _s.length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
parseTerm(&x[0]);
_s.set(x[1].c_str());
result = _s.leftFind('&');
}
return parseTerm(&_s);
}
status_t EtchURL::parseTerm(const EtchString * s) {
if (s == NULL) {
return ETCH_EINVAL;
}
// s is name[=value]
if (s->length() == 0)
return ETCH_OK; //THERE IS NOTHING TO PARSE
capu::int32_t result = s->leftFind('=');
EtchString x[2];
if (s->substring(0, result, &x[0]) != ETCH_OK)
return ETCH_ERROR;
if (s->substring(result + 1, s->length()-(result + 1), &x[1]) != ETCH_OK)
return ETCH_ERROR;
if (result != -1)
addTerm(x[0], x[1]);
return ETCH_OK;
}
EtchString& EtchURL::getScheme() {
return scheme;
}
void EtchURL::setScheme(const EtchString& scheme) {
this->scheme.set(scheme.c_str());
}
status_t EtchURL::setScheme(EtchString* scheme) {
if (scheme != NULL) {
this->scheme.set(scheme->c_str());
return ETCH_OK;
}
return ETCH_EINVAL;
}
EtchString& EtchURL::getUser() {
return user;
}
void EtchURL::setUser(const EtchString& user) {
this->user.set(user.c_str());
}
EtchString& EtchURL::getPassword() {
return password;
}
void EtchURL::setPassword(const EtchString& password) {
this->password.set(password.c_str());
}
EtchString& EtchURL::getHost() {
return host;
}
void EtchURL::setHost(const EtchString& host) {
this->host.set(host.c_str());
}
capu::uint16_t EtchURL::getPort() {
return port;
}
void EtchURL::setPort(const capu::uint16_t port) {
this->port = port;
}
EtchString& EtchURL::getUri() {
return uri;
}
void EtchURL::setUri(const EtchString& uri) {
this->uri.set(uri.c_str());
}
capu::bool_t EtchURL::hasParams() {
return !(params.isEmpty());
}
void EtchURL::addParam(EtchString& param) {
this->params.add(param);
}
void EtchURL::clearParams() {
params.clear();
}
status_t EtchURL::addTerm(EtchString& name, EtchString& value) {
return terms.put(name, value);
}
status_t EtchURL::addTerm(EtchString& name, capu::int32_t value) {
char result [10];
EtchString str;
capu::StringUtils::Sprintf(result, 10, "%d", value);
str.set(result);
return addTerm(name, str);
}
status_t EtchURL::addTerm(EtchString& name, capu::bool_t value) {
char result [2];
EtchString str;
capu::StringUtils::Sprintf(result, 2, "%d", value);
str.set(result);
return addTerm(name, str);
}
status_t EtchURL::addTerm(EtchString& name, capu::double_t value) {
char result [10];
EtchString str;
capu::StringUtils::Sprintf(result, 10, "%f", value);
str.set(result);
return addTerm(name, str);
}
void EtchURL::clearTerms() {
terms.clear();
}
EtchString& EtchURL::getFragment() {
return fragment;
}
void EtchURL::setFragment(EtchString& fragment) {
this->fragment.set(fragment.c_str());
}
EtchList<EtchString>& EtchURL::getParams() {
return params;
}
EtchHashTable<EtchString, EtchString>& EtchURL::getTerms() {
return terms;
}