FileDocCategorySizeDatePackage
Mp4TrackField.javaAPI DocJaudiotagger 2.0.45762Tue Aug 02 17:09:54 BST 2011org.jaudiotagger.tag.mp4.field

Mp4TrackField.java

package org.jaudiotagger.tag.mp4.field;

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;
import java.util.ArrayList;

/**
 * Represents the Track No field
 * <p/>
 * <p>There are a number of reserved fields making matters more complicated
 * Reserved:2 bytes
 * Track Number:2 bytes
 * No of Tracks:2 bytes (or zero if not known)
 * PlayListTitleReserved: 1 byte
 * playtitlenameReserved:0 bytes
 * </p>
 */
public class Mp4TrackField extends Mp4TagTextNumberField
{
    private static final int NONE_VALUE_INDEX = 0;
    private static final int TRACK_NO_INDEX = 1;
    private static final int TRACK_TOTAL_INDEX = 2;
    private static final int NONE_END_VALUE_INDEX = 3;

    /**
     * Create new Track Field parsing the String for the trackno/total
     *
     * @param trackValue
     * @throws org.jaudiotagger.tag.FieldDataInvalidException
     */
    public Mp4TrackField(String trackValue) throws FieldDataInvalidException
    {
        super(Mp4FieldKey.TRACK.getFieldName(), trackValue);

        numbers = new ArrayList<Short>();
        numbers.add(new Short("0"));

        String values[] = trackValue.split("/");
        switch (values.length)
        {
            case 1:
                try
                {
                    numbers.add(Short.parseShort(values[0]));
                }
                catch (NumberFormatException nfe)
                {
                    throw new FieldDataInvalidException("Value of:" + values[0] + " is invalid for field:" + id);
                }
                numbers.add(new Short("0"));
                numbers.add(new Short("0"));
                break;

            case 2:
                try
                {
                    numbers.add(Short.parseShort(values[0]));
                }
                catch (NumberFormatException nfe)
                {
                    throw new FieldDataInvalidException("Value of:" + values[0] + " is invalid for field:" + id);
                }
                try
                {
                    numbers.add(Short.parseShort(values[1]));
                }
                catch (NumberFormatException nfe)
                {
                    throw new FieldDataInvalidException("Value of:" + values[1] + " is invalid for field:" + id);
                }
                numbers.add(new Short("0"));
                break;

            default:
                throw new FieldDataInvalidException("Value is invalid for field:" + id);
        }
    }


    /**
     * Create new Track Field with only track No
     *
     * @param trackNo
     */
    public Mp4TrackField(int trackNo)
    {

        super(Mp4FieldKey.TRACK.getFieldName(), String.valueOf(trackNo));
        numbers = new ArrayList<Short>();
        numbers.add(new Short("0"));
        numbers.add((short) trackNo);
        numbers.add(new Short("0"));
        numbers.add(new Short("0"));
    }

    /**
     * Create new Track Field with track No and total tracks
     *
     * @param trackNo
     * @param total
     */
    public Mp4TrackField(int trackNo, int total)
    {
        super(Mp4FieldKey.TRACK.getFieldName(), String.valueOf(trackNo));
        numbers = new ArrayList<Short>();
        numbers.add(new Short("0"));
        numbers.add((short) trackNo);
        numbers.add((short) total);
        numbers.add(new Short("0"));
    }

    /**
     * Construct from filedata
     *
     * @param id
     * @param data
     * @throws UnsupportedEncodingException
     */
    public Mp4TrackField(String id, ByteBuffer data) throws UnsupportedEncodingException
    {
        super(id, data);
    }


    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();
        numbers = databox.getNumbers();
        //Track number always hold three values, we can discard the first one, the second one is the track no
        //and the third is the total no of tracks so only use if not zero
        StringBuffer sb = new StringBuffer();
        if(numbers!=null)
        {
            if ((numbers.size() > TRACK_NO_INDEX) && (numbers.get(TRACK_NO_INDEX) > 0))
            {
                sb.append(numbers.get(TRACK_NO_INDEX));
            }
            if ((numbers.size() > TRACK_TOTAL_INDEX) && (numbers.get(TRACK_TOTAL_INDEX) > 0))
            {
                sb.append("/").append(numbers.get(TRACK_TOTAL_INDEX));
            }
        }
        content = sb.toString();
    }

    /**
     * @return
     */
    public Short getTrackNo()
    {
        return numbers.get(TRACK_NO_INDEX);
    }

    /**
     * @return
     */
    public Short getTrackTotal()
    {
        if(numbers.size()<=TRACK_TOTAL_INDEX)
        {
            return 0;
        }
        return numbers.get(TRACK_TOTAL_INDEX);
    }

     /**
     * Set Track No
     *
     * @param trackNo
     */
    public void setTrackNo(int trackNo)
    {
        numbers.set(TRACK_NO_INDEX, (short) trackNo);
    }


    /**
     * Set total number of tracks
     *
     * @param trackTotal
     */
    public void setTrackTotal(int trackTotal)
    {
       numbers.set(TRACK_TOTAL_INDEX, (short) trackTotal);
    }
}