LCOV - code coverage report
Current view: top level - cc - data.h (source / functions) Hit Total Coverage
Test: report.info Lines: 75 76 98.7 %
Date: 2012-05-15 Functions: 47 56 83.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 41 92 44.6 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #ifndef _ISC_DATA_H
      16                 :            : #define _ISC_DATA_H 1
      17                 :            : 
      18                 :            : #include <string>
      19                 :            : #include <vector>
      20                 :            : #include <map>
      21                 :            : #include <boost/shared_ptr.hpp>
      22                 :            : #include <stdexcept>
      23                 :            : #include <exceptions/exceptions.h>
      24                 :            : 
      25                 :            : namespace isc { namespace data {
      26                 :            : 
      27                 :            : class Element;
      28                 :            : // todo: describe the rationale behind ElementPtr?
      29                 :            : typedef boost::shared_ptr<Element> ElementPtr;
      30                 :            : typedef boost::shared_ptr<const Element> ConstElementPtr;
      31                 :            : 
      32                 :            : ///
      33                 :            : /// \brief A standard Data module exception that is thrown if a function
      34                 :            : /// is called for an Element that has a wrong type (e.g. int_value on a
      35                 :            : /// ListElement)
      36                 :            : ///
      37                 :        135 : class TypeError : public isc::Exception {
      38                 :            : public:
      39                 :        123 :     TypeError(const char* file, size_t line, const char* what) :
      40 [ +  - ][ -  + ]:        135 :         isc::Exception(file, line, what) {}
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      41                 :            : };
      42                 :            : 
      43                 :            : ///
      44                 :            : /// \brief A standard Data module exception that is thrown if a parse
      45                 :            : /// error is encountered when constructing an Element from a string
      46                 :            : ///
      47                 :            : // i'd like to use Exception here but we need one that is derived from
      48                 :            : // runtime_error (as this one is directly based on external data, and
      49                 :            : // i want to add some values to any static data string that is provided)
      50                 :         44 : class JSONError : public isc::Exception {
      51                 :            : public:
      52                 :         44 :     JSONError(const char* file, size_t line, const char* what) :
      53                 :         44 :         isc::Exception(file, line, what) {}
      54                 :            : };
      55                 :            : 
      56                 :            : ///
      57                 :            : /// \brief The \c Element class represents a piece of data, used by
      58                 :            : /// the command channel and configuration parts.
      59                 :            : ///
      60                 :            : /// An \c Element can contain simple types (int, real, string, bool and
      61                 :            : /// None), and composite types (list and string->element maps)
      62                 :            : ///
      63                 :            : /// Elements should in calling functions usually be referenced through
      64                 :            : /// an \c ElementPtr, which can be created using the factory functions
      65                 :            : /// \c Element::create() and \c Element::fromJSON()
      66                 :            : ///
      67                 :            : /// Notes to developers: Element is a base class, implemented by a
      68                 :            : /// specific subclass for each type (IntElement, BoolElement, etc).
      69                 :            : /// Element does define all functions for all types, and defaults to
      70                 :            : /// raising a \c TypeError for functions that are not supported for
      71                 :            : /// the type in question.
      72                 :            : ///
      73                 :            : class Element {
      74                 :            :     
      75                 :            : private:
      76                 :            :     // technically the type could be omitted; is it useful?
      77                 :            :     // should we remove it or replace it with a pure virtual
      78                 :            :     // function getType?
      79                 :            :     int type;
      80                 :            : 
      81                 :            : protected:
      82                 :      23430 :     Element(int t) { type = t; }
      83                 :            : 
      84                 :            : public:
      85                 :            :     // any is a special type used in list specifications, specifying
      86                 :            :     // that the elements can be of any type
      87                 :            :     enum types { integer, real, boolean, null, string, list, map, any };
      88                 :            :     // base class; make dtor virtual
      89                 :      23439 :     virtual ~Element() {};
      90                 :            : 
      91                 :            :     /// \return the type of this element
      92                 :          0 :     int getType() const { return (type); }
      93                 :            : 
      94                 :            :     /// Returns a string representing the Element and all its
      95                 :            :     /// child elements; note that this is different from stringValue(),
      96                 :            :     /// which only returns the single value of a StringElement
      97                 :            :     ///
      98                 :            :     /// The resulting string will contain the Element in JSON format.
      99                 :            :     ///
     100                 :            :     /// \return std::string containing the string representation
     101                 :            :     std::string str() const;
     102                 :            : 
     103                 :            :     /// Returns the wireformat for the Element and all its child
     104                 :            :     /// elements.
     105                 :            :     ///
     106                 :            :     /// \return std::string containing the element in wire format
     107                 :            :     std::string toWire() const;
     108                 :            :     void toWire(std::ostream& out) const;
     109                 :            : 
     110                 :            :     /// \name pure virtuals, every derived class must implement these
     111                 :            : 
     112                 :            :     /// \returns true if the other ElementPtr has the same type and
     113                 :            :     ///          value
     114                 :            :     virtual bool equals(const Element& other) const = 0;
     115                 :            :     
     116                 :            :     /// Converts the Element to JSON format and appends it to
     117                 :            :     /// the given stringstream.
     118                 :            :     virtual void toJSON(std::ostream& ss) const = 0;
     119                 :            : 
     120                 :            :     /// \name Type-specific getters
     121                 :            :     ///
     122                 :            :     /// \brief These functions only
     123                 :            :     /// work on their corresponding Element type. For all other
     124                 :            :     /// types, a TypeError is thrown.
     125                 :            :     /// If you want an exception-safe getter method, use
     126                 :            :     /// getValue() below
     127                 :            :     //@{
     128                 :         18 :     virtual long int intValue() const
     129 [ +  - ][ +  - ]:         36 :     { isc_throw(TypeError, "intValue() called on non-integer Element"); };
     130                 :          5 :     virtual double doubleValue() const
     131 [ +  - ][ +  - ]:         10 :     { isc_throw(TypeError, "doubleValue() called on non-double Element"); };
     132                 :          5 :     virtual bool boolValue() const
     133 [ +  - ][ +  - ]:         10 :     { isc_throw(TypeError, "boolValue() called on non-Bool Element"); };
     134                 :         30 :     virtual std::string stringValue() const
     135 [ +  - ][ +  - ]:         60 :     { isc_throw(TypeError, "stringValue() called on non-string Element"); };
     136                 :         15 :     virtual const std::vector<ConstElementPtr>& listValue() const {
     137                 :            :         // replace with real exception or empty vector?
     138 [ +  - ][ +  - ]:         30 :         isc_throw(TypeError, "listValue() called on non-list Element");
     139                 :            :     };
     140                 :         32 :     virtual const std::map<std::string, ConstElementPtr>& mapValue() const {
     141                 :            :         // replace with real exception or empty map?
     142 [ +  - ][ +  - ]:         64 :         isc_throw(TypeError, "mapValue() called on non-map Element");
     143                 :            :     };
     144                 :            :     //@}
     145                 :            : 
     146                 :            :     /// \name Exception-safe getters
     147                 :            :     ///
     148                 :            :     /// \brief The getValue() functions return false if the given reference
     149                 :            :     /// is of another type than the element contains
     150                 :            :     /// By default it always returns false; the derived classes
     151                 :            :     /// override the function for their type, copying their
     152                 :            :     /// data to the given reference and returning true
     153                 :            :     ///
     154                 :            :     //@{
     155                 :            :     virtual bool getValue(long int& t);
     156                 :            :     virtual bool getValue(double& t);
     157                 :            :     virtual bool getValue(bool& t);
     158                 :            :     virtual bool getValue(std::string& t);
     159                 :            :     virtual bool getValue(std::vector<ConstElementPtr>& t);
     160                 :            :     virtual bool getValue(std::map<std::string, ConstElementPtr>& t);
     161                 :            :     //@}
     162                 :            : 
     163                 :            :     ///
     164                 :            :     /// \name Exception-safe setters.
     165                 :            :     ///
     166                 :            :     /// \brief Return false if the Element is not
     167                 :            :     /// the right type. Set the value and return true if the Elements
     168                 :            :     /// is of the correct type
     169                 :            :     ///
     170                 :            :     //@{
     171                 :            :     virtual bool setValue(const long int v);
     172                 :            :     virtual bool setValue(const double v);
     173                 :            :     virtual bool setValue(const bool t);
     174                 :            :     virtual bool setValue(const std::string& v);
     175                 :            :     virtual bool setValue(const std::vector<ConstElementPtr>& v);
     176                 :            :     virtual bool setValue(const std::map<std::string, ConstElementPtr>& v);
     177                 :            :     //@}
     178                 :            : 
     179                 :            : 
     180                 :            : 
     181                 :            :     // Other functions for specific subtypes
     182                 :            : 
     183                 :            :     /// \name ListElement functions
     184                 :            :     ///
     185                 :            :     /// \brief If the Element on which these functions are called are not
     186                 :            :     /// an instance of ListElement, a TypeError exception is thrown.
     187                 :            :     //@{
     188                 :            :     /// Returns the ElementPtr at the given index. If the index is out
     189                 :            :     /// of bounds, this function throws an std::out_of_range exception.
     190                 :            :     /// \param i The position of the ElementPtr to return
     191                 :            :     virtual ConstElementPtr get(const int i) const;
     192                 :            : 
     193                 :            :     /// Sets the ElementPtr at the given index. If the index is out
     194                 :            :     /// of bounds, this function throws an std::out_of_range exception.
     195                 :            :     /// \param i The position of the ElementPtr to set
     196                 :            :     /// \param element The ElementPtr to set at the position
     197                 :            :     virtual void set(const size_t i, ConstElementPtr element);
     198                 :            : 
     199                 :            :     /// Adds an ElementPtr to the list
     200                 :            :     /// \param element The ElementPtr to add
     201                 :            :     virtual void add(ConstElementPtr element);
     202                 :            : 
     203                 :            :     /// Removes the element at the given position. If the index is out
     204                 :            :     /// of nothing happens.
     205                 :            :     /// \param i The index of the element to remove.
     206                 :            :     virtual void remove(const int i);
     207                 :            : 
     208                 :            :     /// Returns the number of elements in the list.
     209                 :            :     virtual size_t size() const;
     210                 :            :     //@}
     211                 :            : 
     212                 :            :     
     213                 :            :     /// \name MapElement functions
     214                 :            :     ///
     215                 :            :     /// \brief If the Element on which these functions are called are not
     216                 :            :     /// an instance of MapElement, a TypeError exception is thrown.
     217                 :            :     //@{
     218                 :            :     /// Returns the ElementPtr at the given key
     219                 :            :     /// \param name The key of the Element to return
     220                 :            :     /// \return The ElementPtr at the given key
     221                 :            :     virtual ConstElementPtr get(const std::string& name) const;
     222                 :            : 
     223                 :            :     /// Sets the ElementPtr at the given key
     224                 :            :     /// \param name The key of the Element to set
     225                 :            :     /// \param element The ElementPtr to set at the given key.
     226                 :            :     virtual void set(const std::string& name, ConstElementPtr element);
     227                 :            : 
     228                 :            :     /// Remove the ElementPtr at the given key
     229                 :            :     /// \param name The key of the Element to remove
     230                 :            :     virtual void remove(const std::string& name);
     231                 :            : 
     232                 :            :     /// Checks if there is data at the given key
     233                 :            :     /// \param name The key of the Element to remove
     234                 :            :     /// \return true if there is data at the key, false if not.
     235                 :            :     virtual bool contains(const std::string& name) const;
     236                 :            : 
     237                 :            :     /// Recursively finds any data at the given identifier. The
     238                 :            :     /// identifier is a /-separated list of names of nested maps, with
     239                 :            :     /// the last name being the leaf that is returned.
     240                 :            :     ///
     241                 :            :     /// For instance, if you have a MapElement that contains another
     242                 :            :     /// MapElement at the key "foo", and that second MapElement contains
     243                 :            :     /// Another Element at key "bar", the identifier for that last
     244                 :            :     /// element from the first is "foo/bar".
     245                 :            :     ///
     246                 :            :     /// \param identifier The identifier of the element to find
     247                 :            :     /// \return The ElementPtr at the given identifier. Returns a
     248                 :            :     /// null ElementPtr if it is not found, which can be checked with
     249                 :            :     /// Element::is_null(ElementPtr e).
     250                 :            :     virtual ConstElementPtr find(const std::string& identifier) const;
     251                 :            : 
     252                 :            :     /// See \c Element::find()
     253                 :            :     /// \param identifier The identifier of the element to find
     254                 :            :     /// \param t Reference to store the resulting ElementPtr, if found.
     255                 :            :     /// \return true if the element was found, false if not.
     256                 :            :     virtual bool find(const std::string& identifier, ConstElementPtr t) const;
     257                 :            :     //@}
     258                 :            : 
     259                 :            : 
     260                 :            :     /// \name Factory functions
     261                 :            :     
     262                 :            :     // TODO: should we move all factory functions to a different class
     263                 :            :     // so as not to burden the Element base with too many functions?
     264                 :            :     // and/or perhaps even to a separate header?
     265                 :            : 
     266                 :            :     /// \name Direct factory functions
     267                 :            :     /// \brief These functions simply wrap the given data directly
     268                 :            :     /// in an Element object, and return a reference to it, in the form
     269                 :            :     /// of an \c ElementPtr.
     270                 :            :     /// These factory functions are exception-free (unless there is
     271                 :            :     /// no memory available, in which case bad_alloc is raised by the
     272                 :            :     /// underlying system).
     273                 :            :     /// (Note that that is different from an NullElement, which
     274                 :            :     /// represents an empty value, and is created with Element::create())
     275                 :            :     //@{
     276                 :            :     static ElementPtr create();
     277                 :            :     static ElementPtr create(const long int i);
     278   [ +  -  +  -  :        361 :     static ElementPtr create(const int i) { return (create(static_cast<long int>(i))); };
          +  -  +  -  +  
              - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  -  
          +  -  +  -  +  
                -  +  - ]
         [ +  - ][ +  - ]
     279                 :            :     static ElementPtr create(const double d);
     280                 :            :     static ElementPtr create(const bool b);
     281                 :            :     static ElementPtr create(const std::string& s);
     282                 :            :     // need both std:string and char *, since c++ will match
     283                 :            :     // bool before std::string when you pass it a char *
     284 [ +  - ][ +  - ]:        201 :     static ElementPtr create(const char *s) { return (create(std::string(s))); }
                 [ +  - ]
     285                 :            : 
     286                 :            :     /// \brief Creates an empty ListElement type ElementPtr.
     287                 :            :     static ElementPtr createList();
     288                 :            : 
     289                 :            :     /// \brief Creates an empty MapElement type ElementPtr.
     290                 :            :     static ElementPtr createMap();
     291                 :            :     //@}
     292                 :            : 
     293                 :            : 
     294                 :            :     /// \name Compound factory functions
     295                 :            : 
     296                 :            :     /// \brief These functions will parse the given string (JSON)
     297                 :            :     /// representation  of a compound element. If there is a parse
     298                 :            :     /// error, an exception of the type isc::data::JSONError is thrown.
     299                 :            : 
     300                 :            :     //@{
     301                 :            :     /// Creates an Element from the given JSON string
     302                 :            :     /// \param in The string to parse the element from
     303                 :            :     /// \return An ElementPtr that contains the element(s) specified
     304                 :            :     /// in the given string.
     305                 :            :     static ElementPtr fromJSON(const std::string& in);
     306                 :            : 
     307                 :            :     /// Creates an Element from the given input stream containing JSON
     308                 :            :     /// formatted data.
     309                 :            :     ///
     310                 :            :     /// \param in The string to parse the element from
     311                 :            :     /// \return An ElementPtr that contains the element(s) specified
     312                 :            :     /// in the given input stream.
     313                 :            :     static ElementPtr fromJSON(std::istream& in) throw(JSONError);
     314                 :            :     static ElementPtr fromJSON(std::istream& in, const std::string& file_name) throw(JSONError);
     315                 :            : 
     316                 :            :     /// Creates an Element from the given input stream, where we keep
     317                 :            :     /// track of the location in the stream for error reporting.
     318                 :            :     ///
     319                 :            :     /// \param in The string to parse the element from.
     320                 :            :     /// \param file The input file name.
     321                 :            :     /// \param line A reference to the int where the function keeps
     322                 :            :     /// track of the current line.
     323                 :            :     /// \param pos A reference to the int where the function keeps
     324                 :            :     /// track of the current position within the current line.
     325                 :            :     /// \return An ElementPtr that contains the element(s) specified
     326                 :            :     /// in the given input stream.
     327                 :            :     // make this one private?
     328                 :            :     static ElementPtr fromJSON(std::istream& in, const std::string& file, int& line, int &pos) throw(JSONError);
     329                 :            :     //@}
     330                 :            : 
     331                 :            :     /// \name Type name conversion functions
     332                 :            : 
     333                 :            :     /// Returns the name of the given type as a string
     334                 :            :     ///
     335                 :            :     /// \param type The type to return the name of
     336                 :            :     /// \return The name of the type, or "unknown" if the type
     337                 :            :     ///         is not known.
     338                 :            :     static std::string typeToName(Element::types type);
     339                 :            : 
     340                 :            :     /// Converts the string to the corresponding type
     341                 :            :     /// Throws a TypeError if the name is unknown.
     342                 :            :     ///
     343                 :            :     /// \param type_name The name to get the type of
     344                 :            :     /// \return the corresponding type value
     345                 :            :     static Element::types nameToType(const std::string& type_name);
     346                 :            : 
     347                 :            :     /// \name Wire format factory functions
     348                 :            : 
     349                 :            :     /// These function pparse the wireformat at the given stringstream
     350                 :            :     /// (of the given length). If there is a parse error an exception
     351                 :            :     /// of the type isc::cc::DecodeError is raised.
     352                 :            :     
     353                 :            :     //@{
     354                 :            :     /// Creates an Element from the wire format in the given
     355                 :            :     /// stringstream of the given length.
     356                 :            :     /// Since the wire format is JSON, thise is the same as
     357                 :            :     /// fromJSON, and could be removed.
     358                 :            :     ///
     359                 :            :     /// \param in The input stringstream.
     360                 :            :     /// \param length The length of the wireformat data in the stream
     361                 :            :     /// \return ElementPtr with the data that is parsed.
     362                 :            :     static ElementPtr fromWire(std::stringstream& in, int length);
     363                 :            : 
     364                 :            :     /// Creates an Element from the wire format in the given string
     365                 :            :     /// Since the wire format is JSON, thise is the same as
     366                 :            :     /// fromJSON, and could be removed.
     367                 :            :     ///
     368                 :            :     /// \param s The input string
     369                 :            :     /// \return ElementPtr with the data that is parsed.
     370                 :            :     static ElementPtr fromWire(const std::string& s);
     371                 :            :     //@}
     372                 :            : };
     373                 :            : 
     374                 :       1759 : class IntElement : public Element {
     375                 :            :     long int i;
     376                 :            : 
     377                 :            : public:
     378                 :       3525 :     IntElement(long int v) : Element(integer), i(v) { }
     379                 :        611 :     long int intValue() const { return (i); }
     380                 :            :     using Element::getValue;
     381                 :          1 :     bool getValue(long int& t) { t = i; return (true); }
     382                 :            :     using Element::setValue;
     383                 :          1 :     bool setValue(const long int v) { i = v; return (true); }
     384                 :            :     void toJSON(std::ostream& ss) const;
     385                 :            :     bool equals(const Element& other) const;
     386                 :            : };
     387                 :            : 
     388                 :         77 : class DoubleElement : public Element {
     389                 :            :     double d;
     390                 :            : 
     391                 :            : public:
     392                 :        155 :     DoubleElement(double v) : Element(real), d(v) {};
     393                 :         45 :     double doubleValue() const { return (d); }
     394                 :            :     using Element::getValue;
     395                 :          1 :     bool getValue(double& t) { t = d; return (true); }
     396                 :            :     using Element::setValue;
     397                 :          1 :     bool setValue(const double v) { d = v; return (true); }
     398                 :            :     void toJSON(std::ostream& ss) const;
     399                 :            :     bool equals(const Element& other) const;
     400                 :            : };
     401                 :            : 
     402                 :       2836 : class BoolElement : public Element {
     403                 :            :     bool b;
     404                 :            : 
     405                 :            : public:
     406                 :       5673 :     BoolElement(const bool v) : Element(boolean), b(v) {};
     407                 :       2972 :     bool boolValue() const { return (b); }
     408                 :            :     using Element::getValue;
     409                 :          1 :     bool getValue(bool& t) { t = b; return (true); }
     410                 :            :     using Element::setValue;
     411                 :          1 :     bool setValue(const bool v) { b = v; return (true); }
     412                 :            :     void toJSON(std::ostream& ss) const;
     413                 :            :     bool equals(const Element& other) const;
     414                 :            : };
     415                 :            : 
     416                 :         37 : class NullElement : public Element {
     417                 :            : public:
     418                 :         70 :     NullElement() : Element(null) {};
     419                 :            :     void toJSON(std::ostream& ss) const;
     420                 :            :     bool equals(const Element& other) const;
     421                 :            : };
     422                 :            : 
     423                 :      28835 : class StringElement : public Element {
     424                 :            :     std::string s;
     425                 :            : 
     426                 :            : public:
     427         [ -  + ]:       9638 :     StringElement(std::string v) : Element(string), s(v) {};
           [ -  +  -  + ]
     428 [ +  - ][ +  - ]:      14478 :     std::string stringValue() const { return (s); }
     429                 :            :     using Element::getValue;
     430                 :          1 :     bool getValue(std::string& t) { t = s; return (true); }
     431                 :            :     using Element::setValue;
     432                 :          1 :     bool setValue(const std::string& v) { s = v; return (true); }
     433                 :            :     void toJSON(std::ostream& ss) const;
     434                 :            :     bool equals(const Element& other) const;
     435                 :            : };
     436                 :            : 
     437         [ +  - ]:       6985 : class ListElement : public Element {
     438                 :            :     std::vector<ConstElementPtr> l;
     439                 :            : 
     440                 :            : public:
     441                 :       6826 :     ListElement() : Element(list) {}
     442                 :       2248 :     const std::vector<ConstElementPtr>& listValue() const { return (l); }
     443                 :            :     using Element::getValue;
     444                 :          1 :     bool getValue(std::vector<ConstElementPtr>& t) {
     445                 :          1 :         t = l;
     446                 :          1 :         return (true);
     447                 :            :     }
     448                 :            :     using Element::setValue;
     449                 :          1 :     bool setValue(const std::vector<ConstElementPtr>& v) {
     450                 :          1 :         l = v;
     451                 :          1 :         return (true);
     452                 :            :     }
     453                 :            :     using Element::get;
     454                 :       1949 :     ConstElementPtr get(int i) const { return (l.at(i)); }
     455                 :            :     using Element::set;
     456                 :          3 :     void set(size_t i, ConstElementPtr e) {
     457                 :          2 :         l.at(i) = e;
     458                 :          2 :     }
     459                 :       5572 :     void add(ConstElementPtr e) { l.push_back(e); };
     460                 :            :     using Element::remove;
     461                 :        179 :     void remove(int i) { l.erase(l.begin() + i); };
     462                 :            :     void toJSON(std::ostream& ss) const;
     463                 :       1219 :     size_t size() const { return (l.size()); }
     464                 :            :     bool equals(const Element& other) const;
     465                 :            : };
     466                 :            : 
     467                 :      11319 : class MapElement : public Element {
     468                 :            :     std::map<std::string, ConstElementPtr> m;
     469                 :            : 
     470                 :            : public:
     471                 :      11332 :     MapElement() : Element(map) {}
     472                 :            :     // TODO: should we have direct iterators instead of exposing the std::map here?
     473                 :       1486 :     const std::map<std::string, ConstElementPtr>& mapValue() const {
     474                 :       1486 :         return (m);
     475                 :            :     }
     476                 :            :     using Element::getValue;
     477                 :          1 :     bool getValue(std::map<std::string, ConstElementPtr>& t) {
     478                 :          1 :         t = m;
     479                 :          1 :         return (true);
     480                 :            :     }
     481                 :            :     using Element::setValue;
     482                 :         11 :     bool setValue(const std::map<std::string, ConstElementPtr>& v) {
     483                 :         11 :         m = v;
     484                 :         11 :         return (true);
     485                 :            :     }
     486                 :            :     using Element::get;
     487                 :      31324 :     ConstElementPtr get(const std::string& s) const {
     488         [ +  + ]:      62648 :         return (contains(s) ? m.find(s)->second : ConstElementPtr());
     489                 :            :     }
     490                 :            :     using Element::set;
     491                 :            :     void set(const std::string& key, ConstElementPtr value);
     492                 :            :     using Element::remove;
     493                 :         11 :     void remove(const std::string& s) { m.erase(s); }
     494                 :      46587 :     bool contains(const std::string& s) const {
     495                 :      46587 :         return (m.find(s) != m.end());
     496                 :            :     }
     497                 :            :     void toJSON(std::ostream& ss) const;
     498                 :            :     
     499                 :            :     // we should name the two finds better...
     500                 :            :     // find the element at id; raises TypeError if one of the
     501                 :            :     // elements at path except the one we're looking for is not a
     502                 :            :     // mapelement.
     503                 :            :     // returns an empty element if the item could not be found
     504                 :            :     ConstElementPtr find(const std::string& id) const;
     505                 :            : 
     506                 :            :     // find the Element at 'id', and store the element pointer in t
     507                 :            :     // returns true if found, or false if not found (either because
     508                 :            :     // it doesnt exist or one of the elements in the path is not
     509                 :            :     // a MapElement)
     510                 :            :     bool find(const std::string& id, ConstElementPtr t) const;
     511                 :            : 
     512                 :            :     bool equals(const Element& other) const;
     513                 :            : };
     514                 :            : 
     515                 :            : /// Checks whether the given ElementPtr is a NULL pointer
     516                 :            : /// \param p The ElementPtr to check
     517                 :            : /// \return true if it is NULL, false if not.
     518                 :            : bool isNull(ConstElementPtr p);
     519                 :            : 
     520                 :            : ///
     521                 :            : /// \brief Remove all values from the first ElementPtr that are
     522                 :            : /// equal in the second. Both ElementPtrs MUST be MapElements
     523                 :            : /// The use for this function is to end up with a MapElement that
     524                 :            : /// only contains new and changed values (for ModuleCCSession and
     525                 :            : /// configuration update handlers)
     526                 :            : /// Raises a TypeError if a or b are not MapElements
     527                 :            : void removeIdentical(ElementPtr a, ConstElementPtr b);
     528                 :            : 
     529                 :            : /// \brief Create a new ElementPtr from the first ElementPtr, removing all
     530                 :            : /// values that are equal in the second. Both ElementPtrs MUST be MapElements.
     531                 :            : /// The returned ElementPtr will be a MapElement that only contains new and
     532                 :            : /// changed values (for ModuleCCSession and configuration update handlers).
     533                 :            : /// Raises a TypeError if a or b are not MapElements
     534                 :            : ConstElementPtr removeIdentical(ConstElementPtr a, ConstElementPtr b);
     535                 :            : 
     536                 :            : /// \brief Merges the data from other into element.
     537                 :            : /// (on the first level). Both elements must be
     538                 :            : /// MapElements.
     539                 :            : /// Every string,value pair in other is copied into element
     540                 :            : /// (the ElementPtr of value is copied, this is not a new object)
     541                 :            : /// Unless the value is a NullElement, in which case the
     542                 :            : /// key is removed from element, rather than setting the value to
     543                 :            : /// the given NullElement.
     544                 :            : /// This way, we can remove values from for instance maps with
     545                 :            : /// configuration data (which would then result in reverting back
     546                 :            : /// to the default).
     547                 :            : /// Raises a TypeError if either ElementPtr is not a MapElement
     548                 :            : void merge(ElementPtr element, ConstElementPtr other);
     549                 :            : 
     550                 :            : ///
     551                 :            : /// \brief Insert the Element as a string into stream.
     552                 :            : ///
     553                 :            : /// This method converts the \c ElementPtr into a string with
     554                 :            : /// \c Element::str() and inserts it into the
     555                 :            : /// output stream \c out.
     556                 :            : ///
     557                 :            : /// This function overloads the global operator<< to behave as described in
     558                 :            : /// ostream::operator<< but applied to \c ElementPtr objects.
     559                 :            : ///
     560                 :            : /// \param out A \c std::ostream object on which the insertion operation is
     561                 :            : /// performed.
     562                 :            : /// \param e The \c ElementPtr object to insert.
     563                 :            : /// \return A reference to the same \c std::ostream object referenced by
     564                 :            : /// parameter \c out after the insertion operation.
     565                 :            : std::ostream& operator<<(std::ostream& out, const Element& e);
     566                 :            : 
     567                 :            : bool operator==(const Element& a, const Element& b);
     568                 :            : bool operator!=(const Element& a, const Element& b);
     569                 :            : } }
     570                 :            : #endif // _ISC_DATA_H
     571                 :            : 
     572                 :            : // Local Variables: 
     573                 :            : // mode: c++
     574                 :            : // End: 

Generated by: LCOV version 1.9