FileDocCategorySizeDatePackage
MetadataReader.javaAPI DocJaudiotagger 2.0.46203Wed Mar 30 16:11:50 BST 2011org.jaudiotagger.audio.asf.io

MetadataReader

public class MetadataReader extends Object implements ChunkReader
Reads an interprets "Metadata Object", "Metadata Library Object" and "Extended Content Description" of ASF files.
author
Christian Laireiter

Fields Summary
private static final GUID[]
APPLYING
The GUID this reader {@linkplain #getApplyingIds() applies to}
Constructors Summary
Methods Summary
public booleancanFail()
{@inheritDoc}


          
       
        return false;
    
public GUID[]getApplyingIds()
{@inheritDoc}

        return APPLYING.clone();
    
public Chunkread(GUID guid, java.io.InputStream stream, long streamPosition)
{@inheritDoc}

        final BigInteger chunkLen = Utils.readBig64(stream);

        final MetadataContainer result = new MetadataContainer(guid,
                streamPosition, chunkLen);
        // isExtDesc will be set to true, if a extended content description
        // chunk is read
        // otherwise it is a metadata object, there are only slight differences
        final boolean isExtDesc = result.getContainerType() == ContainerType.EXTENDED_CONTENT;
        final int recordCount = Utils.readUINT16(stream);
        for (int i = 0; i < recordCount; i++) {
            int languageIndex = 0;
            int streamNumber = 0;
            if (!isExtDesc) {
                /*
                 * Metadata objects have a language index and a stream number
                 */
                languageIndex = Utils.readUINT16(stream);
                assert languageIndex >= 0
                        && languageIndex < MetadataDescriptor.MAX_LANG_INDEX;
                assert result.getContainerType() == ContainerType.METADATA_LIBRARY_OBJECT
                        || languageIndex == 0;
                streamNumber = Utils.readUINT16(stream);
                assert streamNumber >= 0
                        && streamNumber <= MetadataDescriptor.MAX_STREAM_NUMBER;
            }
            final int nameLen = Utils.readUINT16(stream);
            String recordName = null;
            if (isExtDesc) {
                recordName = Utils.readFixedSizeUTF16Str(stream, nameLen);
            }
            final int dataType = Utils.readUINT16(stream);
            assert dataType >= 0 && dataType <= 6;
            final long dataLen = isExtDesc ? Utils.readUINT16(stream) : Utils
                    .readUINT32(stream);
            assert dataLen >= 0;
            assert result.getContainerType() == ContainerType.METADATA_LIBRARY_OBJECT
                    || dataLen <= MetadataDescriptor.DWORD_MAXVALUE;
            if (!isExtDesc) {
                recordName = Utils.readFixedSizeUTF16Str(stream, nameLen);
            }
            final MetadataDescriptor descriptor = new MetadataDescriptor(result
                    .getContainerType(), recordName, dataType, streamNumber,
                    languageIndex);
            switch (dataType) {
            case MetadataDescriptor.TYPE_STRING:
                descriptor.setStringValue(Utils.readFixedSizeUTF16Str(stream,
                        (int) dataLen));
                break;
            case MetadataDescriptor.TYPE_BINARY:
                descriptor.setBinaryValue(Utils.readBinary(stream, dataLen));
                break;
            case MetadataDescriptor.TYPE_BOOLEAN:
                assert isExtDesc && dataLen == 4 || !isExtDesc && dataLen == 2;
                descriptor.setBooleanValue(readBoolean(stream, (int) dataLen));
                break;
            case MetadataDescriptor.TYPE_DWORD:
                assert dataLen == 4;
                descriptor.setDWordValue(Utils.readUINT32(stream));
                break;
            case MetadataDescriptor.TYPE_WORD:
                assert dataLen == 2;
                descriptor.setWordValue(Utils.readUINT16(stream));
                break;
            case MetadataDescriptor.TYPE_QWORD:
                assert dataLen == 8;
                descriptor.setQWordValue(Utils.readUINT64(stream));
                break;
            case MetadataDescriptor.TYPE_GUID:
                assert dataLen == GUID.GUID_LENGTH;
                descriptor.setGUIDValue(Utils.readGUID(stream));
                break;
            default:
                // Unknown, hopefully the convention for the size of the
                // value
                // is given, so we could read it binary
                descriptor.setStringValue("Invalid datatype: "
                        + new String(Utils.readBinary(stream, dataLen)));
            }
            result.addDescriptor(descriptor);
        }
        return result;
    
private booleanreadBoolean(java.io.InputStream stream, int bytes)
Reads the given amount of bytes and checks the last byte, if its equal to one or zero (true / false).
All other bytes must be zero. (if assertions enabled).

param
stream stream to read from.
param
bytes amount of bytes
return
true or false.
throws
IOException on I/O Errors

        final byte[] tmp = new byte[bytes];
        stream.read(tmp);
        boolean result = false;
        for (int i = 0; i < bytes; i++) {
            if (i == bytes - 1) {
                result = tmp[i] == 1;
                assert tmp[i] == 0 || tmp[i] == 1;
            } else {
                assert tmp[i] == 0;
            }
        }
        return result;