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

📄 symbian-ikstransport.cpp

📁 symbina上可以使用一个xml解析器,对开发网络应用很有好处
💻 CPP
字号:
/* ikstransport implementation using Symbian 7.0 Socket APIs** Copyright (C) 2004-2005 Darrell Karbott (djk2005@users.sf.net)** This code is free software; you can redistribute it and/or** modify it under the terms of GNU Lesser General Public License.** See http://www.gnu.org/ for further details of the LGPL.*/#include "iksemel.h" // hmmmm <> ?#include "symbian-ikstransport.h"#include "CSocket.h"#include "delmon.h"#include <string.h> #include <utf.h>class CNotifyOnDelete;class CSymbianTransportInstance : public CBase, public MSocketObserver  {public:  // Static hook functions used to fill in the ikstransport struct.  static TInt IksTConnectAsync(iksparser *prs, void **socketptr, 			      const char *server, 			      const char *server_name, 			      TInt port, 			      void *notify_data, 			      iksAsyncNotify *notify_func);  static void IksTClose(void *socket);  static TInt IksTSend(void *socket, const char *data, size_t len);  static TInt IksTRecv(void *socket, char *buffer, size_t buf_len, TInt timeout);protected:  CSymbianTransportInstance(iksparser *prs, const char *server, const char *server_name,                            TInt port, void *notify_data, iksAsyncNotify *notify_func);  // Finishes constructing the instance.  TInt IksConnectAsync(void **socketptr);  ~CSymbianTransportInstance();  TInt IksSend(const char *data, size_t len);  TInt IksRecv(char *buffer, size_t buf_len, TInt timeout);  // Returns true if the instance was deleted during the call.  TBool Notify(TInt reason, TInt data0 = 0, TInt data1 = 0);  // MSocketObserver implementation.  virtual void SocketNotify(CSocket* pSocket, const TSocketReason& reason);private:  iksparser* iParser;  TBool iIgnoreNotifications;  TInt iAlreadyRead;  TBuf8<128> iServer;  TBuf8<128> iServerName;  TInt iPort;  void* iNotifyData;  iksAsyncNotify* iNotifyFunc;  // Used by Notify() to figure out when the instance has  // been deleted out from under it.  CNotifyOnDelete* iDeletionNotifier;  TBool iIsDeleting;  CSocket* iSocket;};EXPORT_C TInt CSymbianTransportInstance::IksTConnectAsync(iksparser *prs, 						void **socket, 						const char *server, 						const char *server_name, 						TInt port, 						void *notify_data, 						iksAsyncNotify *notify_func){  if (!server_name) {    server_name = server;  }  CSymbianTransportInstance* instance = new CSymbianTransportInstance(prs, server, server_name, port,                                                                      notify_data, notify_func);  if (!instance) {    return IKS_NOMEM;  }    TInt ret = instance->IksConnectAsync(socket);  if (ret != IKS_OK) {    delete instance;    *socket = NULL;  }  return ret;}#define IMPL_INST( socket_ptr) ( (CSymbianTransportInstance*) socket_ptr )EXPORT_C void CSymbianTransportInstance::IksTClose(void *socket) {  delete IMPL_INST( socket );}EXPORT_C TInt CSymbianTransportInstance::IksTSend(void *socket, const char *data, size_t len){  return IMPL_INST( socket )->IksSend(data, len);}EXPORT_C TInt CSymbianTransportInstance::IksTRecv(void *socket, char *buffer, size_t buf_len, TInt timeout){  return IMPL_INST( socket )->IksRecv(buffer, buf_len, timeout);}CSymbianTransportInstance::CSymbianTransportInstance(iksparser *prs,                                                      const char *server,                                                      const char *server_name,                                                      TInt port,                                                     void *notify_data,                                                      iksAsyncNotify *notify_func)  : iParser(prs), iIgnoreNotifications(EFalse), iAlreadyRead(0), iPort(port), iNotifyData(notify_data),    iNotifyFunc(notify_func), iDeletionNotifier(NULL), iIsDeleting(EFalse), iSocket(NULL){  iServer.Append((const TUint8*)server, strlen(server));  iServer.ZeroTerminate();  iServerName.Append((const TUint8*)server_name, strlen(server_name));  iServerName.ZeroTerminate();}TInt CSymbianTransportInstance::IksConnectAsync(void **socketptr){  TBuf<128> fatName;  TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(fatName, iServer);  if (ret < 0) {    return IKS_NET_UNKNOWN;  }  iDeletionNotifier = new CNotifyOnDelete();  if (!iDeletionNotifier) {    return IKS_NOMEM;  }  TRAPD(err, iSocket = CSocket::NewL());  if (err != KErrNone) {    return IKS_NET_UNKNOWN;  // hmmm....  }  iIgnoreNotifications = EFalse;  *socketptr = this;  TDeletionMonitor monitor(iDeletionNotifier);  iSocket->SetObserver(this);  TBool deleted = EFalse;  TRAP(err, deleted = iSocket->ConnectL(fatName, iPort, EFalse));  if (monitor.WasDeleted()) {    // Client code called iks_disconnect from    // the socket hook.    *socketptr = NULL;    return IKS_NET_NOCONN;  }  if (err != KErrNone || deleted) {    return IKS_NET_NOCONN;  }  return IKS_OK;}CSymbianTransportInstance::~CSymbianTransportInstance(){  iIsDeleting = ETrue;  if (iSocket) {    iIgnoreNotifications = ETrue;    delete iSocket;    iSocket = NULL;    Notify(IKS_ASYNC_CLOSED);  }  delete iDeletionNotifier;}TInt CSymbianTransportInstance::IksSend(const char *data, size_t len){  if (!iSocket) {    return IKS_NET_NOCONN;  }  if (iSocket->State() != CSocket::EConnected) {    // The socket isn't ready yet.    return IKS_NET_NOCONN;  }  if (((TInt)len) > iSocket->BytesWriteable()) {    // The write buffer overflowed!    // Hmmm this is a recoverable error, but the client code    // has no way of knowing that.    return IKS_NET_RWERR;  }  if (Notify(IKS_ASYNC_WRITE, len)) {    return IKS_NET_NOCONN; // already deleted!  }  TPtrC8 ptr((const TUint8*)data, len);  iSocket->Write(ptr);  return IKS_OK;}TInt CSymbianTransportInstance::IksRecv(char *buffer, size_t buf_len, TInt timeout){  if (!iSocket) {    return -1;  }  if (timeout != 0) {    // We don't support waiting.    return -1;  }  if (iSocket->State() == CSocket::EClosed ||      iSocket->State() == CSocket::EError) {    return -1; // Illegal state, won't recover.  }  if (iSocket->State() == CSocket::EResolving ||      iSocket->State() == CSocket::EConnecting) {    return 0;  // Not fully connected yet.  }  // Important: Don't feed \0's into the parser.  TInt len = iSocket->RecvdData().Length() - 1;  if (len < 1) {    // REDFLAG: required.  I don't think so, but this should be harmless.    // Refill the read buffer.    iSocket->EnableRead(ETrue);    return 0;  }  TInt bytesToRead = len - iAlreadyRead;  if (((size_t)bytesToRead) > buf_len) {    bytesToRead = buf_len;  }  if (bytesToRead < 1) {    // Refill the read buffer.    iSocket->EnableRead(ETrue);    return 0;  }  strncpy(buffer, (const char*)iSocket->RecvdData().Ptr() + iAlreadyRead, bytesToRead);  iAlreadyRead += bytesToRead;  if (iAlreadyRead >=  iSocket->RecvdData().Length() - 1) {    // Refill the read buffer.    iSocket->EnableRead(ETrue);  }  return bytesToRead;}TBool CSymbianTransportInstance::Notify(TInt reason, TInt data0, TInt data1){  if (!iNotifyFunc) { return EFalse; }  iksasyncevent eventInst;  eventInst.event = reason;  eventInst.data0 = data0;  eventInst.data1 = data1;  if (iIsDeleting) {    iNotifyFunc(iNotifyData, &eventInst);    return EFalse; // Not deleted yet.  hmmmm.  }    // Note: Client code in the iNotifyFunc might do something which   //       causes a call back into this function, so it must be reentrant.  TDeletionMonitor monitor(iDeletionNotifier);  iNotifyFunc(iNotifyData, &eventInst);  return monitor.WasDeleted();}void CSymbianTransportInstance::SocketNotify(CSocket* pSocket, const TSocketReason& reason){  if ((!pSocket) && (reason == EClosed)) {    // The socket instance is being deleted.    iSocket = NULL;    // The destructor will post an event.    return;   }  if (iIgnoreNotifications) {    return;  }  switch (reason) {  case EResolving:    break;  case EConnecting:    if (Notify(IKS_ASYNC_RESOLVED)) {      return;    }    break;  case EConnected:    {      // Send the opening header.      TDeletionMonitor monitor(iDeletionNotifier);      TInt ret = iks_send_header (iParser, (const char*)iServerName.PtrZ());      if (monitor.WasDeleted()) {        return; // Bail out.      }      if (ret != IKS_OK) {        Notify(IKS_ASYNC_ERROR, IKS_NET_RWERR);        return;      }      if(Notify(IKS_ASYNC_CONNECTED)) {        return; // Already deleted.      }      // Turn on ERead callbacks.      iSocket->EnableRead(ETrue);    }    break;  case ERead:     iAlreadyRead = 0;    if (Notify(IKS_ASYNC_READ, iSocket->RecvdData().Length())) {      return;    }    break;  case EWrite:      if (Notify(IKS_ASYNC_WRITTEN, (TInt)iSocket->SendLen())) {      return;    }    break;  case EError:    {      // Ignore all other notifications.      iIgnoreNotifications = ETrue;      TInt errCode = IKS_NET_UNKNOWN;      switch (iSocket->LastError()) {      case KErrEof:      errCode = IKS_NET_DROPPED; break;      case KErrNotFound: errCode = IKS_NET_NODNS;   break;      case KErrWrite:    errCode = IKS_NET_RWERR;   break;      case KErrTimedOut: // drop through on purpose.      case KErrCouldNotConnect:         errCode = IKS_NET_NOCONN; break;      default:        errCode = IKS_NET_UNKNOWN;      }            if (Notify(IKS_ASYNC_ERROR, errCode, iSocket->LastError())) {	return;      }    }    break;  case EClosed:    // iIgnoreNotifications keeps us from     // getting here during a normal iks_disconnect    // so if we are seeing this, then the other end    // must have dropped the connection.    if (Notify(IKS_ASYNC_ERROR, IKS_NET_DROPPED)) {      return;    }    break;  }}ikstransport symbian_ikstransport = {  IKS_TRANSPORT_V1, /* ABI version */  NULL /* Synchronous connect not supported. */,  &CSymbianTransportInstance::IksTSend,  &CSymbianTransportInstance::IksTRecv,  &CSymbianTransportInstance::IksTClose,  &CSymbianTransportInstance::IksTConnectAsync,};EXPORT_C ikstransport* iks_symbian_ikstransport(){  return &symbian_ikstransport;}

⌨️ 快捷键说明

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