stringtermsender.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 137 行

C
137
字号
#ifdef _WINDOWS
#include <windows.h>
#include <winsock.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>     /* close        */
#include <sys/time.h>   /* For polling time */
#endif

#include <stdlib.h>
#include <stdio.h>

#include "stringtermsender.h"
#include "libicl_private.h"

struct StringTermSenderStruct 
{
  TermSender* superSender;
}
;

void stringTermSender_sendTerm(TermSender* ts, ICLTerm* toSend);
void stringTermSender_cleanup(TermSender* ts);

StringTermSender* stringTermSender_create(TermSender* t, gint sendSocket) 
{
  StringTermSender* s = (StringTermSender*)malloc(sizeof(StringTermSender));
  s->superSender = t;
  termSender_setSendTermCallback(t, stringTermSender_sendTerm);
  termSender_setCleanupCallback(t, stringTermSender_cleanup);
  termSender_setType(t, STRINGTERMSENDERTYPE);
  termSender_setSocket(t, sendSocket);
  termSender_setSenderSpecificData(t, s);
  return s;
}

void stringTermSender_sendTerm(TermSender* ts, ICLTerm* toSend) 
{
  char* termAsString = NULL;
  size_t termAsStringLen = 0;
  int sendRes = 0;
  int toWireStringRes = 0;
  char* presend = "term(";
  size_t presendLen = 5;
  char* postsend = ").\n";
  size_t postsendLen = 3;

  if(toSend == NULL) {
    termSender_setError(ts, TERMSENDER_NULLTOSEND);
    return;
  }
  
  toWireStringRes = icl_toWireString(toSend, &termAsString, &termAsStringLen);
  //printf("%s: termAsString == %s\n", __PRETTY_FUNCTION__, termAsString);
  if(toWireStringRes == FALSE) {
    fprintf(stderr, "stringTermSender_sendTerm error creating wire string");
    return;
  }

  if(termSender_getSocket(ts) > 0) {
#ifdef _WINDOWS
    while(TRUE) {
      if(send(termSender_getSocket(ts), presend, presendLen, 0) == SOCKET_ERROR) {
        sendRes = -1;
        break;
      }
      if(send(termSender_getSocket(ts), termAsString, termAsStringLen, 0) == SOCKET_ERROR) {
        sendRes = -1;
        break;
      }
      if(send(termSender_getSocket(ts), postsend, postsendLen, 0) == SOCKET_ERROR) {
        sendRes = -1;
        break;
      }
      sendRes = 0;
      break;
    }
#else
    while(TRUE) {
      sendRes = write(termSender_getSocket(ts), presend, presendLen);
      if((size_t)sendRes != presendLen) {
        if(sendRes == -1) {
          perror("stringTermSender_sendTerm() bad write");
        }
        sendRes = -1;
        break;
      }
      sendRes = write(termSender_getSocket(ts), termAsString, termAsStringLen);
      if((size_t)sendRes != termAsStringLen) {
        if(sendRes == -1) {
          perror("stringTermSender_sendTerm() bad write");
        }
        sendRes = -1;
        break;
      }
      sendRes = write(termSender_getSocket(ts), postsend, postsendLen);
      if((size_t)sendRes != postsendLen) {
        if(sendRes == -1) {
          perror("stringTermSender_sendTerm() bad write");
        }
        sendRes = -1;
        break;
      }
      sendRes = 0;
      break;
    }
#endif
  }

  // termAsString was created using glib, so it must be freed using
  // glib. Note that on Unix, it is valid to call free instead of
  // g_free. However, on Windows dlls use their own copy of the c runtime
  // library and have a different heap. The object must be freed from
  // the heap where it was created, or an assertion is thrown. The
  // most efficient workaround to this would be to try and compile
  // everything into a static exe when building an oaa app. The static
  // exe would contain all object code for the glib libraries and oaalib.
  g_free(termAsString);

  if(sendRes == -1) {
    fprintf(stderr, "stringTermSender_sendTerm() sendRes == -1\n");
    termSender_setError(ts, TERMSENDER_BADSEND);
    return;
  }

  termSender_setError(ts, TERMSENDER_OKAY);
}

void stringTermSender_cleanup(TermSender* ts) 
{
  if(termSender_getSenderSpecificData(ts) != NULL) {
    free(termSender_getSenderSpecificData(ts));
    termSender_setSenderSpecificData(ts, NULL);
  }
}

⌨️ 快捷键说明

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