LCOV - code coverage report
Current view: top level - servus - uri.h (source / functions) Hit Total Coverage
Test: Servus Lines: 19 19 100.0 %
Date: 2018-10-03 03:09:57 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2013-2014, ahmet.bilgili@epfl.ch
       2             :  *                    2014, Stefan.Eilemann@epfl.ch
       3             :  *
       4             :  * This file is part of Servus <https://github.com/HBPVIS/Servus>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 3.0 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #ifndef SERVUS_URI_H
      21             : #define SERVUS_URI_H
      22             : 
      23             : #include <servus/api.h>
      24             : #include <servus/types.h>
      25             : 
      26             : #include <map>
      27             : #include <sstream>
      28             : 
      29             : namespace servus
      30             : {
      31             : namespace detail
      32             : {
      33             : class URI;
      34             : }
      35             : 
      36             : /**
      37             :  * The URI class parses the given uri using the generic syntax from RFC3986 and
      38             :  * RFC6570
      39             :  * @verbatim
      40             :  * http://bob@www.example.com:8080/path/?key=value&foo=bar#fragment
      41             :  * ^   ^  ^  ^               ^    ^     ^                 ^
      42             :  * a   b  c  d               e    f     g                 h
      43             :  *
      44             :  * URI part     Range   String
      45             :  * scheme       [a, b)  "http"
      46             :  * userinfo [c, d) bob
      47             :  * host [d, e)  "www.example.com"
      48             :  * port (e, f) 8080
      49             :  * path [f, g)  "/path/"
      50             :  * query (g, h) "key=value&foo=bar"
      51             :  * fragment     (h,-) "fragment"
      52             :  * @endverbatim
      53             :  *
      54             :  * Queries are parsed into key-value pairs and can be accessed using
      55             :  * findQuery(), queryBegin() and queryEnd().
      56             :  *
      57             :  * We enforce schemas to have the separator "://", not only ":" which is enough
      58             :  * for the RFC specification.
      59             :  *
      60             :  * Example: @include tests/uri.cpp
      61             :  */
      62             : class URI
      63             : {
      64             : public:
      65             :     typedef std::map<std::string, std::string> KVMap;
      66             :     typedef KVMap::const_iterator ConstKVIter;
      67             : 
      68             :     /** Construct an empty URI. */
      69             :     SERVUS_API URI();
      70             : 
      71             :     /**
      72             :      * @param uri URI string to parse.
      73             :      * @throw std::exception for incomplete URIs, and std::invalid_argument
      74             :      *        if the port is not a number.
      75             :      */
      76             :     SERVUS_API explicit URI(const std::string& uri);
      77             : 
      78             :     /** @overload URI::URI( const std::string& ) */
      79             :     SERVUS_API explicit URI(const char* uri);
      80             : 
      81             :     /** Copy-construct an URI. */
      82             :     SERVUS_API URI(const URI& from);
      83             : 
      84             :     SERVUS_API ~URI();
      85             : 
      86             :     /** Assign the data from another URI. */
      87             :     SERVUS_API URI& operator=(const URI& rhs);
      88             : 
      89             :     /** Equals operator */
      90             :     SERVUS_API bool operator==(const URI& rhs) const;
      91             : 
      92             :     /** Not equals operator */
      93             :     SERVUS_API bool operator!=(const URI& rhs) const;
      94             : 
      95             :     /** @name Getters for uri data */
      96             :     //@{
      97             :     SERVUS_API const std::string& getScheme() const;
      98             :     SERVUS_API const std::string& getUserinfo() const;
      99             :     SERVUS_API uint16_t getPort() const;
     100             :     SERVUS_API const std::string& getHost() const;
     101             :     /** Return the compound authority part of the URI.
     102             : 
     103             :         User info added only if not empty, port number added only if it's
     104             :         different from 0. */
     105             :     SERVUS_API std::string getAuthority() const;
     106             :     SERVUS_API const std::string& getPath() const;
     107             :     SERVUS_API const std::string& getQuery() const;
     108             :     SERVUS_API const std::string& getFragment() const;
     109             :     //@}
     110             : 
     111             :     /** @name Setters for uri data. */
     112             :     //@{
     113             :     SERVUS_API void setScheme(const std::string& scheme);
     114             :     SERVUS_API void setUserInfo(const std::string& userinfo);
     115             :     SERVUS_API void setHost(const std::string& host);
     116             :     SERVUS_API void setPort(uint16_t port);
     117             :     SERVUS_API void setPath(const std::string& path);
     118             :     SERVUS_API void setQuery(const std::string& query);
     119             :     SERVUS_API void setFragment(const std::string& fragment);
     120             :     //@}
     121             : 
     122             :     /** @name Access to key-value data in query. */
     123             :     //@{
     124             :     /**
     125             :      * @return a const iterator to the beginning of the query map.
     126             :      */
     127             :     SERVUS_API ConstKVIter queryBegin() const;
     128             : 
     129             :     /**
     130             :      * @return a const iterator to end beginning of the query map.
     131             :      */
     132             :     SERVUS_API ConstKVIter queryEnd() const;
     133             : 
     134             :     /**
     135             :      * @return a const iterator to the given key, or queryEnd().
     136             :      */
     137             :     SERVUS_API ConstKVIter findQuery(const std::string& key) const;
     138             : 
     139             :     /** Add a key-value pair to the query. */
     140             :     SERVUS_API void addQuery(const std::string& key, const std::string& value);
     141             :     //@}
     142             : 
     143             : private:
     144             :     detail::URI* const _impl;
     145             : };
     146             : 
     147          13 : inline std::ostream& operator<<(std::ostream& os, const URI& uri)
     148             : {
     149          13 :     if (!uri.getScheme().empty())
     150           7 :         os << uri.getScheme() << "://";
     151             :     // A valid URI can't contain the user info or port number alone, so if
     152             :     // the host name is empty the other two field are simply ignored.
     153          13 :     if (!uri.getHost().empty())
     154             :     {
     155           7 :         if (!uri.getUserinfo().empty())
     156           6 :             os << uri.getUserinfo() << "@";
     157           7 :         os << uri.getHost();
     158           7 :         if (uri.getPort())
     159           6 :             os << ':' << uri.getPort();
     160             :     }
     161          13 :     os << uri.getPath();
     162          13 :     if (!uri.getQuery().empty())
     163           3 :         os << '?' << uri.getQuery();
     164          13 :     if (!uri.getFragment().empty())
     165           3 :         os << '#' << uri.getFragment();
     166          13 :     return os;
     167             : }
     168             : }
     169             : 
     170             : namespace std
     171             : {
     172          10 : inline std::string to_string(const servus::URI& uri)
     173             : {
     174          20 :     ostringstream os;
     175          10 :     os << uri;
     176          20 :     return os.str();
     177             : }
     178             : }
     179             : #endif // SERVUS_URI_H

Generated by: LCOV version 1.11