#ifndef __JDB__JUPI_T__ #define __JDB__JUPI_T__ #include #include #include #include #include #include #include "JDB/JPBS_t.hh" /** * \author mdejong */ namespace JDATABASE {} namespace JPP { using namespace JDATABASE; } namespace JDATABASE { /** * Universal product identifier (%UPI). * * The %UPI consists of a %PBS, variant, version and serial number.\n * The corresponding ASCII format reads \"\[.\]*/\/\.\\".\n * The version and serial number are not subject to I/O in case their value is default. */ struct JUPI_t : public JPBS_t { /** * Separator between %PBS, variant and version. */ static const char SEPARATOR = '/'; static const int DEFAULT_VERSION = -1; //!< Default version static const int DEFAULT_NUMBER = -1; //!< Default number /** * Default constructor. */ JUPI_t() : JPBS_t (), variant(), version(DEFAULT_VERSION), number (DEFAULT_NUMBER) {} /** * Constructor. * * \param pbs %PBS */ JUPI_t(const JPBS_t& pbs) : JPBS_t (pbs), variant(), version(DEFAULT_VERSION), number (DEFAULT_NUMBER) {} /** * Constructor. * * \param pbs %PBS * \param variant variant * \param version version * \param number serial number */ JUPI_t(const JPBS_t& pbs, const std::string& variant, const int version, const int number) : JPBS_t (pbs), variant(variant), version(version), number (number) {} /** * Constructor. * * \param upi %UPI */ JUPI_t(const std::string& upi) { std::istringstream(upi) >> *this; } /** * Get %UPI. * * \return %UPI */ const JUPI_t& getUPI() const { return static_cast(*this); } /** * Get variant. * * \return variant */ const std::string& getVariant() const { return variant; } /** * Get version. * * \return version */ int getVersion() const { return version; } /** * Get serial number. * * \return serial number */ int getNumber() const { return number; } /** * Convert %UPI. * * \return %UPI */ std::string toString() const { std::ostringstream os; os << *this; return os.str(); } /** * Equality. * * \param first first %UPI * \param second second %UPI * \return true if %UPIs are equals; else false */ friend inline bool operator==(const JUPI_t& first, const JUPI_t& second) { return (first.getPBS() == second.getPBS() && first.getVariant() == second.getVariant() && first.getVersion() == second.getVersion() && first.getNumber() == second.getNumber()); } /** * Less-than operator. * * \param first first %UPI * \param second second %UPI * \return true if first %UPI less than second %UPI; else false */ friend inline bool operator<(const JUPI_t& first, const JUPI_t& second) { if (first.getPBS() == second.getPBS()) { if (first.getVariant() == second.getVariant()) { if (first.getVersion() == second.getVersion()) return first.getNumber() < second.getNumber(); else return first.getVersion() < second.getVersion(); } else { return first.getVariant() < second.getVariant(); } } else { return first.getPBS() < second.getPBS(); } } /** * Read %UPI from input stream. * * \param in input stream * \param object %UPI * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JUPI_t& object) { using namespace std; object = JUPI_t(); if (in.peek() != (int) SEPARATOR) { in >> static_cast(object); } if (in.get() == (int) SEPARATOR) { if (in.peek() == (int) SEPARATOR) in.ignore(); else getline(in, object.variant, SEPARATOR); if (in.peek() == (int) DOT) { in.ignore(); object.version = DEFAULT_VERSION; object.number = DEFAULT_NUMBER; return in; } else if (in >> object.version && in.get() == (int) DOT && in >> object.number) { return in; } } in.setstate(ios::failbit); return in; } /** * Write %UPI to output stream. * * \param out output stream * \param object %UPI * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JUPI_t& object) { using namespace std; ostringstream os; // allow for width formatting os << object.getPBS() << JUPI_t::SEPARATOR << object.getVariant() << JUPI_t::SEPARATOR; if (object.getVersion() != DEFAULT_VERSION) { os << object.getVersion(); } os << JUPI_t::DOT; if (object.getNumber() != DEFAULT_NUMBER) { os << object.getNumber(); } return out << os.str(); } ClassDefNV(JUPI_t, 1); protected: std::string variant; int version; int number; }; } #endif