URL.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include "URL.h"
00040 #include "StringBuffer.h"
00041 #include "debug/DebugUtils.h"
00042 
00043 namespace oasys {
00044 
00045 urlerr_t
00046 URL::parse_internal()
00047 {
00048     size_t beg, end;
00049 
00050     // reset all fields
00051     proto_.erase();
00052     host_.erase();
00053     port_ = 0;
00054     path_.erase();
00055 
00056     // extract protocol
00057     if ((end = url_.find(':')) == std::string::npos)
00058         return URLPARSE_BADSEP;
00059     
00060     // skip the separator
00061     if (url_[end+1] != '/' || url_[end+2] != '/')
00062         return URLPARSE_BADPROTO;
00063 
00064     // valid protocol -- assign it and skip
00065     proto_.assign(url_, 0, end);
00066     beg = end + 3;
00067 
00068     // check for no host
00069     if (beg == url_.length())
00070         return URLPARSE_NOHOST;
00071 
00072     // search for the hostname/path separator
00073     end = url_.find_first_of(":/", beg, 2);
00074 
00075     if (end == std::string::npos) {
00076         // there's no port or pathname, it's just a host name, but
00077         // append a / for the canonical form
00078         host_.assign(url_, beg, url_.length());
00079         url_.push_back('/');
00080         return URLPARSE_OK;
00081     }
00082 
00083     // grab the hostname
00084     host_.assign(url_, beg, end - beg);
00085 
00086     // parse the port if it exists
00087     if (url_[end] == ':') {
00088         char* endstr;
00089         beg = end + 1;
00090         end = url_.find('/', beg);
00091         if (end == std::string::npos) {
00092             end = url_.length();
00093 
00094             // again, adjust for no trailing slash
00095             url_.push_back('/');
00096         }
00097         
00098         std::string portstr(url_, beg, end - beg);
00099         u_int32_t portval = strtoul(portstr.c_str(), &endstr, 10);
00100         
00101         if (portval > 65535)
00102             return URLPARSE_BADPORT;
00103 
00104         if (endstr != (portstr.c_str() + portstr.length()))
00105             return URLPARSE_BADPORT;
00106 
00107         port_ = portval;
00108 
00109         beg = end + 1;
00110     } else {
00111         // otherwise just skip past the slash separator
00112         ASSERT(url_[end] == '/');
00113         beg = end + 1;
00114     }
00115 
00116     // check for an empty path
00117     if (beg >= url_.length())
00118         return URLPARSE_OK;
00119 
00120     // otherwise store the path and we're done
00121     path_.assign(url_, beg, url_.length() - beg);
00122     return URLPARSE_OK;
00123 }
00124 
00125 urlerr_t
00126 URL::parse()
00127 {
00128     err_ = parse_internal();
00129     return err_;
00130 }
00131 
00132 void
00133 URL::format(const std::string& proto, const std::string& host, u_int16_t port,
00134             const std::string& path)
00135 {
00136     StringBuffer buf;
00137     
00138     proto_ = proto;
00139     host_ = host;
00140     port_ = port;
00141     path_ = path;
00142 
00143     buf.append(proto);
00144     buf.append("://");
00145     buf.append(host);
00146 
00147     if (port != 0) {
00148         buf.appendf(":%d", port);
00149     }
00150 
00151     if (path[0] != '/')
00152         buf.append('/');
00153 
00154     buf.append(path);
00155     
00156     url_.assign(buf.data(), buf.length());
00157     err_ = URLPARSE_OK;
00158 }
00159 
00160 } // namespace oasys

Generated on Fri Dec 22 14:48:01 2006 for DTN Reference Implementation by  doxygen 1.5.1