FileDocCategorySizeDatePackage
AbstractID3v2FrameBody.javaAPI DocJaudiotagger 2.0.48038Wed Jun 08 12:05:40 BST 2011org.jaudiotagger.tag.id3.framebody

AbstractID3v2FrameBody

public abstract class AbstractID3v2FrameBody extends org.jaudiotagger.tag.id3.AbstractTagFrameBody
Contains the content for an ID3v2 frame, (the header is held directly within the frame

Fields Summary
protected static final String
TYPE_BODY
private int
size
Frame Body Size, originally this is size as indicated in frame header when we come to writing data we recalculate it.
Constructors Summary
protected AbstractID3v2FrameBody()
Create Empty Body. Super Constructor sets up Object list



                  
     
    
    
protected AbstractID3v2FrameBody(AbstractID3v2FrameBody copyObject)
Create Body based on another body

param
copyObject

        super(copyObject);
    
protected AbstractID3v2FrameBody(ByteBuffer byteBuffer, int frameSize)
Creates a new FrameBody dataType from file. The super Constructor sets up the Object list for the frame.

param
byteBuffer from where to read the frame body from
param
frameSize
throws
org.jaudiotagger.tag.InvalidTagException

        super();
        setSize(frameSize);
        this.read(byteBuffer);

    
Methods Summary
public voidcreateStructure()
Return String Representation of Datatype *

        MP3File.getStructureFormatter().openHeadingElement(TYPE_BODY, "");
        for (AbstractDataType nextObject : objectList)
        {
            nextObject.createStructure();
        }
        MP3File.getStructureFormatter().closeHeadingElement(TYPE_BODY);
    
public booleanequals(java.lang.Object obj)
Are two bodies equal

param
obj

        return (obj instanceof AbstractID3v2FrameBody) && super.equals(obj);
        
public abstract java.lang.StringgetIdentifier()
Return the ID3v2 Frame Identifier, must be implemented by concrete subclasses

return
the frame identifier

public intgetSize()
Return size of frame body,if frameBody already exist will take this value from the frame header but it is always recalculated before writing any changes back to disk.

return
size in bytes of this frame body

        return size;
    
public voidread(java.nio.ByteBuffer byteBuffer)
This reads a frame body from a ByteBuffer into the appropriate FrameBody class and update the position of the buffer to be just after the end of this frameBody

The ByteBuffer represents the tag and its position should be at the start of this frameBody. The size as indicated in the header is passed to the frame constructor when reading from file.

param
byteBuffer file to read
throws
InvalidFrameException if unable to construct a frameBody from the ByteBuffer

        int size = getSize();
        logger.config("Reading body for" + this.getIdentifier() + ":" + size);

        //Allocate a buffer to the size of the Frame Body and read from file
        byte[] buffer = new byte[size];
        byteBuffer.get(buffer);

        //Offset into buffer, incremented by length of previous dataType
        //this offset is only used internally to decide where to look for the next
        //dataType within a frameBody, it does not decide where to look for the next frame body
        int offset = 0;

        //Go through the ObjectList of the Frame reading the data into the
        for (AbstractDataType object : objectList)
        //correct dataType.
        {
            logger.finest("offset:" + offset);

            //The read has extended further than the defined frame size (ok to extend upto
            //size because the next datatype may be of length 0.)
            if (offset > (size))
            {
                logger.warning("Invalid Size for FrameBody");
                throw new InvalidFrameException("Invalid size for Frame Body");
            }

            //Try and load it with data from the Buffer
            //if it fails frame is invalid
            try
            {
                object.readByteArray(buffer, offset);
            }
            catch (InvalidDataTypeException e)
            {
                logger.warning("Problem reading datatype within Frame Body:" + e.getMessage());
                throw e;
            }
            //Increment Offset to start of next datatype.
            offset += object.getSize();
        }
    
public voidsetSize(int size)
Set size based on size passed as parameter from frame header, done before read

param
size

        this.size = size;
    
public voidsetSize()
Set size based on size of the DataTypes making up the body,done after write

        size = 0;
        for (AbstractDataType object : objectList)
        {
            size += object.getSize();
        }
        
public voidwrite(java.io.ByteArrayOutputStream tagBuffer)
Write the contents of this datatype to the byte array

param
tagBuffer
throws
IOException on any I/O error

        logger.config("Writing frame body for" + this.getIdentifier() + ":Est Size:" + size);
        //Write the various fields to file in order
        for (AbstractDataType object : objectList)
        {
            byte[] objectData = object.writeByteArray();
            if (objectData != null)
            {
                try
                {
                    tagBuffer.write(objectData);
                }
                catch (IOException ioe)
                {
                    //This could never happen coz not writing to file, so convert to RuntimeException
                    throw new RuntimeException(ioe);
                }
            }
        }
        setSize();
        logger.config("Written frame body for" + this.getIdentifier() + ":Real Size:" + size);