⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsocket.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return -1;

  /* Translate a system address into a GSocket address */
  if (!m_peer)
  {
    m_peer = GAddress_new();
    if (!m_peer)
    {
      m_error = GSOCK_MEMERR;
      return -1;
    }
  }
  err = _GAddress_translate_from(m_peer, &from, fromlen);
  if (err != GSOCK_NOERROR)
  {
    GAddress_destroy(m_peer);
    m_peer  = NULL;
    m_error = err;
    return -1;
  }
#endif
  return ret;
}

int GSocket::Send_Stream(const char *buffer, int size)
{
    OTFlags flags = 0 ;
    OTResult res ;

    res = OTSnd( m_endpoint , (void*) buffer , size , flags ) ;
    return res ;
}

int GSocket::Send_Dgram(const char *buffer, int size)
{
  int ret = -1 ;
// TODO
#if 0
  struct sockaddr *addr;
  int len ;
  GSocketError err;

  if (!m_peer)
  {
    m_error = GSOCK_INVADDR;
    return -1;
  }

  err = _GAddress_translate_to(m_peer, &addr, &len);
  if (err != GSOCK_NOERROR)
  {
    m_error = err;
    return -1;
  }

  ret = sendto(m_endpoint, buffer, size, 0, addr, len);

  /* Frees memory allocated from _GAddress_translate_to */
  free(addr);
#endif
  return ret;
}

/* Compatibility functions for GSocket */
GSocket *GSocket_new(void)
{
    GSocket *newsocket = new GSocket();
    if(newsocket->IsOk())
        return newsocket;
    delete newsocket;
    return NULL;
}


/*
 * -------------------------------------------------------------------------
 * GAddress
 * -------------------------------------------------------------------------
 */

/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
 */
#define CHECK_ADDRESS(address, family, retval)                      \
{                                                                   \
  if (address->m_family == GSOCK_NOFAMILY)                          \
    if (_GAddress_Init_##family(address) != GSOCK_NOERROR)          \
      return address->m_error;                                      \
  if (address->m_family != GSOCK_##family)                          \
  {                                                                 \
    address->m_error = GSOCK_INVADDR;                               \
    return retval;                                                  \
  }                                                                 \
}

GAddress *GAddress_new()
{
  GAddress *address;

  if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
    return NULL;

  address->m_family  = GSOCK_NOFAMILY;
  address->m_host = INADDR_NONE ;
  address->m_port = 0 ;

  return address;
}

GAddress *GAddress_copy(GAddress *address)
{
  GAddress *addr2;

  assert(address != NULL);

  if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
    return NULL;

  memcpy(addr2, address, sizeof(GAddress));
  return addr2;
}

void GAddress_destroy(GAddress *address)
{
  assert(address != NULL);

  free(address);
}

void GAddress_SetFamily(GAddress *address, GAddressType type)
{
  assert(address != NULL);

  address->m_family = type;
}

GAddressType GAddress_GetFamily(GAddress *address)
{
  assert(address != NULL);

  return address->m_family;
}

GSocketError _GAddress_translate_from(GAddress *address,
                                      InetAddress *addr)
{
  switch (addr->fAddressType)
  {
    case AF_INET:
      address->m_family = GSOCK_INET;
      break;
#ifdef AF_INET6
    case AF_INET6:
      address->m_family = GSOCK_INET6;
      break;
#endif
    default:
    {
      address->m_error = GSOCK_INVOP;
      return GSOCK_INVOP;
    }
  }
  address->m_host = addr->fHost ;
  address->m_port = addr->fPort ;
  return GSOCK_NOERROR;
}

GSocketError _GAddress_translate_to(GAddress *address,
                                    InetAddress *addr)
{
  if ( !GSocket_Verify_Inited() )
    return GSOCK_IOERR ;
  memset(addr, 0 , sizeof(struct InetAddress));
  OTInitInetAddress( addr , address->m_port , address->m_host ) ;
  return GSOCK_NOERROR;
}

/*
 * -------------------------------------------------------------------------
 * Internet address family
 * -------------------------------------------------------------------------
 */

GSocketError _GAddress_Init_INET(GAddress *address)
{
  address->m_family = GSOCK_INET;
  address->m_host = kOTAnyInetAddress ;

  return GSOCK_NOERROR;
}

GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
{
  InetHostInfo hinfo ;
  OSStatus ret ;

 if ( !GSocket_Verify_Inited() )
    return GSOCK_IOERR ;

  assert(address != NULL);

  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
  ret = OTInetStringToAddress( gInetSvcRef , (char*) hostname , &hinfo ) ;
  if ( ret != kOTNoError )
  {
    address->m_host = INADDR_NONE ;
    address->m_error = GSOCK_NOHOST;
    return GSOCK_NOHOST;
  }
  address->m_host = hinfo.addrs[0] ;
  return GSOCK_NOERROR;
}

GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
{
  return GAddress_INET_SetHostAddress(address, INADDR_ANY);
}

GSocketError GAddress_INET_SetHostAddress(GAddress *address,
                                          unsigned long hostaddr)
{
  assert(address != NULL);

  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);

  address->m_host = htonl(hostaddr) ;

  return GSOCK_NOERROR;
}

struct service_entry
{
    const char * name ;
    unsigned short port ;
    const char * protocol ;
} ;
typedef struct service_entry service_entry ;

service_entry gServices[] =
{
    { "http" , 80 , "tcp" }
} ;

GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
                                       const char *protocol)
{
  size_t i ;

  assert(address != NULL);
  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);

  if (!port)
  {
    address->m_error = GSOCK_INVPORT;
    return GSOCK_INVPORT;
  }
  for ( i = 0 ; i < sizeof( gServices) / sizeof( service_entry ) ; ++i )
  {
    if ( strcmp( port , gServices[i].name ) == 0 )
    {
      if ( protocol == NULL || strcmp( protocol , gServices[i].protocol ) )
      {
        address->m_port = gServices[i].port ;
        return GSOCK_NOERROR;
      }
    }
  }

  if (isdigit(port[0]))
  {
     address->m_port = atoi(port);
     return GSOCK_NOERROR;
  }

  address->m_error = GSOCK_INVPORT;
  return GSOCK_INVPORT;
}

GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
{
  assert(address != NULL);
  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
  address->m_port = port ;

  return GSOCK_NOERROR;
}

GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
{
  InetDomainName name ;
  if ( !GSocket_Verify_Inited() )
    return GSOCK_IOERR ;

  assert(address != NULL);
  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);

  OTInetAddressToName( gInetSvcRef , address->m_host , name ) ;
  strncpy( hostname , name , sbuf ) ;
  return GSOCK_NOERROR;
}

unsigned long GAddress_INET_GetHostAddress(GAddress *address)
{
  assert(address != NULL);
  CHECK_ADDRESS(address, INET, 0);

  return ntohl(address->m_host);
}

unsigned short GAddress_INET_GetPort(GAddress *address)
{
  assert(address != NULL);
  CHECK_ADDRESS(address, INET, 0);

  return address->m_port;
}

void GSocket::Enable_Events()
{
    if ( m_takesEvents )
        return ;

    {
        OTResult  state ;
        m_takesEvents = true ;
        state = OTGetEndpointState(m_endpoint);

        {
            OTByteCount sz = 0 ;
            OTCountDataBytes( m_endpoint , &sz ) ;
            if ( state == T_INCON || sz > 0 )
            {
                m_detected |= GSOCK_INPUT_FLAG ;
                (m_cbacks[GSOCK_INPUT])(this, GSOCK_INPUT, m_data[GSOCK_INPUT]);
            }
        }
        {
            if ( state == T_DATAXFER || state == T_INREL )
            {
                m_detected |=GSOCK_OUTPUT_FLAG ;
                (m_cbacks[GSOCK_OUTPUT])(this, GSOCK_OUTPUT, m_data[GSOCK_OUTPUT]);
            }
        }
    }
}

void GSocket::Disable_Events()
{
    m_takesEvents = false ;
}

/* _GSocket_Input_Timeout:
 *  For blocking sockets, wait until data is available or
 *  until timeout ellapses.
 */
GSocketError GSocket::Input_Timeout()
{
  if ( !m_non_blocking )
  {
    UnsignedWide now , start ;
    bool formerTakesEvents = m_takesEvents ;
    Microseconds(&start);
    now = start ;
    m_takesEvents = false ;

    while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < m_timeout * 1000.0 )
    {
        OTResult state ;
        OTByteCount sz = 0 ;
        state = OTGetEndpointState(m_endpoint);

        OTCountDataBytes( m_endpoint , &sz ) ;
        if ( state == T_INCON || sz > 0 )
        {
            m_takesEvents = formerTakesEvents ;
            return GSOCK_NOERROR;
        }
        Microseconds(&now);
    }
    m_takesEvents = formerTakesEvents ;
    m_error = GSOCK_TIMEDOUT;
    return GSOCK_TIMEDOUT;
  }
  return GSOCK_NOERROR;
}

/* _GSocket_Output_Timeout:
 *  For blocking sockets, wait until data can be sent without
 *  blocking or until timeout ellapses.
 */
GSocketError GSocket::Output_Timeout()
{
  if ( !m_non_blocking )
  {
    UnsignedWide now , start ;
    bool formerTakesEvents = m_takesEvents ;
    Microseconds(&start);
    now = start ;
    m_takesEvents = false ;

    while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < m_timeout * 1000.0 )
    {
        OTResult state ;
        state = OTGetEndpointState(m_endpoint);

        if ( state == T_DATAXFER || state == T_INREL )
        {
            m_takesEvents = formerTakesEvents ;
            return GSOCK_NOERROR;
        }
        Microseconds(&now);
    }
    m_takesEvents = formerTakesEvents ;
    m_error = GSOCK_TIMEDOUT;
    return GSOCK_TIMEDOUT;
  }
  return GSOCK_NOERROR;
}

/* GSOCK_INPUT:
 *   There is data to be read in the input buffer. If, after a read
 *   operation, there is still data available, the callback function will
 *   be called again.
 * GSOCK_OUTPUT:
 *   The socket is available for writing. That is, the next write call
 *   won't block. This event is generated only once, when the connection is
 *   first established, and then only if a call failed with GSOCK_WOULDBLOCK,
 *   when the output buffer empties again. This means that the app should
 *   assume that it can write since the first OUTPUT event, and no more
 *   OUTPUT events will be generated unless an error occurs.
 * GSOCK_CONNECTION:
 *   Connection successfully established, for client sockets, or incoming
 *   client connection, for server sockets. Wait for this event (also watch
 *   out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
 * GSOCK_LOST:
 *   The connection is lost (or a connection request failed); this could
 *   be due to a failure, or due to the peer closing it gracefully.
 */

void _GSocket_Internal_Proc(unsigned long e , void* d )
{
    GSocket *socket = (GSocket*) d ;

    if ( !socket )
        return ;

    OTEventCode ev = (OTEventCode) e ;
    GSocketEvent event;
    GSocketEvent event2;
    GSocketCallback cback;
    char *data;
    GSocketCallback cback2;
    char *data2;

    event = GSOCK_MAX_EVENT ;
    event2 = GSOCK_MAX_EVENT ;
    cback = NULL;
    data = NULL;
    cback2 = NULL;
    data2 = NULL;

    /* Check that the socket still exists (it has not been
     * destroyed) and for safety, check that the m_endpoint field
     * is what we expect it to be.
     */
    if ( /* (socket != NULL) && */ (socket->m_takesEvents))
    {
        switch (ev)
        {
            case T_LISTEN :
                event = GSOCK_CONNECTION ;
                break ;
            case T_CONNECT :
                event = GSOCK_CONNECTION ;
                event2 = GSOCK_OUTPUT ;
                {
                    TCall retCall;

                    retCall.addr.buf     = NULL;
                    retCall.addr.maxlen  = 0;
                    retCall.opt.buf      = NULL;
                    retCall.opt.maxlen   = 0;
                    retCall.udata.buf    = NULL;
                    retCall.udata.maxlen = 0;
                    OTRcvConnect( socket->m_endpoint , &retCall ) ;
                }
                break ;
            case T_DISCONNECT :
                event = GSOCK_LOST ;
                break ;
            case T_GODATA :
            case T_GOEXDATA :
                event = GSOCK_OUTPUT ;
                break ;
            case T_DATA :
                event = GSOCK_INPUT ;
                break ;
            case T_EXDATA :
                event = GSOCK_INPUT ;
                break ;
      }
      if (event != GSOCK_MAX_EVENT)
      {
        cback = socket->m_cbacks[event];
        data = socket->m_data[event];

        if (event == GSOCK_LOST)
          socket->m_detected = GSOCK_LOST_FLAG;
        else
          socket->m_detected |= (1 << event);
      }
      if (event2 != GSOCK_MAX_EVENT)
      {
        cback2 = socket->m_cbacks[event2];
        data2 = socket->m_data[event2];

        if (event2 == GSOCK_LOST)
          socket->m_detected = GSOCK_LOST_FLAG;
        else
          socket->m_detected |= (1 << event2);
      }
    }

    /* OK, we can now leave the critical section because we have
     * already obtained the callback address (we make no further
     * accesses to socket->whatever). However, the app should
     * be prepared to handle events from a socket that has just
     * been closed!
     */

    if (cback != NULL)
      (cback)(socket, event, data);
    if (cback2 != NULL)
      (cback2)(socket, event2, data2);

}

/* Hack added for Mac OS X */
GSocketError GAddress_UNIX_GetPath(GAddress *addr, char *path, size_t buf)
{
    return GSOCK_INVADDR;
}

GSocketError GAddress_UNIX_SetPath(GAddress *addr, const char *path)
{
    return GSOCK_INVADDR;
}

#endif  /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -