Logo Search packages:      
Sourcecode: earth3d version File versions  Download package

connectNetworkService.cpp

#include "qServiceLib.h"
#include <string.h>
#include "connectNetworkService.h"
#include <vector>
#include <string>
#include <iostream>
#include <qdom.h>
#include "urlDownload.h"

#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

using namespace std;

#define min(a,b) (a)>(b)?(b):(a)

ConnectNetworkService::ConnectNetworkService(const char *host, int port) : ConnectNetworkServiceRequestQueue(5) {
  currentMessageID = 0;
  connect(&sl, SIGNAL(marketplaceConnected()), this, SLOT(marketplaceConnected()));
  sl.connectToServer(host, port);
}

ConnectNetworkService::~ConnectNetworkService() {
}

00029 void ConnectNetworkService::parseDocument(int countParts, struct part_t *parts, char *sender) {
  /* create DOM structure */
  QDomDocument doc;
  QString error;
  int errorLine, errorColumn;
  QString document = QCString(parts[0].content, parts[0].size+1);
  printf("Document: \"%s\"\n", document.latin1());
  if (doc.setContent(document, true, &error, &errorLine, &errorColumn)) {
    QDomNode n = doc.documentElement();
    if (n.isElement() && n.toElement().tagName() != QString("response")) {
      fprintf(stderr,"document of the wrong type (%s), root node != response\n", n.toElement().tagName().latin1());
      return;
    }

    int msgid = n.toElement().attribute("msgid", "0").toInt();

    QString output;
    QTextStream ts(&output, IO_WriteOnly);
    ts << n;

    forwardMessage((const char *) output.latin1(), msgid, sender, countParts, parts);
  }
  else {
    printf("XML Error \"%s\" in line %i at column %i\n", error.latin1(), errorLine, errorColumn);
  }
}

00056 void ConnectNetworkService::send(const char *receiver, const char *message) {
  requesttime = QTime::currentTime();

//  logNetwork->debug(QString("send(\"")+receiver+"\",\""+message+"\"");
#ifdef EARTH3DDEBUG
  cout << QString("send(\"")+receiver+"\",\""+message+"\"" << endl;
#endif

  if (!sl.getIsConnected()) {
    /* queue message */
#ifdef EARTH3DDEBUG
    cout << "queued" << endl;
#endif
    preConnectMessages.push_back(QueuedMessage(QString(receiver), QString(message)));
  }
  else {
    // Receiver
    sl.sendHeader(receiver, 1);

    // Part
    sl.sendPart(strlen(message), message);
  }
}

00080 void ConnectNetworkService::run() {
  // now we are connected to the server

  while(1) {
//     printf("start readParts\n");
    int countParts = sl.readParts(sender, 255, parts, 100);
    if (countParts==0) break;
//     printf("countParts=%i\n", countParts);
    printf("received...\n");
    char line[1024];
    strncpy(line, parts[0].content, min(parts[0].size, 1023));
    line[min(parts[0].size,1023)]=0;
    printf("------------------------------------------------------------\n"
         "Sender: %s\n"
         "XML: %s\n"
         "------------------------------------------------------------\n", sender, line);
    // send to all listeners
    std::vector<ServiceFoundListener *>::iterator it = sflList.begin();
    while(it!=sflList.end()) {
      char *doc = new char[parts[0].size+1];
      memcpy(doc, parts[0].content, parts[0].size);
      doc[parts[0].size]=0;
      ((ServiceFoundListener *)(*it))->serviceFound(doc, sender);
      delete(doc);

      it++;
    }

    // BEGIN Parse the content
    parseDocument(countParts, parts, sender);
    // END Parse the content

    sl.freeParts(parts, countParts);
  }
}

00116 void ConnectNetworkService::addDataReceivedListener(DataReceivedListener *drl) {
  drlList.push_back(drl);
}

/** Sends a request into the network */
00121 void ConnectNetworkService::getOne(const char *xmlconnections, DataReceivedListener *drl, void *userdata, int timeout) {
  if (xmlconnections==NULL) return;
  
  /* parse the connections and choose one */
  char *connection = chooseConnection(xmlconnections);
//   std::cout << "get connection: " << connection << std::endl;

  get(connection, drl, userdata, timeout);
  delete[](connection);
}

00132 long ConnectNetworkService::get(const char *xmlconnection, DataReceivedListener *drl, void *userdata, int timeout, bool allowCache) {
  /* enqueue request until the request queue goes under a certain limit */
  push(new ConnectNetworkServiceRequestQueueObject(xmlconnection, drl, userdata, timeout, allowCache));

  return(0);
}

00139 void ConnectNetworkService::getURL(const char *xmlconnection, long currentMessageID, bool allowCache) {
  TimedDataReceivedListener *listener = getMapHandler(currentMessageID);

  listener->urldownload = new URLDownload(xmlconnection, this, (void *) currentMessageID, allowCache);
  listener->urldownload->run();
}

void ConnectNetworkService::forwardMessage(const char *xmlresponse, long msgid, const char *sender, int countParts, struct part_t *parts) {
  TimedDataReceivedListener *listener = getMapHandler(msgid);

  if (listener) {
    listener->drl->dataReceived(xmlresponse, strlen(xmlresponse), sender, countParts, parts, listener->userdata, this, NULL);
  }
}

00154 char *ConnectNetworkService::chooseConnection(const char *xmlconnections) {
  /* create DOM structure */
  QDomDocument doc;
  if (doc.setContent(QString(xmlconnections))) {
    QDomNode cur = doc.documentElement();
    if (cur.isElement() && cur.toElement().tagName() == QString("connections")) {
      QDomNode start = cur;

      /* search for agent or url connection */
      cur = start.firstChild();
      while(!cur.isNull()) {
      if (cur.isElement() && (cur.toElement().tagName() == QString("agent") || cur.toElement().tagName() == QString("url"))) {

        /* copy agent node into string */
        QString output;
        QTextStream ts(&output, IO_WriteOnly);
        ts << cur;

        char *result = new char[output.length()+1];
        strcpy(result, output.latin1());
        return(result);
      }

      cur = cur.nextSibling();
      }
    }
  }

  return(NULL);
}


00186 QString ConnectNetworkService::getReceiver(const char *xmlconnection) {
  QString result;
  QDomDocument doc;
  if (doc.setContent(QString(xmlconnection))) {
    /* search for agent tag */
    QDomNode n = doc.documentElement();
    while( !n.isNull() ) {
      QDomElement e = n.toElement(); // try to convert the node to an element.
//       logNetwork->debug(e.tagName());
      if( !e.isNull() && e.tagName() == QString("agent")) {
      result = e.attribute("agent"); // get name of the local agent
      }
      n = n.nextSibling();
    }
  }

  printf("getReceiver found receiver %s in %s\n", result.latin1(), xmlconnection);

  return(result);
}

00207 bool ConnectNetworkService::requestData(ConnectNetworkServiceRequestQueueObject *request) {
  int currentMessageID = request->getMessageID();

  // check the tag if it must be send to the agent system or if it is an URL
  bool isAgent = false;
  bool isURL = false;
  QString result;
  QString url;
  QDomDocument doc;
  if (doc.setContent(QString(request->getxmlconnection()))) {
    /* search for agent tag */
    QDomNode n = doc.documentElement();
    while( !n.isNull() ) {
      QDomElement e = n.toElement(); // try to convert the node to an element.
      // logNetwork->debug(e.tagName());
      if( !e.isNull() && e.tagName() == QString("agent")) {
      isAgent = true;
      }
      if( !e.isNull() && e.tagName() == QString("url")) {
      isURL = true;
      url = e.attribute("address");
      if (e.hasAttribute("allowCache")) {
        request->setAllowCache(e.attribute("allowCache") == "true");
      }
      }
      n = n.nextSibling();
    }
  }

  /* agent request */
  if (isAgent) {
    QString xmlrequest = QString("<?xml version=\"1.0\"?><get msgid=\"") + QString::number(currentMessageID) + "\">";
    xmlrequest += request->getxmlconnection();
    xmlrequest += "</get>";

    /* the data goes to the receiver, without using the RequestQueue */
    TimedDataReceivedListener *listener = getMapHandler(currentMessageID);
    listener->userdata = request->getUserData();
    listener->drl = request->getDataReceivedListener();

    send(getReceiver(request->getxmlconnection()), xmlrequest.latin1());
    return(true); // needs to be dequeued immediately
  }
  if (isURL) {
    getURL(url.latin1(), currentMessageID, request->getAllowCache());
    return(false); // needs to stay in queue
  }

  return(true);
}

void ConnectNetworkService::marketplaceConnected() {
#ifdef EARTH3DDEBUG
  printf("CONNECTED\n");
#endif
  sl.login(10);
  start();

  /* send queued messages */
#ifdef EARTH3DDEBUG
  cout << "de-queued" << endl;
#endif
  QValueVector<QueuedMessage>::iterator i;
  for(i=preConnectMessages.begin(); i!=preConnectMessages.end(); i++) {
    send((*i).receiver.latin1(), (*i).message.latin1());
  }

  preConnectMessages.clear();
}


Generated by  Doxygen 1.6.0   Back to index