Skip to content
Snippets Groups Projects
Commit 00f8b449 authored by g0dil's avatar g0dil
Browse files

Socket/Protocols/Raw: Add EUI64 data type

parent 80f927b9
No related branches found
No related tags found
No related merge requests found
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EUI64 non-inline non-template implementation */
#include "EUI64.hh"
//#include "EUI64.ih"
// Custom includes
#include <boost/io/ios_state.hpp>
#include <iomanip>
#include "ParseString.hh"
//#include "EUI64.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::EUI64 senf::EUI64::from_string(std::string const & s)
{
EUI64 eui (senf::noinit);
detail::parseHexString(s, ":-", eui.begin(), eui.end());
return eui;
}
prefix_ std::ostream & senf::operator<<(std::ostream & os, EUI64 const & eui)
{
boost::io::ios_all_saver ias(os);
os << std::hex << std::setfill('0')
<< std::setw(2) << unsigned(eui[0]) << ":"
<< std::setw(2) << unsigned(eui[1]) << ":"
<< std::setw(2) << unsigned(eui[2]) << ":"
<< std::setw(2) << unsigned(eui[3]) << "-"
<< std::setw(2) << unsigned(eui[4]) << ":"
<< std::setw(2) << unsigned(eui[5]) << ":"
<< std::setw(2) << unsigned(eui[6]) << ":"
<< std::setw(2) << unsigned(eui[7]);
return os;
}
prefix_ std::istream & senf::operator>>(std::istream & is, EUI64 & eui)
{
std::string s;
if (!(is >> s))
return is;
try {
eui = EUI64::from_string(s);
}
catch (AddressException &) {
is.setstate(std::ios::failbit);
}
return is;
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "EUI64.mpp"
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EUI64 inline non-template implementation */
//#include "EUI64.ih"
// Custom includes
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include "MACAddress.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
prefix_ senf::EUI64::EUI64(boost::uint64_t v)
{
(*this)[0] = (v>>56) & 0xffu;
(*this)[1] = (v>>48) & 0xffu;
(*this)[2] = (v>>40) & 0xffu;
(*this)[3] = (v>>32) & 0xffu;
(*this)[4] = (v>>24) & 0xffu;
(*this)[5] = (v>>16) & 0xffu;
(*this)[6] = (v>> 8) & 0xffu;
(*this)[7] = (v ) & 0xffu;
}
prefix_ senf::EUI64::EUI64(senf::NoInit_t)
{}
prefix_ senf::EUI64 senf::EUI64::from_mac(MACAddress const & mac)
{
EUI64 eui (senf::noinit);
eui[0] = mac[0];
eui[1] = mac[1];
eui[2] = mac[2];
eui[3] = 0xffu;
eui[4] = 0xfeu;
eui[5] = mac[3];
eui[6] = mac[4];
eui[7] = mac[5];
return eui;
}
prefix_ bool senf::EUI64::isMACCompatible()
const
{
return (*this)[3] == 0xffu && (*this)[4] == 0xfeu;
}
prefix_ bool senf::EUI64::boolean_test()
const
{
using boost::lambda::_1;
return std::find_if(begin(),end(), _1 != 0x00u) != end();
}
prefix_ boost::uint64_t senf::EUI64::uint64()
const
{
return (boost::uint64_t((*this)[0])<<56)
| (boost::uint64_t((*this)[1])<<48)
| (boost::uint64_t((*this)[2])<<40)
| (boost::uint64_t((*this)[3])<<32)
| (boost::uint64_t((*this)[4])<<24)
| (boost::uint64_t((*this)[5])<<16)
| (boost::uint64_t((*this)[6])<< 8)
| (boost::uint64_t((*this)[7]) );
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EUI64 inline template implementation */
//#include "EUI64.ih"
// Custom includes
#include "../../../config.hh"
#define prefix_ inline
///////////////////////////////cti.p///////////////////////////////////////
template <class InputIterator>
prefix_ senf::EUI64 senf::EUI64::from_data(InputIterator i)
{
EUI64 eui (senf::noinit);
SENF_copy_n(i, 8, eui.begin());
return eui;
}
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EUI64 public header */
#ifndef HH_SENF_Socket_Protocols_Raw_EUI64_
#define HH_SENF_Socket_Protocols_Raw_EUI64_ 1
// Custom includes
#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/array.hpp>
#include "../../../Utils/Tags.hh"
#include "../../../Utils/safe_bool.hh"
//#include "EUI64.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
class MACAddress;
/** \brief EUI-64 data type
An EUI-64 is a 64 bit (8 octet) id.
*/
class EUI64
: public boost::array<boost::uint8_t,8>,
public senf::comparable_safe_bool<EUI64>
{
public:
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
// default copy constructor
// default copy assignment
// default destructor
// no conversion constructors
explicit EUI64(boost::uint64_t v=0u);
explicit EUI64(senf::NoInit_t);
static EUI64 from_mac(MACAddress const & mac);
static EUI64 from_string(std::string const & s);
template <class InputIterator>
static EUI64 from_data(InputIterator i);
///@}
///////////////////////////////////////////////////////////////////////////
bool isMACCompatible() const;
bool boolean_test() const;
boost::uint64_t uint64() const;
};
std::ostream & operator<<(std::ostream & os, EUI64 const & v);
std::istream & operator>>(std::istream & is, EUI64 & v);
}
///////////////////////////////hh.e////////////////////////////////////////
#include "EUI64.cci"
//#include "EUI64.ct"
#include "EUI64.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EUI64.test unit tests */
//#include "EUI64.test.hh"
//#include "EUI64.test.ih"
// Custom includes
#include "EUI64.hh"
#include "../../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
BOOST_AUTO_UNIT_TEST(eui64)
{
senf::EUI64 eui;
BOOST_CHECK( !eui );
BOOST_CHECK( !eui.isMACCompatible() );
eui = senf::EUI64::from_mac(senf::MACAddress(0x102030405060ull));
boost::uint8_t data[] = { 0x10u, 0x20u, 0x30u, 0xffu, 0xfeu, 0x40u, 0x50u, 0x60u };
BOOST_CHECK_EQUAL_COLLECTIONS( eui.begin(), eui.end(), data, data+sizeof(data)/sizeof(data[0]) );
BOOST_CHECK( eui );
BOOST_CHECK( eui.isMACCompatible() );
BOOST_CHECK_EQUAL( eui.uint64(), 0x102030fffe405060ull );
BOOST_CHECK_EQUAL( eui, senf::EUI64::from_data(data) );
BOOST_CHECK_EQUAL( eui, senf::EUI64::from_string("10:20:30:ff-FE:40:50:60") );
BOOST_CHECK_THROW( senf::EUI64::from_string("123:20:30:40:50:60:70:80"),
senf::AddressSyntaxException );
BOOST_CHECK_THROW( senf::EUI64::from_string("12:20:30:40:50:60:70"),
senf::AddressSyntaxException );
BOOST_CHECK_THROW( senf::EUI64::from_string("12:20:30:40:50:60:70:8g"),
senf::AddressSyntaxException );
BOOST_CHECK_THROW( senf::EUI64::from_string("12:20:30:40:50:60:70:80:90"),
senf::AddressSyntaxException );
{
std::stringstream ss;
ss << std::uppercase << eui;
BOOST_CHECK_EQUAL( ss.str(), "10:20:30:FF-FE:40:50:60" );
eui = senf::EUI64();
BOOST_CHECK( !eui );
ss >> eui;
BOOST_CHECK_EQUAL( eui, senf::EUI64(0x102030fffe405060ull) );
BOOST_CHECK( (ss >> eui).fail() );
}
{
std::stringstream ss;
ss << "01:02:03:04-05:06:07:108";
BOOST_CHECK( (ss >> eui).fail() );
}
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
...@@ -30,63 +30,20 @@ ...@@ -30,63 +30,20 @@
#include <iomanip> #include <iomanip>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <boost/tokenizer.hpp>
#include <boost/io/ios_state.hpp> #include <boost/io/ios_state.hpp>
#include <boost/range.hpp> #include "ParseString.hh"
//#include "MACAddress.mpp" //#include "MACAddress.mpp"
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
namespace {
boost::uint8_t hexToNibble(char c)
{
if (c<'0')
throw senf::AddressSyntaxException();
else if (c<='9')
return c-'0';
else if (c<'A')
throw senf::AddressSyntaxException();
else if (c<='F')
return c-'A'+10;
else if (c<'a')
throw senf::AddressSyntaxException();
else if (c<='f')
return c-'a'+10;
else
throw senf::AddressSyntaxException();
}
template <class Range>
boost::uint8_t hexToByte(Range const & range)
{
if (boost::size(range) != 2)
throw senf::AddressSyntaxException();
typename boost::range_const_iterator<Range>::type i (boost::begin(range));
return hexToNibble(i[0])*16+hexToNibble(i[1]);
}
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::MACAddress // senf::MACAddress
prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string const & s) prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string const & s)
{ {
MACAddress mac (senf::noinit); MACAddress mac (senf::noinit);
typedef boost::char_separator<char> separator; detail::parseHexString(s, ":-", mac.begin(), mac.end());
typedef boost::tokenizer<separator> tokenizer;
separator sep (":-");
tokenizer tok (s,sep);
tokenizer::iterator i (tok.begin());
tokenizer::iterator const i_end (tok.end());
iterator j (mac.begin());
iterator const j_end (mac.end());
for (; i!=i_end && j!=j_end; ++i, ++j)
*j = hexToByte(*i);
if (i!=i_end || j!=j_end)
throw AddressSyntaxException();
return mac; return mac;
} }
...@@ -113,7 +70,7 @@ senf::MACAddress const senf::MACAddress::None; ...@@ -113,7 +70,7 @@ senf::MACAddress const senf::MACAddress::None;
prefix_ std::ostream & senf::operator<<(std::ostream & os, MACAddress const & mac) prefix_ std::ostream & senf::operator<<(std::ostream & os, MACAddress const & mac)
{ {
boost::io::ios_all_saver ias(os); boost::io::ios_all_saver ias (os);
os << std::hex << std::setfill('0'); os << std::hex << std::setfill('0');
for (MACAddress::const_iterator i (mac.begin()); i != mac.end(); ++i) { for (MACAddress::const_iterator i (mac.begin()); i != mac.end(); ++i) {
if (i != mac.begin()) if (i != mac.begin())
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
//#include "MACAddress.ih" //#include "MACAddress.ih"
// Custom includes // Custom includes
#include "../../../config.hh"
#define prefix_ #define prefix_
///////////////////////////////ct.p//////////////////////////////////////// ///////////////////////////////ct.p////////////////////////////////////////
...@@ -37,10 +38,7 @@ template <class InputIterator> ...@@ -37,10 +38,7 @@ template <class InputIterator>
prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_data(InputIterator i) prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_data(InputIterator i)
{ {
MACAddress mac (senf::noinit); MACAddress mac (senf::noinit);
iterator j (mac.begin()); SENF_copy_n(i, 6, mac.begin());
iterator const j_end (mac.end());
for (;j!=j_end;++j,++i)
*j = *i;
return mac; return mac;
} }
......
...@@ -60,14 +60,14 @@ BOOST_AUTO_UNIT_TEST(macAddress) ...@@ -60,14 +60,14 @@ BOOST_AUTO_UNIT_TEST(macAddress)
{ {
std::stringstream str ( "invalid_mac_address"); std::stringstream str ( "invalid_mac_address");
str >> mac; str >> mac;
BOOST_CHECK( str.fail()); BOOST_CHECK( str.fail() );
} }
{ {
std::stringstream str; std::stringstream str;
str << mac; str << mac;
BOOST_CHECK_EQUAL( str.str(), "a1:b2:c3:d4:e5:f6" ); BOOST_CHECK_EQUAL( str.str(), "a1:b2:c3:d4:e5:f6" );
str >> mac; str >> mac;
BOOST_CHECK( ! str.fail()); BOOST_CHECK( ! str.fail() );
} }
BOOST_CHECK_EQUAL(mac, MACAddress::from_string(test)); BOOST_CHECK_EQUAL(mac, MACAddress::from_string(test));
...@@ -92,7 +92,7 @@ BOOST_AUTO_UNIT_TEST(macAddress) ...@@ -92,7 +92,7 @@ BOOST_AUTO_UNIT_TEST(macAddress)
BOOST_CHECK( mac == mac2 ); BOOST_CHECK( mac == mac2 );
BOOST_CHECK_EQUAL( senf::str(mac2), "a1:b2:c3:d4:e5:f6" ); BOOST_CHECK_EQUAL( senf::str(mac2), "a1:b2:c3:d4:e5:f6" );
BOOST_CHECK_THROW( MACAddress::from_string("1:2:3:4:5:6"), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_string("123:2:3:4:5:6"), AddressSyntaxException );
BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05"), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05"), AddressSyntaxException );
// test all invalid ascii ranges // test all invalid ascii ranges
BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:z6"), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:z6"), AddressSyntaxException );
......
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief ParseString non-inline template implementation */
//#include "ParseString.ih"
// Custom includes
#include <boost/tokenizer.hpp>
#include <boost/range.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include "../../../Utils/String.hh"
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
template <class ForwardIterator>
prefix_ void senf::detail::parseHexString(std::string const & value,
char const * separator, ForwardIterator f,
ForwardIterator l)
{
typedef boost::char_separator<char> Separator;
typedef boost::tokenizer<Separator> Tokenizer;
Separator sep (separator);
Tokenizer tok (value, sep);
Tokenizer::iterator i (tok.begin());
Tokenizer::iterator const i_end (tok.end());
try {
for (; i!=i_end && f!=l; ++i, ++f)
*f = boost::numeric_cast<typename std::iterator_traits<ForwardIterator>::value_type>(
senf::lexical_cast<unsigned long>()[std::hex](
std::string(boost::begin(*i),boost::end(*i))));
}
catch (std::bad_cast &) {
throw AddressSyntaxException();
}
if (i!=i_end || f!=l)
throw AddressSyntaxException();
}
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief ParseString public header */
#ifndef HH_SENF_Socket_Protocols_Raw_ParseString_
#define HH_SENF_Socket_Protocols_Raw_ParseString_ 1
// Custom includes
//#include "ParseString.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace detail {
template <class ForwardIterator>
void parseHexString(std::string const & value, char const * separator,
ForwardIterator f, ForwardIterator l);
}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "ParseString.cci"
#include "ParseString.ct"
//#include "ParseString.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment