// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GIOMM_SOCKET_H
#define _GIOMM_SOCKET_H


#include <glibmm.h>

// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-

/* Copyright (C) 2009 Jonathon Jongsma
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <glibmm/object.h>
#include <giomm/initable.h>
#include <giomm/socketconnectable.h>
#include <giomm/socketaddress.h>
#include <giomm/enums.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GSocket GSocket;
typedef struct _GSocketClass GSocketClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gio
{ class Socket_Class; } // namespace Gio
namespace Gio
{

/** @addtogroup giommEnums Enums and Flags */

/**
 * @ingroup giommEnums
 */
enum SocketType
{
  SOCKET_TYPE_INVALID,
  SOCKET_TYPE_STREAM,
  SOCKET_TYPE_DATAGRAM,
  SOCKET_TYPE_SEQPACKET
};

} // namespace Gio


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gio::SocketType> : public Glib::Value_Enum<Gio::SocketType>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gio
{

/**
 * @ingroup giommEnums
 */
enum SocketProtocol
{
  SOCKET_PROTOCOL_UNKNOWN = -1,
  SOCKET_PROTOCOL_DEFAULT = 0,
  SOCKET_PROTOCOL_TCP = 6,
  SOCKET_PROTOCOL_UDP = 17,
  SOCKET_PROTOCOL_SCTP = 132
};

} // namespace Gio


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gio::SocketProtocol> : public Glib::Value_Enum<Gio::SocketProtocol>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gio
{

/**
 * @ingroup giommEnums
 * @par Bitwise operators:
 * <tt>%SocketMsgFlags operator|(SocketMsgFlags, SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags operator&(SocketMsgFlags, SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags operator^(SocketMsgFlags, SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags operator~(SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags& operator|=(SocketMsgFlags&, SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags& operator&=(SocketMsgFlags&, SocketMsgFlags)</tt><br>
 * <tt>%SocketMsgFlags& operator^=(SocketMsgFlags&, SocketMsgFlags)</tt><br>
 */
enum SocketMsgFlags
{
  SOCKET_MSG_NONE = 0x0,
  SOCKET_MSG_OOB = GLIB_SYSDEF_MSG_OOB,
  SOCKET_MSG_PEEK = GLIB_SYSDEF_MSG_PEEK,
  SOCKET_MSG_DONTROUTE = GLIB_SYSDEF_MSG_DONTROUTE
};

/** @ingroup giommEnums */
inline SocketMsgFlags operator|(SocketMsgFlags lhs, SocketMsgFlags rhs)
  { return static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }

/** @ingroup giommEnums */
inline SocketMsgFlags operator&(SocketMsgFlags lhs, SocketMsgFlags rhs)
  { return static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }

/** @ingroup giommEnums */
inline SocketMsgFlags operator^(SocketMsgFlags lhs, SocketMsgFlags rhs)
  { return static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }

/** @ingroup giommEnums */
inline SocketMsgFlags operator~(SocketMsgFlags flags)
  { return static_cast<SocketMsgFlags>(~static_cast<unsigned>(flags)); }

/** @ingroup giommEnums */
inline SocketMsgFlags& operator|=(SocketMsgFlags& lhs, SocketMsgFlags rhs)
  { return (lhs = static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }

/** @ingroup giommEnums */
inline SocketMsgFlags& operator&=(SocketMsgFlags& lhs, SocketMsgFlags rhs)
  { return (lhs = static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }

/** @ingroup giommEnums */
inline SocketMsgFlags& operator^=(SocketMsgFlags& lhs, SocketMsgFlags rhs)
  { return (lhs = static_cast<SocketMsgFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }

} // namespace Gio


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gio::SocketMsgFlags> : public Glib::Value_Flags<Gio::SocketMsgFlags>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gio
{


/** @defgroup NetworkIO Portable Network I/O Functionality
 */

/** Low-level socket object
 *
 * A Socket is a low-level networking primitive. It is a more or less direct
 * mapping of the BSD socket API in a portable GObject based API. It supports
 * both the UNIX socket implementations and winsock2 on Windows.
 *
 * Socket is the platform independent base upon which the higher level network
 * primitives are based. Applications are not typically meant to use it
 * directly, but rather through classes like SocketClient, SocketService and
 * SocketConnection. However there may be cases where direct use of Socket is
 * useful.
 *
 * Socket implements the Initable interface, and since initialization can fail,
 * the constructor may throw an exception.
 *
 * Sockets operate in two general modes, blocking or non-blocking. When in
 * blocking mode all operations block until the requested operation is finished
 * or there is an error. In non-blocking mode all calls that would block return
 * immediately with a Gio::Error::WOULD_BLOCK error. To know when a call would
 * successfully run you can call condition_check(), or condition_wait(). You can
 * also use create_source() and attach it to a Glib::MainContext to get
 * callbacks when I/O is possible. Note that all sockets are always set to non
 * blocking mode in the system, and blocking mode is emulated in Socket.
 *
 * When working in non-blocking mode applications should always be able to
 * handle getting a Gio::Error::WOULD_BLOCK error even when some other function
 * said that I/O was possible. This can easily happen in case of a race
 * condition in the application, but it can also happen for other reasons. For
 * instance, on Windows a socket is always seen as writable until a write
 * returns Gio::Error::WOULD_BLOCK.
 *
 * Sockets can be either connection oriented or datagram based. For connection
 * oriented types you must first establish a connection by either connecting to
 * an address or accepting a connection from another address. For connectionless
 * socket types the target/source address is specified or received in each I/O
 * operation.
 *
 * All socket file descriptors are set to be close-on-exec.
 *
 * Note that creating a Socket causes the signal SIGPIPE to be ignored for the
 * remainder of the program. If you are writing a command-line utility that uses
 * Socket, you may need to take into account the fact that your program will not
 * automatically be killed if it tries to write to stdout after it has been
 * closed.
 *
 * @newin{2,24}
 * @ingroup NetworkIO
 */

class Socket : public Glib::Object, public Initable
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Socket CppObjectType;
  typedef Socket_Class CppClassType;
  typedef GSocket BaseObjectType;
  typedef GSocketClass BaseClassType;

private:  friend class Socket_Class;
  static CppClassType socket_class_;

private:
  // noncopyable
  Socket(const Socket&);
  Socket& operator=(const Socket&);

protected:
  explicit Socket(const Glib::ConstructParams& construct_params);
  explicit Socket(GSocket* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Socket();

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GSocket*       gobj()       { return reinterpret_cast<GSocket*>(gobject_); }

  ///Provides access to the underlying C GObject.
  const GSocket* gobj() const { return reinterpret_cast<GSocket*>(gobject_); }

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GSocket* gobj_copy();

private:

  
protected:
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Socket(SocketFamily family, SocketType type, SocketProtocol protocol,
         const Glib::RefPtr<Cancellable>& cancellable);
#else
  Socket(SocketFamily family, SocketType type, SocketProtocol protocol,
         std::auto_ptr<Glib::Error>& error,
         const Glib::RefPtr<Cancellable>& cancellable);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Socket(int fd, const Glib::RefPtr<Cancellable>& cancellable);
#else
  Socket(int fd, std::auto_ptr<Glib::Error>& error,
         const Glib::RefPtr<Cancellable>& cancellable);
#endif //GLIBMM_EXCEPTIONS_ENABLED

public:
  
  /** Creates a new Socket with the defined family, type and protocol.
   * If @a protocol is 0 (SOCKET_PROTOCOL_DEFAULT) the default protocol type
   * for the family and type is used.
   * 
   * The @a protocol is a family and type specific int that specifies what
   * kind of protocol to use. SocketProtocol lists several common ones.
   * Many families only support one protocol, and use 0 for this, others
   * support several and using 0 means to use the default protocol for
   * the family and type.
   * 
   * The protocol id is passed directly to the operating
   * system, so you can use protocols not listed in SocketProtocol if you
   * know the protocol number used for it.
   * 
   * @newin{2,22}
   * @param family The socket family to use, e.g. SOCKET_FAMILY_IPV4.
   * @param type The socket type to use.
   * @param protocol The id of the protocol to use, or 0 for default.
   * @return A Socket or <tt>0</tt> on error.
   * Free the returned object with Glib::object_unref().
   */

  /** @throw Glib::Error
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  static Glib::RefPtr<Socket>
  create(SocketFamily family, SocketType type, SocketProtocol protocol,
         const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
#else
  static Glib::RefPtr<Socket>
  create(SocketFamily family, SocketType type, SocketProtocol protocol,
         std::auto_ptr<Glib::Error>& error,
         const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>());
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Creates a new Socket from a native file descriptor
   * or winsock SOCKET handle.
   * 
   * This reads all the settings from the file descriptor so that
   * all properties should work. Note that the file descriptor
   * will be set to non-blocking mode, independent on the blocking
   * mode of the Socket.
   * 
   * @newin{2,22}
   * @param fd A native socket file descriptor.
   * @return A Socket or <tt>0</tt> on error.
   * Free the returned object with Glib::object_unref().
   */

  /** @throw Glib::Error
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  static Glib::RefPtr<Socket> create_from_fd(int fd, const Glib::RefPtr<Cancellable>&
                                             cancellable = Glib::RefPtr<Cancellable>());
#else
  static Glib::RefPtr<Socket> create_from_fd(int fd, std::auto_ptr<Glib::Error>& error,
                                             const Glib::RefPtr<Cancellable>&
                                             cancellable = Glib::RefPtr<Cancellable>());
#endif //GLIBMM_EXCEPTIONS_ENABLED

  //TODO: Writecusotm documetation, mentioning, for instance, the exception, instead of a bool return.
  
  /** When a socket is created it is attached to an address family, but it
   * doesn't have an address in this family. g_socket_bind() assigns the
   * address (sometimes called name) of the socket.
   * 
   * It is generally required to bind to a local address before you can
   * receive connections. (See g_socket_listen() and g_socket_accept() ).
   * In certain situations, you may also want to bind a socket that will be
   * used to initiate connections, though this is not normally required.
   * 
   *  @a allow_reuse should be <tt>true</tt> for server sockets (sockets that you will
   * eventually call g_socket_accept() on), and <tt>false</tt> for client sockets.
   * (Specifically, if it is <tt>true</tt>, then g_socket_bind() will set the
   * So::REUSEADDR flag on the socket, allowing it to bind @a address even if
   * that address was previously used by another socket that has not yet been
   * fully cleaned-up by the kernel. Failing to set this flag on a server
   * socket may cause the bind call to return IO_ERROR_ADDRESS_IN_USE if
   * the server program is stopped and then immediately restarted.)
   * 
   * @newin{2,22}
   * @param address A SocketAddress specifying the local address.
   * @param allow_reuse Whether to allow reusing this address.
   * @return <tt>true</tt> on success, <tt>false</tt> on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void bind(const Glib::RefPtr<SocketAddress>& address, bool allow_reuse);
#else
  void bind(const Glib::RefPtr<SocketAddress>& address, bool allow_reuse, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Marks the socket as a server socket, i.e.\ a socket that is used
   * to accept incoming requests using g_socket_accept().
   * 
   * Before calling this the socket must be bound to a local address using
   * g_socket_bind().
   * 
   * To set the maximum amount of outstanding clients, use
   * g_socket_set_listen_backlog().
   * 
   * @newin{2,22}
   * @return <tt>true</tt> on success, <tt>false</tt> on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void listen();
#else
  void listen(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Accept incoming connections on a connection-based socket. This removes
   * the first outstanding connection request from the listening socket and
   * creates a Socket object for it.
   * 
   * The @a socket must be bound to a local address with g_socket_bind() and
   * must be listening for incoming connections (g_socket_listen()).
   * 
   * If there are no outstanding connections then the operation will block
   * or return IO_ERROR_WOULD_BLOCK if non-blocking I/O is enabled.
   * To be notified of an incoming connection, wait for the IO_IN condition.
   * 
   * @newin{2,22}
   * @param cancellable A Cancellable or <tt>0</tt>.
   * @return A new Socket, or <tt>0</tt> on error.
   * Free the returned object with Glib::object_unref().
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<Socket> accept(const Glib::RefPtr<Cancellable>& cancellable);
#else
  Glib::RefPtr<Socket> accept(const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<Socket> accept();
#else
  Glib::RefPtr<Socket> accept(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  //TODO: Writecusotm documetation, mentioning, for instance, the exception, instead of a bool return.
  
  /** Connect the socket to the specified remote address.
   * 
   * For connection oriented socket this generally means we attempt to make
   * a connection to the @a address. For a connection-less socket it sets
   * the default address for g_socket_send() and discards all incoming datagrams
   * from other sources.
   * 
   * Generally connection oriented sockets can only connect once, but
   * connection-less sockets can connect multiple times to change the
   * default address.
   * 
   * If the connect call needs to do network I/O it will block, unless
   * non-blocking I/O is enabled. Then IO_ERROR_PENDING is returned
   * and the user can be notified of the connection finishing by waiting
   * for the G_IO_OUT condition. The result of the connection can then be
   * checked with g_socket_check_connect_result().
   * 
   * @newin{2,22}
   * @param address A SocketAddress specifying the remote address.
   * @param cancellable A Cancellable or <tt>0</tt>.
   * @return <tt>true</tt> if connected, <tt>false</tt> on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void connect(const Glib::RefPtr<SocketAddress>& address, const Glib::RefPtr<Cancellable>& cancellable);
#else
  void connect(const Glib::RefPtr<SocketAddress>& address, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void connect(const Glib::RefPtr<SocketAddress>& address);
#else
  void connect(const Glib::RefPtr<SocketAddress>& address, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  // FIXME: it doesn't really seem like this is a proper use of exceptions...
  
  /** Checks and resets the pending connect error for the socket.
   * This is used to check for errors when g_socket_connect() is
   * used in non-blocking mode.
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if no error, <tt>false</tt> otherwise, setting @a error to the error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void check_connect_result();
#else
  void check_connect_result(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED


  // TODO: std::string overload?
  
  /** Receive data (up to @a size bytes) from a socket. This is mainly used by
   * connection-oriented sockets; it is identical to g_socket_receive_from()
   * with @a address set to <tt>0</tt>.
   * 
   * For SOCKET_TYPE_DATAGRAM and SOCKET_TYPE_SEQPACKET sockets,
   * g_socket_receive() will always read either 0 or 1 complete messages from
   * the socket. If the received message is too large to fit in @a buffer, then
   * the data beyond @a size bytes will be discarded, without any explicit
   * indication that this has occurred.
   * 
   * For SOCKET_TYPE_STREAM sockets, g_socket_receive() can return any
   * number of bytes, up to @a size. If more than @a size bytes have been
   * received, the additional data will be returned in future calls to
   * g_socket_receive().
   * 
   * If the socket is in blocking mode the call will block until there is
   * some data to receive or there is an error. If there is no data available
   * and the socket is in non-blocking mode, a IO_ERROR_WOULD_BLOCK error
   * will be returned. To be notified when data is available, wait for the
   * IO_IN condition.
   * 
   * On error -1 is returned and @a error is set accordingly.
   * 
   * @newin{2,22}
   * @param buffer A buffer to read data into (which should be at least @a size
   * bytes long).
   * @param size The number of bytes you want to read from the socket.
   * @param cancellable A Cancellable or <tt>0</tt>.
   * @return Number of bytes read, or -1 on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize receive(char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable);
#else
  gssize receive(char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize receive(char* buffer, gsize size);
#else
  gssize receive(char* buffer, gsize size, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize receive_from(Glib::RefPtr<SocketAddress>& address, char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable);
#else
  gssize receive_from(Glib::RefPtr<SocketAddress>& address, char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize receive_from(Glib::RefPtr<SocketAddress>& address, char* buffer, gsize size);
#else
  gssize receive_from(Glib::RefPtr<SocketAddress>& address, char* buffer, gsize size, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED
  // TODO: wrap g_socket_receive_message -- figure out this GInputVector thing
  // TODO: std::string overload?

  
  /** Tries to send @a size bytes from @a buffer on the socket. This is
   * mainly used by connection-oriented sockets; it is identical to
   * g_socket_send_to() with @a address set to <tt>0</tt>.
   * 
   * If the socket is in blocking mode the call will block until there is
   * space for the data in the socket queue. If there is no space available
   * and the socket is in non-blocking mode a IO_ERROR_WOULD_BLOCK error
   * will be returned. To be notified when space is available, wait for the
   * IO_OUT condition. Note though that you may still receive
   * IO_ERROR_WOULD_BLOCK from g_socket_send() even if you were previously
   * notified of a IO_OUT condition. (On Windows in particular, this is
   * very common due to the way the underlying APIs work.)
   * 
   * On error -1 is returned and @a error is set accordingly.
   * 
   * @newin{2,22}
   * @param buffer The buffer containing the data to send.
   * @param size The number of bytes to send.
   * @param cancellable A Cancellable or <tt>0</tt>.
   * @return Number of bytes written (which may be less than @a size), or -1
   * on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize send(const gchar* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable);
#else
  gssize send(const gchar* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize send(const gchar* buffer, gsize size);
#else
  gssize send(const gchar* buffer, gsize size, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  // TODO: std::string overload?
  
  /** Tries to send @a size bytes from @a buffer to @a address. If @a address is
   * <tt>0</tt> then the message is sent to the default receiver (set by
   * g_socket_connect()).
   * 
   * See g_socket_send() for additional information.
   * 
   * @newin{2,22}
   * @param address A SocketAddress, or <tt>0</tt>.
   * @param buffer The buffer containing the data to send.
   * @param size The number of bytes to send.
   * @param cancellable A Cancellable or <tt>0</tt>.
   * @return Number of bytes written (which may be less than @a size), or -1
   * on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize send_to(const Glib::RefPtr<SocketAddress>& address, const char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable);
#else
  gssize send_to(const Glib::RefPtr<SocketAddress>& address, const char* buffer, gsize size, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  gssize send_to(const Glib::RefPtr<SocketAddress>& address, const char* buffer, gsize size);
#else
  gssize send_to(const Glib::RefPtr<SocketAddress>& address, const char* buffer, gsize size, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  // TODO: wrap g_socket_send_message -- figure out this GOutputVector thing
  
  /** Closes the socket, shutting down any active connection.
   * 
   * Closing a socket does not wait for all outstanding I/O operations
   * to finish, so the caller should not rely on them to be guaranteed
   * to complete even if the close returns with no error.
   * 
   * Once the socket is closed, all other operations will return
   * IO_ERROR_CLOSED. Closing a socket multiple times will not
   * return an error.
   * 
   * Sockets will be automatically closed when the last reference
   * is dropped, but you might want to call this function to make sure
   * resources are released as early as possible.
   * 
   * Beware that due to the way that TCP works, it is possible for
   * recently-sent data to be lost if either you close a socket while the
   * IO_IN condition is set, or else if the remote connection tries to
   * send something to you after you close the socket but before it has
   * finished reading all of the data you sent. There is no easy generic
   * way to avoid this problem; the easiest fix is to design the network
   * protocol such that the client will never send data "out of turn".
   * Another solution is for the server to half-close the connection by
   * calling g_socket_shutdown() with only the @a shutdown_write flag set,
   * and then wait for the client to notice this and close its side of the
   * connection, after which the server can safely call g_socket_close().
   * (This is what TcpConnection does if you call
   * g_tcp_connection_set_graceful_disconnect(). But of course, this
   * only works if the client will close its connection after the server
   * does.)
   * 
   * @newin{2,22}
   * @return <tt>true</tt> on success, <tt>false</tt> on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void close();
#else
  void close(std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Checks whether a socket is closed.
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if socket is closed, <tt>false</tt> otherwise.
   */
  bool is_closed();
  
  /** Shut down part of a full-duplex connection.
   * 
   * If @a shutdown_read is <tt>true</tt> then the recieving side of the connection
   * is shut down, and further reading is disallowed.
   * 
   * If @a shutdown_write is <tt>true</tt> then the sending side of the connection
   * is shut down, and further writing is disallowed.
   * 
   * It is allowed for both @a shutdown_read and @a shutdown_write to be <tt>true</tt>.
   * 
   * One example where this is used is graceful disconnect for TCP connections
   * where you close the sending side, then wait for the other side to close
   * the connection, thus ensuring that the other side saw all sent data.
   * 
   * @newin{2,22}
   * @param shutdown_read Whether to shut down the read side.
   * @param shutdown_write Whether to shut down the write side.
   * @return <tt>true</tt> on success, <tt>false</tt> on error.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void shutdown(bool shutdown_read, bool shutdown_write);
#else
  void shutdown(bool shutdown_read, bool shutdown_write, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Check whether the socket is connected. This is only useful for
   * connection-oriented sockets.
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if socket is connected, <tt>false</tt> otherwise.
   */
  bool is_connected();

  // TODO: non-cancellable version
  // This won't work because Glib::Source is abstract, and Glib::IOSource has no
  // constructor that takes a GSource*
//#m4 __CONVERSION(`GSource*',`Glib::RefPtr<Glib::Source>',`Glib::RefPtr<Glib::Source>(new ::Glib::Source($3))')
  //_WRAP_METHOD(Glib::RefPtr<Glib::Source> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable), g_socket_create_source)
  
  /** Checks on the readiness of @a socket to perform operations.
   * The operations specified in @a condition are checked for and masked
   * against the currently-satisfied conditions on @a socket. The result
   * is returned.
   * 
   * It is meaningless to specify IO_ERR or IO_HUP in condition;
   * these conditions will always be set in the output if they are true.
   * 
   * This call never blocks.
   * 
   * @newin{2,22}
   * @param condition A IOCondition mask to check.
   * @return The @a GIOCondition mask of the current state.
   */
  Glib::IOCondition condition_check(Glib::IOCondition condition);

  
  /** Waits for @a condition to become true on @a socket. When the condition
   * is met, <tt>true</tt> is returned.
   * 
   * If @a cancellable is cancelled before the condition is met then <tt>false</tt>
   * is returned and @a error, if non-<tt>0</tt>, is set to IO_ERROR_CANCELLED.
   * 
   * @newin{2,22}
   * @param condition A IOCondition mask to wait for.
   * @param cancellable A Cancellable, or <tt>0</tt>.
   * @return <tt>true</tt> if the condition was met, <tt>false</tt> otherwise.
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void condition_wait(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable);
#else
  void condition_wait(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void condition_wait(Glib::IOCondition condition);
#else
  void condition_wait(Glib::IOCondition condition, std::auto_ptr<Glib::Error>& error);
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Sets the maximum number of outstanding connections allowed
   * when listening on this socket. If more clients than this are
   * connecting to the socket and the application is not handling them
   * on time then the new connections will be refused.
   * 
   * Note that this must be called before g_socket_listen() and has no
   * effect if called after that.
   * 
   * @newin{2,22}
   * @param backlog The maximum number of pending connections.
   */
  void set_listen_backlog(int backlog);
  
  /** Gets the listen backlog setting of the socket. For details on this,
   * see g_socket_set_listen_backlog().
   * 
   * @newin{2,22}
   * @return The maximum number of pending connections.
   */
  int get_listen_backlog() const;
  
  /** Sets the blocking mode of the socket. In blocking mode
   * all operations block until they succeed or there is an error. In
   * non-blocking mode all functions return results immediately or
   * with a IO_ERROR_WOULD_BLOCK error.
   * 
   * All sockets are created in blocking mode. However, note that the
   * platform level socket is always non-blocking, and blocking mode
   * is a GSocket level feature.
   * 
   * @newin{2,22}
   * @param blocking Whether to use blocking I/O or not.
   */
  void set_blocking(bool blocking);
  
  /** Gets the blocking mode of the socket. For details on blocking I/O,
   * see g_socket_set_blocking().
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if blocking I/O is used, <tt>false</tt> otherwise.
   */
  bool get_blocking() const;
  
  /** Sets or unsets the So::KEEPALIVE flag on the underlying socket. When
   * this flag is set on a socket, the system will attempt to verify that the
   * remote socket endpoint is still present if a sufficiently long period of
   * time passes with no data being exchanged. If the system is unable to
   * verify the presence of the remote endpoint, it will automatically close
   * the connection.
   * 
   * This option is only functional on certain kinds of sockets. (Notably,
   * SOCKET_PROTOCOL_TCP sockets.)
   * 
   * The exact time between pings is system- and protocol-dependent, but will
   * normally be at least two hours. Most commonly, you would set this flag
   * on a server socket if you want to allow clients to remain idle for long
   * periods of time, but also want to ensure that connections are eventually
   * garbage-collected if clients crash or become unreachable.
   * 
   * @newin{2,22}
   * @param keepalive Value for the keepalive flag.
   */
  void set_keepalive(bool keepalive);
  
  /** Gets the keepalive mode of the socket. For details on this,
   * see g_socket_set_keepalive().
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if keepalive is active, <tt>false</tt> otherwise.
   */
  bool get_keepalive() const;
  
  /** Gets the socket family of the socket.
   * 
   * @newin{2,22}
   * @return A SocketFamily.
   */
  SocketFamily get_family() const;
  
  /** Returns the underlying OS socket object. On unix this
   * is a socket file descriptor, and on windows this is
   * a Winsock2 SOCKET handle. This may be useful for
   * doing platform specific or otherwise unusual operations
   * on the socket.
   * 
   * @newin{2,22}
   * @return The file descriptor of the socket.
   */
  int get_fd() const;
  
  /** Try to get the local address of a bound socket. This is only
   * useful if the socket has been bound to a local address,
   * either explicitly or implicitly when connecting.
   * 
   * @newin{2,22}
   * @return A SocketAddress or <tt>0</tt> on error.
   * Free the returned object with Glib::object_unref().
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<SocketAddress> get_local_address() const;
#else
  Glib::RefPtr<SocketAddress> get_local_address(std::auto_ptr<Glib::Error>& error) const;
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Try to get the remove address of a connected socket. This is only
   * useful for connection oriented sockets that have been connected.
   * 
   * @newin{2,22}
   * @return A SocketAddress or <tt>0</tt> on error.
   * Free the returned object with Glib::object_unref().
   */
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<SocketAddress> get_remote_address() const;
#else
  Glib::RefPtr<SocketAddress> get_remote_address(std::auto_ptr<Glib::Error>& error) const;
#endif //GLIBMM_EXCEPTIONS_ENABLED

  
  /** Gets the socket protocol id the socket was created with.
   * In case the protocol is unknown, -1 is returned.
   * 
   * @newin{2,22}
   * @return A protocol id, or -1 if unknown.
   */
  SocketProtocol get_protocol() const;
  
  /** Gets the socket type of the socket.
   * 
   * @newin{2,22}
   * @return A SocketType.
   */
  SocketType get_socket_type() const;
  
  /** Checks if a socket is capable of speaking IPv4.
   * 
   * IPv4 sockets are capable of speaking IPv4.  On some operating systems
   * and under some combinations of circumstances IPv6 sockets are also
   * capable of speaking IPv4.  See RFC 3493 section 3.7 for more
   * information.
   * 
   * No other types of sockets are currently considered as being capable
   * of speaking IPv4.
   * 
   * @newin{2,22}
   * @return <tt>true</tt> if this socket can be used with IPv4.
   */
  bool speaks_ipv4() const;

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Whether or not I/O on this socket is blocking.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_blocking() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Whether or not I/O on this socket is blocking.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_blocking() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The sockets address family.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<SocketFamily> property_family() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The sockets file descriptor.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<int> property_fd() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Keep connection alive by sending periodic pings.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_keepalive() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Keep connection alive by sending periodic pings.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_keepalive() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Outstanding connections in the listen queue.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<int> property_listen_backlog() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Outstanding connections in the listen queue.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<int> property_listen_backlog() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The local address the socket is bound to.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<SocketAddress> > property_local_address() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The remote address the socket is connected to.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly< Glib::RefPtr<SocketAddress> > property_remote_address() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The id of the protocol to use
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<SocketProtocol> property_protocol() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The sockets type.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<SocketType> property_type() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

protected:
  //GTK+ Virtual Functions (override these to change behaviour):
#ifdef GLIBMM_VFUNCS_ENABLED
#endif //GLIBMM_VFUNCS_ENABLED

  //Default Signal Handlers::
#ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
#endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED


};

} // namespace Gio


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gio::Socket
   */
  Glib::RefPtr<Gio::Socket> wrap(GSocket* object, bool take_copy = false);
}


#endif /* _GIOMM_SOCKET_H */

