Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package com.sun.media.sound;
   26   
   27   import java.io.EOFException;
   28   import java.io.IOException;
   29   import java.io.InputStream;
   30   
   31   /**
   32    * Resource Interchange File Format (RIFF) stream decoder.
   33    *
   34    * @author Karl Helgason
   35    */
   36   public class RIFFReader extends InputStream {
   37   
   38       private RIFFReader root;
   39       private long filepointer = 0;
   40       private String fourcc;
   41       private String riff_type = null;
   42       private long ckSize = 0;
   43       private InputStream stream;
   44       private long avail;
   45       private RIFFReader lastiterator = null;
   46   
   47       public RIFFReader(InputStream stream) throws IOException {
   48   
   49           if (stream instanceof RIFFReader)
   50               root = ((RIFFReader)stream).root;
   51           else
   52               root = this;
   53   
   54           this.stream = stream;
   55           avail = Integer.MAX_VALUE;
   56           ckSize = Integer.MAX_VALUE;
   57   
   58           // Check for RIFF null paddings,
   59           int b;
   60           while (true) {
   61               b = read();
   62               if (b == -1) {
   63                   fourcc = ""; // don't put null value into fourcc,
   64                   // because it is expected to
   65                   // always contain a string value
   66                   riff_type = null;
   67                   avail = 0;
   68                   return;
   69               }
   70               if (b != 0)
   71                   break;
   72           }
   73   
   74           byte[] fourcc = new byte[4];
   75           fourcc[0] = (byte) b;
   76           readFully(fourcc, 1, 3);
   77           this.fourcc = new String(fourcc, "ascii");
   78           ckSize = readUnsignedInt();
   79   
   80           avail = this.ckSize;
   81   
   82           if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
   83               byte[] format = new byte[4];
   84               readFully(format);
   85               this.riff_type = new String(format, "ascii");
   86           }
   87       }
   88   
   89       public long getFilePointer() throws IOException {
   90           return root.filepointer;
   91       }
   92   
   93       public boolean hasNextChunk() throws IOException {
   94           if (lastiterator != null)
   95               lastiterator.finish();
   96           return avail != 0;
   97       }
   98   
   99       public RIFFReader nextChunk() throws IOException {
  100           if (lastiterator != null)
  101               lastiterator.finish();
  102           if (avail == 0)
  103               return null;
  104           lastiterator = new RIFFReader(this);
  105           return lastiterator;
  106       }
  107   
  108       public String getFormat() {
  109           return fourcc;
  110       }
  111   
  112       public String getType() {
  113           return riff_type;
  114       }
  115   
  116       public long getSize() {
  117           return ckSize;
  118       }
  119   
  120       public int read() throws IOException {
  121           if (avail == 0)
  122               return -1;
  123           int b = stream.read();
  124           if (b == -1)
  125               return -1;
  126           avail--;
  127           filepointer++;
  128           return b;
  129       }
  130   
  131       public int read(byte[] b, int offset, int len) throws IOException {
  132           if (avail == 0)
  133               return -1;
  134           if (len > avail) {
  135               int rlen = stream.read(b, offset, (int)avail);
  136               if (rlen != -1)
  137                   filepointer += rlen;
  138               avail = 0;
  139               return rlen;
  140           } else {
  141               int ret = stream.read(b, offset, len);
  142               if (ret == -1)
  143                   return -1;
  144               avail -= ret;
  145               filepointer += ret;
  146               return ret;
  147           }
  148       }
  149   
  150       public final void readFully(byte b[]) throws IOException {
  151           readFully(b, 0, b.length);
  152       }
  153   
  154       public final void readFully(byte b[], int off, int len) throws IOException {
  155           if (len < 0)
  156               throw new IndexOutOfBoundsException();
  157           while (len > 0) {
  158               int s = read(b, off, len);
  159               if (s < 0)
  160                   throw new EOFException();
  161               if (s == 0)
  162                   Thread.yield();
  163               off += s;
  164               len -= s;
  165           }
  166       }
  167   
  168       public final long skipBytes(long n) throws IOException {
  169           if (n < 0)
  170               return 0;
  171           long skipped = 0;
  172           while (skipped != n) {
  173               long s = skip(n - skipped);
  174               if (s < 0)
  175                   break;
  176               if (s == 0)
  177                   Thread.yield();
  178               skipped += s;
  179           }
  180           return skipped;
  181       }
  182   
  183       public long skip(long n) throws IOException {
  184           if (avail == 0)
  185               return -1;
  186           if (n > avail) {
  187               long len = stream.skip(avail);
  188               if (len != -1)
  189                   filepointer += len;
  190               avail = 0;
  191               return len;
  192           } else {
  193               long ret = stream.skip(n);
  194               if (ret == -1)
  195                   return -1;
  196               avail -= ret;
  197               filepointer += ret;
  198               return ret;
  199           }
  200       }
  201   
  202       public int available() {
  203           return (int)avail;
  204       }
  205   
  206       public void finish() throws IOException {
  207           if (avail != 0) {
  208               skipBytes(avail);
  209           }
  210       }
  211   
  212       // Read ASCII chars from stream
  213       public String readString(int len) throws IOException {
  214           byte[] buff = new byte[len];
  215           readFully(buff);
  216           for (int i = 0; i < buff.length; i++) {
  217               if (buff[i] == 0) {
  218                   return new String(buff, 0, i, "ascii");
  219               }
  220           }
  221           return new String(buff, "ascii");
  222       }
  223   
  224       // Read 8 bit signed integer from stream
  225       public byte readByte() throws IOException {
  226           int ch = read();
  227           if (ch < 0)
  228               throw new EOFException();
  229           return (byte) ch;
  230       }
  231   
  232       // Read 16 bit signed integer from stream
  233       public short readShort() throws IOException {
  234           int ch1 = read();
  235           int ch2 = read();
  236           if (ch1 < 0)
  237               throw new EOFException();
  238           if (ch2 < 0)
  239               throw new EOFException();
  240           return (short)(ch1 | (ch2 << 8));
  241       }
  242   
  243       // Read 32 bit signed integer from stream
  244       public int readInt() throws IOException {
  245           int ch1 = read();
  246           int ch2 = read();
  247           int ch3 = read();
  248           int ch4 = read();
  249           if (ch1 < 0)
  250               throw new EOFException();
  251           if (ch2 < 0)
  252               throw new EOFException();
  253           if (ch3 < 0)
  254               throw new EOFException();
  255           if (ch4 < 0)
  256               throw new EOFException();
  257           return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
  258       }
  259   
  260       // Read 64 bit signed integer from stream
  261       public long readLong() throws IOException {
  262           long ch1 = read();
  263           long ch2 = read();
  264           long ch3 = read();
  265           long ch4 = read();
  266           long ch5 = read();
  267           long ch6 = read();
  268           long ch7 = read();
  269           long ch8 = read();
  270           if (ch1 < 0)
  271               throw new EOFException();
  272           if (ch2 < 0)
  273               throw new EOFException();
  274           if (ch3 < 0)
  275               throw new EOFException();
  276           if (ch4 < 0)
  277               throw new EOFException();
  278           if (ch5 < 0)
  279               throw new EOFException();
  280           if (ch6 < 0)
  281               throw new EOFException();
  282           if (ch7 < 0)
  283               throw new EOFException();
  284           if (ch8 < 0)
  285               throw new EOFException();
  286           return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24)
  287                   | (ch5 << 32) | (ch6 << 40) | (ch7 << 48) | (ch8 << 56);
  288       }
  289   
  290       // Read 8 bit unsigned integer from stream
  291       public int readUnsignedByte() throws IOException {
  292           int ch = read();
  293           if (ch < 0)
  294               throw new EOFException();
  295           return ch;
  296       }
  297   
  298       // Read 16 bit unsigned integer from stream
  299       public int readUnsignedShort() throws IOException {
  300           int ch1 = read();
  301           int ch2 = read();
  302           if (ch1 < 0)
  303               throw new EOFException();
  304           if (ch2 < 0)
  305               throw new EOFException();
  306           return ch1 | (ch2 << 8);
  307       }
  308   
  309       // Read 32 bit unsigned integer from stream
  310       public long readUnsignedInt() throws IOException {
  311           long ch1 = read();
  312           long ch2 = read();
  313           long ch3 = read();
  314           long ch4 = read();
  315           if (ch1 < 0)
  316               throw new EOFException();
  317           if (ch2 < 0)
  318               throw new EOFException();
  319           if (ch3 < 0)
  320               throw new EOFException();
  321           if (ch4 < 0)
  322               throw new EOFException();
  323           return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
  324       }
  325   
  326       public void close() throws IOException {
  327           finish();
  328           if (this == root)
  329               stream.close();
  330           stream = null;
  331       }
  332   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]