LCOV - code coverage report
Current view: top level - snapwebsites - snap_uri.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 133 0.0 %
Date: 2019-12-15 17:13:15 Functions: 0 73 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Snap Websites Server -- path canonicalization
       2             : // Copyright (c) 2011-2019  Made to Order Software Corp.  All Rights Reserved
       3             : //
       4             : // https://snapwebsites.org/
       5             : // contact@m2osw.com
       6             : //
       7             : // This program is free software; you can redistribute it and/or modify
       8             : // it under the terms of the GNU General Public License as published by
       9             : // the Free Software Foundation; either version 2 of the License, or
      10             : // (at your option) any later version.
      11             : //
      12             : // This program is distributed in the hope that it will be useful,
      13             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             : // GNU General Public License for more details.
      16             : //
      17             : // You should have received a copy of the GNU General Public License
      18             : // along with this program; if not, write to the Free Software
      19             : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      20             : #pragma once
      21             : 
      22             : #include "snapwebsites/snap_parser.h"
      23             : #include "snapwebsites/snap_string_list.h"
      24             : 
      25             : #include <QtSerialization/QSerializationReader.h>
      26             : #include <QtSerialization/QSerializationFieldTag.h>
      27             : #include <QtSerialization/QSerializationWriter.h>
      28             : 
      29             : #include <QMap>
      30             : 
      31             : namespace snap
      32             : {
      33             : 
      34           0 : class snap_uri_exception : public snap_exception
      35             : {
      36             : public:
      37           0 :     explicit snap_uri_exception(char const *        what_msg) : snap_exception("snap_uri", what_msg) {}
      38             :     explicit snap_uri_exception(std::string const & what_msg) : snap_exception("snap_uri", what_msg) {}
      39           0 :     explicit snap_uri_exception(QString const &     what_msg) : snap_exception("snap_uri", what_msg) {}
      40             : };
      41             : 
      42           0 : class snap_uri_exception_invalid_uri : public snap_uri_exception
      43             : {
      44             : public:
      45             :     explicit snap_uri_exception_invalid_uri(char const *        what_msg) : snap_uri_exception(what_msg) {}
      46             :     explicit snap_uri_exception_invalid_uri(std::string const & what_msg) : snap_uri_exception(what_msg) {}
      47           0 :     explicit snap_uri_exception_invalid_uri(QString const &     what_msg) : snap_uri_exception(what_msg) {}
      48             : };
      49             : 
      50           0 : class snap_uri_exception_invalid_parameter : public snap_uri_exception
      51             : {
      52             : public:
      53           0 :     explicit snap_uri_exception_invalid_parameter(char const *        what_msg) : snap_uri_exception(what_msg) {}
      54             :     explicit snap_uri_exception_invalid_parameter(std::string const & what_msg) : snap_uri_exception(what_msg) {}
      55           0 :     explicit snap_uri_exception_invalid_parameter(QString const &     what_msg) : snap_uri_exception(what_msg) {}
      56             : };
      57             : 
      58           0 : class snap_uri_exception_invalid_path : public snap_uri_exception
      59             : {
      60             : public:
      61             :     explicit snap_uri_exception_invalid_path(char const *        what_msg) : snap_uri_exception(what_msg) {}
      62             :     explicit snap_uri_exception_invalid_path(std::string const & what_msg) : snap_uri_exception(what_msg) {}
      63           0 :     explicit snap_uri_exception_invalid_path(QString const &     what_msg) : snap_uri_exception(what_msg) {}
      64             : };
      65             : 
      66           0 : class snap_uri_exception_out_of_bounds : public snap_uri_exception
      67             : {
      68             : public:
      69             :     explicit snap_uri_exception_out_of_bounds(char const *        what_msg) : snap_uri_exception(what_msg) {}
      70             :     explicit snap_uri_exception_out_of_bounds(std::string const & what_msg) : snap_uri_exception(what_msg) {}
      71           0 :     explicit snap_uri_exception_out_of_bounds(QString const &     what_msg) : snap_uri_exception(what_msg) {}
      72             : };
      73             : 
      74           0 : class snap_uri_exception_exclusive_parameters : public snap_uri_exception
      75             : {
      76             : public:
      77           0 :     explicit snap_uri_exception_exclusive_parameters(char const *        what_msg) : snap_uri_exception(what_msg) {}
      78             :     explicit snap_uri_exception_exclusive_parameters(std::string const & what_msg) : snap_uri_exception(what_msg) {}
      79             :     explicit snap_uri_exception_exclusive_parameters(QString const &     what_msg) : snap_uri_exception(what_msg) {}
      80             : };
      81             : 
      82             : 
      83             : 
      84             : 
      85             : 
      86             : 
      87             : 
      88             : // Helper class to handle URIs
      89             : // http://tools.ietf.org/html/rfc3986
      90           0 : class snap_uri
      91             : {
      92             : public:
      93             :     // types used by this class
      94             :     typedef QMap<QString, QString>    snap_uri_options_t;
      95             : 
      96             :     // constructors
      97             :                         snap_uri();
      98             :                         snap_uri(QString const & uri);
      99             : 
     100             :     // URI handling
     101             :     bool                set_uri(QString const & uri);
     102             :     QString const &     get_original_uri() const;
     103             :     QString             get_uri(bool use_hash_bang = false) const;
     104             :     QString             get_website_uri(bool include_port = false) const;
     105             : 
     106             :     // get a part by name
     107             :     QString             get_part(QString const & name, int part = -1) const;
     108             : 
     109             :     // protocol handling
     110             :     void                set_protocol(QString const & uri_protocol);
     111             :     QString const &     protocol() const;
     112             : 
     113             :     // domain & sub-domains handling
     114             :     void                set_domain(QString const & full_domain_name);
     115             :     QString             full_domain() const;
     116             :     QString const &     top_level_domain() const;
     117             :     QString const &     domain() const;
     118             :     QString             sub_domains() const;
     119             :     int                 sub_domain_count() const;
     120             :     QString             sub_domain(int part) const;
     121             :     snap_string_list const & sub_domains_list() const;
     122             : 
     123             :     // port handling
     124             :     void                set_port(QString const & port);
     125             :     void                set_port(int port);
     126             :     int                 get_port() const;
     127             : 
     128             :     // path handling
     129             :     void                set_path(QString uri_path);
     130             :     QString             path(bool encoded = true) const;
     131             :     int                 path_count() const;
     132             :     QString             path_folder_name(int part) const;
     133             :     snap_string_list const & path_list() const;
     134             : 
     135             :     // option handling
     136             :     void                set_option(QString const & name, QString const & value);
     137             :     void                unset_option(QString const & name);
     138             :     QString             option(QString const & name) const;
     139             :     int                 option_count() const;
     140             :     QString             option(int part, QString & name) const;
     141             :     snap_uri_options_t const & options_list() const;
     142             : 
     143             :     // query string handling
     144             :     void                set_query_option(QString const & name, QString const & value);
     145             :     void                unset_query_option(QString const & name);
     146             :     void                set_query_string(QString const & uri_query_string);
     147             :     QString             query_string() const;
     148             :     bool                has_query_option(QString const & name) const;
     149             :     void                clear_query_options();
     150             :     QString             query_option(QString const & name) const;
     151             :     int                 query_option_count() const;
     152             :     QString             query_option(int part, QString & name) const;
     153             :     snap_uri_options_t const & query_string_list() const;
     154             : 
     155             :     // anchor handling (note: "#!" is not considered an anchor)
     156             :     void                set_anchor(QString const & uri_anchor);
     157             :     QString const &     anchor() const;
     158             : 
     159             :     // operators
     160             :     bool                operator == (snap_uri const & rhs) const;
     161             :     bool                operator != (snap_uri const & rhs) const;
     162             :     bool                operator <  (snap_uri const & rhs) const;
     163             :     bool                operator <= (snap_uri const & rhs) const;
     164             :     bool                operator >  (snap_uri const & rhs) const;
     165             :     bool                operator >= (snap_uri const & rhs) const;
     166             : 
     167             :     static QString      urlencode(QString const & uri, char const * accepted = "");
     168             :     static QString      urldecode(QString const & uri, bool relax = false);
     169             :     static int          protocol_to_port(QString const & uri_protocol);
     170             : 
     171             : private:
     172             :     bool                process_domain(QString const & full_domain_name, snap_string_list & sub_domain_names, QString & domain_name, QString & tld);
     173             : 
     174             :     // f_original is the unchanged source (from constructor or
     175             :     // last set_uri() call)
     176             :     QString                         f_original = QString();
     177             :     QString                         f_protocol = QString("http");
     178             :     QString                         f_username = QString();
     179             :     QString                         f_password = QString();
     180             :     int                             f_port = 80;
     181             :     QString                         f_domain = QString();
     182             :     QString                         f_top_level_domain = QString();
     183             :     snap_string_list                f_sub_domains = snap_string_list();
     184             :     snap_string_list                f_path = snap_string_list();
     185             :     snap_uri_options_t              f_options = snap_uri_options_t();
     186             :     snap_uri_options_t              f_query_strings = snap_uri_options_t();
     187             :     QString                         f_anchor = QString();
     188             : };
     189             : 
     190             : 
     191             : 
     192             : 
     193             : // The following is used to compile rules as defined for the domains
     194             : // and websites; the result is a set of regular expressions we can
     195             : // use to parse the URI when we receive a hit
     196             : //
     197             : // See https://snapwebsites.org/implementation/basic-concept-url-website/url-test
     198             : class snap_uri_rules
     199             : {
     200             : public:
     201             :     // handling of rule scripts
     202             :     bool            parse_domain_rules(QString const & script, QByteArray & result);
     203             :     bool            parse_website_rules(QString const & script, QByteArray & result);
     204             : 
     205             :     // processing of URIs
     206             :     //QString         process_uri(snap_uri & uri);
     207             : 
     208             :     QString const & errmsg() const { return f_errmsg; }
     209             : 
     210             : private:
     211             :     QString        f_errmsg = QString();
     212             : };
     213             : 
     214             : 
     215             : /** \brief Domain variables
     216             :  *
     217             :  * This class is used to hold the domain variable information.
     218             :  * Each variable has a type that defines how the variable is used
     219             :  * (standard, website, or flag, and when defined as a flag whether
     220             :  * a default was defined.)
     221             :  */
     222           0 : class domain_variable : public parser::parser_user_data
     223             : {
     224             : public:
     225             :     /** \brief Define the type of this variable.
     226             :      *
     227             :      * This enumaration is used to define the exact type of the variable.
     228             :      * This is used to know how to use the variable later. That information
     229             :      * is actually saved in the resulting compiled data.
     230             :      *
     231             :      * \warning
     232             :      * The variable type is saved as is in the database (i.e. as a number)
     233             :      * which means that the order defined below CANNOT CHANGE. If we need
     234             :      * more types, add them afterward. If a type becomes obsolete, do not
     235             :      * delete it nor reuse its position.
     236             :      */
     237             :     typedef int domain_variable_type_t;
     238             :         // WARNING: saved as a number in the database
     239             : 
     240             :     /** \brief Standard variable type.
     241             :      *
     242             :      * The standard variable type is used as is to define a sub-domain
     243             :      * name. It is given a name and a regular expression. It may be
     244             :      * optional, but it does not otherwise required anything specific.
     245             :      *
     246             :      * The result is whatever the regular expression matches.
     247             :      */
     248             :     static domain_variable_type_t const DOMAIN_VARIABLE_TYPE_STANDARD = 0;
     249             :         // WARNING: saved as a number in the database DO NOT CHANGE
     250             : 
     251             :     /** \brief Website variable type.
     252             :      *
     253             :      * This type defines a value which is a regular expression, exactly
     254             :      * the same as the standard variable. However, the result is always
     255             :      * set to the default value (canonicalization.)
     256             :      */
     257             :     static domain_variable_type_t const DOMAIN_VARIABLE_TYPE_WEBSITE = 1;
     258             :         // WARNING: saved as a number in the database DO NOT CHANGE
     259             : 
     260             :     /** \brief Flag variable with a default value.
     261             :      *
     262             :      * This value is used whenever a sub-domain entry is an option which
     263             :      * means it does not participate to the website canonicalization. Any
     264             :      * matches are removed from the result.
     265             :      *
     266             :      * This flag defines a default. If there is no match, then use the
     267             :      * default instead.
     268             :      */
     269             :     static domain_variable_type_t const DOMAIN_VARIABLE_TYPE_FLAG_WITH_DEFAULT = 2;
     270             :         // WARNING: saved as a number in the database DO NOT CHANGE
     271             : 
     272             :     /** \brief Flag variable without a default value.
     273             :      *
     274             :      * This flag is similar to the DOMAIN_VARIABLE_TYPE_FLAG_WITH_DEFAULT
     275             :      * except that no default was defined. This means the flag is either
     276             :      * required, or completely ignored (when marked as optional.)
     277             :      *
     278             :      * In this case, the default value may be defined somewhere else. For
     279             :      * example, the language information is expected to be sent by the
     280             :      * client browser and can be accessed from there instead.
     281             :      */
     282             :     static domain_variable_type_t const DOMAIN_VARIABLE_TYPE_FLAG_NO_DEFAULT = 3;
     283             :         // WARNING: saved as a number in the database DO NOT CHANGE
     284             : 
     285             :     /** \brief Initialize a domain variable.
     286             :      *
     287             :      * This function initializes the domain variable with its type, name
     288             :      * and value. It is not possible to change the type or name of the
     289             :      * variable at a later time. The value can be changed with the
     290             :      * set_value() function.
     291             :      *
     292             :      * The default value is marked as undefined. It can be modified with
     293             :      * the set_default() function.
     294             :      *
     295             :      * Values and default values are always strings. Values are expected
     296             :      * to be regular expressions.
     297             :      *
     298             :      * The required flag is set to false (optional.) The set_required()
     299             :      * function can be used later to change that flag.
     300             :      *
     301             :      * \param[in] type  The type of the new domain variable.
     302             :      * \param[in] name  The name of the variable. The name can be qualified.
     303             :      * \param[in] value  The value of the variable.
     304             :      *
     305             :      * \sa set_value()
     306             :      * \sa set_default()
     307             :      * \sa set_required()
     308             :      */
     309           0 :     domain_variable(domain_variable_type_t type, QString const & name, QString const & value)
     310           0 :         : f_type(type)
     311             :         , f_name(name)
     312           0 :         , f_value(value)
     313             :         //, f_default("") -- auto-init
     314             :         //, f_required(false) -- auto-init
     315             :     {
     316           0 :         switch(type)
     317             :         {
     318           0 :         case DOMAIN_VARIABLE_TYPE_STANDARD:
     319             :         case DOMAIN_VARIABLE_TYPE_WEBSITE:
     320             :         case DOMAIN_VARIABLE_TYPE_FLAG_WITH_DEFAULT:
     321             :         case DOMAIN_VARIABLE_TYPE_FLAG_NO_DEFAULT:
     322           0 :             break;
     323             : 
     324           0 :         default:
     325           0 :             throw std::runtime_error("unknown type specified in domain_variable constructor");
     326             : 
     327             :         }
     328           0 :     }
     329             : 
     330             :     /** \brief Retrieve the variable type.
     331             :      *
     332             :      * This function returns the type of the variable.
     333             :      *
     334             :      * \return The type of this variable.
     335             :      */
     336           0 :     domain_variable_type_t get_type() const
     337             :     {
     338           0 :         return f_type;
     339             :     }
     340             : 
     341             :     /** \brief Retrieve the variable name.
     342             :      *
     343             :      * This function returns the variable name. The name is read-only.
     344             :      *
     345             :      * The only way to set the name of a variable is to define it in
     346             :      * the constructor. It cannot be changed later. This function
     347             :      * returns the fully qualified name of the variable.
     348             :      *
     349             :      * \return The variable name in a QString.
     350             :      */
     351           0 :     QString const & get_name() const
     352             :     {
     353           0 :         return f_name;
     354             :     }
     355             : 
     356             :     /** \brief Get the value of the variable.
     357             :      *
     358             :      * The value of the domain variables is expected to be a valid
     359             :      * regular expression. The return value is read-only. To change
     360             :      * the value, use the set_value() function instead.
     361             :      *
     362             :      * \return The value of the variable in a QString.
     363             :      *
     364             :      * \sa set_value()
     365             :      */
     366           0 :     QString const & get_value() const
     367             :     {
     368           0 :         return f_value;
     369             :     }
     370             : 
     371             :     /** \brief Change the value of the variable.
     372             :      *
     373             :      * This function can be used to change the value of this variable.
     374             :      *
     375             :      * \param[in] value  The new value to set this variable to.
     376             :      */
     377             :     void set_value(QString const & value)
     378             :     {
     379             :         f_value = value;
     380             :     }
     381             : 
     382             :     /** \brief Get the default value of the variable.
     383             :      *
     384             :      * This function can be used to read the default value of the
     385             :      * variable. Note that if the variable is not of a type that
     386             :      * supports a default, the return value is always an empty
     387             :      * string.
     388             :      *
     389             :      * The value returned by this function is read-only. To modify
     390             :      * the default value, use the set_default() function instead.
     391             :      *
     392             :      * \return The default value of this variable.
     393             :      */
     394           0 :     QString const & get_default() const
     395             :     {
     396           0 :         return f_default;
     397             :     }
     398             : 
     399             :     /** \brief Set the default value of the variable.
     400             :      *
     401             :      * This function is used to set the default value of this variable.
     402             :      * By default the default value is an empty string. At this time
     403             :      * there is no function one can use to know whether the default
     404             :      * value was defined, however, the flag uses a different type
     405             :      * when a default or no defaults are defined.
     406             :      *
     407             :      * When the type is DOMAIN_VARIABLE_TYPE_FLAG_NO_DEFAULT then the
     408             :      * default is expected to never be defined.
     409             :      *
     410             :      * \exception std::runtime_error
     411             :      * The runtime error is raised if the default is set when the type
     412             :      * of the variable doesn't allow it. This is an internal error since
     413             :      * the system should never have to raise this error.
     414             :      *
     415             :      * \param[in] default_value  The new default value.
     416             :      */
     417           0 :     void set_default(QString const & default_value)
     418             :     {
     419           0 :         switch(f_type)
     420             :         {
     421           0 :         case DOMAIN_VARIABLE_TYPE_WEBSITE:
     422             :         case DOMAIN_VARIABLE_TYPE_FLAG_WITH_DEFAULT:
     423           0 :             f_default = default_value;
     424           0 :             break;
     425             : 
     426           0 :         default:
     427           0 :             throw std::runtime_error("cannot define a default value for this type of domain variable");
     428             : 
     429             :         }
     430           0 :     }
     431             : 
     432             :     /** \brief Get whether the required flag is true or false.
     433             :      *
     434             :      * This function is the representation of the REQUIRED (true) or
     435             :      * OPTIONAL (false) keywords used in front of variable names.
     436             :      *
     437             :      * \return true when the sub-domain is required.
     438             :      */
     439           0 :     bool get_required() const
     440             :     {
     441           0 :         return f_required;
     442             :     }
     443             : 
     444             :     /** \brief Set whether this variable was marked as required.
     445             :      *
     446             :      * The sub-domain rule defines whether this entry is required or not.
     447             :      * This function is used to reflect this information in this variable.
     448             :      *
     449             :      * \param[in] required  Set whether the variable was marked as required (true) or not (false).
     450             :      */
     451           0 :     void set_required(bool required = true)
     452             :     {
     453           0 :         f_required = required;
     454           0 :     }
     455             : 
     456             :     void read(QtSerialization::QReader & stream);
     457             :     void write(QtSerialization::QWriter & stream) const;
     458             : 
     459             : private:
     460             :     /** \brief The domain variable type.
     461             :      *
     462             :      * This field defines the type of the domain variable. It cannot be
     463             :      * modified once a variable was created.
     464             :      *
     465             :      * \sa get_type()
     466             :      */
     467             :     domain_variable_type_t f_type = DOMAIN_VARIABLE_TYPE_STANDARD;
     468             : 
     469             :     /** \brief The domain variable name.
     470             :      *
     471             :      * This field represents the fully qualified name of the variable.
     472             :      * The name cannot be changed once the variable was created.
     473             :      *
     474             :      * Names are expected to be unique within one rule.
     475             :      *
     476             :      * \sa get_name()
     477             :      */
     478             :     QString f_name = QString();
     479             : 
     480             :     /** \brief The value of this variable.
     481             :      *
     482             :      * This is the value of the variable. It is expected to be a valid
     483             :      * regular expression. The value is generally set at the time the
     484             :      * variable is created. It can be changed later with the set_value()
     485             :      * function.
     486             :      *
     487             :      * \sa get_value()
     488             :      * \sa set_value()
     489             :      */
     490             :     QString f_value = QString();
     491             : 
     492             :     /** \brief The default value of the variable.
     493             :      *
     494             :      * This field holds the default value of the variable. This is used
     495             :      * for websites and flags with a default value. Other types do not
     496             :      * make use of a default value.
     497             :      *
     498             :      * The default value can be modified with the set_default()
     499             :      * function.
     500             :      *
     501             :      * \sa get_default()
     502             :      * \sa set_default()
     503             :      */
     504             :     QString f_default = QString();
     505             : 
     506             :     /** \brief Wether the value is required.
     507             :      *
     508             :      * This value represents one or more sub-domains. If those sub-domains
     509             :      * are required, then this value will be true.
     510             :      *
     511             :      * This value is set using the REQUIRED or OPTIONAL keywords in the
     512             :      * sub_domain rule.
     513             :      *
     514             :      * \sa get_required()
     515             :      * \sa set_required()
     516             :      */
     517             :     bool f_required = false;
     518             : };
     519             : 
     520             : 
     521             : /** \brief Define the information of a domain.
     522             :  *
     523             :  * This class holds a set of sub-domain variables which together
     524             :  * define a domain. The domain is also given a domain.
     525             :  */
     526           0 : class domain_info : public parser::parser_user_data, public QtSerialization::QSerializationObject
     527             : {
     528             : public:
     529             :     /** \brief Add a domain variable to the domain info.
     530             :      *
     531             :      * This function adds a domain variable as defined by
     532             :      * the sub-domain rules to a domain information object.
     533             :      * The variable is expected to be valid, although at
     534             :      * this point the system doesn't check whether it is
     535             :      * unique or properly qualified. Those checks are done
     536             :      * afterward.
     537             :      *
     538             :      * \param[in] var  The variable to add to this domain.
     539             :      */
     540           0 :     void add_var(QSharedPointer<domain_variable> & var)
     541             :     {
     542           0 :         f_vars.push_back(var);
     543           0 :     }
     544             : 
     545             :     /** \brief Retrieve the name of this domain.
     546             :      *
     547             :      * This function returns a read-only reference to the name of
     548             :      * this domain definition.
     549             :      *
     550             :      * To change the name, use the set_name() function.
     551             :      *
     552             :      * \return A reference to the name of this domain.
     553             :      *
     554             :      * \sa set_name()
     555             :      */
     556           0 :     QString const & get_name() const
     557             :     {
     558           0 :         return f_name;
     559             :     }
     560             : 
     561             :     /** \brief Set the name of the domain.
     562             :      *
     563             :      * This function is used to set the name of the domain.
     564             :      * The name is expected to be unique among all the domain
     565             :      * definitions found in a block (i.e. per domain.)
     566             :      *
     567             :      * \param[in] name  The name of the domain.
     568             :      *
     569             :      * \sa get_name()
     570             :      */
     571           0 :     void set_name(QString const & name)
     572             :     {
     573           0 :         f_name = name;
     574           0 :     }
     575             : 
     576             :     /** \brief Retrieve the number of variables defined.
     577             :      *
     578             :      * This function returns the number of variables that were added
     579             :      * to this domain definition. The number may be zero if no variables
     580             :      * were added.
     581             :      *
     582             :      * \return The number of domain variables available in this object.
     583             :      */
     584           0 :     int size() const
     585             :     {
     586           0 :         return f_vars.size();
     587             :     }
     588             : 
     589             :     /** \brief Retrieve one of the domain variables.
     590             :      *
     591             :      * This function returns a domain variable shared pointer.
     592             :      *
     593             :      * The index is expected to be between 0 (inclusive) and size()
     594             :      * (exclusive.) If size() is zero, this function cannot be
     595             :      * used.
     596             :      *
     597             :      * \param[in] idx  The index of the variable.
     598             :      *
     599             :      * \return A shared pointer to the domain variable information.
     600             :      */
     601           0 :     QSharedPointer<domain_variable> get_variable(int idx) const
     602             :     {
     603           0 :         return f_vars[idx];
     604             :     }
     605             : 
     606             :     /** \brief Retrieve one of the domain variables.
     607             :      *
     608             :      * This operator returns a domain variable shared pointer.
     609             :      *
     610             :      * The index is expected to be between 0 (inclusive) and size()
     611             :      * (exclusive.) If size() is zero, this operator cannot be
     612             :      * used.
     613             :      *
     614             :      * \param[in] idx  The index of the variable.
     615             :      *
     616             :      * \return A shared pointer to the domain variable information.
     617             :      */
     618           0 :     QSharedPointer<domain_variable> operator [] (int idx) const
     619             :     {
     620           0 :         return f_vars[idx];
     621             :     }
     622             : 
     623             :     void read(QtSerialization::QReader & r);
     624             :     virtual void readTag(QString const & name, QtSerialization::QReader & r);
     625             :     void write(QtSerialization::QWriter & w) const;
     626             : 
     627             : private:
     628             :     /** \brief The name of this domain definition.
     629             :      *
     630             :      * This field holds the name of the domain definition. The
     631             :      * name should be read-only, although it gets defined after
     632             :      * we create instances of domain_info...
     633             :      */
     634             :     QString f_name = QString();
     635             : 
     636             :     /** \brief The list of variables attached to this domain.
     637             :      *
     638             :      * This array lists all the variables accepted by this domain.
     639             :      * Note that the variables are saved in the order in which
     640             :      * they appear in the source string. It is very important since
     641             :      * they need to be used to parse input URLs in the exact order
     642             :      * they are specified here.
     643             :      */
     644             :     QVector<QSharedPointer<domain_variable> > f_vars = QVector<QSharedPointer<domain_variable> >();
     645             : };
     646             : 
     647             : 
     648             : /** \brief Set of rules defined in a domain declaration.
     649             :  *
     650             :  * This class holds an array of domain information.
     651             :  */
     652           0 : class domain_rules : public parser::parser_user_data, public QtSerialization::QSerializationObject
     653             : {
     654             : public:
     655             :     /** \brief Add one domain information object.
     656             :      *
     657             :      * This function adds one domain information object to the
     658             :      * domain rules object. This is what the result is expected
     659             :      * to be.
     660             :      *
     661             :      * Note that the order is kept as is since the checks of the
     662             :      * domains is always done in order as specified by the user.
     663             :      * If a URL matches more than one domain, the first that matches
     664             :      * is used. The following will be ignored. In debug mode, URLs
     665             :      * may checked to all the domain information definitions in order
     666             :      * to determine whether there is a problem (i.e. a match that
     667             :      * should use Domain B instead of Domain A.) This can be done
     668             :      * on a backend system.
     669             :      *
     670             :      * \param[in] info  The domain information to add to this object.
     671             :      */
     672           0 :     void add_info(QSharedPointer<domain_info> & info)
     673             :     {
     674           0 :         f_info.push_back(info);
     675           0 :     }
     676             : 
     677             :     /** \brief Retrieve the number of domain information object.
     678             :      *
     679             :      * This function returns the number of domain_info objects
     680             :      * that were added to this domain rules object.
     681             :      *
     682             :      * This function will return zero until one or more domain info
     683             :      * was added to the domain rules.
     684             :      *
     685             :      * \return The number of domain_info objects defined in this domain rules.
     686             :      *
     687             :      * \sa operator [] ()
     688             :      * \sa add_info()
     689             :      */
     690           0 :     int size() const
     691             :     {
     692           0 :         return f_info.size();
     693             :     }
     694             : 
     695             :     /** \brief This operator can be used to retrieve a domain info.
     696             :      *
     697             :      * This operator returns the specified domain information from this
     698             :      * domain rules.
     699             :      *
     700             :      * The index must be between 0 (inclusive) and size() (exclusive).
     701             :      *
     702             :      * \param[in] idx  The index of the domain info to retrieve.
     703             :      *
     704             :      * \return A pointer to the specified domain_info object.
     705             :      *
     706             :      * \sa size()
     707             :      */
     708           0 :     QSharedPointer<domain_info> operator [] (int idx) const
     709             :     {
     710           0 :         return f_info[idx];
     711             :     }
     712             : 
     713             :     void read(QtSerialization::QReader & stream);
     714             :     virtual void readTag(QString const & name, QtSerialization::QReader & r);
     715             :     void write(QtSerialization::QWriter & stream) const;
     716             : 
     717             : private:
     718             :     /** \brief The array holding all the domain_info objects.
     719             :      *
     720             :      * This vector holds the domain information that are stored
     721             :      * by this domain rules object. The order in which the
     722             :      * domain_info where added to the domain_rules object
     723             :      * is preserved.
     724             :      */
     725             :     QVector<QSharedPointer<domain_info> > f_info = QVector<QSharedPointer<domain_info> >();
     726             : };
     727             : 
     728             : 
     729             : 
     730             : // Websites data
     731           0 : class website_variable : public parser::parser_user_data
     732             : {
     733             : public:
     734             :         // WARNING: saved as a number in the database -- DO NOT CHANGE #'s
     735             :     typedef int website_variable_type_t;
     736             :     static website_variable_type_t const WEBSITE_VARIABLE_TYPE_STANDARD = 0;
     737             :     static website_variable_type_t const WEBSITE_VARIABLE_TYPE_WEBSITE = 1;
     738             :     static website_variable_type_t const WEBSITE_VARIABLE_TYPE_FLAG_WITH_DEFAULT = 2;
     739             :     static website_variable_type_t const WEBSITE_VARIABLE_TYPE_FLAG_NO_DEFAULT = 3;
     740             : 
     741             :         // WARNING: saved as a number in the database -- DO NOT CHANGE #'s
     742             :     typedef int website_variable_part_t;
     743             :     static website_variable_part_t const WEBSITE_VARIABLE_PART_PATH = 0;
     744             :     static website_variable_part_t const WEBSITE_VARIABLE_PART_PORT = 1;
     745             :     static website_variable_part_t const WEBSITE_VARIABLE_PART_PROTOCOL = 2;
     746             :     static website_variable_part_t const WEBSITE_VARIABLE_PART_QUERY = 3;
     747             : 
     748           0 :     website_variable(website_variable_type_t type, QString const & name, QString const & value)
     749           0 :         : f_type(type)
     750             :         , f_part(WEBSITE_VARIABLE_PART_PATH) // this is the obvious default here, we could define an UNDEFINED = -1 too?
     751             :         , f_name(name)
     752           0 :         , f_value(value)
     753             :         //, f_default("") -- auto-init
     754             :         //, f_required(false) -- auto-init
     755             :     {
     756           0 :         switch(type)
     757             :         {
     758           0 :         case WEBSITE_VARIABLE_TYPE_STANDARD:
     759             :         case WEBSITE_VARIABLE_TYPE_WEBSITE:
     760             :         case WEBSITE_VARIABLE_TYPE_FLAG_WITH_DEFAULT:
     761             :         case WEBSITE_VARIABLE_TYPE_FLAG_NO_DEFAULT:
     762           0 :             break;
     763             : 
     764           0 :         default:
     765           0 :             throw std::runtime_error("unknown type specified in website_variable constructor");
     766             : 
     767             :         }
     768           0 :     }
     769             : 
     770           0 :     website_variable_type_t get_type() const
     771             :     {
     772           0 :         return f_type;
     773             :     }
     774             : 
     775           0 :     QString const & get_name() const
     776             :     {
     777           0 :         return f_name;
     778             :     }
     779             : 
     780           0 :     QString const & get_value() const
     781             :     {
     782           0 :         return f_value;
     783             :     }
     784             : 
     785             :     void set_value(QString const & value)
     786             :     {
     787             :         f_value = value;
     788             :     }
     789             : 
     790           0 :     QString const & get_default() const
     791             :     {
     792           0 :         return f_default;
     793             :     }
     794             : 
     795           0 :     void set_default(QString const & default_value)
     796             :     {
     797           0 :         switch(f_type)
     798             :         {
     799           0 :         case WEBSITE_VARIABLE_TYPE_WEBSITE:
     800             :         case WEBSITE_VARIABLE_TYPE_FLAG_WITH_DEFAULT:
     801           0 :             f_default = default_value;
     802           0 :             break;
     803             : 
     804           0 :         default:
     805           0 :             throw std::runtime_error("cannot define a default value for this type of website variable");
     806             : 
     807             :         }
     808           0 :     }
     809             : 
     810           0 :     bool get_required() const
     811             :     {
     812           0 :         return f_required;
     813             :     }
     814             : 
     815           0 :     void set_required(bool required = true)
     816             :     {
     817           0 :         f_required = required;
     818           0 :     }
     819             : 
     820           0 :     website_variable_part_t get_part() const
     821             :     {
     822           0 :         return f_part;
     823             :     }
     824             : 
     825           0 :     void set_part(website_variable_part_t part)
     826             :     {
     827           0 :         switch(part)
     828             :         {
     829           0 :         case WEBSITE_VARIABLE_PART_PATH:
     830             :         case WEBSITE_VARIABLE_PART_PORT:
     831             :         case WEBSITE_VARIABLE_PART_PROTOCOL:
     832             :         case WEBSITE_VARIABLE_PART_QUERY:
     833           0 :             break;
     834             : 
     835           0 :         default:
     836           0 :             throw std::runtime_error("unknown part specified in website_variable::set_part()");
     837             : 
     838             :         }
     839           0 :         f_part = part;
     840           0 :     }
     841             : 
     842             :     void read(QtSerialization::QReader & r);
     843             :     void write(QtSerialization::QWriter & w) const;
     844             : 
     845             : private:
     846             :     website_variable_type_t     f_type = website_variable_type_t();
     847             :     website_variable_part_t     f_part = website_variable_part_t();
     848             :     QString                     f_name = QString();
     849             :     QString                     f_value = QString();
     850             :     QString                     f_default = QString();
     851             :     bool                        f_required = false;
     852             : };
     853             : 
     854             : 
     855           0 : class website_info : public parser::parser_user_data, public QtSerialization::QSerializationObject
     856             : {
     857             : public:
     858           0 :     void add_var(QSharedPointer<website_variable >& var)
     859             :     {
     860           0 :         f_vars.push_back(var);
     861           0 :     }
     862             : 
     863           0 :     QString const & get_name() const
     864             :     {
     865           0 :         return f_name;
     866             :     }
     867             : 
     868           0 :     void set_name(QString const & name)
     869             :     {
     870           0 :         f_name = name;
     871           0 :     }
     872             : 
     873           0 :     int size() const
     874             :     {
     875           0 :         return f_vars.size();
     876             :     }
     877             : 
     878           0 :     QSharedPointer<website_variable> get_variable(int idx) const
     879             :     {
     880           0 :         return f_vars[idx];
     881             :     }
     882             : 
     883           0 :     QSharedPointer<website_variable> operator [] (int idx) const
     884             :     {
     885           0 :         return f_vars[idx];
     886             :     }
     887             : 
     888             :     void read(QtSerialization::QReader & r);
     889             :     virtual void readTag(QString const & name, QtSerialization::QReader & r);
     890             :     void write(QtSerialization::QWriter & w) const;
     891             : 
     892             : private:
     893             :     QString                                     f_name = QString();
     894             :     QVector<QSharedPointer<website_variable> >  f_vars = QVector<QSharedPointer<website_variable> >();
     895             : };
     896             : 
     897             : 
     898           0 : class website_rules : public parser::parser_user_data, public QtSerialization::QSerializationObject
     899             : {
     900             : public:
     901           0 :     void            add_info(QSharedPointer<website_info> & info)
     902             :                     {
     903           0 :                         f_info.push_back(info);
     904           0 :                     }
     905             : 
     906           0 :     int             size() const
     907             :                     {
     908           0 :                         return f_info.size();
     909             :                     }
     910             : 
     911           0 :     QSharedPointer<website_info> operator [] (int idx) const
     912             :                     {
     913           0 :                         return f_info[idx];
     914             :                     }
     915             : 
     916             :     void            read(QtSerialization::QReader & r);
     917             :     virtual void    readTag(QString const & name, QtSerialization::QReader & r);
     918             :     void            write(QtSerialization::QWriter & w) const;
     919             : 
     920             : private:
     921             :     QVector<QSharedPointer<website_info> > f_info = QVector<QSharedPointer<website_info> >();
     922             : };
     923             : 
     924             : 
     925             : } // namespace snap
     926             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13