Package entagged.audioformats.asf.io

Source Code of entagged.audioformats.asf.io.ContentDescriptionReader

/*
* Entagged Audio Tag library
* Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package entagged.audioformats.asf.io;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.math.BigInteger;

import entagged.audioformats.asf.data.ContentDescription;
import entagged.audioformats.asf.data.Chunk;
import entagged.audioformats.asf.data.GUID;
import entagged.audioformats.asf.util.Utils;

/**
* Reads and interprets the data of a asf chunk containing title, author... <br>
*
* @see entagged.audioformats.asf.data.ContentDescription
*
* @author Christian Laireiter
*/
public class ContentDescriptionReader {

    /**
     * Creates and fills a
     * {@link entagged.audioformats.asf.data.ContentDescription}from given
     * file. <br>
     *
     * @param raf
     *                  Input
     * @param candidate
     *                  Chunk which possibly is a file header.
     * @return FileHeader if filepointer of <code>raf</code> is at valid
     *              fileheader.
     * @throws IOException
     *                   Read errors.
     */
    public static ContentDescription read(RandomAccessFile raf, Chunk candidate)
            throws IOException {
        if (raf == null || candidate == null) {
            throw new IllegalArgumentException("Arguments must not be null.");
        }
        if (GUID.GUID_CONTENTDESCRIPTION.equals(candidate.getGuid())) {
            raf.seek(candidate.getPosition());
            return new ContentDescriptionReader().parseData(raf);
        }
        return null;
    }

    /**
     * This method reads a UTF-16 encoded String. <br>
     * For the use this method the number of bytes used by current string must
     * be known. <br>
     * The ASF spec recommends that those strings end with a terminating zero.
     * However it also says that it is not always the case.
     *
     * @param raf
     *                  Input source
     * @param strLen
     *                  Number of bytes the String may take.
     * @return read String.
     * @throws IOException
     *                   read errors.
     */
    public static String readFixedSizeUTF16Str(RandomAccessFile raf, int strLen)
            throws IOException {
        byte[] strBytes = new byte[strLen];
        int read = raf.read(strBytes);
        if (read == strBytes.length) {
            if (strBytes.length >= 2) {
                /*
                 * Zero termination is recommended but optional.
                 * So check and if, remove.
                 */
                if (strBytes[strBytes.length-1] == 0 && strBytes[strBytes.length-2] == 0) {
                    byte[] copy = new byte[strBytes.length-2];
                    System.arraycopy(strBytes, 0, copy, 0, strBytes.length-2);
                    strBytes = copy;
                }
            }
            return new String(strBytes, "UTF-16LE");
        }
        throw new IllegalStateException(
                "Couldn't read the necessary amount of bytes.");
    }

    /**
     * Should not be used for now.
     * 
     */
    protected ContentDescriptionReader() {
        // NOTHING toDo
    }

    /**
     * Directly behind the GUID and chunkSize of the current chunck comes 5
     * sizes (16-bit) of string lengths. <br>
     *
     * @param raf
     *                  input source
     * @return Number and length of Strings, which are directly behind
     *              filepointer if method exits.
     * @throws IOException
     *                   read errors.
     */
    private int[] getStringSizes(RandomAccessFile raf) throws IOException {
        int[] result = new int[5];
        for (int i = 0; i < result.length; i++) {
            result[i] = Utils.readUINT16(raf);
        }
        return result;
    }

    /**
     * Does the job of {@link #read(RandomAccessFile, Chunk)}
     *
     * @param raf
     *                  input source
     * @return Contentdescription
     * @throws IOException
     *                   read errors.
     */
    private ContentDescription parseData(RandomAccessFile raf)
            throws IOException {
        ContentDescription result = null;
        long chunkStart = raf.getFilePointer();
        GUID guid = Utils.readGUID(raf);
        if (GUID.GUID_CONTENTDESCRIPTION.equals(guid)) {
            BigInteger chunkLen = Utils.readBig64(raf);
            result = new ContentDescription(chunkStart, chunkLen);
            /*
             * Now comes 16-Bit values representing the length of the Strings
             * which follows.
             */
            int[] stringSizes = getStringSizes(raf);
            /*
             * Now we know the String length of each occuring String.
             */
            String[] strings = new String[stringSizes.length];
            for (int i = 0; i < strings.length; i++) {
                if (stringSizes[i] > 0)
                    strings[i] = readFixedSizeUTF16Str(raf, stringSizes[i]);
            }
            if (stringSizes[0] > 0)
                result.setTitle(strings[0]);
            if (stringSizes[1] > 0)
                result.setAuthor(strings[1]);
            if (stringSizes[2] > 0)
                result.setCopyRight(strings[2]);
            if (stringSizes[3] > 0)
                result.setComment(strings[3]);
            if (stringSizes[4] > 0)
                result.setRating(strings[4]);
        }
        return result;
    }
}
TOP

Related Classes of entagged.audioformats.asf.io.ContentDescriptionReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.