/**
   * If the frame body's values have been modified, then resize the raw binary buffer and store the
   * new values there. When finished, the dirty flag is reset to indicate that the buffer is up to
   * date, and the frame is now ready to be saved to the .mp3 file.
   */
  @Override
  public void setBuffer() {
    if (isDirty()) {
      byte[] mimeTypeBytes = stringToBytes(Encoding.ISO_8859_1, mimeType);
      byte[] filenameBytes = stringToBytes(encoding, filename);
      byte[] descriptionBytes = stringToBytes(encoding, description);
      int index = 0;

      buffer =
          new byte
              [1
                  + mimeTypeBytes.length
                  + filenameBytes.length
                  + descriptionBytes.length
                  + object.length];

      buffer[index] = (byte) encoding.ordinal();
      System.arraycopy(mimeTypeBytes, 0, buffer, 0, mimeTypeBytes.length);
      index = mimeTypeBytes.length;
      System.arraycopy(filenameBytes, 0, buffer, index, filenameBytes.length);
      index += filenameBytes.length;
      System.arraycopy(descriptionBytes, 0, buffer, index, descriptionBytes.length);
      index += descriptionBytes.length;
      System.arraycopy(object, 0, buffer, index, object.length);
      dirty = false;
    }
  }
 /**
  * parses the raw bytes of the frame body and stores the parsed values in the frame's fields.
  *
  * @throws IllegalArgumentException if an invalid value is detected while parsing the frame body's
  *     raw bytes.
  */
 @Override
 public void parse() throws IllegalArgumentException {
   try {
     setEncoding(Encoding.valueOf(buffer[0]));
   } catch (
       IllegalArgumentException
           ex) { // ignore the bad value and set it to ISO-8859-1 so we can continue parsing the
                 // tag
     setEncoding(Encoding.ISO_8859_1);
   }
   nullTerminatorIndex = getNextNullTerminator(1, Encoding.ISO_8859_1);
   mimeType =
       new String(buffer, 1, nullTerminatorIndex - 1, Encoding.ISO_8859_1.getCharacterSet())
           .trim();
   nullTerminatorIndex++;
   nextNullTerminatorIndex = getNextNullTerminator(nullTerminatorIndex, encoding);
   filename =
       new String(
               buffer,
               nullTerminatorIndex,
               nextNullTerminatorIndex - nullTerminatorIndex,
               encoding.getCharacterSet())
           .trim();
   nullTerminatorIndex = nextNullTerminatorIndex + encoding.getNumBytesInNullTerminator();
   nextNullTerminatorIndex = getNextNullTerminator(nullTerminatorIndex, encoding);
   description =
       new String(
               buffer,
               nullTerminatorIndex,
               nextNullTerminatorIndex - nullTerminatorIndex,
               encoding.getCharacterSet())
           .trim();
   nullTerminatorIndex = nextNullTerminatorIndex + encoding.getNumBytesInNullTerminator();
   object = new byte[buffer.length - nullTerminatorIndex];
   System.arraycopy(buffer, nullTerminatorIndex, object, 0, object.length);
   dirty =
       false; // we just read in the frame info, so the frame body's internal byte buffer is up to
              // date
 }