stringtermsender.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006  SRI International
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  * SRI International: 333 Ravenswood Ave, Menlo Park, CA 94025
00019  */
00020 
00021 #ifdef _WINDOWS
00022 #include <windows.h>
00023 #include <winsock.h>
00024 #else
00025 #include <sys/types.h>
00026 #include <sys/socket.h>
00027 #include <unistd.h>     /* close        */
00028 #include <sys/time.h>   /* For polling time */
00029 #endif
00030 
00031 #include <stdlib.h>
00032 #include <stdio.h>
00033 
00034 #include "stringtermsender.h"
00035 #include "libicl_private.h"
00036 
00037 struct StringTermSenderStruct 
00038 {
00039   TermSender* superSender;
00040 }
00041 ;
00042 
00043 void stringTermSender_sendTerm(TermSender* ts, ICLTerm* toSend);
00044 void stringTermSender_cleanup(TermSender* ts);
00045 
00046 StringTermSender* stringTermSender_create(TermSender* t, gint sendSocket) 
00047 {
00048   StringTermSender* s = (StringTermSender*)malloc(sizeof(StringTermSender));
00049   s->superSender = t;
00050   termSender_setSendTermCallback(t, stringTermSender_sendTerm);
00051   termSender_setCleanupCallback(t, stringTermSender_cleanup);
00052   termSender_setType(t, STRINGTERMSENDERTYPE);
00053   termSender_setSocket(t, sendSocket);
00054   termSender_setSenderSpecificData(t, s);
00055   return s;
00056 }
00057 
00058 void stringTermSender_sendTerm(TermSender* ts, ICLTerm* toSend) 
00059 {
00060   char* termAsString = NULL;
00061   size_t termAsStringLen = 0;
00062   int sendRes = 0;
00063   int toWireStringRes = 0;
00064   char* presend = "term(";
00065   size_t presendLen = 5;
00066   char* postsend = ").\n";
00067   size_t postsendLen = 3;
00068 
00069   if(toSend == NULL) {
00070     termSender_setError(ts, TERMSENDER_NULLTOSEND);
00071     return;
00072   }
00073   
00074   toWireStringRes = icl_toWireString(toSend, &termAsString, &termAsStringLen);
00075   if(toWireStringRes == FALSE) {
00076     fprintf(stderr, "stringTermSender_sendTerm error creating wire string");
00077     termSender_setError(ts, TERMSENDER_BADTRANSLATION);
00078     return;
00079   }
00080 
00081   if(termSender_getSocket(ts) > 0) {
00082 #ifdef _WINDOWS
00083     while(TRUE) {
00084       if(send(termSender_getSocket(ts), presend, presendLen, 0) == SOCKET_ERROR) {
00085         sendRes = -1;
00086         break;
00087       }
00088       if(send(termSender_getSocket(ts), termAsString, termAsStringLen, 0) == SOCKET_ERROR) {
00089         sendRes = -1;
00090         break;
00091       }
00092       if(send(termSender_getSocket(ts), postsend, postsendLen, 0) == SOCKET_ERROR) {
00093         sendRes = -1;
00094         break;
00095       }
00096       sendRes = 0;
00097       break;
00098     }
00099 #else
00100     while(TRUE) {
00101       sendRes = write(termSender_getSocket(ts), presend, presendLen);
00102       if((size_t)sendRes != presendLen) {
00103         if(sendRes == -1) {
00104           perror("stringTermSender_sendTerm() bad write");
00105         }
00106         sendRes = -1;
00107         break;
00108       }
00109       sendRes = write(termSender_getSocket(ts), termAsString, termAsStringLen);
00110       if((size_t)sendRes != termAsStringLen) {
00111         if(sendRes == -1) {
00112           perror("stringTermSender_sendTerm() bad write");
00113         }
00114         sendRes = -1;
00115         break;
00116       }
00117       sendRes = write(termSender_getSocket(ts), postsend, postsendLen);
00118       if((size_t)sendRes != postsendLen) {
00119         if(sendRes == -1) {
00120           perror("stringTermSender_sendTerm() bad write");
00121         }
00122         sendRes = -1;
00123         break;
00124       }
00125       sendRes = 0;
00126       break;
00127     }
00128 #endif
00129   }
00130 
00131   // termAsString was created using glib, so it must be freed using
00132   // glib. Note that on Unix, it is valid to call free instead of
00133   // g_free. However, on Windows dlls use their own copy of the c runtime
00134   // library and have a different heap. The object must be freed from
00135   // the heap where it was created, or an assertion is thrown. The
00136   // most efficient workaround to this would be to try and compile
00137   // everything into a static exe when building an oaa app. The static
00138   // exe would contain all object code for the glib libraries and oaalib.
00139   g_free(termAsString);
00140 
00141   if(sendRes == -1) {
00142     fprintf(stderr, "stringTermSender_sendTerm() sendRes == -1\n");
00143     termSender_setError(ts, TERMSENDER_BADSEND);
00144     return;
00145   }
00146 
00147   termSender_setError(ts, TERMSENDER_OKAY);
00148 }
00149 
00150 void stringTermSender_cleanup(TermSender* ts) 
00151 {
00152   if(termSender_getSenderSpecificData(ts) != NULL) {
00153     free(termSender_getSenderSpecificData(ts));
00154     termSender_setSenderSpecificData(ts, NULL);
00155   }
00156 }

Generated on Wed May 23 17:20:13 2007 using doxygen 1.5.2