Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / libosip2 / src / osipparser2 / osip_body.c
diff --git a/userapps/opensource/libosip2/src/osipparser2/osip_body.c b/userapps/opensource/libosip2/src/osipparser2/osip_body.c
new file mode 100755 (executable)
index 0000000..1ff1bf9
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+  The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
+  Copyright (C) 2001,2002,2003  Aymeric MOIZARD jack@atosc.org
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+  
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+  
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osipparser2/osip_port.h>
+#include <osipparser2/osip_message.h>
+#include <osipparser2/osip_parser.h>
+#include <osipparser2/osip_body.h>
+#include "parser.h"
+
+static int osip_body_parse_header (osip_body_t * body,
+                                  const char *start_of_osip_body_header,
+                                  const char **next_body);
+
+int
+osip_body_init (osip_body_t ** body)
+{
+  *body = (osip_body_t *) osip_malloc (sizeof (osip_body_t));
+  if (*body == NULL)
+    return -1;
+  (*body)->body = NULL;
+  (*body)->content_type = NULL;
+
+  (*body)->headers = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
+  if ((*body)->headers == NULL)
+    {
+      osip_free (*body);
+      *body = NULL;
+      return -1;
+    }
+  osip_list_init ((*body)->headers);
+  return 0;
+}
+
+/* fill the body of message.                              */
+/* INPUT : char *buf | pointer to the start of body.      */
+/* OUTPUT: osip_message_t *sip | structure to save results.        */
+/* returns -1 on error. */
+int
+osip_message_set_body (osip_message_t * sip, const char *buf)
+{
+  osip_body_t *body;
+  int i;
+
+  i = osip_body_init (&body);
+  if (i != 0)
+    return -1;
+  i = osip_body_parse (body, buf);
+  if (i != 0)
+    {
+      osip_body_free (body);
+      return -1;
+    }
+  sip->message_property = 2;
+  osip_list_add (sip->bodies, body, -1);
+  return 0;
+}
+
+int
+osip_body_clone (const osip_body_t * body, osip_body_t ** dest)
+{
+  int pos;
+  int i;
+  osip_body_t *copy;
+
+  if (body == NULL)
+    return -1;
+
+  i = osip_body_init (&copy);
+  if (i != 0)
+    return -1;
+
+  copy->body = osip_strdup (body->body);
+
+  if (body->content_type != NULL)
+    {
+      i = osip_content_type_clone (body->content_type, &(copy->content_type));
+      if (i != 0)
+       goto bc_error1;
+    }
+
+  {
+    osip_header_t *header;
+    osip_header_t *header2;
+
+    pos = 0;
+    while (!osip_list_eol (body->headers, pos))
+      {
+       header = (osip_header_t *) osip_list_get (body->headers, pos);
+       i = osip_header_clone (header, &header2);
+       if (i != 0)
+         goto bc_error1;
+       osip_list_add (copy->headers, header2, -1);     /* insert as last element */
+       pos++;
+      }
+  }
+
+  *dest = copy;
+  return 0;
+bc_error1:
+  osip_body_free (copy);
+  return -1;
+}
+
+/* returns the pos of body header.                   */
+/* INPUT : int pos | pos of body header.             */
+/* INPUT : osip_message_t *sip | sip message.                 */
+/* OUTPUT: osip_body_t *body | structure to save results. */
+/* returns -1 on error. */
+int
+osip_message_get_body (const osip_message_t * sip, int pos,
+                      osip_body_t ** dest)
+{
+  osip_body_t *body;
+
+  *dest = NULL;
+  if (osip_list_size (sip->bodies) <= pos)
+    return -1;                 /* does not exist */
+  body = (osip_body_t *) osip_list_get (sip->bodies, pos);
+  *dest = body;
+  return pos;
+}
+
+int
+osip_body_set_contenttype (osip_body_t * body, const char *hvalue)
+{
+  int i;
+
+  if (body == NULL)
+    return -1;
+  if (hvalue == NULL)
+    return -1;
+
+  i = osip_content_type_init (&(body->content_type));
+  if (i != 0)
+    return -1;
+  i = osip_content_type_parse (body->content_type, hvalue);
+  if (i != 0)
+    {
+      osip_content_type_free (body->content_type);
+      body->content_type = NULL;
+      return -1;
+    }
+  return 0;
+}
+
+int
+osip_body_set_header (osip_body_t * body, const char *hname,
+                     const char *hvalue)
+{
+  osip_header_t *h;
+  int i;
+
+  if (body == NULL)
+    return -1;
+  if (hname == NULL)
+    return -1;
+  if (hvalue == NULL)
+    return -1;
+
+  i = osip_header_init (&h);
+  if (i != 0)
+    return -1;
+
+  h->hname = osip_strdup (hname);
+  h->hvalue = osip_strdup (hvalue);
+
+  osip_list_add (body->headers, h, -1);
+  return 0;
+}
+
+/* fill the body of message.                              */
+/* INPUT : char *buf | pointer to the start of body.      */
+/* OUTPUT: osip_message_t *sip | structure to save results.        */
+/* returns -1 on error. */
+int
+osip_message_set_body_mime (osip_message_t * sip, const char *buf)
+{
+  osip_body_t *body;
+  int i;
+
+  i = osip_body_init (&body);
+  if (i != 0)
+    return -1;
+  i = osip_body_parse_mime (body, buf);
+  if (i != 0)
+    {
+      osip_body_free (body);
+      return -1;
+    }
+  sip->message_property = 2;
+  osip_list_add (sip->bodies, body, -1);
+  return 0;
+}
+
+static int
+osip_body_parse_header (osip_body_t * body,
+                       const char *start_of_osip_body_header,
+                       const char **next_body)
+{
+  const char *start_of_line;
+  const char *end_of_line;
+  const char *colon_index;
+  char *hname;
+  char *hvalue;
+  int i;
+
+  *next_body = NULL;
+  start_of_line = start_of_osip_body_header;
+  for (;;)
+    {
+      i = __osip_find_next_crlf (start_of_line, &end_of_line);
+      if (i == -1)
+       return -1;              /* error case: no end of body found */
+
+      /* find the headere name */
+      colon_index = strchr (start_of_line, ':');
+      if (colon_index == NULL)
+       return -1;              /* this is also an error case */
+
+      if (colon_index - start_of_line + 1 < 2)
+       return -1;
+      hname = (char *) osip_malloc (colon_index - start_of_line + 1);
+      if (hname == NULL)
+       return -1;
+      osip_strncpy (hname, start_of_line, colon_index - start_of_line);
+      osip_clrspace (hname);
+
+      if ((end_of_line - 2) - colon_index < 2)
+       return -1;
+      hvalue = (char *) osip_malloc ((end_of_line - 2) - colon_index);
+      if (hvalue == NULL)
+       {
+         osip_free (hname);
+         return -1;
+       }
+      osip_strncpy (hvalue, colon_index + 1,
+                   (end_of_line - 2) - colon_index - 1);
+      osip_clrspace (hvalue);
+
+      /* really store the header in the sip structure */
+      if (osip_strncasecmp (hname, "content-type", 12) == 0)
+       i = osip_body_set_contenttype (body, hvalue);
+      else
+       i = osip_body_set_header (body, hname, hvalue);
+      osip_free (hname);
+      osip_free (hvalue);
+      if (i == -1)
+       return -1;
+
+      if (strncmp (end_of_line, CRLF, 2) == 0
+         || strncmp (end_of_line, "\n", 1) == 0
+         || strncmp (end_of_line, "\r", 1) == 0)
+       {
+         *next_body = end_of_line;
+         return 0;
+       }
+      start_of_line = end_of_line;
+    }
+}
+
+int
+osip_body_parse (osip_body_t * body, const char *start_of_body)
+{
+  size_t i;
+
+  if (body == NULL)
+    return -1;
+  if (start_of_body == NULL)
+    return -1;
+  if (body->headers == NULL)
+    return -1;
+
+  /*  i = __osip_find_next_crlfcrlf(start_of_body, &end_of_body);
+     if (i==-1) return -1; 
+     body->body = (char *)osip_malloc(end_of_body-start_of_body+1);
+     osip_strncpy(body->body, start_of_body, end_of_body-start_of_body);
+   */
+
+  i = strlen (start_of_body);
+  body->body = (char *) osip_malloc (i + 1);
+  if (body->body == NULL)
+    return -1;
+  osip_strncpy (body->body, start_of_body, i);
+  return 0;
+}
+
+int
+osip_body_parse_mime (osip_body_t * body, const char *start_of_body)
+{
+  const char *end_of_osip_body_header;
+  const char *start_of_osip_body_header;
+  int i;
+
+  if (body == NULL)
+    return -1;
+  if (start_of_body == NULL)
+    return -1;
+  if (body->headers == NULL)
+    return -1;
+
+  start_of_osip_body_header = start_of_body;
+
+  i =
+    osip_body_parse_header (body, start_of_osip_body_header,
+                           &end_of_osip_body_header);
+  if (i == -1)
+    return -1;
+
+  start_of_osip_body_header = end_of_osip_body_header;
+  /* set the real start of body */
+  if (strncmp (start_of_osip_body_header, CRLF, 2) == 0)
+    start_of_osip_body_header = start_of_osip_body_header + 2;
+  else
+    {
+      if ((strncmp (start_of_osip_body_header, "\n", 1) == 0)
+         || (strncmp (start_of_osip_body_header, "\r", 1) == 0))
+       start_of_osip_body_header = start_of_osip_body_header + 1;
+      else
+       return -1;              /* message does not end with CRLFCRLF, CRCR or LFLF */
+    }
+
+  end_of_osip_body_header =
+    end_of_osip_body_header + strlen (end_of_osip_body_header);
+  body->body =
+    (char *) osip_malloc (end_of_osip_body_header -
+                         start_of_osip_body_header + 1);
+  if (body->body == NULL)
+    return -1;
+  osip_strncpy (body->body, start_of_osip_body_header,
+               end_of_osip_body_header - start_of_osip_body_header);
+
+  return 0;
+
+}
+
+/* returns the body as a string.          */
+/* INPUT : osip_body_t *body | body.  */
+/* returns null on error. */
+int
+osip_body_to_str (const osip_body_t * body, char **dest)
+{
+  char *tmp_body;
+  char *tmp;
+  char *ptr;
+  int pos;
+  int i;
+  size_t length;
+
+  *dest = NULL;
+  if (body == NULL)
+    return -1;
+  if (body->body == NULL)
+    return -1;
+  if (body->headers == NULL)
+    return -1;
+
+  length = strlen (body->body) + (osip_list_size (body->headers) * 40);
+  tmp_body = (char *) osip_malloc (length);
+  if (tmp_body == NULL)
+    return -1;
+  ptr = tmp_body;              /* save the initial address of the string */
+
+  if (body->content_type != NULL)
+    {
+      osip_strncpy (tmp_body, "content-type: ", 14);
+      tmp_body = tmp_body + strlen (tmp_body);
+      i = osip_content_type_to_str (body->content_type, &tmp);
+      if (i == -1)
+       {
+         osip_free (ptr);
+         return -1;
+       }
+      if (length < tmp_body - ptr + strlen (tmp) + 4)
+       {
+         size_t len;
+
+         len = tmp_body - ptr;
+         length = length + strlen (tmp) + 4;
+         ptr = realloc (ptr, length);
+         tmp_body = ptr + len;
+       }
+
+      osip_strncpy (tmp_body, tmp, strlen (tmp));
+      osip_free (tmp);
+      tmp_body = tmp_body + strlen (tmp_body);
+      osip_strncpy (tmp_body, CRLF, 2);
+      tmp_body = tmp_body + 2;
+    }
+
+  pos = 0;
+  while (!osip_list_eol (body->headers, pos))
+    {
+      osip_header_t *header;
+
+      header = (osip_header_t *) osip_list_get (body->headers, pos);
+      i = osip_header_to_str (header, &tmp);
+      if (i == -1)
+       {
+         osip_free (ptr);
+         return -1;
+       }
+      if (length < tmp_body - ptr + strlen (tmp) + 4)
+       {
+         size_t len;
+
+         len = tmp_body - ptr;
+         length = length + strlen (tmp) + 4;
+         ptr = realloc (ptr, length);
+         tmp_body = ptr + len;
+       }
+      osip_strncpy (tmp_body, tmp, strlen (tmp));
+      osip_free (tmp);
+      tmp_body = tmp_body + strlen (tmp_body);
+      osip_strncpy (tmp_body, CRLF, 2);
+      tmp_body = tmp_body + 2;
+      pos++;
+    }
+
+  if ((osip_list_size (body->headers) > 0) || (body->content_type != NULL))
+    {
+      osip_strncpy (tmp_body, CRLF, 2);
+      tmp_body = tmp_body + 2;
+    }
+  if (length < tmp_body - ptr + strlen (body->body) + 4)
+    {
+      size_t len;
+
+      len = tmp_body - ptr;
+      length = length + strlen (body->body) + 4;
+      ptr = realloc (ptr, length);
+      tmp_body = ptr + len;
+    }
+  osip_strncpy (tmp_body, body->body, strlen (body->body));
+  tmp_body = tmp_body + strlen (body->body);
+
+  /* end of this body */
+
+  *dest = ptr;
+  return 0;
+
+}
+
+/* deallocates a body structure.  */
+/* INPUT : osip_body_t *body | body.  */
+void
+osip_body_free (osip_body_t * body)
+{
+  if (body == NULL)
+    return;
+  osip_free (body->body);
+  if (body->content_type != NULL)
+    {
+      osip_content_type_free (body->content_type);
+    }
+
+  {
+    osip_header_t *header;
+
+    while (!osip_list_eol (body->headers, 0))
+      {
+       header = (osip_header_t *) osip_list_get (body->headers, 0);
+       osip_list_remove (body->headers, 0);
+       osip_header_free (header);
+      }
+    osip_free (body->headers);
+  }
+  osip_free (body);
+}