class Sys::Socket {
  use Fn;
  use Sys;
  use Sys::IO;
  use Sys::Socket::Constant;
  use Sys::Socket::Addrinfo;
  use Sys::Socket::AddrinfoLinkedList;
  use Sys::Socket::Sockaddr;
  use Sys::Socket::In_addr;
  use Sys::Socket::In6_addr;
  
  use Sys::Socket::Error::InetInvalidNetworkAddress;

  native static method htonl : int ($hostlong : int);
  
  native static method htons : short ($hostshort : short);

  native static method ntohl : int ($netlong : int);
  
  native static method ntohs : short ($netshort : short);

  native static method inet_aton : int ($cp : string, $inp : Sys::Socket::In_addr);

  native static method inet_ntoa : string ($in : Sys::Socket::In_addr);

  native static method inet_pton : int ($af : int, $src : string, $dst : object of Sys::Socket::In_addr|Sys::Socket::In6_addr);
  
  native static method inet_ntop : mutable string ($af : int, $src : object of Sys::Socket::In_addr|Sys::Socket::In6_addr, $dst : mutable string, $size : int);
  
  native static method socket : int ($domain : int, $type : int, $protocol : int);

  native static method connect_raw : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen : int);
  
  native static method connect : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen : int);

  native static method bind : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen : int);
                 
  native static method accept : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen_ref : int*);

  native static method listen : int ($sockfd : int, $backlog : int);

  native static method shutdown : int ($sockfd : int, $how : int);

  native static method recv : int ($sockfd : int, $buf : mutable string, $len : int, $flags : int, $buf_offset = 0 : int);

  native static method send : int ($sockfd : int, $buf : string, $len : int, $flags : int, $buf_offset = 0 : int);

  native static method getpeername : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen_ref : int*);

  native static method getsockname : int ($sockfd : int, $addr : Sys::Socket::Sockaddr, $addrlen_ref : int*);

  native static method socketpair : int ($domain : int, $type : int, $protocol : int, $pair : int[]);

  native static method setsockopt : int ($sockfd : int, $level : int, $optname : int, $optval : string, $optlen : int);

  native static method setsockopt_int : int ($sockfd : int, $level : int, $optname : int, $optval : int);

  native static method getsockopt : int ($sockfd : int, $level : int, $optname : int, $optval : mutable string, $optlen_ref : int*);

  native static method getsockopt_int : int ($sockfd : int, $level : int, $optname : int, $optval_ref : int*);
  
  native static method getaddrinfo_raw : int ($node : string, $service : string,
                $hints : Sys::Socket::Addrinfo,
                $res : Sys::Socket::AddrinfoLinkedList[]);

  native static method getaddrinfo : int ($node : string, $service : string,
                $hints : Sys::Socket::Addrinfo,
                $res : Sys::Socket::AddrinfoLinkedList[]);

  native static method getnameinfo_raw : int ($sa : Sys::Socket::Sockaddr, $salen : int,
                $host : mutable string, $hostlen : int,
                $serv : mutable string, $servlen : int, $flags : int);
                
  native static method getnameinfo : int ($sa : Sys::Socket::Sockaddr, $salen : int,
                $host : mutable string, $hostlen : int,
                $serv : mutable string, $servlen : int, $flags : int);

  native static method gai_strerror : string ($errcode : int);

  native static method close : int ($fd : int);

  native static method socket_errno : int ();
  native static method socket_strerror : string ($errno : int, $length : int);

  native static method sockatmark : int ($sockfd : int);

  native static method sendto : int ($sockfd : int, $buf : string, $len : int, $flags : int, $addr : Sys::Socket::Sockaddr, $addrlen : int);
}