00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022 #include "binarytermsender.h"
00023 #include "binarytermtypes.h"
00024 #include "glibtojava.h"
00025 #include "libicl_private.h"
00026
00027 #ifdef _WINDOWS
00028 #include <windows.h>
00029 #include <winsock.h>
00030 #else
00031 #include <sys/types.h>
00032 #include <sys/socket.h>
00033 #include <unistd.h>
00034 #endif
00035
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038
00039 struct BinaryTermSenderStruct
00040 {
00041 TermSender* superSender;
00042 }
00043 ;
00044
00045 typedef struct TermRecordStruct
00046 {
00047 ICLTerm* term;
00048 int numTimesVisited;
00049 }
00050 TermRecord;
00051
00052 static TermRecord* binaryTermSender_newTermRecord(ICLTerm* term)
00053 {
00054 TermRecord* t = (TermRecord*)malloc(sizeof(TermRecord));
00055 t->numTimesVisited = 0;
00056 t->term = term;
00057 return t;
00058 }
00059
00060 void binaryTermSender_sendTerm(TermSender* ts, ICLTerm* toSend);
00061 void binaryTermSender_cleanup(TermSender* ts);
00062
00063 BinaryTermSender* binaryTermSender_create(TermSender* t, gint sendSocket)
00064 {
00065 BinaryTermSender* s = (BinaryTermSender*)malloc(sizeof(BinaryTermSender));
00066 s->superSender = t;
00067 termSender_setSendTermCallback(t, binaryTermSender_sendTerm);
00068 termSender_setCleanupCallback(t, binaryTermSender_cleanup);
00069 termSender_setType(t, BINARYTERMSENDERTYPE);
00070 termSender_setSocket(t, sendSocket);
00071 termSender_setSenderSpecificData(t, s);
00072 return s;
00073 }
00074
00078 void binaryTermSender_sendTerm(TermSender* ts, ICLTerm* inputTerm)
00079 {
00087 GByteArray* sendBuf = g_byte_array_new();
00088 GQueue* termRecordList = g_queue_new();
00089 TermRecord* currentRecord;
00090 ssize_t sent;
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 g_queue_push_tail(termRecordList, binaryTermSender_newTermRecord(inputTerm));
00108 while(!g_queue_is_empty(termRecordList)) {
00109 currentRecord = (TermRecord*)g_queue_pop_tail(termRecordList);
00110 ++currentRecord->numTimesVisited;
00111 if(currentRecord->numTimesVisited == 2) {
00112 if(icl_IsStruct(currentRecord->term)) {
00113 gchar* functor = icl_Functor(currentRecord->term);
00114 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLSTRUCT);
00115 sendBuf = glibtojava_writeJavaInt(sendBuf, icl_NumTerms(currentRecord->term));
00116 sendBuf = glibtojava_writeJavaInt(sendBuf, strlen(functor));
00117 sendBuf = glibtojava_writeJavaChars(sendBuf, strlen(functor), functor);
00118 free(currentRecord);
00119 }
00120 else if(icl_IsList(currentRecord->term)) {
00121 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLLIST);
00122 sendBuf = glibtojava_writeJavaInt(sendBuf, icl_NumTerms(currentRecord->term));
00123 free(currentRecord);
00124 }
00125 else if(icl_IsGroup(currentRecord->term)) {
00126 gchar starter;
00127 gchar* sep;
00128 icl_GetGroupChars(currentRecord->term, &starter, &sep);
00129 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLGROUP);
00130 sendBuf = glibtojava_writeJavaInt(sendBuf, icl_NumTerms(currentRecord->term));
00131 sendBuf = glibtojava_writeJavaChar(sendBuf, starter);
00132 free(currentRecord);
00133 }
00134 else {
00135 fprintf(stderr, "binaryTermSender_sendTerm() Unexpected type visited twice\n");
00136 termSender_setError(ts, TERMSENDER_BINUNKNOWNTYPETWICE);
00137 return;
00138 }
00139 continue;
00140 }
00141 else {
00142 if(icl_IsInt(currentRecord->term)) {
00143 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLINT);
00144 sendBuf = glibtojava_writeJavaLong(sendBuf, icl_Int(currentRecord->term));
00145 free(currentRecord);
00146 }
00147 else if(icl_IsFloat(currentRecord->term)) {
00148 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLFLOAT);
00149 sendBuf = glibtojava_writeJavaDouble(sendBuf, icl_Float(currentRecord->term));
00150 free(currentRecord);
00151 }
00152 else if(icl_IsVar(currentRecord->term)) {
00153 gchar* name = icl_Str(currentRecord->term);
00154 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLVAR);
00155 sendBuf = glibtojava_writeJavaInt(sendBuf, strlen(name));
00156 sendBuf = glibtojava_writeJavaChars(sendBuf, strlen(name), name);
00157 free(currentRecord);
00158 }
00159 else if(icl_IsStr(currentRecord->term)) {
00160 gchar* name = icl_Str(currentRecord->term);
00161 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLSTR);
00162 sendBuf = glibtojava_writeJavaInt(sendBuf, strlen(name));
00163 sendBuf = glibtojava_writeJavaChars(sendBuf, strlen(name), name);
00164 free(currentRecord);
00165 }
00166 else if(icl_IsDataQ(currentRecord->term)) {
00167 gchar* data = icl_DataQ(currentRecord->term);
00168 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLDATAQ);
00169 sendBuf = glibtojava_writeJavaInt(sendBuf, currentRecord->term->len);
00170 sendBuf = glibtojava_writeJavaBytes(sendBuf, currentRecord->term->len, (guint8*)data);
00171
00172 free(currentRecord);
00173 }
00174 else if(icl_IsStruct(currentRecord->term) ||
00175 icl_IsList(currentRecord->term) ||
00176 icl_IsGroup(currentRecord->term)) {
00177 ICLListType* args = icl_List(currentRecord->term);
00178 g_queue_push_tail(termRecordList, currentRecord);
00179 while(args != NULL) {
00180 if(icl_IsValid(icl_ListElement(args))) {
00181 g_queue_push_tail(termRecordList, binaryTermSender_newTermRecord(icl_ListElement(args)));
00182 }
00183 else {
00184 fprintf(stderr, "binaryTermSender_sendTerm() invalid element to add to queue\n");
00185 termSender_setError(ts, TERMSENDER_BININVALIDELEMENT);
00186 return;
00187 }
00188 args = icl_ListNextElement(args);
00189 }
00190 }
00191 else {
00192 fprintf(stderr, "binaryTermSender_sendTerm() Unexpected type visited once\n");
00193 termSender_setError(ts, TERMSENDER_BINUNKNOWNTYPEONCE);
00194 return;
00195 }
00196 }
00197 }
00198
00199
00200
00201 {
00202 gchar* functor = "term";
00203 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_ICLSTRUCT);
00204 sendBuf = glibtojava_writeJavaInt(sendBuf, 1);
00205 sendBuf = glibtojava_writeJavaInt(sendBuf, 4);
00206 sendBuf = glibtojava_writeJavaChars(sendBuf, 4, functor);
00207 }
00208
00209 sendBuf = glibtojava_writeJavaInt(sendBuf, BTT_SENTINEL);
00210
00211 #ifdef _WINDOWS
00212 if(send(termSender_getSocket(ts), sendBuf->data, sendBuf->len, 0) == SOCKET_ERROR) {
00213 termSender_setError(ts, TERMSENDER_BADSEND);
00214 return;
00215 }
00216 #else
00217 sent = write(termSender_getSocket(ts), sendBuf->data, sendBuf->len);
00218 if((sent < 0) ||
00219 ((sent > 0) && ((size_t)sent != sendBuf->len)))
00220 {
00221 termSender_setError(ts, TERMSENDER_BADSEND);
00222 return;
00223 }
00224 fsync(termSender_getSocket(ts));
00225 #endif
00226
00227 g_queue_free(termRecordList);
00228 g_byte_array_free(sendBuf, TRUE);
00229 }
00230
00231 void binaryTermSender_cleanup(TermSender* ts)
00232 {
00233 if(termSender_getSenderSpecificData(ts) != NULL) {
00234 free(termSender_getSenderSpecificData(ts));
00235 termSender_setSenderSpecificData(ts, NULL);
00236 }
00237 }