/* osip_message_t *sip is filled while analysing buf */
static int
_osip_message_parse (osip_message_t * sip, const char *buf, size_t length, int sipfrag)
{
  int i;
  const char *next_header_index;
  char *tmp;
  char *beg;

  tmp = osip_malloc (length + 2);
  if (tmp == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not allocate memory.\n"));
    return OSIP_NOMEM;
  }
  beg = tmp;
  memcpy (tmp, buf, length);    /* may contain binary data */
  tmp[length] = '\0';
  /* skip initial \r\n */
  while (tmp[0] == '\r' || tmp[0] == '\n')
    tmp++;
  osip_util_replace_all_lws (tmp);
  /* parse request or status line */
  i = __osip_message_startline_parse (sip, tmp, &next_header_index);
  if (i != 0 && !sipfrag) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse start line of message.\n"));
    osip_free (beg);
    return i;
  }
  tmp = (char *) next_header_index;

  /* parse headers */
  i = msg_headers_parse (sip, tmp, &next_header_index);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_headers_parse()\n"));
    osip_free (beg);
    return i;
  }
  tmp = (char *) next_header_index;

  /* this is a *very* simple test... (which handle most cases...) */
  if (tmp[0] == '\0' || tmp[1] == '\0' || tmp[2] == '\0') {
    /* this is mantory in the oSIP stack */
    if (sip->content_length == NULL)
      osip_message_set_content_length (sip, "0");
    osip_free (beg);
    return OSIP_SUCCESS;        /* no body found */
  }

  i = msg_osip_body_parse (sip, tmp, &next_header_index, length - (tmp - beg));
  osip_free (beg);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_osip_body_parse()\n"));
    return i;
  }

  /* this is mandatory in the oSIP stack */
  if (sip->content_length == NULL)
    osip_message_set_content_length (sip, "0");

  return OSIP_SUCCESS;
}
/* osip_message_t *sip is filled while analysing buf */
static int
_osip_message_parse (osip_message_t * sip, const char *buf, size_t length, int sipfrag)
{
  int i;
  const char *next_header_index;
  char *tmp;
  char *beg;

  tmp = osip_malloc (length + 2);
  if (tmp == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not allocate memory.\n"));
    return OSIP_NOMEM;
  }
  beg = tmp;
  memcpy (tmp, buf, length);    /* may contain binary data */
  tmp[length] = '\0';
  /* skip initial \r\n */
  while (tmp[0] == '\r' || tmp[0] == '\n')
    tmp++;
  osip_util_replace_all_lws (tmp);
  /* parse request or status line */
  i = __osip_message_startline_parse (sip, tmp, &next_header_index);
  if (i != 0 && !sipfrag) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse start line of message.\n"));
    osip_free (beg);
    return i;
  }
  tmp = (char *) next_header_index;

  /* parse headers */
  i = msg_headers_parse (sip, tmp, &next_header_index);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_headers_parse()\n"));
    osip_free (beg);
    return i;
  }
  tmp = (char *) next_header_index;

  if (sip->content_length != NULL && sip->content_length->value == NULL) {
    /* empty content_length header */
    osip_content_length_free(sip->content_length);
    sip->content_length=NULL;
  }

  if (sip->content_length != NULL && sip->content_length->value != NULL && atoi(sip->content_length->value) >0) {
    /* body exist */
  } else if (sip->content_length == NULL && '\r' == next_header_index[0] && '\n' == next_header_index[1] && length - (tmp - beg) - (2) >0) {
    /* body exist */
  } else if (sip->content_length == NULL && '\n' == next_header_index[0] && length - (tmp - beg) - (1) >0) {
    /* body exist */
  } else {
    if (sip->content_length == NULL)
      osip_message_set_content_length (sip, "0");
    osip_free (beg);
    return OSIP_SUCCESS;        /* no body found */
  }

  i = msg_osip_body_parse (sip, tmp, &next_header_index, length - (tmp - beg));
  osip_free (beg);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_osip_body_parse()\n"));
    return i;
  }

  /* this is mandatory in the oSIP stack */
  if (sip->content_length == NULL)
    osip_message_set_content_length (sip, "0");

  return OSIP_SUCCESS;
}