~ubuntu-branches/ubuntu/utopic/libjaudiotagger-java/utopic-proposed

« back to all changes in this revision

Viewing changes to src/org/jaudiotagger/audio/asf/io/MetadataReader.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-12-30 21:58:38 UTC
  • mfrom: (3.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20091230215838-113vy313ak2ap51i
Tags: 2.0.0-1
* New upstream release
* Update my email address
* Bump debhelper version to >= 7
* Bump Standards-Version to 3.8.3 (no changes needed)
* Depends on java5-runtime-headless as we build java5 bytecode
* Maven POMs:
  - Add a Build-Depends-Indep dependency on maven-repo-helper
  - Use mh_installpoms and mh_installjar to install the POM and the jar to the
    Maven repository

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.jaudiotagger.audio.asf.io;
 
2
 
 
3
import org.jaudiotagger.audio.asf.data.*;
 
4
import org.jaudiotagger.audio.asf.util.Utils;
 
5
 
 
6
import java.io.IOException;
 
7
import java.io.InputStream;
 
8
import java.math.BigInteger;
 
9
 
 
10
/**
 
11
 * Reads an interprets "Metadata Object", "Metadata Library
 
12
 * Object&quot; and &quot;Extended Content Description&quot; of ASF files.<br>
 
13
 * 
 
14
 * @author Christian Laireiter
 
15
 */
 
16
public class MetadataReader implements ChunkReader {
 
17
 
 
18
    /**
 
19
     * The GUID this reader {@linkplain #getApplyingIds() applies to}
 
20
     */
 
21
    private final static GUID[] APPLYING = {
 
22
            ContainerType.EXTENDED_CONTENT.getContainerGUID(),
 
23
            ContainerType.METADATA_OBJECT.getContainerGUID(),
 
24
            ContainerType.METADATA_LIBRARY_OBJECT.getContainerGUID() };
 
25
 
 
26
    /**
 
27
     * {@inheritDoc}
 
28
     */
 
29
    public boolean canFail() {
 
30
        return false;
 
31
    }
 
32
 
 
33
    /**
 
34
     * {@inheritDoc}
 
35
     */
 
36
    public GUID[] getApplyingIds() {
 
37
        return APPLYING.clone();
 
38
    }
 
39
 
 
40
    /**
 
41
     * {@inheritDoc}
 
42
     */
 
43
    public Chunk read(final GUID guid, final InputStream stream,
 
44
            final long streamPosition) throws IOException {
 
45
        final BigInteger chunkLen = Utils.readBig64(stream);
 
46
 
 
47
        final MetadataContainer result = new MetadataContainer(guid,
 
48
                streamPosition, chunkLen);
 
49
        // isExtDesc will be set to true, if a extended content description
 
50
        // chunk is read
 
51
        // otherwise it is a metadata object, there are only slight differences
 
52
        final boolean isExtDesc = result.getContainerType() == ContainerType.EXTENDED_CONTENT;
 
53
        final int recordCount = Utils.readUINT16(stream);
 
54
        for (int i = 0; i < recordCount; i++) {
 
55
            int languageIndex = 0;
 
56
            int streamNumber = 0;
 
57
            if (!isExtDesc) {
 
58
                /*
 
59
                 * Metadata objects have a language index and a stream number
 
60
                 */
 
61
                languageIndex = Utils.readUINT16(stream);
 
62
                assert languageIndex >= 0
 
63
                        && languageIndex < MetadataDescriptor.MAX_LANG_INDEX;
 
64
                assert result.getContainerType() == ContainerType.METADATA_LIBRARY_OBJECT
 
65
                        || languageIndex == 0;
 
66
                streamNumber = Utils.readUINT16(stream);
 
67
                assert streamNumber >= 0
 
68
                        && streamNumber <= MetadataDescriptor.MAX_STREAM_NUMBER;
 
69
            }
 
70
            final int nameLen = Utils.readUINT16(stream);
 
71
            String recordName = null;
 
72
            if (isExtDesc) {
 
73
                recordName = Utils.readFixedSizeUTF16Str(stream, nameLen);
 
74
            }
 
75
            final int dataType = Utils.readUINT16(stream);
 
76
            assert dataType >= 0 && dataType <= 6;
 
77
            final long dataLen = isExtDesc ? Utils.readUINT16(stream) : Utils
 
78
                    .readUINT32(stream);
 
79
            assert dataLen >= 0;
 
80
            assert result.getContainerType() == ContainerType.METADATA_LIBRARY_OBJECT
 
81
                    || dataLen <= MetadataDescriptor.DWORD_MAXVALUE;
 
82
            if (!isExtDesc) {
 
83
                recordName = Utils.readFixedSizeUTF16Str(stream, nameLen);
 
84
            }
 
85
            final MetadataDescriptor descriptor = new MetadataDescriptor(result
 
86
                    .getContainerType(), recordName, dataType, streamNumber,
 
87
                    languageIndex);
 
88
            switch (dataType) {
 
89
            case MetadataDescriptor.TYPE_STRING:
 
90
                descriptor.setStringValue(Utils.readFixedSizeUTF16Str(stream,
 
91
                        (int) dataLen));
 
92
                break;
 
93
            case MetadataDescriptor.TYPE_BINARY:
 
94
                descriptor.setBinaryValue(Utils.readBinary(stream, dataLen));
 
95
                break;
 
96
            case MetadataDescriptor.TYPE_BOOLEAN:
 
97
                assert isExtDesc && dataLen == 4 || !isExtDesc && dataLen == 2;
 
98
                descriptor.setBooleanValue(readBoolean(stream, (int) dataLen));
 
99
                break;
 
100
            case MetadataDescriptor.TYPE_DWORD:
 
101
                assert dataLen == 4;
 
102
                descriptor.setDWordValue(Utils.readUINT32(stream));
 
103
                break;
 
104
            case MetadataDescriptor.TYPE_WORD:
 
105
                assert dataLen == 2;
 
106
                descriptor.setWordValue(Utils.readUINT16(stream));
 
107
                break;
 
108
            case MetadataDescriptor.TYPE_QWORD:
 
109
                assert dataLen == 8;
 
110
                descriptor.setQWordValue(Utils.readUINT64(stream));
 
111
                break;
 
112
            case MetadataDescriptor.TYPE_GUID:
 
113
                assert dataLen == GUID.GUID_LENGTH;
 
114
                descriptor.setGUIDValue(Utils.readGUID(stream));
 
115
                break;
 
116
            default:
 
117
                // Unknown, hopefully the convention for the size of the
 
118
                // value
 
119
                // is given, so we could read it binary
 
120
                descriptor.setStringValue("Invalid datatype: "
 
121
                        + new String(Utils.readBinary(stream, dataLen)));
 
122
            }
 
123
            result.addDescriptor(descriptor);
 
124
        }
 
125
        return result;
 
126
    }
 
127
 
 
128
    /**
 
129
     * Reads the given amount of bytes and checks the last byte, if its equal to
 
130
     * one or zero (true / false).<br>
 
131
     * All other bytes must be zero. (if assertions enabled).
 
132
     * 
 
133
     * @param stream
 
134
     *            stream to read from.
 
135
     * @param bytes
 
136
     *            amount of bytes
 
137
     * @return <code>true</code> or <code>false</code>.
 
138
     * @throws IOException
 
139
     *             on I/O Errors
 
140
     */
 
141
    private boolean readBoolean(final InputStream stream, final int bytes)
 
142
            throws IOException {
 
143
        final byte[] tmp = new byte[bytes];
 
144
        stream.read(tmp);
 
145
        boolean result = false;
 
146
        for (int i = 0; i < bytes; i++) {
 
147
            if (i == bytes - 1) {
 
148
                result = tmp[i] == 1;
 
149
                assert tmp[i] == 0 || tmp[i] == 1;
 
150
            } else {
 
151
                assert tmp[i] == 0;
 
152
            }
 
153
        }
 
154
        return result;
 
155
    }
 
156
 
 
157
}