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

📄 iksdemo.cpp

📁 symbina上可以使用一个xml解析器,对开发网络应用很有好处
💻 CPP
字号:
/* ** Copyright (C) 2005 Darrell Karbott (djk2005@users.sf.net)** This code is free software; you can redistribute it and/or modify** it under the terms of the GNU Public Licence (GPL) version 2 See** http://www.gnu.org/ for further details of the GPL.*/#include "iksdemo.h"#include <string.h>#include <stdio.h>#include <stdlib.h>// Helper macros to check return values from iksemel functions.#define IKS_CHK(iksErrCode) { checkIksReturnValue(iksErrCode, __FILE__, __LINE__); }#define IKS_CHK_PTR(ptr) { checkIksReturnValue((ptr ? IKS_OK : IKS_NOMEM), __FILE__, __LINE__); }// MUST be static or the symbian linker complains.static const char DEFAULT_JABBER_RESOURCE[] = "iksdemo";IUserInterface::~IUserInterface() {}IUserInteractions::~IUserInteractions() {}////////////////////////////////////////////////////////////class CInteractions : public IUserInteractions {public:  CInteractions(CIksDemo* parent) : mParent(parent) {}  virtual ~CInteractions() {}  virtual int connect(const char* jid, const char* password, int port)  {    return mParent->connect(jid, password, port);  }  virtual void disconnect()  {    // Send the end of stream tag and wait for the server    // to drop the connection.    mParent->disconnect(0);  }  virtual int sendMsg(const char* toJid, const char* msg)  {    return mParent->send(toJid, msg);  }private:  CIksDemo* mParent;};////////////////////////////////////////////////////////////// Malloc wrappers used to test iks_set_mem_funcs()#ifdef USE_IKS_MALLOC_HOOKS// SYMBIAN// The log file ends up in the emulator root directory.// e.g. for UIQ_21:// C:\Symbian\UIQ_21\epoc32\winscw\c\logged_malloc.log// or in the phone's root directory when running on a// real device.void *logged_malloc(size_t size){  void* ret = malloc(size);  FILE* fOut = fopen("logged_malloc.log", "a+");  if (fOut) {    fprintf(fOut, "%p mallocd [%x]\n", ret, size);    fflush(fOut);    fclose(fOut);  }  return ret;}void logged_free(void *ptr){  FILE* fOut = fopen("logged_malloc.log", "a+");  if (fOut) {    fprintf(fOut, "%p free\n", ptr);    fflush(fOut);    fclose(fOut);  }  free(ptr);}#endif////////////////////////////////////////////////////////////CIksDemo::CIksDemo(ikstransport* transport)  : mTransport(transport),    mUi(NULL), mInteractions(NULL), mPrs(NULL),    mState(QUIESCENT),    mWriteCount(0),    mWrittenCount(0),    mReadCount(0),    mIsDisconnecting(0){  mJid[0] = 0;  mPassword[0] = 0;#ifdef USE_IKS_MALLOC_HOOKS  iks_set_mem_funcs(logged_malloc, logged_free);#endif}CIksDemo::~CIksDemo(){  disconnect();  delete mInteractions;#ifdef USE_IKS_MALLOC_HOOKS  // You must do this or the TLS memory will leak.  iks_set_mem_funcs(NULL, NULL);#endif}int CIksDemo::init(IUserInterface* ui){  mInteractions = new CInteractions(this);  if (!mInteractions) { return 0; }  mUi = ui;  if (!mTransport) {    mUi->displayErrorMsg("ASSERTION: mTransport");    return 0;  }  if (!mTransport->connect_async) {    mUi->displayErrorMsg("ASSERTION: mTransport->connect_async");    return 0;  }   return 1;}void CIksDemo::releaseUi() { mUi = NULL; }IUserInteractions* CIksDemo::cmd(){  return mInteractions;}int CIksDemo::StreamHook(void *user_data, int type, iks *node){  return ((CIksDemo*)user_data)->streamHook(type, node);}void CIksDemo::LogHook(void *user_data, const char *data, size_t size, int is_incoming){  ((CIksDemo*)user_data)->logHook(data, size, is_incoming);}int CIksDemo::SocketHook(void *user_data, iksasyncevent* event){  return ((CIksDemo*)user_data)->socketHook(event->event, event->data0, event->data1);}int CIksDemo::streamHook(int type, iks *node){#ifdef ENABLE_DEBUG_PRINTFS  printf("CIksDemo::streamHook: %i\n", type);#endif  if (mIsDisconnecting) {    iks_delete(node);    // Tell parser to stop parsing.    return IKS_HOOK;  }  switch (type) {  case IKS_NODE_START:    {       // First send authorization       iksid* id  = iks_id_new(iks_stack(node), mJid);       IKS_CHK_PTR(id);       id->resource = (char*)DEFAULT_JABBER_RESOURCE; // REDFLAG: resource really is const right? investigate.       ikspak* pak = iks_packet(node);       IKS_CHK_PTR(pak);       char* sid = iks_find_attrib(pak->x, "id");       IKS_CHK_PTR(sid);       iks* msg = iks_make_auth (id, mPassword, sid);       IKS_CHK_PTR(msg);       IKS_CHK_PTR(iks_insert_attrib(msg, "id", "auth"));       IKS_CHK(iks_send(mPrs, msg));       iks_delete(msg);    }    break;  case IKS_NODE_NORMAL:    {      ikspak* pak = iks_packet(node);      IKS_CHK_PTR(pak);      char* id = iks_find_attrib(pak->x, "id");      //IKS_CHK_PTR(id); not an error      if (id) {        if (0 == strcmp("auth", id)) {          if (pak->subtype == IKS_TYPE_RESULT) {            state(AUTHORIZED);            // Set presence to available.            iks* pres = iks_make_pres (IKS_SHOW_AVAILABLE, NULL);            IKS_CHK_PTR(pres);            IKS_CHK(iks_send(mPrs, pres));            iks_delete(pres);          }          else if (pak->subtype == IKS_TYPE_ERROR) {            displayErrorPacket(pak);            state(ERROR);            iks_delete(node);            disconnect();             return IKS_HOOK;          }          else {            iks_delete(node);            return IKS_HOOK;          }        }      }      packet(pak);    }    break;  // hmmmm....  case IKS_NODE_STOP:  case IKS_NODE_ERROR:    iks_delete(node);    // This will eventually cause iks_parse to return     // an error code.    return IKS_HOOK;  }  iks_delete(node);  return IKS_OK;}#ifndef ENABLE_DEBUG_PRINTFSvoid CIksDemo::logHook(const char* , size_t, int ) {}#elsevoid CIksDemo::logHook(const char * data, size_t /*size*/, int is_incoming){  if (is_incoming) {    printf("RECV:%s\n", data);  }  else {    printf("SENT:%s\n", data);  }}#endif int CIksDemo::socketHook(int reason, int data0, int data1){#ifdef ENABLE_DEBUG_PRINTFS  printf("CIksDemo::socketHook: %i %i %i\n", reason, data0, data1);#endif  switch (reason) {  case IKS_ASYNC_RESOLVED:    state(RESOLVED);    break;  case IKS_ASYNC_CONNECTED:    state(CONNECTED);    break;  case IKS_ASYNC_WRITE:    mWriteCount += data0;    break;  case IKS_ASYNC_WRITTEN:    mWrittenCount += data0;    break;  case IKS_ASYNC_READ:    if (mPrs) {      int ret = iks_recv(mPrs, 0);      // Ignore the IKS_HOOK we caused in the streamHook.      if (ret != IKS_HOOK) {        IKS_CHK(ret);        if (IKS_OK != ret) {          disconnect();          break;        }      }      mReadCount += data0;    }    break;  case IKS_ASYNC_CLOSED:    if (mPrs && mUi) {      // You shouldn't be able to get here except      // as the result of iks_disconnect();      mUi->displayErrorMsg("ASSERTION: !mPrs");    }    state(QUIESCENT);    break;  case IKS_ASYNC_ERROR:    // We expect the server to drop the connection    // when the </stream:stream> tag is sent.    if (data0 == IKS_NET_DROPPED && mIsDisconnecting) {      disconnect();      return IKS_OK;    }    // The error was not expected.    displaySocketError(data0, data1);    state(ERROR);    disconnect();    break;  }  return IKS_OK;}void CIksDemo::state(const LoginStates& state){  if (mState == state) { return; }  mState = state;  const char* statusMsg = "???";  switch (mState) {  case QUIESCENT : statusMsg="QUIESCENT"; break;  case CONNECTING: statusMsg="CONNECTING"; break;  case RESOLVING: statusMsg="RESOLVING"; break;  case RESOLVED: statusMsg="RESOLVED"; break;  case CONNECTED: statusMsg="CONNECTED"; break;  case AUTHORIZED: statusMsg="AUTHORIZED"; break;  case ERROR: statusMsg="ERROR"; break;  }  if (mUi) {    mUi->displayStatusMsg(statusMsg);  }}int CIksDemo::connect(const char* jid, const char* password, int port){  if (strlen(jid) >= MAX_JID_LEN ||       strlen(password) >= MAX_PASSWORD_LEN)     { return 0; }  disconnect();    // Parse user id and server name out of the jid  ikstack* s = iks_stack_new(256, 0);  IKS_CHK_PTR(s);  if (!s) { return 0; }  iksid* id = iks_id_new (s, jid);  IKS_CHK_PTR(id);  if (!id) { iks_stack_delete(s); return 0; }  if ((!(id->user)) || (!(id->server))) { iks_stack_delete(s); return 0; }    mPrs = NULL;  strcpy(mJid, jid);  strcpy(mPassword, password);  mWriteCount = 0;  mWrittenCount = 0;  mReadCount = 0;  mIsDisconnecting = 0;  // Create parser instance  mPrs = iks_stream_new (IKS_NS_CLIENT, this, CIksDemo::StreamHook);  IKS_CHK_PTR(mPrs);#ifdef ENABLE_DEBUG_PRINTFS  // Optional logging of data coming into and out of socket.  iks_set_log_hook (mPrs, CIksDemo::LogHook);#endif  // Connect.  int ret = iks_connect_async_with (mPrs, id->server, port,  id->server,                                     mTransport, this, CIksDemo::SocketHook);  IKS_CHK(ret);  iks_stack_delete(s);    return ret == IKS_OK;}void CIksDemo::disconnect(int bHard){  if (!mPrs) { return; }  // Force a hard disconnect when called while waiting for  // a soft disconnect to complete.  if (bHard || mIsDisconnecting) {    iksparser* deadManWalking = mPrs;    mPrs = NULL;    iks_disconnect(deadManWalking);    iks_parser_delete(deadManWalking);  }  else {    // Tell the server we have gone away.    iks* pres = iks_make_pres (IKS_SHOW_UNAVAILABLE, NULL);    IKS_CHK_PTR(pres);    IKS_CHK(iks_send(mPrs, pres));    iks_delete(pres);    // Send the end of stream tag.    IKS_CHK(iks_send_raw(mPrs, "</stream:stream>"));    // Wait for the server to drop the socket connection.    mIsDisconnecting = 1;  }}void CIksDemo::packet(ikspak* packet){  // For now, all all we do is display the  // body of message packets.  //  if (packet->type == IKS_PAK_MESSAGE) {    const char* from = "";    const char* msg = "";    if (packet->from->full) { from = packet->from->full; }    iks* body = iks_find(packet->x, "body");    if (body) {      if (iks_cdata(iks_child(body))) {        msg = iks_cdata(iks_child(body));      }    }    if (mUi) {      mUi->displayJabberMsgFrom(from, msg );    }  }}// Send a Jabber message.int CIksDemo::send(const char* toJid, const char* msg){  if (mState != AUTHORIZED) { return 0; }    iks* node = iks_new("message");  IKS_CHK_PTR(node);  IKS_CHK_PTR(iks_insert_attrib(node, "to", toJid));  iks* body = iks_insert(node, "body");  IKS_CHK_PTR(body);  IKS_CHK_PTR(iks_insert_cdata(body, msg, 0));  int ret = iks_send(mPrs, node);  IKS_CHK(ret);  iks_delete(node);  return ret == IKS_OK;}void CIksDemo::checkIksReturnValue(int err, const char* file,  int line){  if (err == IKS_OK || (!mUi)) { return; }  char buff[512];  sprintf(buff, "iks function failed: %s:%i ret: %i", file, line, err);#ifdef ENABLE_DEBUG_PRINTFS  printf("RUNTIME ERROR: %s\n", buff);#endif  mUi->displayErrorMsg(buff);}void CIksDemo::displayErrorPacket(ikspak* pak){  if (!mUi) { return; }  const char* code = "";   const char* msg =  "";    iks* node = iks_find(pak->x, "error");  if (node) {    code = iks_find_attrib(node, "code");    msg = iks_cdata(iks_child(node));  }  char buff[512];  sprintf(buff, "%s %s", code, msg);#ifdef ENABLE_DEBUG_PRINTFS  printf("ERROR PACKET: %s\n", buff);#endif  mUi->displayErrorMsg(buff);}void CIksDemo::displaySocketError(int data0, int data1){  if (!mUi) { return; }  char buff[512];  sprintf(buff, "IKS_ASYNC_ERROR: %i %i", data0, data1);#ifdef ENABLE_DEBUG_PRINTFS  printf("%s\n", buff);#endif  mUi->displayErrorMsg(buff);}

⌨️ 快捷键说明

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