FileDocCategorySizeDatePackage
Mp4TagByteField.javaAPI DocJaudiotagger 2.0.44898Wed Mar 30 16:12:10 BST 2011org.jaudiotagger.tag.mp4.field

Mp4TagByteField.java

package org.jaudiotagger.tag.mp4.field;

import org.jaudiotagger.audio.generic.Utils;
import org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader;
import org.jaudiotagger.tag.FieldDataInvalidException;
import org.jaudiotagger.tag.mp4.Mp4FieldKey;
import org.jaudiotagger.tag.mp4.atom.Mp4DataBox;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

/**
 * Represents a single byte as a number
 * <p/>
 * <p>Usually single byte fields are used as a boolean field, but not always so we dont do this conversion
 */
public class Mp4TagByteField extends Mp4TagTextField
{
    public static String TRUE_VALUE="1";  //when using this field to hold a boolean

    //Holds the actual size of the data content as held in the databoxitem, this is required when creating new
    //items because we cant accurately work out the size by looking at the content because sometimes field must be longer
    //than is actually required to hold the value
    //e.g byte data length seems to be 1 for pgap and cpil but 2 for tmpo, so we stored the dataSize
    //when we loaded the value so if greater than 1 we pad the value.
    private int realDataLength;

    //Preserved from data from file
    private byte[] bytedata;

    /**
     * Create new field
     * <p/>
     * Assume length of 1 which is correct for most but not all byte fields
     *
     * @param id
     * @param value is a String representation of a number
     * @throws org.jaudiotagger.tag.FieldDataInvalidException
     */
    public Mp4TagByteField(Mp4FieldKey id, String value) throws FieldDataInvalidException
    {
        this(id, value, 1);
    }

    /**
     * Create new field with known length
     *
     * @param id
     * @param value is a String representation of a number
     * @param realDataLength
     * @throws org.jaudiotagger.tag.FieldDataInvalidException
     */
    public Mp4TagByteField(Mp4FieldKey id, String value, int realDataLength) throws FieldDataInvalidException
    {
        super(id.getFieldName(), value);
        this.realDataLength = realDataLength;
        //Check that can actually be stored numercially, otherwise will have big problems
        //when try and save the field
        try
        {
            Long.parseLong(value);
        }
        catch (NumberFormatException nfe)
        {
            throw new FieldDataInvalidException("Value of:" + value + " is invalid for field:" + id);
        }
    }

    /**
     * Construct from rawdata from audio file
     *
     * @param id
     * @param raw
     * @throws UnsupportedEncodingException
     */
    public Mp4TagByteField(String id, ByteBuffer raw) throws UnsupportedEncodingException
    {
        super(id, raw);
    }

    public Mp4FieldType getFieldType()
    {
        return Mp4FieldType.INTEGER;
    }

    /**
     * Return raw data bytes
     * <p/>
     * TODO this code should be done better so generalised to any length
     *
     * @return
     * @throws UnsupportedEncodingException
     */
    protected byte[] getDataBytes() throws UnsupportedEncodingException
    {

        //Write original data
        if (bytedata != null)
        {
            return bytedata;
        }

        //new field, lets hope the realDataLength is correct
        switch (realDataLength)
        {
            case 2:
            {
                //Save as two bytes
                Short shortValue = new Short(content);
                byte rawData[] = Utils.getSizeBEInt16(shortValue);
                return rawData;
            }
            case 1:
            {
                //Save as 1 bytes
                Short shortValue = new Short(content);
                byte rawData[] = new byte[1];
                rawData[0] = shortValue.byteValue();
                return rawData;
            }
            case 4:
            {
                //Assume could be int
                Integer intValue = new Integer(content);
                byte rawData[] = Utils.getSizeBEInt32(intValue);
                return rawData;
            }
            default:
            {
                //TODO
                throw new RuntimeException(id + ":" + realDataLength + ":" + "Dont know how to write byte fields of this length");
            }
        }

    }

    protected void build(ByteBuffer data) throws UnsupportedEncodingException
    {
        //Data actually contains a 'Data' Box so process data using this
        Mp4BoxHeader header = new Mp4BoxHeader(data);
        Mp4DataBox databox = new Mp4DataBox(header, data);
        dataSize = header.getDataLength();
        //Needed for subsequent write
        realDataLength = dataSize - Mp4DataBox.PRE_DATA_LENGTH;
        bytedata = databox.getByteData();
        content = databox.getContent();

    }
}