00001 /*---------------------------------------------------------------------------- 00002 Name: xmlBlasterSocket.c 00003 Project: xmlBlaster.org 00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file 00005 Comment: Contains some socket specific helper methods 00006 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info> 00007 -----------------------------------------------------------------------------*/ 00008 #include <stdio.h> 00009 #include <string.h> 00010 #include <socket/xmlBlasterSocket.h> 00011 00012 void closeSocket(int fd) { 00013 #ifdef _WINDOWS 00014 closesocket(fd); 00015 #else 00016 (void)close(fd); 00017 #endif 00018 } 00019 00033 ssize_t writen(const int fd, const char * ptr, const size_t nbytes) 00034 { 00035 ssize_t nleft, nwritten; 00036 int flag = 0; /* MSG_WAITALL; */ 00037 00038 nleft = (ssize_t)nbytes; 00039 while(nleft > 0) { 00040 nwritten = send(fd, ptr, (int)nleft, flag); /* write() is deprecated on Win */ 00041 if (nwritten <= 0) { 00042 return nwritten; /* error */ 00043 } 00044 nleft -= nwritten; 00045 ptr += nwritten; 00046 } 00047 return (ssize_t)nbytes - nleft; 00048 } 00049 00068 ssize_t readn(const int fd, char *ptr, const size_t nbytes, XmlBlasterNumReadFunc fpNumRead, void *userP) 00069 { 00070 ssize_t nread; 00071 ssize_t nleft; 00072 int flag = 0; /* MSG_WAITALL; */ 00073 nleft = (ssize_t)nbytes; 00074 00075 if (fpNumRead != 0 && nbytes > 10) { /* Ignore to report the msgLength read (first 10 bytes of a message) */ 00076 fpNumRead(userP, (ssize_t)0, nbytes); /* Callback with startup status */ 00077 } 00078 00079 while(nleft > 0) { 00080 nread = recv(fd, ptr, (int)nleft, flag); /* read() is deprecated on Win */ 00081 if (nread <= 0) /* -1 is error, 0 is no more data to read which should not happen as we are blocking */ 00082 break; /* EOF is -1 */ 00083 nleft -= nread; 00084 00085 if (fpNumRead != 0 && nbytes > 10) { /* Ignore to report the msgLength read (first 10 bytes of a message) */ 00086 fpNumRead(userP, (ssize_t)nbytes-nleft, nbytes); /* Callback with current status */ 00087 } 00088 00089 ptr += nread; 00090 } 00091 return (ssize_t)nbytes-nleft; 00092 } 00093 00100 bool xbl_isOneway(XMLBLASTER_MSG_TYPE msgType, const char *const methodName) { 00101 if (msgType==MSG_TYPE_RESPONSE || msgType==MSG_TYPE_EXCEPTION) 00102 return true; /* Responses and exceptions are oneway */ 00103 if (methodName == 0) 00104 return false; 00105 if ( 00106 !strcmp(XMLBLASTER_PUBLISH_ONEWAY, methodName) 00107 /*|| !strcmp(XMLBLASTER_DISCONNECT, methodName)*/ /* according to protocol.socket it returns an ACK: shall we remove it? */ 00108 ) return true; 00109 return false; 00110 } 00111 00119 Dll_Export BlobHolder encodeMsgUnit(MsgUnit *msgUnit, bool debug) 00120 { 00121 size_t qosLen=0, keyLen=0, contentLenStrLen=0; 00122 enum { SIZE = 126 }; 00123 char contentLenStr[SIZE]; 00124 size_t currpos = 0; 00125 BlobHolder blob; 00126 memset(&blob, 0, sizeof(BlobHolder)); 00127 00128 if (msgUnit == 0) { 00129 if (debug) printf("[xmlBlasterSocket] ERROR Invalid msgUnit=NULL in encodeMsgUnit()\n"); 00130 return blob; 00131 } 00132 if (msgUnit->content == 0) 00133 msgUnit->contentLen = 0; 00134 SNPRINTF(contentLenStr, SIZE, "%ld", (long)msgUnit->contentLen); 00135 contentLenStrLen = strlen(contentLenStr); 00136 00137 if (msgUnit->qos != 0) 00138 qosLen = strlen(msgUnit->qos); 00139 00140 if (msgUnit->key != 0) 00141 keyLen = strlen(msgUnit->key); 00142 00143 blob.dataLen = qosLen + 1 + keyLen + 1 + contentLenStrLen + 1 + msgUnit->contentLen; 00144 00145 blob.data = (char *)malloc(blob.dataLen); 00146 00147 if (msgUnit->qos != 0) 00148 memcpy(blob.data+currpos, msgUnit->qos, qosLen+1); /* inclusive '\0' */ 00149 else 00150 *(blob.data+currpos) = 0; 00151 currpos += qosLen+1; 00152 00153 if (msgUnit->key != 0) 00154 memcpy(blob.data+currpos, msgUnit->key, keyLen+1); /* inclusive '\0' */ 00155 else 00156 *(blob.data+currpos) = 0; 00157 currpos += keyLen+1; 00158 00159 memcpy(blob.data+currpos, contentLenStr, contentLenStrLen+1); /* inclusive '\0' */ 00160 currpos += contentLenStrLen+1; 00161 00162 if (msgUnit->content != 0) 00163 memcpy(blob.data+currpos, msgUnit->content, msgUnit->contentLen); 00164 /* currpos += msgUnit->contentLen; */ 00165 00166 return blob; 00167 } 00168 00176 Dll_Export BlobHolder encodeMsgUnitArr(MsgUnitArr *msgUnitArr, bool debug) 00177 { 00178 size_t i; 00179 size_t currpos = 0; 00180 00181 BlobHolder blob; 00182 memset(&blob, 0, sizeof(BlobHolder)); 00183 00184 if (msgUnitArr == 0) { 00185 if (debug) printf("[xmlBlasterSocket] ERROR Invalid msgUnitArr=NULL in encodeMsgUnitArr()\n"); 00186 return blob; 00187 } 00188 00189 /* First calculate total length to allocate */ 00190 for (i=0; i<msgUnitArr->len; i++) { 00191 MsgUnit* msgUnit = &msgUnitArr->msgUnitArr[i]; 00192 size_t qosLen=0, keyLen=0; 00193 enum { SIZE = 126 }; 00194 char contentLenStr[SIZE]; 00195 00196 if (msgUnit->content == 0) 00197 msgUnit->contentLen = 0; 00198 snprintf0(contentLenStr, SIZE, "%ld", (long)msgUnit->contentLen); 00199 00200 if (msgUnit->qos != 0) 00201 qosLen = strlen(msgUnit->qos); 00202 00203 if (msgUnit->key != 0) 00204 keyLen = strlen(msgUnit->key); 00205 00206 blob.dataLen += qosLen + 1 + keyLen + 1 + strlen(contentLenStr) + 1 + msgUnit->contentLen; 00207 } 00208 00209 blob.data = (char *)malloc(blob.dataLen); 00210 00211 /* Now dump the message ... */ 00212 for (i=0; i<msgUnitArr->len; i++) { 00213 MsgUnit* msgUnit = &msgUnitArr->msgUnitArr[i]; 00214 size_t qosLen=0, keyLen=0, contentLenStrLen=0; 00215 enum { SIZE = 126 }; 00216 char contentLenStr[SIZE]; 00217 00218 if (msgUnit->content == 0) 00219 msgUnit->contentLen = 0; 00220 snprintf0(contentLenStr, SIZE, "%ld", (long)msgUnit->contentLen); 00221 contentLenStrLen = strlen(contentLenStr); 00222 00223 if (msgUnit->qos != 0) { 00224 qosLen = strlen(msgUnit->qos); 00225 memcpy(blob.data+currpos, msgUnit->qos, qosLen+1); /* inclusive '\0' */ 00226 } 00227 else 00228 *(blob.data+currpos) = 0; 00229 currpos += qosLen+1; 00230 00231 if (msgUnit->key != 0) { 00232 keyLen = strlen(msgUnit->key); 00233 memcpy(blob.data+currpos, msgUnit->key, keyLen+1); /* inclusive '\0' */ 00234 } 00235 else 00236 *(blob.data+currpos) = 0; 00237 currpos += keyLen+1; 00238 00239 memcpy(blob.data+currpos, contentLenStr, contentLenStrLen+1); /* inclusive '\0' */ 00240 currpos += contentLenStrLen+1; 00241 00242 if (msgUnit->content != 0) 00243 memcpy(blob.data+currpos, msgUnit->content, msgUnit->contentLen); 00244 currpos += msgUnit->contentLen; 00245 } 00246 return blob; 00247 } 00248 00249 char *encodeSocketMessage( 00250 enum XMLBLASTER_MSG_TYPE_ENUM msgType, 00251 const char * const requestId, 00252 const char * const methodName, 00253 const char * const secretSessionId, 00254 const char *data, 00255 size_t dataLen, 00256 bool debug, 00257 size_t *rawMsgLen) 00258 { 00259 char *rawMsg = (char *)0; 00260 char *rawMsgStr; 00261 size_t currpos = 0; 00262 enum { SIZE = 256 }; 00263 char tmp[SIZE]; 00264 size_t lenUnzipped = dataLen; 00265 enum { SIZEF = 56 }; 00266 char lenFormatStr[56]; /* = "%10.d"; */ 00267 char lenStr[MSG_LEN_FIELD_LEN+1]; 00268 00269 if (data == 0) { 00270 data = ""; 00271 dataLen = 0; 00272 lenUnzipped = 0; 00273 } 00274 00275 rawMsg = (char *)calloc(50 + MAX_SESSIONID_LEN + MAX_METHODNAME_LEN + dataLen, sizeof(char)); 00276 00277 *(rawMsg+MSG_FLAG_POS_TYPE) = (char)msgType; /* e.g. MSG_TYPE_INVOKE */ 00278 *(rawMsg+MSG_FLAG_POS_VERSION) = XMLBLASTER_SOCKET_VERSION; 00279 00280 currpos = MSG_POS_REQESTID; 00281 if (requestId == 0) printf("*** assert: xmlBlasterSocket.c requestId is NULL!\n"); 00282 memcpy(rawMsg+currpos, requestId, strlen(requestId)+1); /* inclusive '\0' */ 00283 currpos += strlen(requestId)+1; 00284 00285 if (methodName == 0) printf("*** assert: xmlBlasterSocket.c methodName is NULL!\n"); 00286 memcpy(rawMsg+currpos, methodName, strlen(methodName)+1); /* inclusive '\0' */ 00287 currpos += strlen(methodName)+1; 00288 00289 if (secretSessionId == 0) printf("*** assert: xmlBlasterSocket.c secretSessionId is NULL!\n"); 00290 memcpy(rawMsg+currpos, secretSessionId, strlen(secretSessionId)+1); /* inclusive '\0' */ 00291 currpos += strlen(secretSessionId)+1; 00292 00293 snprintf0(tmp, SIZE, "%lu", (unsigned long)lenUnzipped); 00294 memcpy(rawMsg+currpos, tmp, strlen(tmp)+1); /* inclusive '\0' */ 00295 currpos += strlen(tmp)+1; 00296 00297 if (data == 0) printf("*** assert: xmlBlasterSocket.c data is NULL!\n"); 00298 memcpy(rawMsg+currpos, data, dataLen); /* add the msgUnit data */ 00299 *rawMsgLen = currpos+dataLen; 00300 00301 snprintf0(lenFormatStr, SIZEF, "%%%d.d", MSG_LEN_FIELD_LEN); 00302 snprintf0(lenStr, MSG_LEN_FIELD_LEN+1, lenFormatStr, *rawMsgLen); 00303 memcpy(rawMsg, lenStr, MSG_LEN_FIELD_LEN); 00304 00305 if (debug) { 00306 rawMsgStr = toReadableDump(rawMsg, *rawMsgLen); 00307 printf("[xmlBlasterSocket] Sending now %lu bytes -> '%s'\n", (unsigned long)*rawMsgLen, rawMsgStr); 00308 free(rawMsgStr); 00309 } 00310 00311 return rawMsg; 00312 } 00313 00330 bool parseSocketData(int xmlBlasterSocket, const XmlBlasterReadFromSocketFuncHolder *fpHolder, 00331 SocketDataHolder *socketDataHolder, XmlBlasterException *exception, bool *stopP, bool udp, bool debug) 00332 { 00333 char msgLenPtr[MSG_LEN_FIELD_LEN+1]; 00334 char *rawMsg = 0; 00335 char tmpPtr[256]; 00336 ssize_t numRead; 00337 size_t currPos = 0; 00338 unsigned long msgLenL; /* to have 64 bit portable sscanf */ 00339 00340 char packet[MAX_PACKET_SIZE]; 00341 /* initialize */ 00342 memset(msgLenPtr, 0, MSG_LEN_FIELD_LEN+1); 00343 memset(socketDataHolder, 0, sizeof(SocketDataHolder)); 00344 memset(exception, 0, sizeof(XmlBlasterException)); 00345 exception->remote = false; 00346 00347 if (debug) printf("[xmlBlasterSocket] Blocking now for %s callback messages ...\n", (udp) ? "udp" : "tcp"); 00348 if (udp) 00349 numRead = recv(xmlBlasterSocket, packet, MAX_PACKET_SIZE, 0); 00350 else 00351 /* read the first 10 bytes to determine the length */ 00352 numRead = fpHolder->readFromSocketFuncP(fpHolder->userP, xmlBlasterSocket, msgLenPtr, MSG_LEN_FIELD_LEN, fpHolder->numReadFuncP, fpHolder->numReadUserP); 00353 if (numRead <= 0 || *stopP == true) { 00354 return false; /* EOF on socket */ 00355 } 00356 if ((!udp && numRead != MSG_LEN_FIELD_LEN) || 00357 ( udp && numRead < MSG_LEN_FIELD_LEN)) { 00358 strncpy0(exception->errorCode, "user.connect", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00359 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, "[xmlBlasterSocket] ERROR Received numRead=%ld header bytes but expected %d", (long)numRead, MSG_LEN_FIELD_LEN); 00360 if (debug) { printf(exception->message); printf("\n"); } 00361 return true; 00362 } 00363 if (udp) { 00364 memcpy(msgLenPtr, packet, MSG_LEN_FIELD_LEN); 00365 } 00366 *(msgLenPtr + MSG_LEN_FIELD_LEN) = 0; 00367 trim(msgLenPtr); 00368 if (strToULong(&msgLenL, msgLenPtr) == false) { 00369 strncpy0(exception->errorCode, "user.connect", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00370 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, 00371 "[xmlBlasterSocket] ERROR Received numRead=%ld header bytes with invalid message length='%s'", 00372 (long)numRead, msgLenPtr); 00373 if (debug) { printf(exception->message); printf("\n"); } 00374 return true; 00375 } 00376 socketDataHolder->msgLen = (size_t)msgLenL; 00377 if (debug) printf("[xmlBlasterSocket] Receiving message of size %lu ...\n", (unsigned long)socketDataHolder->msgLen); 00378 00379 if (socketDataHolder->msgLen <= MSG_LEN_FIELD_LEN || socketDataHolder->msgLen > MAX_MSG_LEN) { 00380 strncpy0(exception->errorCode, "user.connect", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00381 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, 00382 "[xmlBlasterSocket] ERROR Received numRead=%ld header bytes with invalid message length='%s' parsed to '%ld'", 00383 (long)numRead, msgLenPtr, (long)socketDataHolder->msgLen); 00384 if (debug) { printf(exception->message); printf("\n"); } 00385 return true; 00386 } 00387 00388 /* read the complete message */ 00389 rawMsg = (char *)calloc(socketDataHolder->msgLen, sizeof(char)); 00390 memcpy(rawMsg, msgLenPtr, MSG_LEN_FIELD_LEN); 00391 if (udp) { 00392 memcpy(rawMsg+MSG_LEN_FIELD_LEN, packet+MSG_LEN_FIELD_LEN, socketDataHolder->msgLen-MSG_LEN_FIELD_LEN); 00393 numRead -= MSG_LEN_FIELD_LEN; 00394 } 00395 else 00396 numRead = fpHolder->readFromSocketFuncP(fpHolder->userP, xmlBlasterSocket, rawMsg+MSG_LEN_FIELD_LEN, 00397 (int)socketDataHolder->msgLen-MSG_LEN_FIELD_LEN, fpHolder->numReadFuncP, fpHolder->numReadUserP); 00398 if (numRead <= 0 || *stopP == true) { 00399 free(rawMsg); 00400 return false; /* EOF on socket */ 00401 } 00402 if ((size_t)numRead != (socketDataHolder->msgLen-MSG_LEN_FIELD_LEN)) { 00403 strncpy0(exception->errorCode, "user.response", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00404 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, "[xmlBlasterSocket] ERROR Received numRead=%ld message bytes but expected %lu", (long)numRead, (unsigned long)(socketDataHolder->msgLen-MSG_LEN_FIELD_LEN)); 00405 if (debug) { printf(exception->message); printf("\n"); } 00406 free(rawMsg); 00407 return true; 00408 } 00409 00410 if (debug) { 00411 char *rawMsgStr = toReadableDump(rawMsg, socketDataHolder->msgLen); 00412 printf("[xmlBlasterSocket] Read %lu bytes from socket -> '%s'\n", (unsigned long)socketDataHolder->msgLen, rawMsgStr); 00413 free(rawMsgStr); 00414 } 00415 00416 /* if (debug) { 00417 char *tmp = toReadableDump(rawMsg, socketDataHolder->msgLen); 00418 printf("[xmlBlasterSocket] Read %u bytes from socket\n%s\n", socketDataHolder->msgLen, tmp); 00419 free(tmp); 00420 }*/ 00421 00422 socketDataHolder->type = *(rawMsg+MSG_FLAG_POS_TYPE); 00423 if (socketDataHolder->type != MSG_TYPE_INVOKE && 00424 socketDataHolder->type != MSG_TYPE_RESPONSE && 00425 socketDataHolder->type != MSG_TYPE_EXCEPTION) { 00426 strncpy0(exception->errorCode, "user.response", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00427 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, "[xmlBlasterSocket] ERROR Received response message of type=%c", socketDataHolder->type); 00428 if (debug) { printf(exception->message); printf("\n"); } 00429 free(rawMsg); 00430 return true; 00431 } 00432 00433 socketDataHolder->version = *(rawMsg+MSG_FLAG_POS_VERSION); 00434 if (socketDataHolder->version != XMLBLASTER_SOCKET_VERSION) { 00435 strncpy0(exception->errorCode, "user.response", XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00436 snprintf0(exception->message, EXCEPTIONSTRUCT_MESSAGE_LEN, "[xmlBlasterSocket] ERROR Received response message of unsupported version=%c", socketDataHolder->version); 00437 if (debug) { printf(exception->message); printf("\n"); } 00438 free(rawMsg); 00439 return true; 00440 } 00441 00442 00443 currPos = MSG_POS_REQESTID; 00444 00445 strncpy0(socketDataHolder->requestId, rawMsg+currPos, MAX_REQUESTID_LEN); 00446 currPos += strlen(socketDataHolder->requestId)+1; 00447 00448 strncpy0(socketDataHolder->methodName, rawMsg+currPos, MAX_METHODNAME_LEN); 00449 currPos += strlen(socketDataHolder->methodName)+1; 00450 00451 strncpy0(socketDataHolder->secretSessionId, rawMsg+currPos, MAX_SESSIONID_LEN); 00452 currPos += strlen(socketDataHolder->secretSessionId)+1; 00453 00454 strncpy0(tmpPtr, rawMsg+currPos, 256); 00455 currPos += strlen(tmpPtr)+1; 00456 trim(tmpPtr); 00457 socketDataHolder->dataLenUncompressed = 0; 00458 msgLenL = 0; 00459 if (strlen(tmpPtr) > 0 && strToULong(&msgLenL, tmpPtr) != 1) { 00460 printf("[xmlBlasterSocket] WARN uncompressed data length '%s' is invalid, we continue nevertheless\n", tmpPtr); 00461 } 00462 else { 00463 socketDataHolder->dataLenUncompressed = (size_t)msgLenL; 00464 } 00465 00466 /* Read the payload */ 00467 socketDataHolder->blob.dataLen = socketDataHolder->msgLen - currPos; 00468 if (socketDataHolder->blob.dataLen > 0) { 00469 socketDataHolder->blob.data = (char *)malloc(socketDataHolder->blob.dataLen * sizeof(char)); 00470 memcpy(socketDataHolder->blob.data, rawMsg+currPos, socketDataHolder->blob.dataLen); 00471 } 00472 else { 00473 /* 00474 socketDataHolder->blob.dataLen = 6; 00475 socketDataHolder->blob.data = strcpyAlloc("<qos/>"); 00476 */ 00477 /* 00478 Allow empty message for example for get() returns with no match 00479 socketDataHolder->blob.dataLen = 1; 00480 socketDataHolder->blob.data = (char *)malloc(1); 00481 *socketDataHolder->blob.data = 0; 00482 */ 00483 } 00484 00485 free(rawMsg); 00486 rawMsg = 0; 00487 return true; 00488 } 00489 00494 void convertToXmlBlasterException(const XmlBlasterBlob *blob, XmlBlasterException *exception, bool debug) 00495 { 00496 size_t currpos = 0; 00497 size_t len; 00498 /* initializeXmlBlasterException(exception); */ 00499 exception->remote = true; 00500 strncpy0(exception->errorCode, blob->data+currpos, XMLBLASTEREXCEPTION_ERRORCODE_LEN); 00501 currpos += strlen(exception->errorCode) + 1; 00502 len = ((blob->dataLen-currpos) > XMLBLASTEREXCEPTION_MESSAGE_LEN) ? XMLBLASTEREXCEPTION_MESSAGE_LEN : (blob->dataLen-currpos); 00503 strncpy0(exception->message, blob->data+currpos, len); 00504 trim(exception->message); 00505 if (debug) printf("[xmlBlasterSocket] Converted to XmlBlasterException\n"); 00506 } 00507 00515 void encodeXmlBlasterException(XmlBlasterBlob *blob, const XmlBlasterException *exception, bool debug) 00516 { 00517 MsgUnit msgUnit; 00518 BlobHolder b; 00519 00520 memset(&msgUnit, 0, sizeof(MsgUnit)); 00521 msgUnit.qos = exception->errorCode; 00522 msgUnit.key = exception->message; 00523 00524 b = encodeMsgUnit(&msgUnit, debug); 00525 blob->data = b.data; 00526 blob->dataLen = b.dataLen; 00527 if (debug) printf("[xmlBlasterSocket] Converted XmlBlasterException to SOCKET blob\n"); 00528 } 00529 00534 QosArr *parseQosArr(size_t dataLen, char *data) 00535 { 00536 size_t ii; 00537 MsgUnitArr *msgUnitArr = parseMsgUnitArr(dataLen, data); 00538 QosArr* qosArr = (QosArr *)calloc(1, sizeof(QosArr)); 00539 qosArr->len = msgUnitArr->len; 00540 qosArr->qosArr = (const char **)calloc(qosArr->len, sizeof(const char *)); 00541 for (ii=0; ii<msgUnitArr->len; ii++) { 00542 qosArr->qosArr[ii] = strcpyAlloc(msgUnitArr->msgUnitArr[ii].qos); 00543 } 00544 freeMsgUnitArr(msgUnitArr); 00545 return qosArr; 00546 } 00547 00553 Dll_Export MsgUnitArr *parseMsgUnitArr(size_t dataLen, char *data) 00554 { 00555 MsgUnitArr *msgUnitArr = (MsgUnitArr *)calloc(1, sizeof(MsgUnitArr)); 00556 size_t currpos = 0; 00557 uint32_t currIndex = 0; 00558 enum { SIZE = 56 }; 00559 msgUnitArr->isOneway = false; 00560 if (dataLen <= 0) { 00561 return msgUnitArr; /* Empty messageUnit array, only a first \0 for the qos */ 00562 } 00563 msgUnitArr->len = 10; 00564 msgUnitArr->msgUnitArr = (MsgUnit *)calloc(msgUnitArr->len, sizeof(MsgUnit)); 00565 while (currpos < dataLen) { 00566 char ptr[SIZE]; 00567 00568 if (currIndex >= msgUnitArr->len) { 00569 msgUnitArr->len += 10; 00570 msgUnitArr->msgUnitArr = (MsgUnit *)realloc(msgUnitArr->msgUnitArr, msgUnitArr->len * sizeof(MsgUnit)); 00571 } 00572 00573 { 00574 unsigned long msgLenL; /* to have 64 bit portable sscanf */ 00575 MsgUnit *msgUnit = &msgUnitArr->msgUnitArr[currIndex++]; 00576 memset(msgUnit, 0, sizeof(MsgUnit)); 00577 00578 /* read QoS */ 00579 msgUnit->qos = strcpyAlloc(data+currpos); 00580 currpos += strlen(msgUnit->qos)+1; 00581 00582 /* read key */ 00583 if (currpos < dataLen) { 00584 if (strlen(data+currpos) > 0) { 00585 msgUnit->key = strcpyAlloc(data+currpos); 00586 currpos += strlen(msgUnit->key)+1; 00587 } 00588 else { 00589 currpos++; 00590 } 00591 } 00592 00593 /* read content */ 00594 if (currpos < dataLen) { 00595 char *tmp; 00596 strncpy0(ptr, data+currpos, SIZE); 00597 currpos += strlen(ptr)+1; 00598 trim(ptr); 00599 msgLenL = 0; 00600 if (strToULong(&msgLenL, ptr) != 1) { 00601 printf("[xmlBlasterSocket] WARN MsgUnit content length '%s' is invalid, we continue nevertheless\n", ptr); 00602 } 00603 msgUnit->contentLen = (size_t)msgLenL; 00604 00605 tmp = (char *)malloc(msgUnit->contentLen * sizeof(char)); 00606 memcpy(tmp, data+currpos, msgUnit->contentLen); 00607 msgUnit->content = tmp; 00608 currpos += msgUnit->contentLen; 00609 } 00610 } 00611 } 00612 00613 if (currIndex == 0) { 00614 free(msgUnitArr->msgUnitArr); 00615 msgUnitArr->len = 0; 00616 } 00617 else if (currIndex < msgUnitArr->len) { 00618 msgUnitArr->msgUnitArr = (MsgUnit *)realloc(msgUnitArr->msgUnitArr, currIndex * sizeof(MsgUnit)); 00619 msgUnitArr->len = currIndex; 00620 } 00621 00622 return msgUnitArr; 00623 }