/**
  * This reads the subtype from the MIME type. This will fill the subtype <code>ParseBuffer</code>.
  * This will read all chars upto but not including the first instance of a ';'. The subtype of a
  * media-type as defined by RFC 2616 is <code>type/subtype;param=val;param2=val</code>.
  */
 private void secondary() {
   while (off < count) {
     if (buf[off] == ';') {
       break;
     }
     type.append(buf[off]);
     secondary.append(buf[off]);
     off++;
   }
 }
 /**
  * This reads the type from the MIME type. This will fill the type <code>ParseBuffer</code>. This
  * will read all chars upto but not including the first instance of a '/'. The type of a
  * media-type as defined by RFC 2616 is <code>type/subtype;param=val;param2=val</code>.
  */
 private void primary() {
   while (off < count) {
     if (buf[off] == '/') {
       type.append('/');
       break;
     }
     type.append(buf[off]);
     primary.append(buf[off]);
     off++;
   }
 }
 /**
  * This will simply read all characters from the buffer before the first '=' character. This
  * represents a parameter name (see RFC 2616 for token). The parameter name is not buffered it is
  * simply read from the buffer. This will not cause an <code>IndexOutOfBoundsException</code> as
  * each offset is checked before it is acccessed.
  */
 private void name() {
   while (off < count) {
     if (buf[off] == '=') {
       break;
     }
     name.append(buf[off]);
     off++;
   }
 }
 /**
  * This is used to read the value from the <code>charset</code> param. This will fill the <code>
  * charset</code> <code>ParseBuffer</code> and with the <code>charset</code> value. This will read
  * a literal or a token as the <code>charset</code> value. If the <code>charset</code> is a
  * literal then the quotes will be read as part of the charset.
  */
 private void charset() {
   if (buf[off] == '"') {
     charset.append('"');
     for (off++; off < count; ) {
       charset.append(buf[off]);
       if (buf[off++] == '"')
         if (buf[off - 2] != '\\') {
           break;
         }
     }
   } else {
     while (off < count) {
       if (buf[off] == ';') {
         break;
       }
       charset.append(buf[off]);
       off++;
     }
   }
 }
 /**
  * This is used to read a parameters value from the buf. This will read all <code>char</code>'s
  * upto but excluding the first terminal <code>char</code> encountered from the off within the
  * buf, or if the value is a literal it will read a literal from the buffer (literal is any data
  * between quotes except if the quote is prefixed with a backward slash character).
  */
 private void value() {
   if (quote(buf[off])) {
     for (off++; off < count; ) {
       if (quote(buf[off])) {
         if (buf[++off - 2] != '\\') {
           break;
         }
       }
       value.append(buf[off++]);
     }
   } else {
     while (off < count) {
       if (buf[off] == ';') {
         break;
       }
       value.append(buf[off]);
       off++;
     }
   }
 }
  /**
   * This will return the value of the MIME type as a string. This will concatenate the primary and
   * secondary type values and add the <code>charset</code> parameter to the type which will
   * recreate the content type.
   *
   * @return this returns the string representation of the type
   */
  private String encode() {
    StringBuilder text = new StringBuilder();

    if (primary != null) {
      text.append(primary);
      text.append("/");
      text.append(secondary);
    }
    if (charset.length() > 0) {
      text.append("; charset=");
      text.append(charset);
    }
    return encode(text);
  }
 /**
  * This is used to clear all previously collected tokens. This allows the parser to be reused when
  * there are multiple source strings to be parsed. Clearing of the tokens is performed when the
  * parser is initialized.
  */
 private void clear() {
   primary.clear();
   secondary.clear();
   charset.clear();
   name.clear();
   value.clear();
   type.clear();
   map.clear();
   off = 0;
 }
 /**
  * This method is used to get the primary and secondary parts joined together with a "/". This is
  * typically how a content type is examined. Here convenience is most important, we can easily
  * compare content types without any parameters.
  *
  * @return this returns the primary and secondary types
  */
 public String getType() {
   return type.toString();
 }
 /**
  * This will add the given name and value to the parameters map. If any previous value of the
  * given name has been inserted into the map then this will overwrite that value. This is used to
  * ensure that the string value is inserted to the map.
  *
  * @param name this is the name of the value to be inserted
  * @param value this is the value of a that is to be inserted
  */
 private void insert(ParseBuffer name, ParseBuffer value) {
   map.put(name.toString(), value.toString());
 }
 /**
  * This will add the name and value tokens to the parameters map. If any previous value of the
  * given name has been inserted into the map then this will overwrite that value. This is used to
  * ensure that the string value is inserted to the map.
  */
 private void insert() {
   insert(name, value);
   name.clear();
   value.clear();
 }
 /**
  * This is used to retrieve the <code>charset</code> of this MIME type. This is a special
  * parameter associated with the type, if the parameter is not contained within the type then this
  * will return null, which typically means the default of ISO-8859-1.
  *
  * @return the value that this parameter contains
  */
 public String getCharset() {
   return charset.toString();
 }
 /**
  * This will set the <code>charset</code> to whatever value the string contains. If the string is
  * null then this will not set the parameter to any value and the <code>toString</code> method
  * will not contain any details of the parameter.
  *
  * @param enc parameter value to add to the MIME type
  */
 public void setCharset(String enc) {
   charset.reset(enc);
 }
 /**
  * This is used to retrieve the secondary type of this MIME type. The secondary type part within
  * the MIME type defines the generic type. For example <code>text/html; charset=UTF-8</code>. This
  * will return the HTML value. If there is no secondary type then this will return <code>null
  * </code> otherwise the string value.
  *
  * @return the primary type part of this MIME type
  */
 public String getSecondary() {
   return secondary.toString();
 }
 /**
  * This sets the secondary type to whatever value is in the string provided is. If the string is
  * null then this will contain a null string for the secondary type of the parameter, which is
  * likely invalid in most cases.
  *
  * @param value the type to set for the primary type of this
  */
 public void setSecondary(String value) {
   type.reset(primary);
   type.append('/');
   type.append(value);
   secondary.reset(value);
 }
 /**
  * This is used to retrieve the primary type of this MIME type. The primary type part within the
  * MIME type defines the generic type. For example <code>text/plain; charset=UTF-8</code>. This
  * will return the text value. If there is no primary type then this will return <code>null</code>
  * otherwise the string value.
  *
  * @return the primary type part of this MIME type
  */
 public String getPrimary() {
   return primary.toString();
 }