1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-28 12:44:25 +01:00

Added PDU::rfind_pdu.

This commit is contained in:
Matias Fontanini
2013-04-19 22:27:48 -03:00
parent 91bdcca577
commit 2ea952d6ab
8 changed files with 83 additions and 22 deletions

View File

@@ -30,12 +30,27 @@
#ifndef TINS_CXXSTD_H
#define TINS_CXXSTD_H
#include <memory>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#define TINS_CXXSTD_GCC_FIX 1
#else
#define TINS_CXXSTD_GCC_FIX 0
#endif // __GXX_EXPERIMENTAL_CXX0X__
namespace Tins{
namespace Internals {
template<typename T>
struct smart_ptr {
#if TINS_IS_CXX11
typedef std::unique_ptr<T> type;
#else
typedef std::auto_ptr<T> type;
#endif
};
}
}
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
#endif // TINS_CXXSTD_H

View File

@@ -48,7 +48,7 @@ public:
};
/**
* \brief Exception thrown when an option is not found.
* \brief Exception thrown when a malformed packet is parsed.
*/
class malformed_packet : public std::runtime_error {
public:
@@ -56,7 +56,20 @@ public:
: std::runtime_error(std::string()) { }
const char* what() const throw() {
return "Option not found";
return "Malformed packet";
}
};
/**
* \brief Exception thrown when a PDU is not found when using PDU::rfind_pdu.
*/
class pdu_not_found : public std::runtime_error {
public:
pdu_not_found()
: std::runtime_error(std::string()) { }
const char* what() const throw() {
return "PDU not found";
}
};
}

View File

@@ -35,6 +35,7 @@
#include <vector>
#include "macros.h"
#include "cxxstd.h"
#include "exceptions.h"
/** \brief The Tins namespace.
*/
@@ -220,14 +221,14 @@ namespace Tins {
serialization_type serialize();
/**
* \brief Find and returns the first PDU that matches the given flag.
* \brief Finds and returns the first PDU that matches the given flag.
*
* This method searches for the first PDU which has the same type flag as
* the given one. If the first PDU matches that flag, it is returned.
* If no PDU matches, 0 is returned.
* \param flag The flag which being searched.
*/
template<class T>
template<typename T>
T *find_pdu(PDUType type = T::pdu_flag) {
PDU *pdu = this;
while(pdu) {
@@ -239,15 +240,42 @@ namespace Tins {
}
/**
* \brief Find and returns the first PDU that matches the given flag.
* \brief Finds and returns the first PDU that matches the given flag.
*
* \param flag The flag which being searched.
*/
template<class T>
template<typename T>
const T *find_pdu(PDUType type = T::pdu_flag) const {
return const_cast<PDU*>(this)->find_pdu<T>();
}
/**
* \brief Finds and returns the first PDU that matches the given flag.
*
* If the PDU is not found, a pdu_not_found exception is thrown.
*
* \sa PDU::find_pdu
*
* \param flag The flag which being searched.
*/
template<typename T>
T &rfind_pdu(PDUType type = T::pdu_flag) {
T *ptr = find_pdu<T>(type);
if(!ptr)
throw pdu_not_found();
return *ptr;
}
/**
* \brief Finds and returns the first PDU that matches the given flag.
*
* \param flag The flag which being searched.
*/
template<typename T>
const T &rfind_pdu(PDUType type = T::pdu_flag) const {
return const_cast<PDU*>(this)->rfind_pdu<T>();
}
/**
* \brief Clones this packet.
*

View File

@@ -272,7 +272,7 @@ namespace Tins {
bool ret_val(false);
LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args);
try {
std::auto_ptr<PDU> pdu;
Internals::smart_ptr<PDU>::type pdu;
if(data->iface_type == DLT_EN10MB)
ret_val = call_functor<Tins::EthernetII>(data, packet, header);
else if(data->iface_type == DLT_IEEE802_11_RADIO)