content: package gov2.nist.javax2.sip.message;
  
  import gov2.nist.javax2.sip.header.HeaderFactoryExt;
  import gov2.nist.javax2.sip.header.HeaderFactoryImpl;
  import gov2.nist.javax2.sip.parser.StringMsgParser;
  
  import java.text.ParseException;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  
  import javax2.sip.header.ContentDispositionHeader;
  import javax2.sip.header.ContentTypeHeader;
  import javax2.sip.header.Header;
  import javax2.sip.header.HeaderFactory;
  import javax2.sip.message.Message;
  
  
  
  /**
   * Content list for multipart mime content type.
   * 
   * @author M. Ranganathan
   * 
   */
  public class MultipartMimeContentImpl implements MultipartMimeContent {
      private List<Content> contentList = new LinkedList<Content>();
  
      private ContentTypeHeader multipartMimeContentTypeHeader;
  
      private String boundary;
  
      public static String BOUNDARY = "boundary";
  
      /**
       * Creates a default content list.
       */
      public MultipartMimeContentImpl(ContentTypeHeader contentTypeHeader) {
          this.multipartMimeContentTypeHeader = contentTypeHeader;
          this.boundary = contentTypeHeader.getParameter(BOUNDARY);
  
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see gov2.nist.javax2.sip.message.MultipartMimeContentExt#add(gov2.nist.javax2.sip.message.Content)
       */
      public boolean add(Content content) {
          return contentList.add((ContentImpl) content);
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see gov2.nist.javax2.sip.message.MultipartMimeContentExt#getContentTypeHeader()
       */
      public ContentTypeHeader getContentTypeHeader() {
          return multipartMimeContentTypeHeader;
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see gov2.nist.javax2.sip.message.MultipartMimeContentExt#toString()
       */
      @Override
      public String toString() {
          StringBuffer stringBuffer = new StringBuffer();
  
          for (Content content : this.contentList) {
              stringBuffer.append(content.toString());
          }
          return stringBuffer.toString();
  
      }
  
      /**
       * unpack a multipart mime packet and return a list of content packets.
       * 
       * @return -- an iterator of Content blocks.
       * 
       */
      public void createContentList(String body) throws ParseException {
          try {
              HeaderFactoryExt headerFactory = new HeaderFactoryImpl();
              String delimiter = this.getContentTypeHeader().getParameter(BOUNDARY);
  
              if (delimiter == null) {
                  this.contentList = new LinkedList<Content>();
                  ContentImpl content = new ContentImpl(body, delimiter);
                  content.setContentTypeHeader(this.getContentTypeHeader());
                  this.contentList.add(content);
                  return;
              }
  
              String[] fragments = body.split("--" + delimiter + "\r\n");
  
  
              for (String nextPart : fragments) {
                  // NOTE - we are not hanlding line folding for the sip header here.
  
                  if (nextPart == null) {
                      return;
                  }
                  StringBuffer strbuf = new StringBuffer(nextPart);
                  while (strbuf.length() > 0
                          && (strbuf.charAt(0) == '\r' || strbuf.charAt(0) == '\n'))
                      strbuf.deleteCharAt(0);
  
                  if (strbuf.length() == 0)
                      continue;
                  nextPart = strbuf.toString();
                  int position = nextPart.indexOf("\r\n\r\n");
                  int off = 4;
                  if (position == -1) {
                      position = nextPart.indexOf("\n");
                      off = 2;
                  }
                  if (position == -1)
                      throw new ParseException("no content type header found in " + nextPart, 0);
                  String rest = nextPart.substring(position + off);
  
                  if (rest == null)
                      throw new ParseException("No content [" + nextPart + "]", 0);
                  // logger.debug("rest = [[" + rest + "]]");
                  String headers = nextPart.substring(0, position);
                  ContentImpl content = new ContentImpl(rest, boundary);
  
                  String[] headerArray = headers.split("\r\n");
                  for (String hdr : headerArray) {
                      Header header = headerFactory.createHeader(hdr);
                      if (header instanceof ContentTypeHeader) {
                          content.setContentTypeHeader((ContentTypeHeader) header);
                      } else if (header instanceof ContentDispositionHeader) {
                          content.setContentDispositionHeader((ContentDispositionHeader) header);
                      } else {
                          throw new ParseException("Unexpected header type " + header.getName(), 0);
                      }
                      contentList.add(content);
                  }
  
              }
          } catch (StringIndexOutOfBoundsException ex) {
              throw new ParseException("Invalid Multipart mime format", 0);
          }
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see gov2.nist.javax2.sip.message.MultipartMimeContentExt#getContentByType(java.lang.String,
       *      java.lang.String)
       */
      public Content getContentByType(String contentType, String contentSubtype) {
          Content retval = null;
          if (contentList == null)
              return null;
          for (Content content : contentList) {
              if (content.getContentTypeHeader().getContentType().equalsIgnoreCase(contentType)
                      && content.getContentTypeHeader().getContentSubType().equalsIgnoreCase(
                              contentSubtype)) {
                  retval = content;
                  break;
              }
  
          }
          return retval;
      }
  
      /*
       * (non-Javadoc)
       * 
       * @see gov2.nist.javax2.sip.message.MultipartMimeContentExt#setContent(java.lang.String,
       *      java.lang.String, gov2.nist.javax2.sip.message.Content)
       */
      public void addContent(Content content) {
          this.add(content);
      }
  
      public Iterator<Content> getContents() {
          return this.contentList.iterator();
      }
  
      
      public int getContentCount() {
          return this.contentList.size();
      }
  
  }
  