void belle_sip_multipart_body_handler_add_part(belle_sip_multipart_body_handler_t *obj, belle_sip_body_handler_t *part){ obj->base.expected_size+=part->expected_size+strlen(obj->boundary) + 4; /* add the separator length to the body length as each part start with a separator. 4 is for "--" and "\r\n" */ if (part->headers != NULL) { /* there is a declared header for this part, add its length to the expected total length */ size_t headerStringBufferSize = DEFAULT_HEADER_STRING_SIZE; size_t offset = 0; belle_sip_list_t *headerList = part->headers; part->headerStringBuffer = (char *)belle_sip_malloc(DEFAULT_HEADER_STRING_SIZE); while (headerList != NULL) { size_t offsetBackup=offset; /* we must backup the offset as it will be messed up by the marshal function in case of failure */ belle_sip_error_code returnCode = belle_sip_object_marshal(headerList->data, part->headerStringBuffer, headerStringBufferSize-5, &offset); /* -5 to leave room for carriage returns */ if (returnCode == BELLE_SIP_BUFFER_OVERFLOW) { /* increase buffer size */ offset=offsetBackup; /* restore the offset, no data were written to the buffer */ headerStringBufferSize+=DEFAULT_HEADER_STRING_SIZE; part->headerStringBuffer = (char *)belle_sip_realloc(part->headerStringBuffer, headerStringBufferSize); } else if (returnCode == BELLE_SIP_OK) { /* add the carriage return chars */ part->headerStringBuffer[offset++]='\r'; part->headerStringBuffer[offset++]='\n'; headerList = belle_sip_list_next(headerList); } } part->headerStringBuffer[offset++]='\r'; part->headerStringBuffer[offset++]='\n'; obj->base.expected_size += offset; part->headerStringBuffer[offset++]='\0'; /* null terminate the buffer in order to be able to get it length later using strlen */ } obj->parts=belle_sip_list_append(obj->parts,belle_sip_object_ref(part)); }
static void belle_sip_multipart_body_handler_recv_chunk(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, size_t offset, const uint8_t *buffer, size_t size){ /* Store the whole buffer, the parts will be split when belle_sip_multipart_body_handler_progress_cb() is called with transfered size equal to expected size. */ belle_sip_multipart_body_handler_t *obj_multipart = (belle_sip_multipart_body_handler_t *)obj; obj_multipart->buffer = belle_sip_realloc(obj_multipart->buffer,offset + size + 1); memcpy(obj_multipart->buffer + offset, buffer, size); obj_multipart->buffer[offset + size] = '\0'; }
static char * belle_sip_object_to_alloc_string(belle_sip_object_t *obj, int size_hint){ char *buf=belle_sip_malloc(size_hint); size_t offset=0; belle_sip_error_code error = belle_sip_object_marshal(obj,buf,size_hint-1,&offset); obj->vptr->tostring_bufsize_hint=size_hint; if (error==BELLE_SIP_BUFFER_OVERFLOW){ belle_sip_message("belle_sip_object_to_alloc_string(): hint buffer was too short while doing to_string() for %s, retrying", obj->vptr->type_name); belle_sip_free(buf); return belle_sip_object_to_alloc_string(obj,2*size_hint); } buf=belle_sip_realloc(buf,offset+1); buf[offset]='\0'; return buf; }
char * belle_sip_strcat_vprintf(char* dst, const char *fmt, va_list ap){ char *ret; unsigned long dstlen, retlen; ret=belle_sip_strdup_vprintf(fmt, ap); dstlen = strlen(dst); retlen = strlen(ret); if ((dst = belle_sip_realloc(dst, dstlen+retlen+1)) != NULL){ strncat(dst,ret,retlen); dst[dstlen+retlen] = '\0'; belle_sip_free(ret); return dst; } else { belle_sip_free(ret); return NULL; } }
static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) { belle_sip_header_content_type_t* content_type ; belle_sip_header_content_length_t* content_length; belle_sip_error_code error = BELLE_SIP_BUFFER_OVERFLOW; size_t length = 0; if (session_desc) { size_t bufLen = 2048; size_t hardlimit = 16*1024; /* 16k SDP limit seems reasonable */ char* buff = belle_sip_malloc(bufLen); content_type = belle_sip_header_content_type_create("application","sdp"); /* try to marshal the description. This could go higher than 2k so we iterate */ while( error != BELLE_SIP_OK && bufLen <= hardlimit && buff != NULL){ error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length); if( error != BELLE_SIP_OK ){ bufLen *= 2; length = 0; buff = belle_sip_realloc(buff,bufLen); } } /* give up if hard limit reached */ if (error != BELLE_SIP_OK || buff == NULL) { ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen); return -1; } content_length = belle_sip_header_content_length_create(length); belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_type)); belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_length)); belle_sip_message_assign_body(msg,buff,length); return 0; } else { return -1; } }
static void belle_sip_memory_body_handler_recv_chunk(belle_sip_body_handler_t *base, belle_sip_message_t *msg, size_t offset, const uint8_t *buf, size_t size){ belle_sip_memory_body_handler_t *obj=(belle_sip_memory_body_handler_t*)base; obj->buffer=belle_sip_realloc(obj->buffer,offset+size+1); memcpy(obj->buffer+offset,buf,size); obj->buffer[offset+size]='\0'; }