FileDocCategorySizeDatePackage
Utils.javaAPI DocJaudiotagger 2.0.419304Wed Mar 30 16:11:52 BST 2011org.jaudiotagger.audio.asf.util

Utils

public class Utils extends Object
Some static Methods which are used in several Classes.
author
Christian Laireiter

Fields Summary
public static final long
DIFF_BETWEEN_ASF_DATE_AND_JAVA_DATE
public static final String
LINE_SEPARATOR
Stores the default line separator of the current underlying system.
private static final int
MAXIMUM_STRING_LENGTH_ALLOWED
Constructors Summary
Methods Summary
public static voidcheckStringLengthNullSafe(java.lang.String value)
This method checks given string will not exceed limit in bytes[] when converted UTF-16LE encoding (2 bytes per character) and checks whether the length doesn't exceed 65535 bytes.

param
value The string to check.
throws
IllegalArgumentException If byte representation takes more than 65535 bytes.


                                                                              
        
              
        if (value != null) {
            if (value.length() > MAXIMUM_STRING_LENGTH_ALLOWED) {
                throw new IllegalArgumentException(
                        ErrorMessage.WMA_LENGTH_OF_STRING_IS_TOO_LARGE
                                .getMsg((value.length() * 2)));
            }
        }
    
public static voidcopy(java.io.InputStream source, java.io.OutputStream dest, long amount)
effectively copies a specified amount of bytes from one stream to another.

param
source stream to read from
param
dest stream to write to
param
amount amount of bytes to copy
throws
IOException on I/O errors, and if the source stream depletes before all bytes have been copied.

        byte[] buf = new byte[8192];
        long copied = 0;
        while (copied < amount) {
            int toRead = 8192;
            if ((amount - copied) < 8192) {
                toRead = (int) (amount - copied);
            }
            int read = source.read(buf, 0, toRead);
            if (read == -1) {
                throw new IOException(
                        "Inputstream has to continue for another "
                                + (amount - copied) + " bytes.");
            }
            dest.write(buf, 0, read);
            copied += read;
        }
    
public static voidflush(java.io.InputStream source, java.io.OutputStream dest)
Copies all of the source to the destination.

param
source source to read from
param
dest stream to write to
throws
IOException on I/O errors.

        final byte[] buf = new byte[8192];
        int read;
        while ((read = source.read(buf)) != -1) {
            dest.write(buf, 0, read);
        }
    
public static byte[]getBytes(long value, int byteCount)
This method will create a byte[] at the size of byteCount and insert the bytes of value (starting from lowset byte) into it.
You can easily create a Word (16-bit), DWORD (32-bit), QWORD (64 bit) out of the value, ignoring the original type of value, since java automatically performs transformations.
Warning: This method works with unsigned numbers only.

param
value The value to be written into the result.
param
byteCount The number of bytes the array has got.
return
A byte[] with the size of byteCount containing the lower byte values of value.

        byte[] result = new byte[byteCount];
        for (int i = 0; i < result.length; i ++) {
            result[i] = (byte) ((value >>> (i*8)) & 0xFF);
        }
        return result;
    
public static byte[]getBytes(java.lang.String source, java.nio.charset.Charset charset)
Convenience method to convert the given string into a byte sequence which has the format of the charset given.

param
source string to convert.
param
charset charset to apply
return
the source's binary representation according to the charset.

        assert charset != null;
        assert source != null;
        final ByteBuffer encoded = charset.encode(source);
        final byte[] result = new byte[encoded.limit()];
        encoded.rewind();
        encoded.get(result);
        return result;
    
public static java.util.GregorianCalendargetDateOf(java.math.BigInteger fileTime)
Date values in ASF files are given in 100 ns (10 exp -4) steps since first

param
fileTime Time in 100ns since 1 jan 1601
return
Calendar holding the date representation.

        final GregorianCalendar result = new GregorianCalendar();

        // Divide by 10 to convert from -4 to -3 (millisecs)
        BigInteger time = fileTime.divide(new BigInteger("10"));
        // Construct Date taking into the diff between 1601 and 1970
        Date date = new Date(time.longValue() - DIFF_BETWEEN_ASF_DATE_AND_JAVA_DATE);
        result.setTime(date);
        return result;
    
public static booleanisBlank(java.lang.String toTest)
Tests if the given string is null or just contains whitespace characters.

param
toTest String to test.
return
see description.

        if (toTest == null)
        {
            return true;
        }

        for (int i = 0; i < toTest.length(); i++)
        {
            if(!Character.isWhitespace(toTest.charAt(i)))
            {
                return false;
            }
        }
        return true;
    
public static booleanisStringLengthValidNullSafe(java.lang.String value)

param
value String to check for null
return
true unless string is too long

        if (value != null) {
            if (value.length() > MAXIMUM_STRING_LENGTH_ALLOWED) {
                return false;
            }
        }
        return true;
    
public static java.math.BigIntegerreadBig64(java.io.InputStream stream)
Reads 8 bytes from stream and interprets them as a UINT64 which is returned as {@link BigInteger}.

param
stream stream to readm from.
return
a BigInteger which represents the read 8 bytes value.
throws
IOException if problem reading bytes

        byte[] bytes = new byte[8];
        byte[] oa = new byte[8];
        int read = stream.read(bytes);
        if (read != 8) {
            // 8 bytes mandatory.
            throw new EOFException();
        }
        for (int i = 0; i < bytes.length; i++) {
            oa[7 - i] = bytes[i];
        }
        return new BigInteger(oa);
    
public static byte[]readBinary(java.io.InputStream stream, long size)
Reads size bytes from the stream.

param
stream stream to read from.
param
size amount of bytes to read.
return
the read bytes.
throws
IOException on I/O errors.

        byte[] result = new byte[(int) size];
        stream.read(result);
        return result;
    
public static java.lang.StringreadCharacterSizedString(java.io.InputStream stream)
This method reads a UTF-16 String, which length is given on the number of characters it consists of.
The stream must be at the number of characters. This number contains the terminating zero character (UINT16).

param
stream Input source
return
String
throws
IOException read errors

        StringBuilder result = new StringBuilder();
        int strLen = readUINT16(stream);
        int character = stream.read();
        character |= stream.read() << 8;
        do {
            if (character != 0) {
                result.append((char) character);
                character = stream.read();
                character |= stream.read() << 8;
            }
        } while (character != 0 || (result.length() + 1) > strLen);
        if (strLen != (result.length() + 1)) {
            throw new IllegalStateException(
                    "Invalid Data for current interpretation"); //$NON-NLS-1$
        }
        return result.toString();
    
public static java.lang.StringreadFixedSizeUTF16Str(java.io.InputStream stream, int strLen)
This method reads a UTF-16 encoded String.
For the use this method the number of bytes used by current string must be known.
The ASF specification recommends that those strings end with a terminating zero. However it also says that it is not always the case.

param
stream Input source
param
strLen Number of bytes the String may take.
return
read String.
throws
IOException read errors.

        byte[] strBytes = new byte[strLen];
        int read = stream.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.");
    
public static org.jaudiotagger.audio.asf.data.GUIDreadGUID(java.io.InputStream stream)
This Method reads a GUID (which is a 16 byte long sequence) from the given raf and creates a wrapper.
Warning :
There is no way of telling if a byte sequence is a guid or not. The next 16 bytes will be interpreted as a guid, whether it is or not.

param
stream Input source.
return
A class wrapping the guid.
throws
IOException happens when the file ends before guid could be extracted.

        if (stream == null) {
            throw new IllegalArgumentException("Argument must not be null"); //$NON-NLS-1$
        }
        int[] binaryGuid = new int[GUID.GUID_LENGTH];
        for (int i = 0; i < binaryGuid.length; i++) {
            binaryGuid[i] = stream.read();
        }
        return new GUID(binaryGuid);
    
public static intreadUINT16(java.io.InputStream stream)
Reads 2 bytes from stream and interprets them as UINT16.

param
stream stream to read from.
return
UINT16 value
throws
IOException on I/O Errors.

        int result = stream.read();
        result |= stream.read() << 8;
        return result;
    
public static longreadUINT32(java.io.InputStream stream)
Reads 4 bytes from stream and interprets them as UINT32.

param
stream stream to read from.
return
UINT32 value
throws
IOException on I/O Errors.

        long result = 0;
        for (int i = 0; i <= 24; i += 8) {
            // Warning, always cast to long here. Otherwise it will be
            // shifted as int, which may produce a negative value, which will
            // then be extended to long and assign the long variable a negative
            // value.
            result |= (long) stream.read() << i;
        }
        return result;
    
public static longreadUINT64(java.io.InputStream stream)
Reads long as little endian.

param
stream Data source
return
long value
throws
IOException read error, or eof is reached before long is completed

        long result = 0;
        for (int i = 0; i <= 56; i += 8) {
            // Warning, always cast to long here. Otherwise it will be
            // shifted as int, which may produce a negative value, which will
            // then be extended to long and assign the long variable a negative
            // value.
            result |= (long) stream.read() << i;
        }
        return result;
    
public static java.lang.StringreadUTF16LEStr(java.io.InputStream stream)
This method reads a UTF-16 encoded String, beginning with a 16-bit value representing the number of bytes needed. The String is terminated with as 16-bit ZERO.

param
stream Input source
return
read String.
throws
IOException read errors.

        int strLen = readUINT16(stream);
        byte[] buf = new byte[strLen];
        int read = stream.read(buf);
        if (read == strLen || (strLen == 0 && read == -1)) {
            /*
             * Check on zero termination
             */
            if (buf.length >= 2) {
                if (buf[buf.length - 1] == 0 && buf[buf.length - 2] == 0) {
                    byte[] copy = new byte[buf.length - 2];
                    System.arraycopy(buf, 0, copy, 0, buf.length - 2);
                    buf = copy;
                }
            }
            return new String(buf, AsfHeader.ASF_CHARSET.name());
        }
        throw new IllegalStateException(
                "Invalid Data for current interpretation"); //$NON-NLS-1$
    
public static voidwriteUINT16(int number, java.io.OutputStream out)
Writes the given value as UINT16 into the stream.

param
number value to write.
param
out stream to write into.
throws
IOException On I/O errors

        if (number < 0) {
            throw new IllegalArgumentException("positive value expected."); //$NON-NLS-1$
        }
        byte[] toWrite = new byte[2];
        for (int i = 0; i <= 8; i += 8) {
            toWrite[i / 8] = (byte) ((number >> i) & 0xFF);
        }
        out.write(toWrite);
    
public static voidwriteUINT32(long number, java.io.OutputStream out)
Writes the given value as UINT32 into the stream.

param
number value to write.
param
out stream to write into.
throws
IOException On I/O errors

        if (number < 0) {
            throw new IllegalArgumentException("positive value expected."); //$NON-NLS-1$
        }
        byte[] toWrite = new byte[4];
        for (int i = 0; i <= 24; i += 8) {
            toWrite[i / 8] = (byte) ((number >> i) & 0xFF);
        }
        out.write(toWrite);
    
public static voidwriteUINT64(long number, java.io.OutputStream out)
Writes the given value as UINT64 into the stream.

param
number value to write.
param
out stream to write into.
throws
IOException On I/O errors

        if (number < 0) {
            throw new IllegalArgumentException("positive value expected."); //$NON-NLS-1$
        }
        byte[] toWrite = new byte[8];
        for (int i = 0; i <= 56; i += 8) {
            toWrite[i / 8] = (byte) ((number >> i) & 0xFF);
        }
        out.write(toWrite);