com.beaglebuddy.id3.v24

## Class ID3v24FrameHeader

- java.lang.Object
- - com.beaglebuddy.id3.v24.ID3v24FrameHeader

-     public class ID3v24FrameHeader
      extends java.lang.Object

  This class provides methods for reading and writing frame headers in ID3V2.4 frames. An ID3v2.4 frame header is 10 bytes long and precedes the `frame body` in an ID3v2.4 `frame`, as shown below.

  An ID3v2.4 frame header has the following fields:

  Frame Header Fields
  | Field | Description
  --- | --- | ---
  1. | `frameType` | which of the 83 ID3v2.4 defined types of frame is this the header for.
  2. | frameBodySize | number of bytes in the associated frame body.
  3. | tagAlterPreservation | an indicator to mp3 software whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
  4. | fileAlterPreservation | an indicator to mp3 software whether the frame should be preserved or discarded if the frame is unknown and the audio is altered in any way. note: this does not apply when the audio is completely replaced with other audio data.
  5. | readOnly | whether the contents of this frame are intended to be read only.
  6. | belongsToGroup | whether the frame belongs in a group with other frames. If it does, then the groupId field will contain the group's id. Every frame belonging to the same group will have the same group id.
  7. | compressed | whether the frame has been compressed using zlib. If it has, then the uncompressedSize field will contain the uncompressed size of the frame.
  8. | encrypted | whether the frame has been encrypted. If it has, then the encryptionMethod field will contain the method used to encrypt the frame.
  9. | unsynchronized | whether the frame has been whether or not unsynchronisation was applied to this frame. If this flag is set all data from the end of this header to the end of this frame has been unsynchronised.
  10. | dataLengthIndicatorPresent | whether the frame has a data length indicator added to it. If set, then the data length indicator fiels will have the value one would write as the 'frame length' if all of the frame format flags were zeroed.
  11. | groupId | optional field set only if the belongsToGroup field is true, it contains the id of the group to which the frame belongs.
  12. | uncompressedSize | optional field set only if the compressed field is true, it contains the uncompressed size of the frame.
  13. | encryptionMethod | optional field set only if the encrypted field is true, it contains the id of the method used to encrypt the frame.
  14. | dataLengthIndicator | optional field set only if the dataLengthIndicatorPresent field is true, it contains the value one would write as the 'frame length' if all of the frame format flags were zeroed.
  15. | dirty | whether the frame header has been modified.

  See Also:
    ID3 tag version 2.4.0 standard, wikipedia history of ID3 tags

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `ID3v24FrameHeader(FrameType frameType)` This constructor is called when creating a new frame header.
    `ID3v24FrameHeader(ID3v24FrameHeader header)` copy constructor.
    `ID3v24FrameHeader(java.io.InputStream inputStream)` This constructor is called when an existing frame header is being read in from an .mp3 file.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `int` | `getDataLengthIndicator()` if the frame has a data length indicator as indicated by the dataLengthIndicatorPresent field, then this method returns the data length indicator of the frame.
    `byte` | `getEncryptionMethod()` if the frame has been encrypted, as indicated by the encrypted field, then this method gets the method used to encrypt the frame.
    `int` | `getFrameBodySize()` gets the size of the associated frame body.
    `FrameType` | `getFrameType()` gets the ID3v2.4 frame type.
    `byte` | `getGroupId()` if the frame belongs to a group, as indicated by the belongsToGroup field, then this method gets the id used to uniquely indentify the group.
    `java.lang.String` | `getInvalidFrameId()` if the frame id read in is not a valid ID3v2.4 frame id, then this field is set so that the error can be reported later after the entire frame has been read in (and discarded) so that we may continue processing the remaining frames.
    `int` | `getSize()` gets the size (in bytes) of the frame header.
    `int` | `getUncompressedSize()` if the frame has been compressed using zlib as indicated by the compressed field, then this method returns the uncompressed size of the frame.
    `boolean` | `isBelongsToGroup()` gets whether the frame belongs in a group with other frames.
    `boolean` | `isCompressed()` gets whether the frame is compressed using zlib.
    `boolean` | `isDataLengthIndicatorPresent()` gets whether the frame has a data length indicator.
    `boolean` | `isDirty()` gets whether the frame header has been modified since the last time it was saved.
    `boolean` | `isEncrypted()` gets whether the frame is encrypted.
    `boolean` | `isFileAlterPreservation()` gets whether the frame should be preserved or discarded if the frame is unknown and the file, excluding the tag, is altered.
    `boolean` | `isPadding()` although an ID3v2.4 tag header specifies the size of the tag, it does not specifiy how many frames there are, the total size of the frames, nor the size of the padding.
    `boolean` | `isReadOnly()` gets whether the contents of this frame are intended to be read only.
    `boolean` | `isTagAlterPreservation()` gets whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
    `boolean` | `isUnsynchronized()` gets whether the frame is unsynchronized.
    `void` | `save(java.io.OutputStream outputStream)` save the frame header to the .mp3 file.
    `void` | `save(java.io.RandomAccessFile file)` save the frame header to the .mp3 file.
    `void` | `setBelongsToGroup(boolean belongsToGroup)` sets whether the frame belongs in a group with other frames.
    `void` | `setBuffer()` if the frame header's values have been modified, then resize the raw binary buffer and store the new values there.
    `void` | `setCompressed(boolean compressed)` sets whether the frame is compressed using zlib.
    `void` | `setDataLengthIndicator(int dataLengthIndicator)` sets the frame's data length indicator as well as the dataLengthIndicatorPresent flag.
    `void` | `setDataLengthIndicatorPresent(boolean dataLengthIndicatorPresent)` sets whether the frame has a data length indicator.
    `void` | `setEncrypted(boolean encrypted)` sets whether the frame is encrypted.
    `void` | `setEncryptionMethod(byte encryptionMethod)` sets the frame's encryption method as well as the encrypted flag.
    `void` | `setFileAlterPreservation(boolean fileAlterPreservation)` sets whether the frame should be preserved or discarded if the frame is unknown and the file, excluding the tag, is altered.
    `void` | `setFrameBodySize(int frameBodySize)` sets the size of the frame body.
    `void` | `setFrameType(FrameType frameType)` sets the frame type.
    `void` | `setGroupId(byte groupId)` sets the frame's group id as well as the belongsToGroup flag.
    `void` | `setReadOnly(boolean readOnly)` sets whether the contents of this frame are intended to be read only.
    `void` | `setTagAlterPreservation(boolean tagAlterPreservation)` sets whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
    `void` | `setUncompressedSize(int uncompressedSize)` sets the frame's uncompressed size as well as the compressed flag.
    `void` | `setUnsynchronized(boolean unsynchronized)` sets whether the frame is unsynchronized.
    `java.lang.String` | `toString()` gets a string representation of an ID3v2.4 frame's header.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### ID3v24FrameHeader

          public ID3v24FrameHeader(FrameType frameType)

      This constructor is called when creating a new frame header. The default values used are:
      - frame body size is 0
      - tag alter preservation is false
      - file alter preservation is false
      - read only is false
      - compressed is false
      - encrypted is false
      - unsynchronized is false
      - belongs to a group is false
      - data length indicator is not present
      Parameters:
        `frameType` - ID3v2.4 frame type.

    - #### ID3v24FrameHeader

          public ID3v24FrameHeader(java.io.InputStream inputStream)
                            throws java.io.IOException

      This constructor is called when an existing frame header is being read in from an .mp3 file. If the frame id read in is not one of the 83 frame types defined in the ID3v2.4 specification, then the frame is marked as invalid, but we continue to read and parse the remainder of the header. This allows an attempt to be made to read in the invalid frame's corresponding body, at which point the entire invalid frame can be discarded and the remainder of the frames can be read in from the .mp3 file.
      Parameters:
        `inputStream` - input stream pointing to an ID3v2.4 frame header in the .mp3 file.
      Throws:
        `java.io.IOException` - if there is an error while reading the frame header in from the .mp3 file.

    - #### ID3v24FrameHeader

          public ID3v24FrameHeader(ID3v24FrameHeader header)

      copy constructor.
      Parameters:
        `header` - an ID3v2.4 header that was previously read in.

  - ### Method Detail

    - #### getFrameType

          public FrameType getFrameType()

      gets the ID3v2.4 frame type.
      Returns:
        the frame id.
      See Also:
        `setFrameType(FrameType)`

    - #### setFrameType

          public void setFrameType(FrameType frameType)

      sets the frame type.
      Parameters:
        `frameType` - the type of ID3v2.4 frame.
      See Also:
        `getFrameType()`

    - #### getFrameBodySize

          public int getFrameBodySize()

      gets the size of the associated frame body.
      Returns:
        the frame body size.
      See Also:
        `setFrameBodySize(int)`

    - #### setFrameBodySize

          public void setFrameBodySize(int frameBodySize)

      sets the size of the frame body.
      Parameters:
        `frameBodySize` - the size of the frame body (in bytes).
      See Also:
        `getFrameBodySize()`

    - #### isTagAlterPreservation

          public boolean isTagAlterPreservation()

      gets whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
      Returns:
        whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
      See Also:
        `setTagAlterPreservation(boolean)`

    - #### setTagAlterPreservation

          public void setTagAlterPreservation(boolean tagAlterPreservation)

      sets whether the frame should be preserved or discarded if the frame is unknown and the tag is altered in any way.
      Parameters:
        `tagAlterPreservation` - the tag alteration preservation flag.
      See Also:
        `isTagAlterPreservation()`

    - #### isFileAlterPreservation

          public boolean isFileAlterPreservation()

      gets whether the frame should be preserved or discarded if the frame is unknown and the file, excluding the tag, is altered. This does not include when the audio is completely replaced with other audio data.
      Returns:
        the whether the frame should be preserved or discarded if the frame is unknown and the file, excluding the tag, is altered.
      See Also:
        `setFileAlterPreservation(boolean)`

    - #### setFileAlterPreservation

          public void setFileAlterPreservation(boolean fileAlterPreservation)

      sets whether the frame should be preserved or discarded if the frame is unknown and the file, excluding the tag, is altered. This does not apply when the audio is completely replaced with other audio data.
      Parameters:
        `fileAlterPreservation` - the file alteration preservation flag.
      See Also:
        `isFileAlterPreservation()`

    - #### isReadOnly

          public boolean isReadOnly()

      gets whether the contents of this frame are intended to be read only.
      Returns:
        whether the contents of this frame are intended to be read only.
      See Also:
        `setReadOnly(boolean)`

    - #### setReadOnly

          public void setReadOnly(boolean readOnly)

      sets whether the contents of this frame are intended to be read only.
      Parameters:
        `readOnly` - booleain indicating whether the contents of this frame are intended to be read only.
      See Also:
        `isReadOnly()`

    - #### isBelongsToGroup

          public boolean isBelongsToGroup()

      gets whether the frame belongs in a group with other frames. If it does, then the groupId field will contain the group's id. Every frame belonging to the same group will have the same group id.
      Returns:
        whether the frame belongs in a group with other frames.
      See Also:
        `setBelongsToGroup(boolean)`

    - #### setBelongsToGroup

          public void setBelongsToGroup(boolean belongsToGroup)

      sets whether the frame belongs in a group with other frames. If it does, then the groupId field will contain the group's id. Every frame belonging to the same group will have the same group id.
      Parameters:
        `belongsToGroup` - boolean indicating whether the frame belongs in a group with other frames.
      See Also:
        `isBelongsToGroup()`

    - #### isCompressed

          public boolean isCompressed()

      gets whether the frame is compressed using zlib. If so, then the uncompressedSize field will contain the uncompressed size of the frame.
      Returns:
        whether the frame is compressed using zlib.
      See Also:
        `setCompressed(boolean)`, `getUncompressedSize()`

    - #### setCompressed

          public void setCompressed(boolean compressed)

      sets whether the frame is compressed using zlib. If so, then the uncompressedSize field should be set to contain the uncompressed size of the frame. Otherwise, the uncompressedSize field should be set to 0.
      Parameters:
        `compressed` - boolean indicating whether the frame is compressed using zlib.
      See Also:
        `isCompressed()`

    - #### isEncrypted

          public boolean isEncrypted()

      gets whether the frame is encrypted.
      Returns:
        whether the frame is encrypted.
      See Also:
        `setEncrypted(boolean)`

    - #### setEncrypted

          public void setEncrypted(boolean encrypted)

      sets whether the frame is encrypted. If so, then the encryptionMethod field will contain the method used to encrypt the frame. Otherwise, the encryptionMethod field should be set to 0.
      Parameters:
        `encrypted` - whether the frame is encrypted.
      See Also:
        `isEncrypted()`, `setEncryptionMethod(byte)`

    - #### isUnsynchronized

          public boolean isUnsynchronized()

      gets whether the frame is unsynchronized.
      Returns:
        whether the frame is unsynchronized.
      See Also:
        `setUnsynchronized(boolean)`

    - #### setUnsynchronized

          public void setUnsynchronized(boolean unsynchronized)

      sets whether the frame is unsynchronized.
      Parameters:
        `unsynchronized` - whether the frame is unsynchronized.
      See Also:
        `isUnsynchronized()`

    - #### isDataLengthIndicatorPresent

          public boolean isDataLengthIndicatorPresent()

      gets whether the frame has a data length indicator.
      Returns:
        whether the frame has a data length indicator.
      See Also:
        `setDataLengthIndicatorPresent(boolean)`, `getDataLengthIndicator()`, `setDataLengthIndicator(int)`

    - #### setDataLengthIndicatorPresent

          public void setDataLengthIndicatorPresent(boolean dataLengthIndicatorPresent)

      sets whether the frame has a data length indicator. If so, then the dataLengthIndicator field will contain the value one would write as the 'Frame length' if all of the frame format flags were zeroed. Otherwise, the dataLengthIndicator field should be set to 0.
      Parameters:
        `dataLengthIndicatorPresent` - whether the frame has a data length indicator.
      See Also:
        `isDataLengthIndicatorPresent()`, `getDataLengthIndicator()`, `setDataLengthIndicator(int)`

    - #### getUncompressedSize

          public int getUncompressedSize()

      if the frame has been compressed using zlib as indicated by the compressed field, then this method returns the uncompressed size of the frame.
      Returns:
        if compressed is true, then the frame's uncompressed size (in bytes) is returned. Otherwise, 0 is returned.
      See Also:
        `setUncompressedSize(int)`, `setCompressed(boolean)`

    - #### setUncompressedSize

          public void setUncompressedSize(int uncompressedSize)

      sets the frame's uncompressed size as well as the compressed flag. If the uncompressed size is 0, then the compressed flag is set to false. Otherwise, it is set to true.
      Parameters:
        `uncompressedSize` - the frame's uncompressed size or 0 to indicate that the frame is not compressed.
      See Also:
        `getUncompressedSize()`, `setCompressed(boolean)`

    - #### getEncryptionMethod

          public byte getEncryptionMethod()

      if the frame has been encrypted, as indicated by the encrypted field, then this method gets the method used to encrypt the frame.
      Returns:
        if encrypted is true, then the method used to encrypt the frame is returned. Otherwise, 0 is returned.
      See Also:
        `setEncryptionMethod(byte)`, `setEncrypted(boolean)`

    - #### setEncryptionMethod

          public void setEncryptionMethod(byte encryptionMethod)

      sets the frame's encryption method as well as the encrypted flag. If the encryption method is 0, then the encrypted flag is set to false. Otherwise, it it set to true.
      Parameters:
        `encryptionMethod` - the encryption algorithm used to encrypt the frame or 0 to indicate that the frame is not encrypted.
      See Also:
        `getEncryptionMethod()`, `setEncrypted(boolean)`

    - #### getDataLengthIndicator

          public int getDataLengthIndicator()

      if the frame has a data length indicator as indicated by the dataLengthIndicatorPresent field, then this method returns the data length indicator of the frame.
      Returns:
        if dataLengthIndicatorPresent is true, then the frame's data length indicator (in bytes) is returned. Otherwise, 0 is returned.
      See Also:
        `setDataLengthIndicator(int)`, `setDataLengthIndicatorPresent(boolean)`

    - #### setDataLengthIndicator

          public void setDataLengthIndicator(int dataLengthIndicator)

      sets the frame's data length indicator as well as the dataLengthIndicatorPresent flag. If the data length indicator is 0, then the dataLengthIndicatorPresent flag is set to false. Otherwise, it is set to true.
      Parameters:
        `dataLengthIndicator` - the frame's data length indicator or 0 to indicate that the frame does not have a data length indicator.
      See Also:
        `getDataLengthIndicator()`, `setDataLengthIndicatorPresent(boolean)`

    - #### getGroupId

          public byte getGroupId()

      if the frame belongs to a group, as indicated by the belongsToGroup field, then this method gets the id used to uniquely indentify the group.
      Returns:
        if belongsToGroup is true, then the id used to uniquely indentify the group is returned. Otherwise 0 is returned.
      See Also:
        `setGroupId(byte)`, `setBelongsToGroup(boolean)`

    - #### setGroupId

          public void setGroupId(byte groupId)

      sets the frame's group id as well as the belongsToGroup flag. If the group id is 0, then the belongsToGroup flag is set to false. Otherwise, it it set to true.
      Parameters:
        `groupId` - the id that will uniquely indentify a frame group or 0 to indicate that the frame does not belong to a group of frames.
      See Also:
        `getGroupId()`, `setBelongsToGroup(boolean)`

    - #### getSize

          public int getSize()

      gets the size (in bytes) of the frame header.
      Returns:
        the size (in bytes) of the frame header.
      See Also:
        `getFrameBodySize()`

    - #### isDirty

          public boolean isDirty()

      gets whether the frame header has been modified since the last time it was saved.
      Returns:
        whether any value(s) in the frame's header have been modified.
      See Also:
        `setBuffer()`

    - #### isPadding

          public boolean isPadding()

      although an ID3v2.4 tag header specifies the size of the tag, it does not specifiy how many frames there are, the total size of the frames, nor the size of the padding. Thus, in order to detect when the frames have ended and the padding has begun, one must read in a single byte where a frame header should be and determine if the byte is 0x00. If it is, then the end of the frames have been reached and the padding has begun. Thus, this boolean indicates whether this condition has occurred, and thus there is no longer any need to continue to try and read any more frames.
      Returns:
        whether the last frame in the ID3v2.4 tag has been read and the padding has begun.
      See Also:
        `ID3v24Frame`

    - #### getInvalidFrameId

          public java.lang.String getInvalidFrameId()

      if the frame id read in is not a valid ID3v2.4 frame id, then this field is set so that the error can be reported later after the entire frame has been read in (and discarded) so that we may continue processing the remaining frames.
      Returns:
        the invalid ID3v2.4 frame id that was encountered while reading in the frame header from the .mp3 file.

    - #### save

          public void save(java.io.OutputStream outputStream)
                    throws java.io.IOException

      save the frame header to the .mp3 file.
      Parameters:
        `outputStream` - output stream pointing to the starting location of the ID3v2.4 frame header within the .mp3 file.
      Throws:
        `java.io.IOException` - if there was an error writing the ID3v2.4 frame header to the .mp3 file.

    - #### save

          public void save(java.io.RandomAccessFile file)
                    throws java.io.IOException

      save the frame header to the .mp3 file.
      Parameters:
        `file` - random access file pointing to the starting location of the ID3v2.4 frame header within the .mp3 file.
      Throws:
        `java.io.IOException` - if there was an error writing the ID3v2.4 frame header to the .mp3 file.

    - #### setBuffer

          public void setBuffer()

      if the frame header'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.

    - #### toString

          public java.lang.String toString()

      gets a string representation of an ID3v2.4 frame's header.
      Overrides:
        `toString` in class `java.lang.Object`
      Returns:
        a string representation of an ID3v2.4 frame's header.