AgentXcpp  Revision:0.1
Internals Documentation
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends
/home/tanjeff/projekte/agentxcpp/src/oid.hpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2011-2012 Tanjeff-Nicolai Moos <tanjeff@cccmz.de>
00003  *
00004  * This file is part of the agentXcpp library.
00005  *
00006  * AgentXcpp is free software: you can redistribute it and/or modify
00007  * it under the terms of the AgentXcpp library license, version 1, which 
00008  * consists of the GNU General Public License and some additional 
00009  * permissions.
00010  *
00011  * AgentXcpp is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * See the AgentXcpp library license in the LICENSE file of this package 
00017  * for more details.
00018  */
00019 
00020 #ifndef _OID_H_
00021 #define _OID_H_
00022 
00023 #include <vector>
00024 #include <ostream>
00025 #include <string>
00026 #include "variable.hpp"
00027 #include "types.hpp"
00028 #include "exceptions.hpp"
00029 
00030 namespace agentxcpp
00031 {
00032     /**
00033      * \brief Represents an SNMP object identifier (OID).
00034      *
00035      * This class represents an OID. OID's are sequences of sub-identifiers, 
00036      * which are integers.
00037      *
00038      * This class provides constructors taking a string which contains an OID.  
00039      * For example, this works:
00040      *
00041      * \code
00042      * oid myCompany = oid("1.3.6.1.4.1.355");
00043      * \endcode
00044      *
00045      * Also a constructor is provided which takes an oid and a string and 
00046      * concatenates them, so this works also:
00047      *
00048      * \code
00049      * oid myObject = oid(myCompany, "1.1.3.0");
00050      * \endcode
00051      *
00052      * In addition, some common oid's are provided as constants, e.g.  
00053      * 'enterprises_oid', so the following will also work (note that the second 
00054      * argument is a string, not an integer!):
00055      *
00056      * \code
00057      * oid yourCompany = oid(enterprises_oid, "42"); // second param is a string!
00058      * \endcode
00059      *
00060      * The string given to the constructors must have a valid syntax. If a 
00061      * malformed string is provided, inval_param is thrown and the object is 
00062      * not constructed. For example, the following strings are malformed:
00063      *
00064      * \code
00065      * "1,3,6"  // wrong separator (must be a period)
00066      * "1.3.6." // trailing character at the end
00067      * "1.3.6.1.4.1.123456789123" // last subid is too big (must fit in a 32 bit unsigned integer)
00068      * \endcode
00069      *
00070      * However, the following strings are accepted:
00071      *
00072      * \code
00073      * "1.3.6"
00074      * "1"  // a single subid is ok
00075      * "1.3.6.1.4.1.42.1.0" // 0 as subid is ok
00076      * ""   // empty string is ok
00077      * \endcode
00078      *
00079      * This class inherits from std:vector<uint32_t>, which means that an oid 
00080      * object can be manipulated the same way as a std::vector<> can be 
00081      * manipulated:
00082      *
00083      * \code
00084      * oid theirCompany = enterprises_oid;
00085      * theirCompany.push_back(23);    // Don't use a string here!
00086      * \endcode
00087      *
00088      */
00089     class oid: public variable, public std::vector<uint32_t>
00090     {
00091         private:
00092 
00093             /**
00094              * \brief the 'include' field.
00095              */
00096             bool include;
00097 
00098             /**
00099              * \brief Parse an OID from a string and append it.
00100              *
00101              * The OID contained within the string 's' is parsed and appended 
00102              * this object. The format of the string is described above 
00103              *
00104              * \param s The OID to be parsed.
00105              *
00106              * \exception inval_param If the string is malformed.
00107              */
00108             void parse_string(std::string s);
00109 
00110         public:
00111 
00112             /**
00113              * \brief Default Constructor
00114              *
00115              * This constructs an empty oid (the null oid).
00116              *
00117              * \internal
00118              * The 'include' field is initialized to 'false'.
00119              * \endinternal
00120              *
00121              * \exception None.
00122              */
00123             oid()
00124             {
00125                 include = false;
00126             }
00127 
00128 
00129             /**
00130              * \brief Initialize an oid object with an OID in string format.
00131              *
00132              * This constructor takes a string and initializes the oid object 
00133              * with the OID contained within this string. The format of the 
00134              * string is described above.
00135              * 
00136              * \internal
00137              * The 'include' field is initialized to 'false'.
00138              * \endinternal
00139              *
00140              * \param id The initial object identifier.
00141              *
00142              * \exception inval_param If the string is malformed.
00143              */
00144             oid(std::string id);
00145 
00146             /**
00147              * \brief Initialize an oid object with another oid plus an OID in 
00148              * string format.
00149              *
00150              * All subid's are copied from 'o'.  Then, the OID contained within 
00151              * the string 'id' is appended.  The format of the string is 
00152              * described in the documentation of this class.
00153              *
00154              * \internal
00155              * The 'include' field is copied from 'o'.
00156              * \endinternal
00157              *
00158              * \param o The starting OID.
00159              *
00160              * \param id The OID to append.
00161              *
00162              * \exception inval_param If the string is malformed.
00163              */
00164             oid(const oid& o, std::string id);
00165 
00166             /**
00167              * \brief Assignment operator
00168              *
00169              * Copies all data from 'o' into this OID.
00170              *
00171              * \param o The OID to copy from.
00172              *
00173              * \return A reference to this OID.
00174              */
00175             oid& operator=(const oid& o);
00176 
00177             /**
00178              * \internal
00179              *
00180              * \brief Get the current include value.
00181              *
00182              * The include value is present in the serialized form of an OID.  
00183              * If an OID object is created by parsing a AgentX message, the 
00184              * 'include' member is set accordingly.
00185              *
00186              * See RFC 2741, sections 5.1 and 5.2 for details.
00187              */
00188             bool get_include()
00189             {
00190                 return include;
00191             }
00192 
00193             /**
00194              * \internal
00195              *
00196              * \brief set the include value
00197              *
00198              * The include value is present in the serialized form of an OID.  
00199              * If an OID object is serialized, the include field is encoded 
00200              * into the stream.
00201              *
00202              * See RFC 2741, sections 5.1 and 5.2 for details.
00203              */
00204             void set_include(bool i)
00205             {
00206                 include = i;
00207             }
00208 
00209             /**
00210              * \internal
00211              *
00212              * \brief Encode an OID object as described in RFC 2741,
00213              *        section 5.1.
00214              */
00215             data_t serialize() const;
00216 
00217             /**
00218              * \internal
00219              *
00220              * \brief Construct the object from input stream
00221              *
00222              * This constructor parses the serialized form of the object.
00223              * It takes an iterator, starts parsing at the position of the 
00224              * iterator and advances the iterator to the position right behind 
00225              * the object.
00226              *
00227              * The constructor expects valid data from the stream; if parsing 
00228              * fails, parse_error is thrown. In this case, the iterator is left 
00229              * at an undefined position.
00230              *
00231              * \param pos Iterator pointing to the current stream position.
00232              *            The iterator is advanced while reading the header.
00233              *
00234              * \param end Iterator pointing one element past the end of the
00235              *            current stream. This is needed to mark the end of the 
00236              *            buffer.
00237              *
00238              * \param big_endian Whether the input stream is in big endian
00239              *                   format
00240              *
00241              * \exception parse_error If parsing fails. In this case, the
00242              *                        iterator is left at an undefined 
00243              *                        position.
00244              */
00245             oid(data_t::const_iterator& pos,
00246                 const data_t::const_iterator& end,
00247                 bool big_endian=true);
00248 
00249             /**
00250              * \brief The less-than operator
00251              *
00252              * An OID is less than another OID if either the first 
00253              * not-identical part is lesser or if all parts are identical and 
00254              * it has lesser parts.
00255              *
00256              * Example:\n
00257              * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n
00258              * is less than \n
00259              * 1.3.6.1.4.1.42.3<b>.4</b>.1 \n
00260              * Note the next to last number.
00261              *
00262              * Also,\n
00263              * 1.3.6.1.4.1.42.3.3.1 \n
00264              * is less than \n
00265              * 1.3.6.1.4.1.42.3.3.1<b>.1</b> \n
00266              * because it is shorter.
00267              *
00268              * However, \n
00269              * 1.3.6.1.4.1.42.3<b>.3</b>.1 \n
00270              * is greater than \n
00271              * 1.3.6.1.4.1.42.3<b>.2</b>.1.1 \n
00272              * because the 9th number is greater (although the first OID has 
00273              * less numbers than the second).
00274              *
00275              * \param o The OID tocompare to.
00276              *
00277              * \return True if the OID is less than 'o', false otherwise.
00278              */
00279             bool operator<(const oid& o) const;
00280 
00281             /**
00282              * \brief The equal-operator
00283              *
00284              * See operator<() for a more detailed description about comparing 
00285              * OIDs.
00286              *
00287              * \param o The OID tocompare to.
00288              *
00289              * \return True if the OIDs are equal, false otherwise.
00290              */
00291             bool operator==(const oid& o) const;
00292 
00293             /**
00294              * \brief The not-equal-operator for oids
00295              *
00296              * See operator<() for a more detailed description about comparing 
00297              * OIDs.
00298              *
00299              * \param o The OID tocompare to.
00300              *
00301              * \return False if the OIDs are equal, true otherwise.
00302              */
00303             bool operator!=(const oid& o) const
00304             {
00305                 return ! (*this == o);
00306             }
00307 
00308             /**
00309              * \brief The greater-than operator
00310              *
00311              * See operator<() for a more detailed description about comparing 
00312              * OIDs.
00313              *
00314              * \param o The OID tocompare to.
00315              *
00316              * \return True if the OID is greater than 'o', false otherwise.
00317              */
00318             bool operator>(const oid& o) const
00319             {
00320                 // a > b is the same as b < a :-)
00321                 return o < *this;
00322             }
00323 
00324             /**
00325              * \brief Checks whether the given oid is in the subtree of this
00326              *        oid.
00327              *
00328              * This method checks whether the given OID is included in the 
00329              * subtree which has this oid as root.
00330              *
00331              * Examples:\n
00332              * \code
00333              * oid id("1.3.6.1.4.1.42.3");
00334              * id.contains( oid(1.3.6.1.4.1.42.3) ); // true
00335              * id.contains( oid(1.3.6.1.4.1.42) ); // false
00336              * id.contains( oid(1.3.6.1.4.1.43.3) ); // false
00337              * id.contains( oid(1.3.6.1.4.1.42.3.3.1) ); // true
00338              * \endcode
00339              *
00340              * \param id The OID to check.
00341              *
00342              * \return True if id is contained in the subtree, false
00343              *         otherwise.
00344              */
00345             bool contains(const oid& id);
00346 
00347             /**
00348              * \internal
00349              *
00350              * \brief Whether it is the null Object Identifier
00351              *
00352              * According to RFC 2741, 5.1 "Object Identifier", a null object 
00353              * identifier has serial representation of for 4 bytes which are 
00354              * all set to 0. An OID with no subid's and the index field set to 
00355              * 0 results in that representation and is thus considered to be 
00356              * the null OID.
00357              *
00358              * \return True if the object is the null OID, false otherwise.
00359              */
00360             bool is_null() const;
00361 
00362             friend std::ostream& operator<<(std::ostream& out,
00363                                             const agentxcpp::oid& o);
00364 
00365             /**
00366              * \internal
00367              *
00368              * \brief Update the internal state of the object.
00369              *
00370              * This function calls get() to obtain a new value and stores that 
00371              * value within this object.
00372              *
00373              * \exception generic_error If obtaining the new value failed.
00374              */
00375             virtual void update()
00376             {
00377                 *this = this->get();
00378             }
00379 
00380             /**
00381              * \brief Obtain the current value for the object.
00382              *
00383              * This member function is derived by classes representing SNMP 
00384              * variables and shall return the current value of the object.
00385              *
00386              * The default implementation throws generic_error.
00387              *
00388              * \return The current value of the object.
00389              *
00390              * \exception generic_error If obtaining the current value fails.
00391              *                          No other exception shall be thrown.
00392              */
00393             virtual oid get()
00394             {
00395                 throw( generic_error() );
00396             }
00397     };
00398 
00399     /**
00400      * \brief The output operator for the oid class.
00401      *
00402      * Object identifiers (oid objects) can be output as follows:
00403      * 
00404      * \code
00405      * oid led_state(enterprises_oid, "1.3.3.1");
00406      * cout << "LED state OID: " << led_state << endl;
00407      * \endcode
00408      *
00409      * The last line will output "LED state OID:  .1.3.6.1.4.1.3.3.1".
00410      *
00411      * \param out The stream to which to write the output.
00412      *
00413      * \param o The OID to output.
00414      *
00415      * \return The 'out' parameter.
00416      */
00417     std::ostream& operator<<(std::ostream& out, const agentxcpp::oid& o);
00418 
00419 
00420     // TODO: Possibly these should be put into the agentxcpp::oid namespace?  
00421     // The use of \memberof is not elegant.
00422 
00423     /**
00424      * \memberof oid
00425      *
00426      * \brief The 'iso' OID according to RFC 1155.
00427      */
00428     const oid iso_oid("1");
00429 
00430     /**
00431      * \memberof oid
00432      *
00433      * \brief The 'ccitt' OID according to RFC 1155.
00434      */
00435     const oid ccitt_oid("0");
00436 
00437     /**
00438      * \memberof oid
00439      *
00440      * \brief The 'joint.iso.ccitt' OID according to RFC 1155.
00441      */
00442     const oid joint_iso_ccitt_oid("2");
00443 
00444     /**
00445      * \memberof oid
00446      *
00447      * \brief The 'iso.org' OID according to RFC 1155.
00448      */
00449     const oid org_oid(iso_oid,"3");
00450 
00451     /**
00452      * \memberof oid
00453      *
00454      * \brief The 'iso.org.dod' OID according to RFC 1155.
00455      */
00456     const oid dod_oid(org_oid,"6");
00457 
00458     /**
00459      * \memberof oid
00460      *
00461      * \brief The 'iso.org.dod.internet' OID according to RFC 1155.
00462      */
00463     const oid internet_oid(dod_oid,"1");
00464 
00465     /**
00466      * \memberof oid
00467      *
00468      * \brief The 'iso.org.dod.internet.directory' OID according to RFC 1155.
00469      */
00470     const oid directory_oid(internet_oid,"1");
00471 
00472     /**
00473      * \memberof oid
00474      *
00475      * \brief The 'iso.org.dod.internet.mgmt' OID according to RFC 1155.
00476      */
00477     const oid mgmt_oid(internet_oid,"2");
00478 
00479     /**
00480      * \memberof oid
00481      *
00482      * \brief The 'iso.org.dod.internet.experimental' OID according to
00483      *        RFC 1155.
00484      */
00485     const oid experimental_oid(internet_oid,"3");
00486 
00487     /**
00488      * \memberof oid
00489      *
00490      * \brief The 'iso.org.dod.internet.private' OID according to RFC 1155.
00491      */
00492     const oid private_oid(internet_oid,"4");
00493 
00494     /**
00495      * \memberof oid
00496      *
00497      * \brief The 'iso.org.dod.internet.private.enterprises' OID according to
00498      *        RFC 1155.
00499      */
00500     const oid enterprises_oid(private_oid, "1");
00501 }
00502 
00503 
00504 #endif