gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

pipmsg.cxx (3790B)


      1 /*
      2  *
      3  *  C++ Portable Types Library (PTypes)
      4  *  Version 2.1.1  Released 27-Jun-2007
      5  *
      6  *  Copyright (C) 2001-2007 Hovik Melikyan
      7  *
      8  *  http://www.melikyan.com/ptypes/
      9  *
     10  */
     11 
     12 #ifdef WIN32
     13 #  include <winsock2.h>
     14 #else
     15 #  include <sys/time.h>
     16 #  include <sys/types.h>
     17 #  include <sys/socket.h>
     18 #  include <netinet/in.h>
     19 #  include <arpa/inet.h>
     20 #  include <netdb.h>
     21 #  include <unistd.h>
     22 #  include <time.h>
     23 #endif
     24 
     25 
     26 #include "pinet.h"
     27 
     28 
     29 namespace ptypes {
     30 
     31 
     32 //
     33 // ipmessage: IPv4 UDP message class
     34 //
     35 
     36 
     37 ipmessage::ipmessage()
     38     : unknown(), ippeerinfo(ipnone, nullstring, 0), handle(invhandle)  {}
     39 
     40 
     41 ipmessage::ipmessage(ipaddress iip, int iport)
     42     : unknown(), ippeerinfo(iip, nullstring, iport), handle(invhandle)  {}
     43 
     44 
     45 ipmessage::ipmessage(const char* ihost, int iport)
     46     : unknown(), ippeerinfo(ipnone, ihost, iport), handle(invhandle)  {}
     47 
     48 
     49 ipmessage::ipmessage(const string& ihost, int iport)
     50     : unknown(), ippeerinfo(ipnone, ihost, iport), handle(invhandle)  {}
     51 
     52 
     53 ipmessage::~ipmessage()
     54 {
     55     close();
     56 }
     57 
     58 
     59 void ipmessage::set_ip(ipaddress iip)
     60 {
     61     ip = iip;
     62     ptypes::clear(host);
     63 }
     64 
     65 
     66 void ipmessage::set_host(const string& ihost)
     67 {
     68     host = ihost;
     69     ip = 0;
     70 }
     71 
     72 
     73 void ipmessage::set_host(const char* ihost)
     74 {
     75     host = ihost;
     76     ip = 0;
     77 }
     78 
     79 
     80 void ipmessage::set_port(int iport)
     81 {
     82     port = iport;
     83 }
     84 
     85 
     86 ipaddress ipmessage::get_myip()
     87 {
     88     ippeerinfo p;
     89     if (!psockname(handle, p))
     90         error(usockerrno(), "Couldn't get my IP");
     91     return p.get_ip();
     92 }
     93 
     94 
     95 int ipmessage::get_myport()
     96 {
     97     ippeerinfo p;
     98     if (!psockname(handle, p))
     99         error(usockerrno(), "Couldn't get my port number");
    100     return p.get_port();
    101 }
    102 
    103 
    104 void ipmessage::close()
    105 {
    106     if (handle != invhandle)
    107         ::closesocket(pexchange(&handle, invhandle));
    108 }
    109 
    110 
    111 void ipmessage::open()
    112 {
    113     close();
    114     if ((handle = ::socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    115         error(usockerrno(), "Couldn't create socket");
    116     // allow broadcasts
    117     int one = 1;
    118     if (::setsockopt(handle, SOL_SOCKET, SO_BROADCAST, (sockval_t)&one, sizeof(one)) != 0)
    119         error(usockerrno(), "Couldn't enable broadcasts");
    120     sockopt(handle);
    121 }
    122 
    123 
    124 void ipmessage::sockopt(int)
    125 {
    126 }
    127 
    128 
    129 bool ipmessage::waitfor(int timeout)
    130 {
    131     return psockwait(handle, timeout);
    132 }
    133 
    134 
    135 void ipmessage::send(const char* buf, int count)
    136 {
    137     if (handle == invhandle)
    138         open();
    139 
    140     sockaddr_in sa;
    141     memset(&sa, 0, sizeof(sa));
    142     sa.sin_family = AF_INET;
    143     sa.sin_port = htons(ushort(get_port()));
    144     sa.sin_addr.s_addr = get_ip();
    145     if (sendto(handle, buf, count, 0, (sockaddr*)&sa, sizeof(sa)) < 0)
    146         error(usockerrno(), "Couldn't write");
    147 }
    148 
    149 
    150 int ipmessage::receive(char* buf, int count, ipaddress& src)
    151 {
    152     if (handle == invhandle)
    153         error(EINVAL, "Couldn't read");  // must send() first
    154 
    155     sockaddr_in sa;
    156     psocklen fromlen = sizeof(sa);
    157     int result = ::recvfrom(handle, buf, count, 0, (sockaddr*)&sa, &fromlen);
    158     if (result < 0)
    159         error(usockerrno(), "Couldn't read");
    160     src = sa.sin_addr.s_addr;
    161     return result;
    162 }
    163 
    164 
    165 int ipmessage::receive(char* buf, int count)
    166 {
    167     ipaddress src;
    168     return receive(buf, count, src);
    169 }
    170 
    171 
    172 string ipmessage::receive(int max, ipaddress& src)
    173 {
    174     string result;
    175     setlength(result, max);
    176     int numread = receive(pchar(pconst(result)), max, src);
    177     setlength(result, numread);
    178     return result;
    179 }
    180 
    181 
    182 string ipmessage::receive(int max)
    183 {
    184     ipaddress src;
    185     return receive(max, src);
    186 }
    187 
    188 
    189 #ifdef _MSC_VER
    190 // disable "unreachable code" warning for throw (known compiler bug)
    191 #  pragma warning (disable: 4702)
    192 #endif
    193 
    194 void ipmessage::error(int code, const char* msg)
    195 {
    196     string s = usockerrmsg(code);
    197     if (isempty(s))
    198         s = msg;
    199     throw new estream(nil, code, s + " [" + ippeerinfo::asstring(true) + ']');
    200 }
    201 
    202 
    203 }