#pragma once #include #include #include #include #include #include namespace Aftr { //These methods were originally written to parse GenICam GigE compliant messages where the //primitives are bools, int64s, doubles, and std::strings. So this converts 48 bit mac //address and IP Address into handy formats for displaying, converting, and resending. //For example usage, see AftrUtil_net_test.cpp at: //"...\aburn\engine\src\aftr\gtest\AftrUtil_net_test.cpp" //---------------- BEGIN MAC Address methods //Output will look like A8-5E-45-E1-8F-16 (each octet will be two hex digits like 04-5E-45-E1-00-01 std::string toStringMACAddr( std::int64_t mac48bit ); //only considers lower 48 bits std::string toStringMACAddr( std::array< std::byte, 6 > const& mac48bit ); //Valid sample inputs: //A8-5E-45-E1-8F-16 (upper or lower case) //A8:5E:45:E1:8F:16 //A85E45E18F16 //0xA85E45E18F16 std::optional< std::array< std::byte, 6 > > fromStringMACAddr_toBytes( std::string const& macAddr ); std::optional fromStringMACAddr_toI64( std::string const& macAddr ); std::array< std::byte, 6 > toBytes_fromI64_MACAddr( std::int64_t bits ); //Places the data in the lower 48 bits of the 64 bit integer std::int64_t toI64_MACAddr_fromBytes( std::array const& bytes ); //---------------- END MAC Address methods //---------------- BEGIN IPv4 Address methods //IP Address functions std::string toStringIPv4Addr( std::int64_t ip32bits ); //only considers lower 32 bits if int64 std::string toStringIPv4Addr( std::array< std::byte, 4 > const& ip32bits ); std::optional< std::array< std::byte, 4 > > fromStringIPv4Addr_toBytes( std::string const& IPv4Addr ); std::optional< std::int64_t> fromStringIPv4Addr_toI64( std::string const& IPv4Addr ); std::array< std::byte, 4 > toBytes_fromI64_IPv4Addr( std::int64_t octets ); std::int64_t toI64_IPv4Addr_fromBytes( std::array const& bytes ); //---------------- END IPv4 Address methods struct IP_PORT_sv { std::string_view ip; //"127.0.0.1" std::string_view port; //"12683" }; ///Parses "127.0.0.1:12683 to a string view where ip="127.0.0.1" and port="12683". *NO* allocation /// is performed - returns string_views refer into the in passed const ref string std::optional< IP_PORT_sv > parse_IP_PORT( std::string const& ip_port_colon_separated ); //Endian Conversions for host to network and network to host. Based on boost's implemenation, but //extended to support 64-bit values and beyond. //#include //To CONVERT endian-ness from NETWORK to your CPU, do this: // Networks always send data in BIG ENDIAN. Native endian depends on your local CPU. //int64_t val = boost::endian::big_to_native( int64_t fromNetwork_int64_t ); //To CONVERT endian-ness from your CPU to NETWORK, do this: // Networks always send data in BIG ENDIAN. Native endian depends on your local CPU. //int64_t val_big_endian_forNetwork = boost::endian::native_to_big( int64_t local_cpu_64_bit_int ); //These method avoid strict type aliasing and are standards compliant (compared to type punning implementations) template< std::floating_point F > //for float or double F native_to_big( F native_endian_val ); /// converts val from native (local CPU) to big endian (for sending out on the network) template< std::floating_point F > //for float or double F big_to_native( F big_endian_val ); /// converts val from big endian (from a network) to native (local CPU) (such as little endian on Intel x86 / AMD x64) template< std::integral T > //for char, short, int, long, etc (all integral types) T native_to_big( T native_endian_val ); /// converts val from native (local CPU) to big endian (for sending out on the network) template< std::integral T > //for char, short, int, long, etc (all integral types) T big_to_native( T big_endian_val ); /// converts val from big endian (from a network) to native (local CPU) (such as little endian on Intel x86 / AMD x64) } //namespace Aftr