changes.
authoryeom <yeom>
Mon, 15 Aug 2011 01:27:45 +0000 (01:27 +0000)
committeryeom <yeom>
Mon, 15 Aug 2011 01:27:45 +0000 (01:27 +0000)
15 files changed:
Robust/src/ClassLibrary/SSJava/BufferedInputStream.java
Robust/src/ClassLibrary/SSJava/Enumeration.java [new file with mode: 0644]
Robust/src/ClassLibrary/SSJava/FileInputStream.java
Robust/src/ClassLibrary/SSJava/FilterInputStream.java
Robust/src/ClassLibrary/SSJava/PushbackInputStream.java
Robust/src/ClassLibrary/SSJava/String.java
Robust/src/ClassLibrary/SSJava/System.java
Robust/src/ClassLibrary/SSJava/Vector.java [new file with mode: 0644]
Robust/src/Tests/ssJava/mp3decoder/Bitstream.java
Robust/src/Tests/ssJava/mp3decoder/Decoder.java
Robust/src/Tests/ssJava/mp3decoder/Header.java
Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java
Robust/src/Tests/ssJava/mp3decoder/MP3Player.java
Robust/src/Tests/ssJava/mp3decoder/Player.java
Robust/src/Tests/ssJava/mp3decoder/huffcodetab.java

index ead2f26f3c514e1aa2f328fc702256df41f93fc4..e1144a3fddf78f7afb96517d53255123ea77a073 100644 (file)
@@ -35,36 +35,33 @@ this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
  * "The Java Language Specification", ISBN 0-201-63451-1
  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
  * Status:  Believed complete and correct.
  */
+
 /**
- * This subclass of <code>FilterInputStream</code> buffers input from an 
+ * This subclass of <code>FilterInputStream</code> buffers input from an
  * underlying implementation to provide a possibly more efficient read
- * mechanism.  It maintains the buffer and buffer state in instance 
- * variables that are available to subclasses.  The default buffer size
- * of 2048 bytes can be overridden by the creator of the stream.
+ * mechanism. It maintains the buffer and buffer state in instance variables
+ * that are available to subclasses. The default buffer size of 2048 bytes can
+ * be overridden by the creator of the stream.
  * <p>
- * This class also implements mark/reset functionality.  It is capable
- * of remembering any number of input bytes, to the limits of
- * system memory or the size of <code>Integer.MAX_VALUE</code>
+ * This class also implements mark/reset functionality. It is capable of
+ * remembering any number of input bytes, to the limits of system memory or the
+ * size of <code>Integer.MAX_VALUE</code>
  * <p>
- * Please note that this class does not properly handle character
- * encodings.  Consider using the <code>BufferedReader</code> class which
- * does.
- *
+ * Please note that this class does not properly handle character encodings.
+ * Consider using the <code>BufferedReader</code> class which does.
+ * 
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Warren Levy (warrenl@cygnus.com)
  * @author Jeroen Frijters (jeroen@frijters.net)
  */
 @LATTICE("BUF<C,IN<T")
 @METHODDEFAULT("D<IN,D<C,THISLOC=D")
-public class BufferedInputStream extends FilterInputStream
-{
+public class BufferedInputStream extends FilterInputStream {
 
   /**
    * This is the default buffer size
@@ -74,66 +71,70 @@ public class BufferedInputStream extends FilterInputStream
   /**
    * The buffer used for storing data from the underlying stream.
    */
-  @LOC("BUF") protected byte[] buf;
+  @LOC("BUF")
+  protected byte[] buf;
 
   /**
-   * The number of valid bytes currently in the buffer.  It is also the index
-   * of the buffer position one byte past the end of the valid data.
+   * The number of valid bytes currently in the buffer. It is also the index of
+   * the buffer position one byte past the end of the valid data.
    */
-  @LOC("C") protected int count;
+  @LOC("C")
+  protected int count;
 
   /**
-   * The index of the next character that will by read from the buffer.
-   * When <code>pos == count</code>, the buffer is empty.
+   * The index of the next character that will by read from the buffer. When
+   * <code>pos == count</code>, the buffer is empty.
    */
-  @LOC("C") protected int pos;
+  @LOC("C")
+  protected int pos;
 
   /**
    * The value of <code>pos</code> when the <code>mark()</code> method was
-   * called.  
-   * This is set to -1 if there is no mark set.
+   * called. This is set to -1 if there is no mark set.
    */
- @LOC("C")  protected int markpos = -1;
+  @LOC("C")
+  protected int markpos = -1;
 
   /**
-   * This is the maximum number of bytes than can be read after a 
-   * call to <code>mark()</code> before the mark can be discarded.
-   * After this may bytes are read, the <code>reset()</code> method
-   * may not be called successfully.
+   * This is the maximum number of bytes than can be read after a call to
+   * <code>mark()</code> before the mark can be discarded. After this may bytes
+   * are read, the <code>reset()</code> method may not be called successfully.
    */
   protected int marklimit;
 
   /**
-   * This is the initial buffer size. When the buffer is grown because
-   * of marking requirements, it will be grown by bufferSize increments.
-   * The underlying stream will be read in chunks of bufferSize.
+   * This is the initial buffer size. When the buffer is grown because of
+   * marking requirements, it will be grown by bufferSize increments. The
+   * underlying stream will be read in chunks of bufferSize.
    */
   private final int bufferSize;
 
   /**
    * This method initializes a new <code>BufferedInputStream</code> that will
-   * read from the specified subordinate stream with a default buffer size
-   * of 2048 bytes
-   *
-   * @param in The subordinate stream to read from
+   * read from the specified subordinate stream with a default buffer size of
+   * 2048 bytes
+   * 
+   * @param in
+   *          The subordinate stream to read from
    */
-  public BufferedInputStream(InputStream in)
-  {
+  public BufferedInputStream(InputStream in) {
     this(in, DEFAULT_BUFFER_SIZE);
   }
 
   /**
    * This method initializes a new <code>BufferedInputStream</code> that will
-   * read from the specified subordinate stream with a buffer size that
-   * is specified by the caller.
-   *
-   * @param in The subordinate stream to read from
-   * @param size The buffer size to use
-   *
-   * @exception IllegalArgumentException when size is smaller then 1
+   * read from the specified subordinate stream with a buffer size that is
+   * specified by the caller.
+   * 
+   * @param in
+   *          The subordinate stream to read from
+   * @param size
+   *          The buffer size to use
+   * 
+   * @exception IllegalArgumentException
+   *              when size is smaller then 1
    */
-  public BufferedInputStream(InputStream in, int size)
-  {
+  public BufferedInputStream(InputStream in, int size) {
     super(in);
     if (size <= 0)
       throw new IllegalArgumentException();
@@ -144,31 +145,31 @@ public class BufferedInputStream extends FilterInputStream
   }
 
   /**
-   * This method returns the number of bytes that can be read from this
-   * stream before a read can block.  A return of 0 indicates that blocking
-   * might (or might not) occur on the very next read attempt.
+   * This method returns the number of bytes that can be read from this stream
+   * before a read can block. A return of 0 indicates that blocking might (or
+   * might not) occur on the very next read attempt.
    * <p>
-   * The number of available bytes will be the number of read ahead bytes 
-   * stored in the internal buffer plus the number of available bytes in
-   * the underlying stream.
-   *
+   * The number of available bytes will be the number of read ahead bytes stored
+   * in the internal buffer plus the number of available bytes in the underlying
+   * stream.
+   * 
    * @return The number of bytes that can be read before blocking could occur
-   *
-   * @exception IOException If an error occurs
+   * 
+   * @exception IOException
+   *              If an error occurs
    */
-  public synchronized int available() throws IOException
-  {
+  public synchronized int available() throws IOException {
     return count - pos + super.available();
   }
 
   /**
-   * This method closes the underlying input stream and frees any
-   * resources associated with it. Sets <code>buf</code> to <code>null</code>.
-   *
-   * @exception IOException If an error occurs.
+   * This method closes the underlying input stream and frees any resources
+   * associated with it. Sets <code>buf</code> to <code>null</code>.
+   * 
+   * @exception IOException
+   *              If an error occurs.
    */
-  public void close() throws IOException
-  {
+  public void close() throws IOException {
     // Free up the array memory.
     buf = null;
     pos = count = 0;
@@ -178,86 +179,88 @@ public class BufferedInputStream extends FilterInputStream
 
   /**
    * This method marks a position in the input to which the stream can be
-   * "reset" by calling the <code>reset()</code> method.  The parameter
-   * <code>readlimit</code> is the number of bytes that can be read from the 
-   * stream after setting the mark before the mark becomes invalid.  For
-   * example, if <code>mark()</code> is called with a read limit of 10, then
-   * when 11 bytes of data are read from the stream before the
-   * <code>reset()</code> method is called, then the mark is invalid and the
-   * stream object instance is not required to remember the mark.
+   * "reset" by calling the <code>reset()</code> method. The parameter
+   * <code>readlimit</code> is the number of bytes that can be read from the
+   * stream after setting the mark before the mark becomes invalid. For example,
+   * if <code>mark()</code> is called with a read limit of 10, then when 11
+   * bytes of data are read from the stream before the <code>reset()</code>
+   * method is called, then the mark is invalid and the stream object instance
+   * is not required to remember the mark.
    * <p>
-   * Note that the number of bytes that can be remembered by this method
-   * can be greater than the size of the internal read buffer.  It is also
-   * not dependent on the subordinate stream supporting mark/reset
-   * functionality.
-   *
-   * @param readlimit The number of bytes that can be read before the mark
-   * becomes invalid
+   * Note that the number of bytes that can be remembered by this method can be
+   * greater than the size of the internal read buffer. It is also not dependent
+   * on the subordinate stream supporting mark/reset functionality.
+   * 
+   * @param readlimit
+   *          The number of bytes that can be read before the mark becomes
+   *          invalid
    */
-  public synchronized void mark(@LOC("IN") int readlimit)
-  {
-    marklimit = readlimit; 
+  public synchronized void mark(@LOC("IN") int readlimit) {
+    marklimit = readlimit;
     markpos = pos;
   }
 
   /**
-   * This method returns <code>true</code> to indicate that this class
-   * supports mark/reset functionality.
-   *
+   * This method returns <code>true</code> to indicate that this class supports
+   * mark/reset functionality.
+   * 
    * @return <code>true</code> to indicate that mark/reset functionality is
-   * supported
-   *
+   *         supported
+   * 
    */
-  public boolean markSupported()
-  {
+  public boolean markSupported() {
     return true;
   }
 
   /**
-   * This method reads an unsigned byte from the input stream and returns it
-   * as an int in the range of 0-255.  This method also will return -1 if
-   * the end of the stream has been reached.
+   * This method reads an unsigned byte from the input stream and returns it as
+   * an int in the range of 0-255. This method also will return -1 if the end of
+   * the stream has been reached.
    * <p>
    * This method will block until the byte can be read.
-   *
+   * 
    * @return The byte read or -1 if end of stream
-   *
-   * @exception IOException If an error occurs
+   * 
+   * @exception IOException
+   *              If an error occurs
    */
-  public synchronized int read() throws IOException
-  {
+  public synchronized int read() throws IOException {
     if (pos >= count && !refill())
-      return -1;       // EOF
+      return -1; // EOF
 
     return buf[pos++] & 0xFF;
   }
 
   /**
    * This method reads bytes from a stream and stores them into a caller
-   * supplied buffer.  It starts storing the data at index <code>off</code>
-   * into the buffer and attempts to read <code>len</code> bytes.  This method
-   * can return before reading the number of bytes requested, but it will try
-   * to read the requested number of bytes by repeatedly calling the underlying
+   * supplied buffer. It starts storing the data at index <code>off</code> into
+   * the buffer and attempts to read <code>len</code> bytes. This method can
+   * return before reading the number of bytes requested, but it will try to
+   * read the requested number of bytes by repeatedly calling the underlying
    * stream as long as available() for this stream continues to return a
-   * non-zero value (or until the requested number of bytes have been read).
-   * The actual number of bytes read is returned as an int.  A -1 is returned
-   * to indicate the end of the stream.
+   * non-zero value (or until the requested number of bytes have been read). The
+   * actual number of bytes read is returned as an int. A -1 is returned to
+   * indicate the end of the stream.
    * <p>
    * This method will block until some data can be read.
-   *
-   * @param b The array into which the bytes read should be stored
-   * @param off The offset into the array to start storing bytes
-   * @param len The requested number of bytes to read
-   *
+   * 
+   * @param b
+   *          The array into which the bytes read should be stored
+   * @param off
+   *          The offset into the array to start storing bytes
+   * @param len
+   *          The requested number of bytes to read
+   * 
    * @return The actual number of bytes read, or -1 if end of stream.
-   *
-   * @exception IOException If an error occurs.
-   * @exception IndexOutOfBoundsException when <code>off</code> or
-   *            <code>len</code> are negative, or when <code>off + len</code>
-   *            is larger then the size of <code>b</code>,
+   * 
+   * @exception IOException
+   *              If an error occurs.
+   * @exception IndexOutOfBoundsException
+   *              when <code>off</code> or <code>len</code> are negative, or
+   *              when <code>off + len</code> is larger then the size of
+   *              <code>b</code>,
    */
-  public synchronized int read(byte[] b, int off, int len) throws IOException
-  {
+  public synchronized int read(byte[] b, int off, int len) throws IOException {
     if (off < 0 || len < 0 || b.length - off < len)
       throw new IndexOutOfBoundsException();
 
@@ -265,7 +268,7 @@ public class BufferedInputStream extends FilterInputStream
       return 0;
 
     if (pos >= count && !refill())
-      return -1;               // No bytes were read before EOF.
+      return -1; // No bytes were read before EOF.
 
     int totalBytesRead = Math.min(count - pos, len);
     System.arraycopy(buf, pos, b, off, totalBytesRead);
@@ -273,34 +276,33 @@ public class BufferedInputStream extends FilterInputStream
     off += totalBytesRead;
     len -= totalBytesRead;
 
-    while (len > 0 && super.available() > 0 && refill())
-      {
-       int remain = Math.min(count - pos, len);
-       System.arraycopy(buf, pos, b, off, remain);
-       pos += remain;
-       off += remain;
-       len -= remain;
-       totalBytesRead += remain;
-      }
+    while (len > 0 && super.available() > 0 && refill()) {
+      int remain = Math.min(count - pos, len);
+      System.arraycopy(buf, pos, b, off, remain);
+      pos += remain;
+      off += remain;
+      len -= remain;
+      totalBytesRead += remain;
+    }
 
     return totalBytesRead;
   }
 
   /**
    * This method resets a stream to the point where the <code>mark()</code>
-   * method was called.  Any bytes that were read after the mark point was
-   * set will be re-read during subsequent reads.
+   * method was called. Any bytes that were read after the mark point was set
+   * will be re-read during subsequent reads.
    * <p>
-   * This method will throw an IOException if the number of bytes read from
-   * the stream since the call to <code>mark()</code> exceeds the mark limit
-   * passed when establishing the mark.
-   *
-   * @exception IOException If <code>mark()</code> was never called or more
-   *            then <code>marklimit</code> bytes were read since the last
-   *            call to <code>mark()</code>
+   * This method will throw an IOException if the number of bytes read from the
+   * stream since the call to <code>mark()</code> exceeds the mark limit passed
+   * when establishing the mark.
+   * 
+   * @exception IOException
+   *              If <code>mark()</code> was never called or more then
+   *              <code>marklimit</code> bytes were read since the last call to
+   *              <code>mark()</code>
    */
-  public synchronized void reset() throws IOException
-  {
+  public synchronized void reset() throws IOException {
     if (markpos == -1)
       throw new IOException(buf == null ? "Stream closed." : "Invalid mark.");
 
@@ -308,69 +310,64 @@ public class BufferedInputStream extends FilterInputStream
   }
 
   /**
-   * This method skips the specified number of bytes in the stream.  It
-   * returns the actual number of bytes skipped, which may be less than the
-   * requested amount.
-   *
-   * @param n The requested number of bytes to skip
-   *
+   * This method skips the specified number of bytes in the stream. It returns
+   * the actual number of bytes skipped, which may be less than the requested
+   * amount.
+   * 
+   * @param n
+   *          The requested number of bytes to skip
+   * 
    * @return The actual number of bytes skipped.
-   *
-   * @exception IOException If an error occurs
+   * 
+   * @exception IOException
+   *              If an error occurs
    */
-  public synchronized long skip(long n) throws IOException
-  {
+  public synchronized long skip(long n) throws IOException {
     if (buf == null)
       throw new IOException("Stream closed.");
 
     final long origN = n;
 
-    while (n > 0L)
-      {
-       if (pos >= count && !refill())
-          break;
+    while (n > 0L) {
+      if (pos >= count && !refill())
+        break;
 
-       int numread = (int) Math.min((long) (count - pos), n);
-       pos += numread;
-       n -= numread;
-      }
+      int numread = (int) Math.min((long) (count - pos), n);
+      pos += numread;
+      n -= numread;
+    }
 
     return origN - n;
   }
 
   /**
    * Called to refill the buffer (when count is equal to pos).
-   *
-   * @return <code>true</code> when at least one additional byte was read
-   *         into <code>buf</code>, <code>false</code> otherwise (at EOF).
+   * 
+   * @return <code>true</code> when at least one additional byte was read into
+   *         <code>buf</code>, <code>false</code> otherwise (at EOF).
    */
-  private boolean refill() throws IOException
-  {
+  private boolean refill() throws IOException {
     if (buf == null)
       throw new IOException("Stream closed.");
 
-    if (markpos == -1 || count - markpos >= marklimit)
-      {
-       markpos = -1;
-       pos = count = 0;
-      }
-    else
-      {
-       byte[] newbuf = buf;
-       if (markpos < bufferSize)
-         {
-           newbuf = new byte[count - markpos + bufferSize];
-         }
-       System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
-       buf = newbuf;
-       count -= markpos;
-       pos -= markpos;
-       markpos = 0;
+    if (markpos == -1 || count - markpos >= marklimit) {
+      markpos = -1;
+      pos = count = 0;
+    } else {
+      byte[] newbuf = buf;
+      if (markpos < bufferSize) {
+        newbuf = new byte[count - markpos + bufferSize];
       }
+      System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
+      buf = newbuf;
+      count -= markpos;
+      pos -= markpos;
+      markpos = 0;
+    }
 
     int numread = super.read(buf, count, bufferSize);
 
-    if (numread <= 0)  // EOF
+    if (numread <= 0) // EOF
       return false;
 
     count += numread;
diff --git a/Robust/src/ClassLibrary/SSJava/Enumeration.java b/Robust/src/ClassLibrary/SSJava/Enumeration.java
new file mode 100644 (file)
index 0000000..e8da9fe
--- /dev/null
@@ -0,0 +1,13 @@
+public class Enumeration {
+
+  public Enumeration() {
+  }
+
+  public boolean hasMoreElements() {
+    return false;
+  }
+
+  public Object nextElement() {
+    return null;
+  }
+}
index c5b608dc67ee770dfdc75ce976c133508ad3b922..be3c76f4c479d4d1cbaf20a64746be8d7587738c 100644 (file)
@@ -2,30 +2,35 @@ public class FileInputStream extends InputStream {
   private int fd;
 
   public FileInputStream(String pathname) {
-    fd=nativeOpen(pathname.getBytes());
+    fd = nativeOpen(pathname.getBytes());
   }
 
   public FileInputStream(File path) {
-    fd=nativeOpen(path.getPath().getBytes());
+    fd = nativeOpen(path.getPath().getBytes());
   }
+
   public int getfd() {
     return fd;
   }
 
   private static native int nativeOpen(byte[] filename);
+
   private static native int nativeRead(int fd, byte[] array, int numBytes);
+
   private static native int nativePeek(int fd);
+
   private static native void nativeClose(int fd);
+
   private static native int nativeAvailable(int fd);
 
   public int read() {
-    byte b[]=new byte[1];
-    int retval=read(b);
-    if (retval==-1 || retval==0)
+    byte b[] = new byte[1];
+    int retval = read(b);
+    if (retval == -1 || retval == 0)
       return -1;
 
     // if carriage return comes back, dump it
-    if( b[0] == 13 ) {
+    if (b[0] == 13) {
       return read();
     }
 
@@ -36,15 +41,15 @@ public class FileInputStream extends InputStream {
   public int peek() {
     return nativePeek(fd);
   }
-  
-  public int read(byte[] b, int offset,  int len) {
-    if (offset < 0 || len < 0 || offset + len > b.length){
+
+  public int read(byte[] b, int offset, int len) {
+    if (offset < 0 || len < 0 || offset + len > b.length) {
       return -1;
-    }      
-    byte readbuf[]=new byte[len];
-    int rtr=nativeRead(fd, readbuf, len);
-    for(int i=offset;i<len+offset;i++){
-      b[i]=readbuf[i-offset];
+    }
+    byte readbuf[] = new byte[len];
+    int rtr = nativeRead(fd, readbuf, len);
+    for (int i = offset; i < len + offset; i++) {
+      b[i] = readbuf[i - offset];
     }
     return rtr;
   }
@@ -60,13 +65,13 @@ public class FileInputStream extends InputStream {
     // if we're already at the end of the file
     // or there is an error, don't even return
     // the empty string
-    if( c <= 0 ) {
+    if (c <= 0) {
       return null;
     }
 
     // ASCII 13 is carriage return, check for that also
-    while( c != '\n' && c != 13 && c > 0 ) {
-      line += (char)c;
+    while (c != '\n' && c != 13 && c > 0) {
+      line += (char) c;
       c = read();
     }
 
@@ -74,7 +79,7 @@ public class FileInputStream extends InputStream {
     // returns or line feeds so the whole line is read
     // and returned, and none of the line-ending chars
     c = peek();
-    while( c == '\n' || c == 13 ) {
+    while (c == '\n' || c == 13) {
       c = read();
       c = peek();
     }
@@ -85,8 +90,8 @@ public class FileInputStream extends InputStream {
   public void close() {
     nativeClose(fd);
   }
-  
-  public int available(){
+
+  public int available() {
     return nativeAvailable(fd);
   }
 }
index 0508e4bd197d1e75166753be854d523e851ec1ba..38550de6e85885e3a3bed595c95a0771c309f76b 100644 (file)
@@ -86,7 +86,6 @@ public class FilterInputStream extends InputStream
     protected FilterInputStream(@LOC("IN") InputStream in)
   {
     this.in = in;
-    in = null;
   }
 
   /**
index c9910732f8e0fdb8c7bbd43340ed5a19fbfc0deb..904ab203d321a26cc7cc95738faacef20eb46760 100644 (file)
@@ -38,64 +38,67 @@ exception statement from your version. */
 //package java.io;
 
 /**
-  * This subclass of <code>FilterInputStream</code> provides the ability to 
-  * unread data from a stream.  It maintains an internal buffer of unread
-  * data that is supplied to the next read operation.  This is conceptually
-  * similar to mark/reset functionality, except that in this case the 
 * position to reset the stream to does not need to be known in advance.
 * <p>
-  * The default pushback buffer size one byte, but this can be overridden
 * by the creator of the stream.
 * <p>
-  *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy (warrenl@cygnus.com)
 */
+ * This subclass of <code>FilterInputStream</code> provides the ability to
+ * unread data from a stream. It maintains an internal buffer of unread data
+ * that is supplied to the next read operation. This is conceptually similar to
+ * mark/reset functionality, except that in this case the position to reset the
* stream to does not need to be known in advance.
+ * <p>
+ * The default pushback buffer size one byte, but this can be overridden by the
* creator of the stream.
+ * <p>
+ * 
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
 @LATTICE("IN<T,IN<POS,POS<SH,SH<F,SH*,POS*")
 @METHODDEFAULT("OUT<SH,SH<IN,SH*,THISLOC=OUT,GLOBALLOC=OUT")
-public class PushbackInputStream extends FilterInputStream
-{
+public class PushbackInputStream extends FilterInputStream {
   /**
    * This is the default buffer size
    */
-  @LOC("F") private static final int DEFAULT_BUFFER_SIZE = 1;
+  @LOC("F")
+  private static final int DEFAULT_BUFFER_SIZE = 1;
 
   /**
    * This is the buffer that is used to store the pushed back data
    */
-  @LOC("SH") protected byte[] buf;
+  @LOC("SH")
+  protected byte[] buf;
 
   /**
-   * This is the position in the buffer from which the next byte will be
-   * read.  Bytes are stored in reverse order in the buffer, starting from
-   * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>.  Thus when 
-   * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when 
+   * This is the position in the buffer from which the next byte will be read.
+   * Bytes are stored in reverse order in the buffer, starting from
+   * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
+   * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
    * it is empty
    */
-  @LOC("POS") protected int pos;
+  @LOC("POS")
+  protected int pos;
 
   /**
-   * This method initializes a <code>PushbackInputStream</code> to
-   * read from the specified subordinate <code>InputStream</code>
-   * with a default pushback buffer size of 1.
-   *
-   * @param in The subordinate stream to read from
+   * This method initializes a <code>PushbackInputStream</code> to read from the
+   * specified subordinate <code>InputStream</code> with a default pushback
+   * buffer size of 1.
+   * 
+   * @param in
+   *          The subordinate stream to read from
    */
-  public PushbackInputStream(InputStream in)
-  {
+  public PushbackInputStream(InputStream in) {
     this(in, DEFAULT_BUFFER_SIZE);
   }
 
   /**
-   * This method initializes a <code>PushbackInputStream</code> to
-   * read from the specified subordinate <code>InputStream</code> with
-   * the specified buffer size
-   *
-   * @param in The subordinate <code>InputStream</code> to read from
-   * @param size The pushback buffer size to use
+   * This method initializes a <code>PushbackInputStream</code> to read from the
+   * specified subordinate <code>InputStream</code> with the specified buffer
+   * size
+   * 
+   * @param in
+   *          The subordinate <code>InputStream</code> to read from
+   * @param size
+   *          The pushback buffer size to use
    */
-    public PushbackInputStream(@LOC("IN")InputStream in, @LOC("IN")int size)
-  {
+  public PushbackInputStream(@LOC("IN") InputStream in, @LOC("IN") int size) {
     super(in);
     if (size < 0)
       throw new IllegalArgumentException();
@@ -104,79 +107,74 @@ public class PushbackInputStream extends FilterInputStream
   }
 
   /**
-   * This method returns the number of bytes that can be read from this
-   * stream before a read can block.  A return of 0 indicates that blocking
-   * might (or might not) occur on the very next read attempt.
+   * This method returns the number of bytes that can be read from this stream
+   * before a read can block. A return of 0 indicates that blocking might (or
+   * might not) occur on the very next read attempt.
    * <p>
-   * This method will return the number of bytes available from the
-   * pushback buffer plus the number of bytes available from the 
-   * underlying stream.
-   *
+   * This method will return the number of bytes available from the pushback
+   * buffer plus the number of bytes available from the underlying stream.
+   * 
    * @return The number of bytes that can be read before blocking could occur
-   *
-   * @exception IOException If an error occurs
+   * 
+   * @exception IOException
+   *              If an error occurs
    */
-  public int available() throws IOException
-  {
-    try 
-      {
-       return (buf.length - pos) + super.available();
-      } 
-    catch (NullPointerException npe) 
-      {
-       throw new IOException ("Stream closed");
-      }
+  public int available() throws IOException {
+    try {
+      return (buf.length - pos) + super.available();
+    } catch (NullPointerException npe) {
+      throw new IOException("Stream closed");
+    }
   }
 
   /**
    * This method closes the stream and releases any associated resources.
    * 
-   * @exception IOException If an error occurs.
+   * @exception IOException
+   *              If an error occurs.
    */
-  public synchronized void close() throws IOException
-  {
+  public synchronized void close() throws IOException {
     buf = null;
     super.close();
   }
 
   /**
-   * This method returns <code>false</code> to indicate that it does
-   * not support mark/reset functionality.
-   *
-   * @return This method returns <code>false</code> to indicate that
-   * this class does not support mark/reset functionality
+   * This method returns <code>false</code> to indicate that it does not support
+   * mark/reset functionality.
+   * 
+   * @return This method returns <code>false</code> to indicate that this class
+   *         does not support mark/reset functionality
    */
-  public boolean markSupported()
-  {
+  public boolean markSupported() {
     return false;
   }
 
   /**
-   * This method always throws an IOException in this class because
-   * mark/reset functionality is not supported.
-   *
-   * @exception IOException Always thrown for this class
+   * This method always throws an IOException in this class because mark/reset
+   * functionality is not supported.
+   * 
+   * @exception IOException
+   *              Always thrown for this class
    */
-  public void reset() throws IOException
-  {
+  public void reset() throws IOException {
     throw new IOException("Mark not supported in this class");
   }
 
   /**
-   * This method reads an unsigned byte from the input stream and returns it
-   * as an int in the range of 0-255.  This method also will return -1 if
-   * the end of the stream has been reached.  The byte returned will be read
-   * from the pushback buffer, unless the buffer is empty, in which case
-   * the byte will be read from the underlying stream.
+   * This method reads an unsigned byte from the input stream and returns it as
+   * an int in the range of 0-255. This method also will return -1 if the end of
+   * the stream has been reached. The byte returned will be read from the
+   * pushback buffer, unless the buffer is empty, in which case the byte will be
+   * read from the underlying stream.
    * <p>
    * This method will block until the byte can be read.
-   *
+   * 
    * @return The byte read or -1 if end of stream
-   *
-   * @exception IOException If an error occurs
+   * 
+   * @exception IOException
+   *              If an error occurs
    */
-  public synchronized int read() throws IOException
-  {
+  public synchronized int read() throws IOException {
     if (pos < buf.length)
       return ((int) buf[pos++]) & 0xFF;
 
@@ -184,71 +182,74 @@ public class PushbackInputStream extends FilterInputStream
   }
 
   /**
-   * This method read bytes from a stream and stores them into a
-   * caller supplied buffer.  It starts storing the data at index
-   * <code>offset</code> into the buffer and attempts to read
-   * <code>len</code> bytes.  This method can return before reading the
-   * number of bytes requested.  The actual number of bytes read is
-   * returned as an int.  A -1 is returned to indicate the end of the
+   * This method read bytes from a stream and stores them into a caller supplied
+   * buffer. It starts storing the data at index <code>offset</code> into the
+   * buffer and attempts to read <code>len</code> bytes. This method can return
+   * before reading the number of bytes requested. The actual number of bytes
+   * read is returned as an int. A -1 is returned to indicate the end of the
    * stream.
-   *  <p>
+   * <p>
    * This method will block until some data can be read.
    * <p>
-   * This method first reads bytes from the pushback buffer in order to 
-   * satisfy the read request.  If the pushback buffer cannot provide all
-   * of the bytes requested, the remaining bytes are read from the 
-   * underlying stream.
-   *
-   * @param b The array into which the bytes read should be stored
-   * @param off The offset into the array to start storing bytes
-   * @param len The requested number of bytes to read
-   *
+   * This method first reads bytes from the pushback buffer in order to satisfy
+   * the read request. If the pushback buffer cannot provide all of the bytes
+   * requested, the remaining bytes are read from the underlying stream.
+   * 
+   * @param b
+   *          The array into which the bytes read should be stored
+   * @param off
+   *          The offset into the array to start storing bytes
+   * @param len
+   *          The requested number of bytes to read
+   * 
    * @return The actual number of bytes read, or -1 if end of stream.
-   *
-   * @exception IOException If an error occurs.
+   * 
+   * @exception IOException
+   *              If an error occurs.
    */
   @LATTICE("OUT<THIS,THISLOC=THIS")
   @RETURNLOC("THIS")
-  public synchronized int read(@LOC("OUT") byte[] b,
-                               @LOC("THIS,PushbackInputStream.POS") int off,
-                               @LOC("THIS,PushbackInputStream.POS") int len) throws IOException
-  {
-    @LOC("THIS,PushbackInputStream.POS") int numBytes = Math.min(buf.length - pos,len);
+  public synchronized int read(@LOC("OUT") byte[] b, @LOC("THIS,PushbackInputStream.POS") int off,
+      @LOC("THIS,PushbackInputStream.POS") int len) throws IOException {
+    @LOC("THIS,PushbackInputStream.POS") int numBytes = Math.min(buf.length - pos, len);
+System.out.println("numBytes="+numBytes+" buf.length="+buf.length+" pos="+pos);
+    if (numBytes > 0) {
+      
+      System.out.println("buf[pos]="+buf[pos]);
+      
+      System.arraycopy(buf, pos, b, off, numBytes);
+      pos += numBytes;
+      len -= numBytes;
+      off += numBytes;
+    }
 
-    if (numBytes > 0)
-      {
-       System.arraycopy (buf, pos, b, off, numBytes);
-       pos += numBytes;
-       len -= numBytes;
-       off += numBytes;
-      }
-
-    if (len > 0) 
-      {
-        len = super.read(b, off, len);
-        if (len == -1) //EOF
-         return numBytes > 0 ? numBytes : -1;
-       numBytes += len;
-      }
+    if (len > 0) {
+      System.out.println("len>0");
+      len = super.read(b, off, len);
+      if (len == -1) // EOF
+        return numBytes > 0 ? numBytes : -1;
+      numBytes += len;
+    }
     return numBytes;
   }
 
   /**
-   * This method pushes a single byte of data into the pushback buffer.
-   * The byte pushed back is the one that will be returned as the first byte
-   * of the next read.
+   * This method pushes a single byte of data into the pushback buffer. The byte
+   * pushed back is the one that will be returned as the first byte of the next
+   * read.
    * <p>
    * If the pushback buffer is full, this method throws an exception.
    * <p>
-   * The argument to this method is an <code>int</code>.  Only the low
-   * eight bits of this value are pushed back.
-   *
-   * @param b The byte to be pushed back, passed as an int
-   *
-   * @exception IOException If the pushback buffer is full.
+   * The argument to this method is an <code>int</code>. Only the low eight bits
+   * of this value are pushed back.
+   * 
+   * @param b
+   *          The byte to be pushed back, passed as an int
+   * 
+   * @exception IOException
+   *              If the pushback buffer is full.
    */
-  public synchronized void unread(int b) throws IOException
-  {
+  public synchronized void unread(int b) throws IOException {
     if (pos <= 0)
       throw new IOException("Insufficient space in pushback buffer");
 
@@ -256,43 +257,46 @@ public class PushbackInputStream extends FilterInputStream
   }
 
   /**
-   * This method pushes all of the bytes in the passed byte array into 
-   * the pushback bfer.  These bytes are pushed in reverse order so that
-   * the next byte read from the stream after this operation will be
-   * <code>b[0]</code> followed by <code>b[1]</code>, etc.
+   * This method pushes all of the bytes in the passed byte array into the
+   * pushback bfer. These bytes are pushed in reverse order so that the next
+   * byte read from the stream after this operation will be <code>b[0]</code>
+   * followed by <code>b[1]</code>, etc.
    * <p>
-   * If the pushback buffer cannot hold all of the requested bytes, an
-   * exception is thrown.
-   *
-   * @param b The byte array to be pushed back
-   *
-   * @exception IOException If the pushback buffer is full
+   * If the pushback buffer cannot hold all of the requested bytes, an exception
+   * is thrown.
+   * 
+   * @param b
+   *          The byte array to be pushed back
+   * 
+   * @exception IOException
+   *              If the pushback buffer is full
    */
-  public synchronized void unread(byte[] b) throws IOException
-  {
+  public synchronized void unread(byte[] b) throws IOException {
     unread(b, 0, b.length);
   }
 
   /**
-   * This method pushed back bytes from the passed in array into the
-   * pushback buffer.  The bytes from <code>b[offset]</code> to
-   * <code>b[offset + len]</code> are pushed in reverse order so that
-   * the next byte read from the stream after this operation will be
-   * <code>b[offset]</code> followed by <code>b[offset + 1]</code>,
-   * etc.
+   * This method pushed back bytes from the passed in array into the pushback
+   * buffer. The bytes from <code>b[offset]</code> to
+   * <code>b[offset + len]</code> are pushed in reverse order so that the next
+   * byte read from the stream after this operation will be
+   * <code>b[offset]</code> followed by <code>b[offset + 1]</code>, etc.
    * <p>
-   * If the pushback buffer cannot hold all of the requested bytes, an
-   * exception is thrown.
-   *
-   * @param b The byte array to be pushed back
-   * @param off The index into the array where the bytes to be push start
-   * @param len The number of bytes to be pushed.
-   *
-   * @exception IOException If the pushback buffer is full
+   * If the pushback buffer cannot hold all of the requested bytes, an exception
+   * is thrown.
+   * 
+   * @param b
+   *          The byte array to be pushed back
+   * @param off
+   *          The index into the array where the bytes to be push start
+   * @param len
+   *          The number of bytes to be pushed.
+   * 
+   * @exception IOException
+   *              If the pushback buffer is full
    */
   public synchronized void unread(@LOC("IN") byte[] b, @LOC("IN") int off, @LOC("IN") int len)
-    throws IOException
-  {
+      throws IOException {
     if (pos < len)
       throw new IOException("Insufficient space in pushback buffer");
 
@@ -307,34 +311,34 @@ public class PushbackInputStream extends FilterInputStream
   }
 
   /**
-   * This method skips the specified number of bytes in the stream.  It
-   * returns the actual number of bytes skipped, which may be less than the
-   * requested amount.
+   * This method skips the specified number of bytes in the stream. It returns
+   * the actual number of bytes skipped, which may be less than the requested
+   * amount.
    * <p>
    * This method first discards bytes from the buffer, then calls the
-   * <code>skip</code> method on the underlying <code>InputStream</code> to 
-   * skip additional bytes if necessary.
-   *
-   * @param n The requested number of bytes to skip
-   *
+   * <code>skip</code> method on the underlying <code>InputStream</code> to skip
+   * additional bytes if necessary.
+   * 
+   * @param n
+   *          The requested number of bytes to skip
+   * 
    * @return The actual number of bytes skipped.
-   *
-   * @exception IOException If an error occurs
-   *
+   * 
+   * @exception IOException
+   *              If an error occurs
+   * 
    * @since 1.2
    */
-  public synchronized long skip(long n) throws IOException
-  {
+  public synchronized long skip(long n) throws IOException {
     final long origN = n;
 
-    if (n > 0L)
-      {
-       int numread = (int) Math.min((long) (buf.length - pos), n);
-       pos += numread;
-       n -= numread;
-       if (n > 0)
-         n -= super.skip(n);
-      }
+    if (n > 0L) {
+      int numread = (int) Math.min((long) (buf.length - pos), n);
+      pos += numread;
+      n -= numread;
+      if (n > 0)
+        n -= super.skip(n);
+    }
 
     return origN - n;
   }
index 4fcfb6cbc47f37cf71176cea98170b8d3e09ddd7..ddacb966d41c17cdedf9425d5bf1087f645a4044 100644 (file)
@@ -1,20 +1,29 @@
-import Object;
-import String;
-import StringBuffer;
-import System;
+import Vector;
 
-@LATTICE("V<C, V<O")
-@METHODDEFAULT("O<V,V<C,C<IN,THISLOC=O,C*")
 public class String {
-
-  @LOC("V") char value[];
-  @LOC("C") int count;
-  @LOC("O") int offset;
-  @LOC("V") private int cachedHashcode;
+  char value[];
+  int count;
+  int offset;
+  private int cachedHashcode;
 
   private String() {
   }
-  
+
+  public String(char c) {
+    char[] str = new char[1];
+    str[0] = c;
+    String(str);
+  }
+
+  public String(char str[]) {
+    char charstr[]=new char[str.length];
+    for(int i=0; i<str.length; i++)
+      charstr[i]=str[i];
+    this.value=charstr;
+    this.count=str.length;
+    this.offset=0;
+  }
+
   public String(byte str[]) {
     char charstr[]=new char[str.length];
     for(int i=0; i<str.length; i++)
@@ -23,18 +32,17 @@ public class String {
     this.count=str.length;
     this.offset=0;
   }
-  
-  public String(char str[], int offset, int length) {
+
+  public String(byte str[], int offset, int length) {
     if (length>(str.length-offset))
       length=str.length-offset;
     char charstr[]=new char[length];
     for(int i=0; i<length; i++)
-      charstr[i]=str[i+offset];
+      charstr[i]=(char)str[i+offset];
     this.value=charstr;
     this.count=length;
     this.offset=0;
   }
-  
 
   public String(byte str[], String encoding) {
     int length = this.count;
@@ -47,14 +55,24 @@ public class String {
     this.count=length;
     this.offset=0;
   }
-  
-  public String( @DELEGATE  @LOC("IN") String str) {
+
+  public String(char str[], int offset, int length) {
+    if (length>(str.length-offset))
+      length=str.length-offset;
+    char charstr[]=new char[length];
+    for(int i=0; i<length; i++)
+      charstr[i]=str[i+offset];
+    this.value=charstr;
+    this.count=length;
+    this.offset=0;
+  }
+
+  public String(String str) {
     this.value=str.value;
-    str.value=null;
     this.count=str.count;
     this.offset=str.offset;
   }
-  
+
   public String(StringBuffer strbuf) {
     value=new char[strbuf.length()];
     count=strbuf.length();
@@ -63,80 +81,122 @@ public class String {
       value[i]=strbuf.value[i];
   }
 
-  public String(@LOC("IN") char c) {
-    @LOC("V") char[] str = new char[1];
-    str[0] = c;
-    String(str);
+  public boolean endsWith(String suffix) {
+    return regionMatches(count - suffix.count, suffix, 0, suffix.count);
   }
 
-  public String(@LOC("IN") char str[]) {
-    @LOC("V") char charstr[]=new char[str.length];
-    for(@LOC("C") int i=0; i<str.length; i++)
-      charstr[i]=str[i];
-    this.value=charstr;
-    charstr=null;
-    this.count=str.length;
-    this.offset=0;
+
+  public String substring(int beginIndex) {
+    return substring(beginIndex, this.count);
   }
-  
-  @LATTICE("O<V,V<C,C<IN,THISLOC=IN,C*")
-  @RETURNLOC("O")
-  public String concat(@LOC("IN") String str) {
-    @LOC("O") String newstr=new String(); // create new one, it has OUT location
-    @LOC("C") int newCount=this.count+str.count;
 
-    @LOC("V") char charstr[]=new char[newCount];
+  public String subString(int beginIndex, int endIndex) {
+    return substring(beginIndex, endIndex);
+  }
 
-    // here, for loop introduces indirect flow from [C] to [V]
-    for(@LOC("C") int i=0; i<count; i++) {
-      // value flows from GLB(THISLOC,C,THISLOC.V)=(THISLOC,TOP) to [V]
-      charstr[i]=value[i+offset]; 
-    }
-    for(@LOC("C") int i=0; i<str.count; i++) {
-      charstr[i+count]=str.value[i+str.offset];
+  public String substring(int beginIndex, int endIndex) {
+    String str=new String();
+    if (beginIndex>this.count||endIndex>this.count||beginIndex>endIndex) {
+      // FIXME
+      System.printString("Index error: "+beginIndex+" "+endIndex+" "+count+"\n"+this);
     }
+    str.value=this.value;
+    str.count=endIndex-beginIndex;
+    str.offset=this.offset+beginIndex;
+    return str;
+  }
+
+  public String subString(int beginIndex) {
+    return this.subString(beginIndex, this.count);
+  }
 
+  public int lastindexOf(int ch) {
+    return this.lastindexOf(ch, count - 1);
+  }
+
+  public int lastIndexOf(char ch) {
+    return this.lastindexOf((int)ch, count - 1);
+  }
+
+  public static String concat2(String s1, String s2) {
+    if (s1==null)
+      return "null".concat(s2);
+    else
+      return s1.concat(s2);
+  }
+
+  public String concat(String str) {
+    String newstr=new String();
+    newstr.count=this.count+str.count;
+    char charstr[]=new char[newstr.count];
     newstr.value=charstr;
-    charstr=null;
-    // LOC(newstr.value)=[O,V] 
-    // LOC(charstr)=[V]
-    // [O,V] < [V]
-    
+    newstr.offset=0;
+    for(int i=0; i<count; i++) {
+      charstr[i]=value[i+offset];
+    }
+    for(int i=0; i<str.count; i++) {
+      charstr[i+count]=str.value[i+str.offset];
+    }
     return newstr;
   }
-  
-  @RETURNLOC("O")
-  public boolean equals(@LOC("IN") Object o) {
-    if (o.getType()!=getType()) // values are coming from [IN] and [THISLOC]
-      return false;
-    @LOC("V") String s=(String)o;
-    o=null;
-    if (s.count!=count)
-      return false;
-    for(@LOC("C") int i=0; i<count; i++) {
-      if (s.value[i+s.offset]!=value[i+offset])
-        return false;
+
+  public int lastindexOf(int ch, int fromIndex) {
+    for(int i=fromIndex; i>0; i--)
+      if (this.charAt(i)==ch)
+        return i;
+    return -1;
+  }
+
+  public String replace(char oldch, char newch) {
+    char[] buffer=new char[count];
+    for(int i=0; i<count; i++) {
+      char x=charAt(i);
+      if (x==oldch)
+        x=newch;
+      buffer[i]=x;
     }
-    return true;
+    return new String(buffer);
   }
-  
-  public void getChars(char dst[], int dstBegin) {
-    getChars(0, count, dst, dstBegin);
+
+  public String toUpperCase() {
+    char[] buffer=new char[count];
+    for(int i=0; i<count; i++) {
+      char x=charAt(i);
+      if (x>='a'&&x<='z') {
+        x=(char) ((x-'a')+'A');
+      }
+      buffer[i]=x;
+    }
+    return new String(buffer);
   }
 
-  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
-    if((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
-      // FIXME
-      System.printString("Index error: "+srcBegin+" "+srcEnd+" "+count+"\n"+this);
-      System.exit(-1);
+  public String toLowerCase() {
+    char[] buffer=new char[count];
+    for(int i=0; i<count; i++) {
+      char x=charAt(i);
+      if (x>='A'&&x<='Z') {
+        x=(char) ((x-'A')+'a');
+      }
+      buffer[i]=x;
     }
-    int len = srcEnd - srcBegin;
-    int j = dstBegin;
-    for(int i=srcBegin; i<srcEnd; i++)
-      dst[j++]=value[i+offset];
-    return;
+    return new String(buffer);
+  }
+
+  public int indexOf(int ch) {
+    return this.indexOf(ch, 0);
   }
-  
+
+  public int indexOf(int ch, int fromIndex) {
+    for(int i=fromIndex; i<count; i++)
+      if (this.charAt(i)==ch)
+        return i;
+    return -1;
+  }
+
+  public int indexOf(String str) {
+    return this.indexOf(str, 0);
+  }
+
   public int indexOf(String str, int fromIndex) {
     if (fromIndex<0)
       fromIndex=0;
@@ -145,7 +205,35 @@ public class String {
         return i;
     return -1;
   }
-  
+
+  public int indexOfIgnoreCase(String str, int fromIndex) {
+    if (fromIndex < 0)
+      fromIndex = 0;
+  }
+
+  public int lastIndexOf(String str, int fromIndex) {
+    int k=count-str.count;
+    if (k>fromIndex)
+      k=fromIndex;
+    for(; k>=0; k--) {
+      if (regionMatches(k, str, 0, str.count))
+        return k;
+    }
+    return -1;
+  }
+
+  public int lastIndexOf(String str) {
+    return lastIndexOf(str, count-str.count);
+  }
+
+  public boolean startsWith(String str) {
+    return regionMatches(0, str, 0, str.count);
+  }
+
+  public boolean startsWith(String str, int toffset) {
+    return regionMatches(toffset, str, 0, str.count);
+  }
+
   public boolean regionMatches(int toffset, String other, int ooffset, int len) {
     if (toffset<0 || ooffset <0 || (toffset+len)>count || (ooffset+len)>other.count)
       return false;
@@ -155,22 +243,64 @@ public class String {
         return false;
     return true;
   }
-  
-  @RETURNLOC("O")
-  public static String valueOf(@LOC("IN") Object o) {
+
+  public char[] toCharArray() {
+    char str[]=new char[count];
+    for(int i=0; i<count; i++)
+      str[i]=value[i+offset];
+    return str;
+  }
+
+  public byte[] getBytes() {
+    byte str[]=new byte[count];
+    for(int i=0; i<count; i++)
+      str[i]=(byte)value[i+offset];
+    return str;
+  }
+
+  public void getChars(char dst[], int dstBegin) {
+    getChars(0, count, dst, dstBegin);
+  }
+
+  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
+    if((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
+      // FIXME
+      System.printString("Index error: "+srcBegin+" "+srcEnd+" "+count+"\n"+this);
+      System.exit(-1);
+    }
+    int len = srcEnd - srcBegin;
+    int j = dstBegin;
+    for(int i=srcBegin; i<srcEnd; i++)
+      dst[j++]=value[i+offset];
+    return;
+  }
+
+  public int length() {
+    return count;
+  }
+
+  public char charAt(int i) {
+    return value[i+offset];
+  }
+
+  public String toString() {
+    return this;
+  }
+
+  public static String valueOf(Object o) {
     if (o==null)
       return "null";
     else
       return o.toString();
   }
-  
+
   public static String valueOf(boolean b) {
     if (b)
       return new String("true");
     else
       return new String("false");
   }
-  
+
   public static String valueOf(char c) {
     char ar[]=new char[1];
     ar[0]=c;
@@ -217,9 +347,8 @@ public class String {
     s.value=chararray;
     return s;
   }
-  
-  public static native int convertdoubletochar(double val, char [] chararray);
 
+  public static native int convertdoubletochar(double val, char [] chararray);
 
   public static String valueOf(long x) {
     int length=0;
@@ -252,28 +381,138 @@ public class String {
     } while (length!=0);
     return new String(chararray);
   }
-  
-  @LATTICE("O<V,V<C,C<IN,THISLOC=IN,C*")
-  @RETURNLOC("O")
-  public byte[] getBytes() {
-    @LOC("V") byte str[]=new byte[count];
-    for(@LOC("C") int i=0; i<count; i++)
-      str[i]=(byte)value[i+offset];
-    return str;
+
+  public int compareTo(String s) {
+    int smallerlength=count<s.count?count:s.count;
+
+    for( int i = 0; i < smallerlength; i++ ) {
+      int valDiff = this.charAt(i) - s.charAt(i);
+      if( valDiff != 0 ) {
+        return valDiff;
+      }
+    }
+    return count-s.count;
   }
-  
-  
-  
-  @RETURNLOC("IN")
-  public int length() {
-    return count;
+
+  public int hashCode() {
+    if (cachedHashcode!=0)
+      return cachedHashcode;
+    int hashcode=0;
+    for(int i=0; i<count; i++)
+      hashcode=hashcode*31+value[i+offset];
+    cachedHashcode=hashcode;
+    return hashcode;
   }
-  
-  @RETURNLOC("O")
-  public char charAt(@LOC("IN") int index){
-    return value[index];
+
+  public boolean equals(Object o) {
+    if (o.getType()!=getType())
+      return false;
+    String s=(String)o;
+    if (s.count!=count)
+      return false;
+    for(int i=0; i<count; i++) {
+      if (s.value[i+s.offset]!=value[i+offset])
+        return false;
+    }
+    return true;
   }
 
-    //public static native int convertdoubletochar(double val, char [] chararray);
+  public boolean equalsIgnoreCase(String s) {
+    if (s.count!=count)
+      return false;
+    for(int i=0; i<count; i++) {
+      char l=s.value[i+s.offset];
+      char r=value[i+offset];
+      if (l>='a'&&l<='z')
+        l=(char)((l-'a')+'A');
+      if (r>='a'&&r<='z')
+        r=(char)((r-'a')+'A');
+      if (l!=r)
+        return false;
+    }
+    return true;
+  }
 
+  public Vector split() {
+    Vector splitted = new Vector();
+    int i;
+    int cnt =0;
+
+    // skip first spaces
+    for(i = 0; i< count; i++) {
+      if(value[i+offset] != '\n' && value[i+offset] != '\t' && value[i+offset] != ' ')
+        break;
+    }
+
+    int oldi=i;
+
+    while(i<count) {
+      if(value[i+offset] == '\n' || value[i+offset] == '\t' || value[i+offset] == ' ') {
+        String t=new String();
+        t.value=value;
+        t.offset=oldi;
+        t.count=i-oldi;
+        splitted.addElement(t);
+
+        // skip extra spaces
+        while( i < count && ( value[i+offset] == '\n' || value[i+offset] == '\t' || value[i+offset] == ' ')) {
+          i++;
+        }
+        oldi=i;
+      } else {
+        i++;
+      }
+    }
+
+    if(i!=oldi) {
+      String t=new String();
+      t.value=value;
+      t.offset=oldi;
+      t.count=i-oldi;
+      splitted.addElement(t);
+    }
+
+    return splitted;
+  }
+
+  public boolean contains(String str) {
+    int i,j;
+    char[] strChar = str.toCharArray();
+    int cnt;
+
+    for(i = 0; i < count; i++) {
+      if(value[i] == strChar[0]) {
+        cnt=0;
+        for(j=0; j < str.length() && i+j < count; j++) {
+          if(value[i+j] == strChar[j])
+            cnt++;
+        }
+        if(cnt == str.length())
+          return true;
+      }
+    }
+
+    return false;
+
+  }
+
+  public String trim() {
+    int len = count;
+    int st = 0;
+    int off = offset;      /* avoid getfield opcode */
+    char[] val = value;    /* avoid getfield opcode */
+
+    while ((st < len) && (val[off + st] <= ' ')) {
+      st++;
+    }
+    while ((st < len) && (val[off + len - 1] <= ' ')) {
+      len--;
+    }
+    return ((st > 0) || (len < count))?substring(st, len):this;
+  }
+
+  public boolean matches(String regex) {
+    System.println("String.matches() is not fully supported");
+    return this.equals(regex);
+  }
 }
index 4c773f08c887e8b675404a7d67cdd1cb57797990..3d18547e651158e90cd90c3153dce77edc7c9845 100644 (file)
@@ -16,10 +16,22 @@ public class System {
 
   public static native void printString(String s);
 
-    public static void println(@LOC("IN") String s) {
+  public static void println(@LOC("IN") String s) {
     System.printString(s + "\n");
   }
 
+  public static void println(int o) {
+    System.printString("" + o + "\n");
+  }
+
+  public static void println(double o) {
+    System.printString("" + o + "\n");
+  }
+
+  public static void println(long o) {
+    System.printString("" + o + "\n");
+  }
+
   public static void println() {
     System.printString("\n");
   }
@@ -28,6 +40,22 @@ public class System {
     System.printString(s);
   }
 
+  public static void print(Object o) {
+    System.printString("" + o);
+  }
+
+  public static void print(int o) {
+    System.printString("" + o);
+  }
+
+  public static void print(double o) {
+    System.printString("" + o);
+  }
+
+  public static void print(long o) {
+    System.printString("" + o);
+  }
+
   public static void error() {
     System
         .printString("Error (Use Breakpoint on ___System______error method for more information!)\n");
diff --git a/Robust/src/ClassLibrary/SSJava/Vector.java b/Robust/src/ClassLibrary/SSJava/Vector.java
new file mode 100644 (file)
index 0000000..adcd4ef
--- /dev/null
@@ -0,0 +1,149 @@
+public class Vector {
+  Object[] array;
+  int size;
+  int capacityIncrement;
+
+  public Vector() {
+    capacityIncrement=0;
+    size=0;
+    array=new Object[10];
+  }
+
+  public Vector(int size) {
+    capacityIncrement=0;
+    this.size=0;
+    array=new Object[size];
+  }
+
+  //used for internal cloning
+  private Vector(int size, int capacityIncrement, Object[] array) {
+    this.size = size;
+    this.capacityIncrement = capacityIncrement;
+    this.array = new Object[array.length];
+    System.arraycopy(array, 0, this.array, 0, size);
+  }
+
+  public Vector clone() {
+    return new Vector(size,capacityIncrement, array);
+  }
+
+  public boolean isEmpty() {
+    return size==0;
+  }
+
+  public void clear() {
+    size=0;
+    array=new Object[10];
+  }
+
+  public int indexOf(Object elem) {
+    return indexOf(elem, 0);
+  }
+
+  public int indexOf(Object elem, int index) {
+    for(int i=index; i<size; i++) {
+      if (elem.equals(array[i]))
+        return i;
+    }
+    return -1;
+  }
+
+  public boolean contains(Object e) {
+    return indexOf(e)!=-1;
+  }
+
+  public boolean  remove(Object o) {
+    int in=indexOf(o);
+    if (in!=-1) {
+      removeElementAt(in);
+      return true;
+    }
+
+    return false;
+  }
+
+  public Object elementAt(int index) {
+    if (index<0 | index >=size) {
+      System.printString("Illegal Vector.elementAt\n");
+      System.exit(-1);
+      return null;
+    }
+    return array[index];
+  }
+
+  public void setElementAt(Object obj, int index) {
+    if (index <size)
+      array[index]=obj;
+    else {
+      System.printString("Illegal Vector.setElementAt\n");
+      System.exit(-1);
+    }
+  }
+
+  private void ensureCapacity(int minCapacity) {
+    if (minCapacity>array.length) {
+      int newsize;
+      if (capacityIncrement<=0)
+        newsize=array.length*2;
+      else
+        newsize=array.length+capacityIncrement;
+      if (newsize<minCapacity)
+        newsize=minCapacity;
+      Object [] newarray=new Object[newsize];
+      for(int i=0; i<size; i++)
+        newarray[i]=array[i];
+      array=newarray;
+    }
+  }
+
+  public int size() {
+    return size;
+  }
+
+  public Enumeration elements() {
+    System.printString("Vector.elements not implemented\n");
+    System.exit(-1);
+  }
+
+  public void addElement(Object obj) {
+    if (size==array.length) {
+      ensureCapacity(size+1);
+    }
+    array[size++]=obj;
+  }
+
+  public void insertElementAt(Object obj, int index) {
+    if (index<0||index>size) {
+      System.printString("Illegal Vector.insertElementAt\n");
+      System.exit(-1);
+    }
+
+    if (size==array.length) {
+      ensureCapacity(size+1);
+    }
+    size++;
+    for(int i=size-1; i>index; --i) {
+      array[i] = array[i-1];
+    }
+    array[index] = obj;
+  }
+
+  public void removeElementAt(int index) {
+    if (index<0||index>=size) {
+      System.printString("Illegal Vector.removeElementAt\n");
+      System.exit(-1);
+    }
+    removeElement(array, index, size);
+    size--;
+    array[size]=null;
+  }
+
+  public static native void removeElement(Object[] array, int index, int size);
+
+  public void removeAllElements() {
+    int s = size;
+    for(int i = 0; i<s; ++i ) {
+      removeElementAt(0);
+    }
+  }
+}
index daf25e22b5604417ed423e68f0c7cbc09c42be9e..b7430c8b6b16103a4c971251ebccb4f7838573c5 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * 11/19/04  1.0 moved to LGPL.
  * 
- * 11/17/04     Uncomplete frames discarded. E.B, javalayer@javazoom.net 
+ * 11/17/04     Uncomplete frames discarded. E.B, javalayer@javazoom.net 
  *
- * 12/05/03     ID3v2 tag returned. E.B, javalayer@javazoom.net 
+ * 12/05/03     ID3v2 tag returned. E.B, javalayer@javazoom.net 
  *
- * 12/12/99     Based on Ibitstream. Exceptions thrown on errors,
- *                      Temporary removed seek functionality. mdm@techie.com
+ * 12/12/99     Based on Ibitstream. Exceptions thrown on errors,
+ *              Temporary removed seek functionality. mdm@techie.com
  *
  * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
  *
@@ -107,8 +107,8 @@ public final class Bitstream implements BitstreamErrors {
   private int header_pos = 0;
 
   /**
-        *
-        */
+      *
+      */
   @LOC("F")
   private boolean single_ch_mode;
   // private int current_frame_number;
@@ -266,19 +266,30 @@ public final class Bitstream implements BitstreamErrors {
    *         of the stream has been reached.
    */
   public Header readFrame() throws BitstreamException {
+    
+    System.out.println("ST");
+    
     Header result = null;
     try {
+      System.out.println("HERE?");
       result = readNextFrame();
+      System.out.println("HERE?2");
       // E.B, Parse VBR (if any) first frame.
       if (firstframe == true) {
         result.parseVBR(frame_bytes);
         firstframe = false;
       }
+      
+      int channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
+      result.setSideInfoBuf(getSideInfoBuffer(channels));
+      result.setBitReserve(getBitReserve(result.slots()));
+      
     } catch (BitstreamException ex) {
       if ((ex.getErrorCode() == INVALIDFRAME)) {
         // Try to skip this frame.
         // System.out.println("INVALIDFRAME");
-        try {
+        try {    System.out.println("ET");
+
           closeFrame();
           result = readNextFrame();
         } catch (BitstreamException e) {
@@ -292,6 +303,8 @@ public final class Bitstream implements BitstreamErrors {
         throw newBitstreamException(ex.getErrorCode(), ex);
       }
     }
+    System.out.println("EN");
+
     return result;
   }
 
@@ -302,6 +315,7 @@ public final class Bitstream implements BitstreamErrors {
    * @throws BitstreamException
    */
   private Header readNextFrame() throws BitstreamException {
+    System.out.println("framesize="+framesize);
     if (framesize == -1) {
       nextFrame();
     }
@@ -315,6 +329,7 @@ public final class Bitstream implements BitstreamErrors {
    */
   private void nextFrame() throws BitstreamException {
     // entire frame is read by the header class.
+    System.out.println("nextFrame()");
     header.read_header(this, crc);
   }
 
index 363e2dec6d27ef22441674c9f4b64fc8b6b3f5ae..87f1b7f325acd50dd72591ed6f8ab744f875fffb 100644 (file)
@@ -59,10 +59,10 @@ public class Decoder implements DecoderErrors {
    */\r
   @LOC("DE")\r
   private LayerIIIDecoder l3decoder;\r
-  @LOC("DE")\r
-  private LayerIIDecoder l2decoder;\r
-  @LOC("DE")\r
-  private LayerIDecoder l1decoder;\r
+  // @LOC("DE")\r
+  // private LayerIIDecoder l2decoder;\r
+  // @LOC("DE")\r
+  // private LayerIDecoder l1decoder;\r
 \r
   @LOC("O")\r
   private int outputFrequency;\r
@@ -146,7 +146,7 @@ public class Decoder implements DecoderErrors {
     @LOC("TH") int layer = header.layer();\r
 \r
     output.clear_buffer();\r
-\r
+System.out.println("HERE?="+layer);\r
     @LOC("DE,Decoder.DE") FrameDecoder decoder = retrieveDecoder(header, stream, layer); // return\r
                                                                                          // ceil=DELTA(TH)\r
     decoder.decodeFrame();\r
@@ -254,22 +254,24 @@ public class Decoder implements DecoderErrors {
       return l3decoder;\r
       // decoder = l3decoder;\r
       break;\r
-    case 2:\r
-      if (l2decoder == null) {\r
-        l2decoder = new LayerIIDecoder();\r
-        l2decoder.create(stream, header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS);\r
-      }\r
-      return l2decoder;\r
-      // decoder = l2decoder;\r
-      break;\r
-    case 1:\r
-      if (l1decoder == null) {\r
-        l1decoder = new LayerIDecoder();\r
-        l1decoder.create(stream, header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS);\r
-      }\r
-      return l1decoder;\r
-      // decoder = l1decoder;\r
-      break;\r
+    // case 2:\r
+    // if (l2decoder == null) {\r
+    // l2decoder = new LayerIIDecoder();\r
+    // l2decoder.create(stream, header, filter1, filter2, output,\r
+    // OutputChannels.BOTH_CHANNELS);\r
+    // }\r
+    // return l2decoder;\r
+    // // decoder = l2decoder;\r
+    // break;\r
+    // case 1:\r
+    // if (l1decoder == null) {\r
+    // l1decoder = new LayerIDecoder();\r
+    // l1decoder.create(stream, header, filter1, filter2, output,\r
+    // OutputChannels.BOTH_CHANNELS);\r
+    // }\r
+    // return l1decoder;\r
+    // // decoder = l1decoder;\r
+    // break;\r
     }\r
     //\r
     // if (decoder==null)\r
index 4ffcada41b1e9953b0cfd13631b449f5a1d21bb3..6da0e4ddbaca0e031faaf8f0c656fd310ef02d19 100644 (file)
-/*\r
- * 11/19/04 : 1.0 moved to LGPL.\r
- *            VBRI header support added, E.B javalayer@javazoom.net\r
- * \r
- * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net\r
- *\r
- * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net\r
- *\r
- * Declarations for MPEG header class\r
- * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.\r
- * Last modified : 04/19/97\r
- *\r
- *  @(#) header.h 1.7, last edit: 6/15/94 16:55:33\r
- *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)\r
- *  @(#) Berlin University of Technology\r
- *-----------------------------------------------------------------------\r
- *   This program is free software; you can redistribute it and/or modify\r
- *   it under the terms of the GNU Library General Public License as published\r
- *   by the Free Software Foundation; either version 2 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU Library General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU Library General Public\r
- *   License along with this program; if not, write to the Free Software\r
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- *----------------------------------------------------------------------\r
- */\r
-\r
-/**\r
- * Class for extracting information from a frame header.\r
- */\r
-@LATTICE("HI<HNS,HNS<H,C<H,NS<FS,FS<H,FS<HV,H<SYNC,HV<SYNC,HV<T,SYNC*,HV*,FS*,HI*")\r
-@METHODDEFAULT("OUT<V,V<THIS,THIS<SH,SH<IN,SH*,THISLOC=THIS,GLOBALLOC=IN")\r
-public final class Header {\r
-\r
-  public static final int[][] frequencies = { { 22050, 24000, 16000, 1 },\r
-      { 44100, 48000, 32000, 1 }, { 11025, 12000, 8000, 1 } }; // SZD: MPEG25\r
-\r
-  /**\r
-   * Constant for MPEG-2 LSF version\r
-   */\r
-  public static final int MPEG2_LSF = 0;\r
-  public static final int MPEG25_LSF = 2; // SZD\r
-\r
-  /**\r
-   * Constant for MPEG-1 version\r
-   */\r
-  public static final int MPEG1 = 1;\r
-\r
-  public static final int STEREO = 0;\r
-  public static final int JOINT_STEREO = 1;\r
-  public static final int DUAL_CHANNEL = 2;\r
-  public static final int SINGLE_CHANNEL = 3;\r
-  public static final int FOURTYFOUR_POINT_ONE = 0;\r
-  public static final int FOURTYEIGHT = 1;\r
-  public static final int THIRTYTWO = 2;\r
-\r
-  @LOC("H")\r
-  private int h_layer;\r
-  @LOC("H")\r
-  private int h_protection_bit;\r
-  @LOC("H")\r
-  private int h_bitrate_index;\r
-  @LOC("H")\r
-  private int h_padding_bit;\r
-  @LOC("H")\r
-  private int h_mode_extension;\r
-  @LOC("HV")\r
-  private int h_version;\r
-  @LOC("H")\r
-  private int h_mode;\r
-  @LOC("H")\r
-  private int h_sample_frequency;\r
-  @LOC("HNS")\r
-  private int h_number_of_subbands;\r
-  @LOC("HI")\r
-  private int h_intensity_stereo_bound;\r
-  @LOC("H")\r
-  private boolean h_copyright;\r
-  @LOC("H")\r
-  private boolean h_original;\r
-  // VBR support added by E.B\r
-  @LOC("T")\r
-  private double[] h_vbr_time_per_frame = { -1.0, 384.0, 1152.0, 1152.0 };\r
-  @LOC("T")\r
-  private boolean h_vbr;\r
-  @LOC("T")\r
-  private int h_vbr_frames;\r
-  @LOC("T")\r
-  private int h_vbr_scale;\r
-  @LOC("T")\r
-  private int h_vbr_bytes;\r
-  @LOC("T")\r
-  private byte[] h_vbr_toc;\r
-\r
-  @LOC("SYNC")\r
-  private byte syncmode = Bitstream.INITIAL_SYNC;\r
-  @LOC("C")\r
-  private Crc16 crc;\r
-\r
-  @LOC("C")\r
-  public short checksum;\r
-  @LOC("FS")\r
-  public int framesize;\r
-  @LOC("NS")\r
-  public int nSlots;\r
-\r
-  @LOC("T")\r
-  private int _headerstring = -1; // E.B\r
-\r
-  private SideInfoBuffer sib;\r
-  private BitReserve br;\r
-\r
-  Header() {\r
-  }\r
-\r
-  public String toString() {\r
-    StringBuffer buffer = new StringBuffer(200);\r
-    buffer.append("Layer ");\r
-    buffer.append(layer_string());\r
-    buffer.append(" frame ");\r
-    buffer.append(mode_string());\r
-    buffer.append(' ');\r
-    buffer.append(version_string());\r
-    if (!checksums())\r
-      buffer.append(" no");\r
-    buffer.append(" checksums");\r
-    buffer.append(' ');\r
-    buffer.append(sample_frequency_string());\r
-    buffer.append(',');\r
-    buffer.append(' ');\r
-    buffer.append(bitrate_string());\r
-\r
-    String s = buffer.toString();\r
-    return s;\r
-  }\r
-\r
-  /**\r
-   * Read a 32-bit header from the bitstream.\r
-   */\r
-  void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException {\r
-    int headerstring;\r
-    int channel_bitrate;\r
-    boolean sync = false;\r
-    do {\r
-      headerstring = stream.syncHeader(syncmode);\r
-      _headerstring = headerstring; // E.B\r
-      if (syncmode == Bitstream.INITIAL_SYNC) {\r
-        h_version = ((headerstring >>> 19) & 1);\r
-        if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection\r
-          if (h_version == MPEG2_LSF)\r
-            h_version = MPEG25_LSF;\r
-          else\r
-            throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
-        if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) {\r
-          throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
-        }\r
-      }\r
-      h_layer = 4 - (headerstring >>> 17) & 3;\r
-      h_protection_bit = (headerstring >>> 16) & 1;\r
-      h_bitrate_index = (headerstring >>> 12) & 0xF;\r
-      h_padding_bit = (headerstring >>> 9) & 1;\r
-      h_mode = ((headerstring >>> 6) & 3);\r
-      h_mode_extension = (headerstring >>> 4) & 3;\r
-      if (h_mode == JOINT_STEREO)\r
-        h_intensity_stereo_bound = (h_mode_extension << 2) + 4;\r
-      else\r
-        h_intensity_stereo_bound = 0; // should never be used\r
-      if (((headerstring >>> 3) & 1) == 1)\r
-        h_copyright = true;\r
-      if (((headerstring >>> 2) & 1) == 1)\r
-        h_original = true;\r
-      // calculate number of subbands:\r
-      if (h_layer == 1)\r
-        h_number_of_subbands = 32;\r
-      else {\r
-        channel_bitrate = h_bitrate_index;\r
-        // calculate bitrate per channel:\r
-        if (h_mode != SINGLE_CHANNEL)\r
-          if (channel_bitrate == 4)\r
-            channel_bitrate = 1;\r
-          else\r
-            channel_bitrate -= 4;\r
-        if ((channel_bitrate == 1) || (channel_bitrate == 2))\r
-          if (h_sample_frequency == THIRTYTWO)\r
-            h_number_of_subbands = 12;\r
-          else\r
-            h_number_of_subbands = 8;\r
-        else if ((h_sample_frequency == FOURTYEIGHT)\r
-            || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))\r
-          h_number_of_subbands = 27;\r
-        else\r
-          h_number_of_subbands = 30;\r
-      }\r
-      if (h_intensity_stereo_bound > h_number_of_subbands)\r
-        h_intensity_stereo_bound = h_number_of_subbands;\r
-      // calculate framesize and nSlots\r
-      calculate_framesize();\r
-      // read framedata:\r
-      int framesizeloaded = stream.read_frame_data(framesize);\r
-      if ((framesize >= 0) && (framesizeloaded != framesize)) {\r
-        // Data loaded does not match to expected framesize,\r
-        // it might be an ID3v1 TAG. (Fix 11/17/04).\r
-        throw stream.newBitstreamException(Bitstream.INVALIDFRAME);\r
-      }\r
-      if (stream.isSyncCurrentPosition(syncmode)) {\r
-        if (syncmode == Bitstream.INITIAL_SYNC) {\r
-          syncmode = Bitstream.STRICT_SYNC;\r
-          stream.set_syncword(headerstring & 0xFFF80CC0);\r
-        }\r
-        sync = true;\r
-      } else {\r
-        stream.unreadFrame();\r
-      }\r
-    } while (!sync);\r
-    stream.parse_frame();\r
-    if (h_protection_bit == 0) {\r
-      // frame contains a crc checksum\r
-      checksum = (short) stream.get_bits(16);\r
-      if (crc == null)\r
-        crc = new Crc16();\r
-      crc.add_bits(headerstring, 16);\r
-      crcp[0] = crc;\r
-    } else\r
-      crcp[0] = null;\r
-    if (h_sample_frequency == FOURTYFOUR_POINT_ONE) {\r
-      /*\r
-       * if (offset == null) { int max = max_number_of_frames(stream); offset =\r
-       * new int[max]; for(int i=0; i<max; i++) offset[i] = 0; } // E.B :\r
-       * Investigate more int cf = stream.current_frame(); int lf =\r
-       * stream.last_frame(); if ((cf > 0) && (cf == lf)) { offset[cf] =\r
-       * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; }\r
-       */\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Parse frame to extract optionnal VBR frame.\r
-   * \r
-   * @param firstframe\r
-   * @author E.B (javalayer@javazoom.net)\r
-   */\r
-  void parseVBR(byte[] firstframe) throws BitstreamException {\r
-    // Trying Xing header.\r
-    String xing = "Xing";\r
-    byte tmp[] = new byte[4];\r
-    int offset = 0;\r
-    // Compute "Xing" offset depending on MPEG version and channels.\r
-    if (h_version == MPEG1) {\r
-      if (h_mode == SINGLE_CHANNEL)\r
-        offset = 21 - 4;\r
-      else\r
-        offset = 36 - 4;\r
-    } else {\r
-      if (h_mode == SINGLE_CHANNEL)\r
-        offset = 13 - 4;\r
-      else\r
-        offset = 21 - 4;\r
-    }\r
-    try {\r
-      System.arraycopy(firstframe, offset, tmp, 0, 4);\r
-      // Is "Xing" ?\r
-      if (xing.equals(new String(tmp))) {\r
-        // Yes.\r
-        h_vbr = true;\r
-        h_vbr_frames = -1;\r
-        h_vbr_bytes = -1;\r
-        h_vbr_scale = -1;\r
-        h_vbr_toc = new byte[100];\r
-\r
-        int length = 4;\r
-        // Read flags.\r
-        byte flags[] = new byte[4];\r
-        System.arraycopy(firstframe, offset + length, flags, 0, flags.length);\r
-        length += flags.length;\r
-        // Read number of frames (if available).\r
-        if ((flags[3] & (byte) (1 << 0)) != 0) {\r
-          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
-          h_vbr_frames =\r
-              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
-                  & 0x0000FF00 | tmp[3] & 0x000000FF;\r
-          length += 4;\r
-        }\r
-        // Read size (if available).\r
-        if ((flags[3] & (byte) (1 << 1)) != 0) {\r
-          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
-          h_vbr_bytes =\r
-              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
-                  & 0x0000FF00 | tmp[3] & 0x000000FF;\r
-          length += 4;\r
-        }\r
-        // Read TOC (if available).\r
-        if ((flags[3] & (byte) (1 << 2)) != 0) {\r
-          System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);\r
-          length += h_vbr_toc.length;\r
-        }\r
-        // Read scale (if available).\r
-        if ((flags[3] & (byte) (1 << 3)) != 0) {\r
-          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
-          h_vbr_scale =\r
-              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
-                  & 0x0000FF00 | tmp[3] & 0x000000FF;\r
-          length += 4;\r
-        }\r
-        // System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames\r
-        // +" Size:"+h_vbr_bytes);\r
-      }\r
-    } catch (ArrayIndexOutOfBoundsException e) {\r
-      throw new BitstreamException("XingVBRHeader Corrupted", e);\r
-    }\r
-\r
-    // Trying VBRI header.\r
-    String vbri = "VBRI";\r
-    offset = 36 - 4;\r
-    try {\r
-      System.arraycopy(firstframe, offset, tmp, 0, 4);\r
-      // Is "VBRI" ?\r
-      if (vbri.equals(new String(tmp))) {\r
-        // Yes.\r
-        h_vbr = true;\r
-        h_vbr_frames = -1;\r
-        h_vbr_bytes = -1;\r
-        h_vbr_scale = -1;\r
-        h_vbr_toc = new byte[100];\r
-        // Bytes.\r
-        int length = 4 + 6;\r
-        System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
-        h_vbr_bytes =\r
-            (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
-                | tmp[3] & 0x000000FF;\r
-        length += 4;\r
-        // Frames.\r
-        System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
-        h_vbr_frames =\r
-            (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
-                | tmp[3] & 0x000000FF;\r
-        length += 4;\r
-        // System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames\r
-        // +" Size:"+h_vbr_bytes);\r
-        // TOC\r
-        // TODO\r
-      }\r
-    } catch (ArrayIndexOutOfBoundsException e) {\r
-      throw new BitstreamException("VBRIVBRHeader Corrupted", e);\r
-    }\r
-  }\r
-\r
-  // Functions to query header contents:\r
-  /**\r
-   * Returns version.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int version() {\r
-    return h_version;\r
-  }\r
-\r
-  /**\r
-   * Returns Layer ID.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int layer() {\r
-    return h_layer;\r
-  }\r
-\r
-  /**\r
-   * Returns bitrate index.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int bitrate_index() {\r
-    return h_bitrate_index;\r
-  }\r
-\r
-  /**\r
-   * Returns Sample Frequency.\r
-   */\r
-  public int sample_frequency() {\r
-    return h_sample_frequency;\r
-  }\r
-\r
-  /**\r
-   * Returns Frequency.\r
-   */\r
-  public int frequency() {\r
-    return frequencies[h_version][h_sample_frequency];\r
-  }\r
-\r
-  /**\r
-   * Returns Mode.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int mode() {\r
-    return h_mode;\r
-  }\r
-\r
-  /**\r
-   * Returns Protection bit.\r
-   */\r
-  public boolean checksums() {\r
-    if (h_protection_bit == 0)\r
-      return true;\r
-    else\r
-      return false;\r
-  }\r
-\r
-  /**\r
-   * Returns Copyright.\r
-   */\r
-  public boolean copyright() {\r
-    return h_copyright;\r
-  }\r
-\r
-  /**\r
-   * Returns Original.\r
-   */\r
-  public boolean original() {\r
-    return h_original;\r
-  }\r
-\r
-  /**\r
-   * Return VBR.\r
-   * \r
-   * @return true if VBR header is found\r
-   */\r
-  public boolean vbr() {\r
-    return h_vbr;\r
-  }\r
-\r
-  /**\r
-   * Return VBR scale.\r
-   * \r
-   * @return scale of -1 if not available\r
-   */\r
-  public int vbr_scale() {\r
-    return h_vbr_scale;\r
-  }\r
-\r
-  /**\r
-   * Return VBR TOC.\r
-   * \r
-   * @return vbr toc ot null if not available\r
-   */\r
-  public byte[] vbr_toc() {\r
-    return h_vbr_toc;\r
-  }\r
-\r
-  /**\r
-   * Returns Checksum flag. Compares computed checksum with stream checksum.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public boolean checksum_ok() {\r
-    return (checksum == crc.checksum());\r
-  }\r
-\r
-  // Seeking and layer III stuff\r
-  /**\r
-   * Returns Layer III Padding bit.\r
-   */\r
-  public boolean padding() {\r
-    if (h_padding_bit == 0)\r
-      return false;\r
-    else\r
-      return true;\r
-  }\r
-\r
-  /**\r
-   * Returns Slots.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int slots() {\r
-    return nSlots;\r
-  }\r
-\r
-  /**\r
-   * Returns Mode Extension.\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int mode_extension() {\r
-    return h_mode_extension;\r
-  }\r
-\r
-  // E.B -> private to public\r
-  @LOC("T")\r
-  public static final int bitrates[][][] = {\r
-      {\r
-          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
-              160000, 176000, 192000, 224000, 256000, 0 },\r
-          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
-              96000, 112000, 128000, 144000, 160000, 0 },\r
-          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
-              96000, 112000, 128000, 144000, 160000, 0 } },\r
-\r
-      {\r
-          { 0 /* free format */, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000,\r
-              288000, 320000, 352000, 384000, 416000, 448000, 0 },\r
-          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000,\r
-              192000, 224000, 256000, 320000, 384000, 0 },\r
-          { 0 /* free format */, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000,\r
-              160000, 192000, 224000, 256000, 320000, 0 } },\r
-      // SZD: MPEG2.5\r
-      {\r
-          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
-              160000, 176000, 192000, 224000, 256000, 0 },\r
-          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
-              96000, 112000, 128000, 144000, 160000, 0 },\r
-          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
-              96000, 112000, 128000, 144000, 160000, 0 } },\r
-\r
-  };\r
-\r
-  // E.B -> private to public\r
-  /**\r
-   * Calculate Frame size. Calculates framesize in bytes excluding header size.\r
-   */\r
-  public int calculate_framesize() {\r
-\r
-    if (h_layer == 1) {\r
-      framesize =\r
-          (12 * bitrates[h_version][0][h_bitrate_index])\r
-              / frequencies[h_version][h_sample_frequency];\r
-      if (h_padding_bit != 0)\r
-        framesize++;\r
-      framesize <<= 2; // one slot is 4 bytes long\r
-      nSlots = 0;\r
-    } else {\r
-      framesize =\r
-          (144 * bitrates[h_version][h_layer - 1][h_bitrate_index])\r
-              / frequencies[h_version][h_sample_frequency];\r
-      if (h_version == MPEG2_LSF || h_version == MPEG25_LSF)\r
-        framesize >>= 1; // SZD\r
-      if (h_padding_bit != 0)\r
-        framesize++;\r
-      // Layer III slots\r
-      if (h_layer == 3) {\r
-        if (h_version == MPEG1) {\r
-          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side\r
-                                                                      // info\r
-                                                                      // size\r
-              - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
-              - 4; // header size\r
-        } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
-          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side\r
-                                                                     // info\r
-                                                                     // size\r
-              - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
-              - 4; // header size\r
-        }\r
-      } else {\r
-        nSlots = 0;\r
-      }\r
-    }\r
-    framesize -= 4; // subtract header size\r
-    return framesize;\r
-  }\r
-\r
-  /**\r
-   * Returns the maximum number of frames in the stream.\r
-   * \r
-   * @param streamsize\r
-   * @return number of frames\r
-   */\r
-  public int max_number_of_frames(int streamsize) // E.B\r
-  {\r
-    if (h_vbr == true)\r
-      return h_vbr_frames;\r
-    else {\r
-      if ((framesize + 4 - h_padding_bit) == 0)\r
-        return 0;\r
-      else\r
-        return (streamsize / (framesize + 4 - h_padding_bit));\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Returns the maximum number of frames in the stream.\r
-   * \r
-   * @param streamsize\r
-   * @return number of frames\r
-   */\r
-  public int min_number_of_frames(int streamsize) // E.B\r
-  {\r
-    if (h_vbr == true)\r
-      return h_vbr_frames;\r
-    else {\r
-      if ((framesize + 5 - h_padding_bit) == 0)\r
-        return 0;\r
-      else\r
-        return (streamsize / (framesize + 5 - h_padding_bit));\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Returns ms/frame.\r
-   * \r
-   * @return milliseconds per frame\r
-   */\r
-  public float ms_per_frame() // E.B\r
-  {\r
-    if (h_vbr == true) {\r
-      double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
-      if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF))\r
-        tpf /= 2;\r
-      return ((float) (tpf * 1000));\r
-    } else {\r
-      float ms_per_frame_array[][] =\r
-          { { 8.707483f, 8.0f, 12.0f }, { 26.12245f, 24.0f, 36.0f }, { 26.12245f, 24.0f, 36.0f } };\r
-      return (ms_per_frame_array[h_layer - 1][h_sample_frequency]);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Returns total ms.\r
-   * \r
-   * @param streamsize\r
-   * @return total milliseconds\r
-   */\r
-  public float total_ms(int streamsize) // E.B\r
-  {\r
-    return (max_number_of_frames(streamsize) * ms_per_frame());\r
-  }\r
-\r
-  /**\r
-   * Returns synchronized header.\r
-   */\r
-  public int getSyncHeader() // E.B\r
-  {\r
-    return _headerstring;\r
-  }\r
-\r
-  // functions which return header informations as strings:\r
-  /**\r
-   * Return Layer version.\r
-   */\r
-  public String layer_string() {\r
-    switch (h_layer) {\r
-    case 1:\r
-      return "I";\r
-    case 2:\r
-      return "II";\r
-    case 3:\r
-      return "III";\r
-    }\r
-    return null;\r
-  }\r
-\r
-  // E.B -> private to public\r
-  @LOC("T")\r
-  public static final String bitrate_str[][][] = {\r
-      {\r
-          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
-              "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
-              "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
-          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
-              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
-              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
-          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
-              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
-              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } },\r
-\r
-      {\r
-          { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",\r
-              "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",\r
-              "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" },\r
-          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
-              "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",\r
-              "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" },\r
-          { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
-              "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s",\r
-              "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } },\r
-      // SZD: MPEG2.5\r
-      {\r
-          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
-              "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
-              "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
-          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
-              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
-              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
-          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
-              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
-              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, };\r
-\r
-  /**\r
-   * Return Bitrate.\r
-   * \r
-   * @return bitrate in bps\r
-   */\r
-  public String bitrate_string() {\r
-    if (h_vbr == true) {\r
-      return Integer.toString(bitrate() / 1000) + " kb/s";\r
-    } else\r
-      return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
-  }\r
-\r
-  /**\r
-   * Return Bitrate.\r
-   * \r
-   * @return bitrate in bps and average bitrate for VBR header\r
-   */\r
-  public int bitrate() {\r
-    if (h_vbr == true) {\r
-      return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000;\r
-    } else\r
-      return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
-  }\r
-\r
-  /**\r
-   * Return Instant Bitrate. Bitrate for VBR is not constant.\r
-   * \r
-   * @return bitrate in bps\r
-   */\r
-  public int bitrate_instant() {\r
-    return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
-  }\r
-\r
-  /**\r
-   * Returns Frequency\r
-   * \r
-   * @return frequency string in kHz\r
-   */\r
-  public String sample_frequency_string() {\r
-    switch (h_sample_frequency) {\r
-    case THIRTYTWO:\r
-      if (h_version == MPEG1)\r
-        return "32 kHz";\r
-      else if (h_version == MPEG2_LSF)\r
-        return "16 kHz";\r
-      else\r
-        // SZD\r
-        return "8 kHz";\r
-    case FOURTYFOUR_POINT_ONE:\r
-      if (h_version == MPEG1)\r
-        return "44.1 kHz";\r
-      else if (h_version == MPEG2_LSF)\r
-        return "22.05 kHz";\r
-      else\r
-        // SZD\r
-        return "11.025 kHz";\r
-    case FOURTYEIGHT:\r
-      if (h_version == MPEG1)\r
-        return "48 kHz";\r
-      else if (h_version == MPEG2_LSF)\r
-        return "24 kHz";\r
-      else\r
-        // SZD\r
-        return "12 kHz";\r
-    }\r
-    return (null);\r
-  }\r
-\r
-  /**\r
-   * Returns Mode.\r
-   */\r
-  public String mode_string() {\r
-    switch (h_mode) {\r
-    case STEREO:\r
-      return "Stereo";\r
-    case JOINT_STEREO:\r
-      return "Joint stereo";\r
-    case DUAL_CHANNEL:\r
-      return "Dual channel";\r
-    case SINGLE_CHANNEL:\r
-      return "Single channel";\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * Returns Version.\r
-   * \r
-   * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
-   */\r
-  public String version_string() {\r
-    switch (h_version) {\r
-    case MPEG1:\r
-      return "MPEG-1";\r
-    case MPEG2_LSF:\r
-      return "MPEG-2 LSF";\r
-    case MPEG25_LSF: // SZD\r
-      return "MPEG-2.5 LSF";\r
-    }\r
-    return (null);\r
-  }\r
-\r
-  /**\r
-   * Returns the number of subbands in the current frame.\r
-   * \r
-   * @return number of subbands\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int number_of_subbands() {\r
-    return h_number_of_subbands;\r
-  }\r
-\r
-  /**\r
-   * Returns Intensity Stereo. (Layer II joint stereo only). Returns the number\r
-   * of subbands which are in stereo mode, subbands above that limit are in\r
-   * intensity stereo mode.\r
-   * \r
-   * @return intensity\r
-   */\r
-  @RETURNLOC("OUT")\r
-  public int intensity_stereo_bound() {\r
-    return h_intensity_stereo_bound;\r
-  }\r
-\r
-  public void setSideInfoBuf(SideInfoBuffer sib) {\r
-    this.sib = sib;\r
-  }\r
-\r
-  public void setBitReserve(BitReserve br) {\r
-    this.br = br;\r
-  }\r
-\r
-  public SideInfoBuffer getSideInfoBuffer() {\r
-    return sib;\r
-  }\r
-\r
-  public BitReserve getBitReserve() {\r
-    return br;\r
-  }\r
-\r
-}\r
+/*
+ * 11/19/04 : 1.0 moved to LGPL.
+ *            VBRI header support added, E.B javalayer@javazoom.net
+ * 
+ * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net
+ *
+ * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net
+ *
+ * Declarations for MPEG header class
+ * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.
+ * Last modified : 04/19/97
+ *
+ *  @(#) header.h 1.7, last edit: 6/15/94 16:55:33
+ *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
+ *  @(#) Berlin University of Technology
+ *-----------------------------------------------------------------------
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as published
+ *   by the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program 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 Library General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *----------------------------------------------------------------------
+ */
+
+/**
+ * Class for extracting information from a frame header.
+ */
+@LATTICE("HI<HNS,HNS<H,C<H,NS<FS,FS<H,FS<HV,H<SYNC,HV<SYNC,HV<T,SYNC*,HV*,FS*,HI*")
+@METHODDEFAULT("OUT<V,V<THIS,THIS<SH,SH<IN,SH*,THISLOC=THIS,GLOBALLOC=IN")
+public final class Header {
+
+  public static final int[][] frequencies = { { 22050, 24000, 16000, 1 },
+      { 44100, 48000, 32000, 1 }, { 11025, 12000, 8000, 1 } }; // SZD: MPEG25
+
+  /**
+   * Constant for MPEG-2 LSF version
+   */
+  public static final int MPEG2_LSF = 0;
+  public static final int MPEG25_LSF = 2; // SZD
+
+  /**
+   * Constant for MPEG-1 version
+   */
+  public static final int MPEG1 = 1;
+
+  public static final int STEREO = 0;
+  public static final int JOINT_STEREO = 1;
+  public static final int DUAL_CHANNEL = 2;
+  public static final int SINGLE_CHANNEL = 3;
+  public static final int FOURTYFOUR_POINT_ONE = 0;
+  public static final int FOURTYEIGHT = 1;
+  public static final int THIRTYTWO = 2;
+
+  @LOC("H")
+  private int h_layer;
+  @LOC("H")
+  private int h_protection_bit;
+  @LOC("H")
+  private int h_bitrate_index;
+  @LOC("H")
+  private int h_padding_bit;
+  @LOC("H")
+  private int h_mode_extension;
+  @LOC("HV")
+  private int h_version;
+  @LOC("H")
+  private int h_mode;
+  @LOC("H")
+  private int h_sample_frequency;
+  @LOC("HNS")
+  private int h_number_of_subbands;
+  @LOC("HI")
+  private int h_intensity_stereo_bound;
+  @LOC("H")
+  private boolean h_copyright;
+  @LOC("H")
+  private boolean h_original;
+  // VBR support added by E.B
+  @LOC("T")
+  private double[] h_vbr_time_per_frame = { -1.0, 384.0, 1152.0, 1152.0 };
+  @LOC("T")
+  private boolean h_vbr;
+  @LOC("T")
+  private int h_vbr_frames;
+  @LOC("T")
+  private int h_vbr_scale;
+  @LOC("T")
+  private int h_vbr_bytes;
+  @LOC("T")
+  private byte[] h_vbr_toc;
+
+  @LOC("SYNC")
+  private byte syncmode = Bitstream.INITIAL_SYNC;
+  @LOC("C")
+  private Crc16 crc;
+
+  @LOC("C")
+  public short checksum;
+  @LOC("FS")
+  public int framesize;
+  @LOC("NS")
+  public int nSlots;
+
+  @LOC("T")
+  private int _headerstring = -1; // E.B
+
+  private SideInfoBuffer sib;
+  private BitReserve br;
+
+  Header() {
+  }
+
+  public String toString() {
+    StringBuffer buffer = new StringBuffer(200);
+    buffer.append("Layer ");
+    buffer.append(layer_string());
+    buffer.append(" frame ");
+    buffer.append(mode_string());
+    buffer.append(' ');
+    buffer.append(version_string());
+    if (!checksums())
+      buffer.append(" no");
+    buffer.append(" checksums");
+    buffer.append(' ');
+    buffer.append(sample_frequency_string());
+    buffer.append(',');
+    buffer.append(' ');
+    buffer.append(bitrate_string());
+
+    String s = buffer.toString();
+    return s;
+  }
+
+  /**
+   * Read a 32-bit header from the bitstream.
+   */
+  void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException {
+    System.out.print("READ_HEADER_ST");
+    int headerstring;
+    int channel_bitrate;
+    boolean sync = false;
+    do {
+      System.out.println("DO!");
+      headerstring = stream.syncHeader(syncmode);
+      _headerstring = headerstring; // E.B
+      if (syncmode == Bitstream.INITIAL_SYNC) {
+        h_version = ((headerstring >>> 19) & 1);
+        if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection
+          if (h_version == MPEG2_LSF)
+            h_version = MPEG25_LSF;
+          else
+            throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
+        if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) {
+          throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
+        }
+      }
+      h_layer = 4 - (headerstring >>> 17) & 3;
+      h_protection_bit = (headerstring >>> 16) & 1;
+      h_bitrate_index = (headerstring >>> 12) & 0xF;
+      h_padding_bit = (headerstring >>> 9) & 1;
+      h_mode = ((headerstring >>> 6) & 3);
+      h_mode_extension = (headerstring >>> 4) & 3;
+      if (h_mode == JOINT_STEREO)
+        h_intensity_stereo_bound = (h_mode_extension << 2) + 4;
+      else
+        h_intensity_stereo_bound = 0; // should never be used
+      if (((headerstring >>> 3) & 1) == 1)
+        h_copyright = true;
+      if (((headerstring >>> 2) & 1) == 1)
+        h_original = true;
+      // calculate number of subbands:
+      if (h_layer == 1)
+        h_number_of_subbands = 32;
+      else {
+        channel_bitrate = h_bitrate_index;
+        // calculate bitrate per channel:
+        if (h_mode != SINGLE_CHANNEL)
+          if (channel_bitrate == 4)
+            channel_bitrate = 1;
+          else
+            channel_bitrate -= 4;
+        if ((channel_bitrate == 1) || (channel_bitrate == 2))
+          if (h_sample_frequency == THIRTYTWO)
+            h_number_of_subbands = 12;
+          else
+            h_number_of_subbands = 8;
+        else if ((h_sample_frequency == FOURTYEIGHT)
+            || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))
+          h_number_of_subbands = 27;
+        else
+          h_number_of_subbands = 30;
+      }
+      if (h_intensity_stereo_bound > h_number_of_subbands)
+        h_intensity_stereo_bound = h_number_of_subbands;
+      // calculate framesize and nSlots
+      calculate_framesize();
+      // read framedata:
+      int framesizeloaded = stream.read_frame_data(framesize);
+      if ((framesize >= 0) && (framesizeloaded != framesize)) {
+        // Data loaded does not match to expected framesize,
+        // it might be an ID3v1 TAG. (Fix 11/17/04).
+        throw stream.newBitstreamException(Bitstream.INVALIDFRAME);
+      }
+      if (stream.isSyncCurrentPosition(syncmode)) {
+        if (syncmode == Bitstream.INITIAL_SYNC) {
+          syncmode = Bitstream.STRICT_SYNC;
+          stream.set_syncword(headerstring & 0xFFF80CC0);
+        }
+        sync = true;
+      } else {
+        stream.unreadFrame();
+      }
+      System.out.println("do");
+    } while (!sync);
+    stream.parse_frame();
+    if (h_protection_bit == 0) {
+      // frame contains a crc checksum
+      checksum = (short) stream.get_bits(16);
+      if (crc == null)
+        crc = new Crc16();
+      crc.add_bits(headerstring, 16);
+      crcp[0] = crc;
+    } else
+      crcp[0] = null;
+    if (h_sample_frequency == FOURTYFOUR_POINT_ONE) {
+      /*
+       * if (offset == null) { int max = max_number_of_frames(stream); offset =
+       * new int[max]; for(int i=0; i<max; i++) offset[i] = 0; } // E.B :
+       * Investigate more int cf = stream.current_frame(); int lf =
+       * stream.last_frame(); if ((cf > 0) && (cf == lf)) { offset[cf] =
+       * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; }
+       */
+    }
+    System.out.print("READ_HEADER_ED");
+  }
+
+  /**
+   * Parse frame to extract optionnal VBR frame.
+   * 
+   * @param firstframe
+   * @author E.B (javalayer@javazoom.net)
+   */
+  void parseVBR(byte[] firstframe) throws BitstreamException {
+    // Trying Xing header.
+    String xing = "Xing";
+    byte tmp[] = new byte[4];
+    int offset = 0;
+    // Compute "Xing" offset depending on MPEG version and channels.
+    if (h_version == MPEG1) {
+      if (h_mode == SINGLE_CHANNEL)
+        offset = 21 - 4;
+      else
+        offset = 36 - 4;
+    } else {
+      if (h_mode == SINGLE_CHANNEL)
+        offset = 13 - 4;
+      else
+        offset = 21 - 4;
+    }
+    try {
+      System.arraycopy(firstframe, offset, tmp, 0, 4);
+      // Is "Xing" ?
+      if (xing.equals(new String(tmp))) {
+        // Yes.
+        h_vbr = true;
+        h_vbr_frames = -1;
+        h_vbr_bytes = -1;
+        h_vbr_scale = -1;
+        h_vbr_toc = new byte[100];
+
+        int length = 4;
+        // Read flags.
+        byte flags[] = new byte[4];
+        System.arraycopy(firstframe, offset + length, flags, 0, flags.length);
+        length += flags.length;
+        // Read number of frames (if available).
+        if ((flags[3] & (byte) (1 << 0)) != 0) {
+          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+          h_vbr_frames =
+              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+                  & 0x0000FF00 | tmp[3] & 0x000000FF;
+          length += 4;
+        }
+        // Read size (if available).
+        if ((flags[3] & (byte) (1 << 1)) != 0) {
+          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+          h_vbr_bytes =
+              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+                  & 0x0000FF00 | tmp[3] & 0x000000FF;
+          length += 4;
+        }
+        // Read TOC (if available).
+        if ((flags[3] & (byte) (1 << 2)) != 0) {
+          System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);
+          length += h_vbr_toc.length;
+        }
+        // Read scale (if available).
+        if ((flags[3] & (byte) (1 << 3)) != 0) {
+          System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+          h_vbr_scale =
+              (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)
+                  & 0x0000FF00 | tmp[3] & 0x000000FF;
+          length += 4;
+        }
+        // System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames
+        // +" Size:"+h_vbr_bytes);
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new BitstreamException("XingVBRHeader Corrupted", e);
+    }
+
+    // Trying VBRI header.
+    String vbri = "VBRI";
+    offset = 36 - 4;
+    try {
+      System.arraycopy(firstframe, offset, tmp, 0, 4);
+      // Is "VBRI" ?
+      if (vbri.equals(new String(tmp))) {
+        // Yes.
+        h_vbr = true;
+        h_vbr_frames = -1;
+        h_vbr_bytes = -1;
+        h_vbr_scale = -1;
+        h_vbr_toc = new byte[100];
+        // Bytes.
+        int length = 4 + 6;
+        System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+        h_vbr_bytes =
+            (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00
+                | tmp[3] & 0x000000FF;
+        length += 4;
+        // Frames.
+        System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
+        h_vbr_frames =
+            (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00
+                | tmp[3] & 0x000000FF;
+        length += 4;
+        // System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames
+        // +" Size:"+h_vbr_bytes);
+        // TOC
+        // TODO
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new BitstreamException("VBRIVBRHeader Corrupted", e);
+    }
+  }
+
+  // Functions to query header contents:
+  /**
+   * Returns version.
+   */
+  @RETURNLOC("OUT")
+  public int version() {
+    return h_version;
+  }
+
+  /**
+   * Returns Layer ID.
+   */
+  @RETURNLOC("OUT")
+  public int layer() {
+    return h_layer;
+  }
+
+  /**
+   * Returns bitrate index.
+   */
+  @RETURNLOC("OUT")
+  public int bitrate_index() {
+    return h_bitrate_index;
+  }
+
+  /**
+   * Returns Sample Frequency.
+   */
+  public int sample_frequency() {
+    return h_sample_frequency;
+  }
+
+  /**
+   * Returns Frequency.
+   */
+  public int frequency() {
+    return frequencies[h_version][h_sample_frequency];
+  }
+
+  /**
+   * Returns Mode.
+   */
+  @RETURNLOC("OUT")
+  public int mode() {
+    return h_mode;
+  }
+
+  /**
+   * Returns Protection bit.
+   */
+  public boolean checksums() {
+    if (h_protection_bit == 0)
+      return true;
+    else
+      return false;
+  }
+
+  /**
+   * Returns Copyright.
+   */
+  public boolean copyright() {
+    return h_copyright;
+  }
+
+  /**
+   * Returns Original.
+   */
+  public boolean original() {
+    return h_original;
+  }
+
+  /**
+   * Return VBR.
+   * 
+   * @return true if VBR header is found
+   */
+  public boolean vbr() {
+    return h_vbr;
+  }
+
+  /**
+   * Return VBR scale.
+   * 
+   * @return scale of -1 if not available
+   */
+  public int vbr_scale() {
+    return h_vbr_scale;
+  }
+
+  /**
+   * Return VBR TOC.
+   * 
+   * @return vbr toc ot null if not available
+   */
+  public byte[] vbr_toc() {
+    return h_vbr_toc;
+  }
+
+  /**
+   * Returns Checksum flag. Compares computed checksum with stream checksum.
+   */
+  @RETURNLOC("OUT")
+  public boolean checksum_ok() {
+    return (checksum == crc.checksum());
+  }
+
+  // Seeking and layer III stuff
+  /**
+   * Returns Layer III Padding bit.
+   */
+  public boolean padding() {
+    if (h_padding_bit == 0)
+      return false;
+    else
+      return true;
+  }
+
+  /**
+   * Returns Slots.
+   */
+  @RETURNLOC("OUT")
+  public int slots() {
+    return nSlots;
+  }
+
+  /**
+   * Returns Mode Extension.
+   */
+  @RETURNLOC("OUT")
+  public int mode_extension() {
+    return h_mode_extension;
+  }
+
+  // E.B -> private to public
+  @LOC("T")
+  public static final int bitrates[][][] = {
+      {
+          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,
+              160000, 176000, 192000, 224000, 256000, 0 },
+          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+              96000, 112000, 128000, 144000, 160000, 0 },
+          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+              96000, 112000, 128000, 144000, 160000, 0 } },
+
+      {
+          { 0 /* free format */, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000,
+              288000, 320000, 352000, 384000, 416000, 448000, 0 },
+          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000,
+              192000, 224000, 256000, 320000, 384000, 0 },
+          { 0 /* free format */, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000,
+              160000, 192000, 224000, 256000, 320000, 0 } },
+      // SZD: MPEG2.5
+      {
+          { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,
+              160000, 176000, 192000, 224000, 256000, 0 },
+          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+              96000, 112000, 128000, 144000, 160000, 0 },
+          { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,
+              96000, 112000, 128000, 144000, 160000, 0 } },
+
+  };
+
+  // E.B -> private to public
+  /**
+   * Calculate Frame size. Calculates framesize in bytes excluding header size.
+   */
+  public int calculate_framesize() {
+
+    if (h_layer == 1) {
+      framesize =
+          (12 * bitrates[h_version][0][h_bitrate_index])
+              / frequencies[h_version][h_sample_frequency];
+      if (h_padding_bit != 0)
+        framesize++;
+      framesize <<= 2; // one slot is 4 bytes long
+      nSlots = 0;
+    } else {
+      framesize =
+          (144 * bitrates[h_version][h_layer - 1][h_bitrate_index])
+              / frequencies[h_version][h_sample_frequency];
+      if (h_version == MPEG2_LSF || h_version == MPEG25_LSF)
+        framesize >>= 1; // SZD
+      if (h_padding_bit != 0)
+        framesize++;
+      // Layer III slots
+      if (h_layer == 3) {
+        if (h_version == MPEG1) {
+          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side
+                                                                      // info
+                                                                      // size
+              - ((h_protection_bit != 0) ? 0 : 2) // CRC size
+              - 4; // header size
+        } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF
+          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side
+                                                                     // info
+                                                                     // size
+              - ((h_protection_bit != 0) ? 0 : 2) // CRC size
+              - 4; // header size
+        }
+      } else {
+        nSlots = 0;
+      }
+    }
+    framesize -= 4; // subtract header size
+    return framesize;
+  }
+
+  /**
+   * Returns the maximum number of frames in the stream.
+   * 
+   * @param streamsize
+   * @return number of frames
+   */
+  public int max_number_of_frames(int streamsize) // E.B
+  {
+    if (h_vbr == true)
+      return h_vbr_frames;
+    else {
+      if ((framesize + 4 - h_padding_bit) == 0)
+        return 0;
+      else
+        return (streamsize / (framesize + 4 - h_padding_bit));
+    }
+  }
+
+  /**
+   * Returns the maximum number of frames in the stream.
+   * 
+   * @param streamsize
+   * @return number of frames
+   */
+  public int min_number_of_frames(int streamsize) // E.B
+  {
+    if (h_vbr == true)
+      return h_vbr_frames;
+    else {
+      if ((framesize + 5 - h_padding_bit) == 0)
+        return 0;
+      else
+        return (streamsize / (framesize + 5 - h_padding_bit));
+    }
+  }
+
+  /**
+   * Returns ms/frame.
+   * 
+   * @return milliseconds per frame
+   */
+  public float ms_per_frame() // E.B
+  {
+    if (h_vbr == true) {
+      double tpf = h_vbr_time_per_frame[layer()] / frequency();
+      if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF))
+        tpf /= 2;
+      return ((float) (tpf * 1000));
+    } else {
+      float ms_per_frame_array[][] =
+          { { 8.707483f, 8.0f, 12.0f }, { 26.12245f, 24.0f, 36.0f }, { 26.12245f, 24.0f, 36.0f } };
+      return (ms_per_frame_array[h_layer - 1][h_sample_frequency]);
+    }
+  }
+
+  /**
+   * Returns total ms.
+   * 
+   * @param streamsize
+   * @return total milliseconds
+   */
+  public float total_ms(int streamsize) // E.B
+  {
+    return (max_number_of_frames(streamsize) * ms_per_frame());
+  }
+
+  /**
+   * Returns synchronized header.
+   */
+  public int getSyncHeader() // E.B
+  {
+    return _headerstring;
+  }
+
+  // functions which return header informations as strings:
+  /**
+   * Return Layer version.
+   */
+  public String layer_string() {
+    switch (h_layer) {
+    case 1:
+      return "I";
+    case 2:
+      return "II";
+    case 3:
+      return "III";
+    }
+    return null;
+  }
+
+  // E.B -> private to public
+  @LOC("T")
+  public static final String bitrate_str[][][] = {
+      {
+          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+              "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",
+              "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },
+          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },
+          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } },
+
+      {
+          { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",
+              "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",
+              "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" },
+          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+              "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",
+              "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" },
+          { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
+              "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s",
+              "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } },
+      // SZD: MPEG2.5
+      {
+          { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
+              "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",
+              "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },
+          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },
+          { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",
+              "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",
+              "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, };
+
+  /**
+   * Return Bitrate.
+   * 
+   * @return bitrate in bps
+   */
+  public String bitrate_string() {
+    if (h_vbr == true) {
+      return Integer.toString(bitrate() / 1000) + " kb/s";
+    } else
+      return bitrate_str[h_version][h_layer - 1][h_bitrate_index];
+  }
+
+  /**
+   * Return Bitrate.
+   * 
+   * @return bitrate in bps and average bitrate for VBR header
+   */
+  public int bitrate() {
+    if (h_vbr == true) {
+      return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000;
+    } else
+      return bitrates[h_version][h_layer - 1][h_bitrate_index];
+  }
+
+  /**
+   * Return Instant Bitrate. Bitrate for VBR is not constant.
+   * 
+   * @return bitrate in bps
+   */
+  public int bitrate_instant() {
+    return bitrates[h_version][h_layer - 1][h_bitrate_index];
+  }
+
+  /**
+   * Returns Frequency
+   * 
+   * @return frequency string in kHz
+   */
+  public String sample_frequency_string() {
+    switch (h_sample_frequency) {
+    case THIRTYTWO:
+      if (h_version == MPEG1)
+        return "32 kHz";
+      else if (h_version == MPEG2_LSF)
+        return "16 kHz";
+      else
+        // SZD
+        return "8 kHz";
+    case FOURTYFOUR_POINT_ONE:
+      if (h_version == MPEG1)
+        return "44.1 kHz";
+      else if (h_version == MPEG2_LSF)
+        return "22.05 kHz";
+      else
+        // SZD
+        return "11.025 kHz";
+    case FOURTYEIGHT:
+      if (h_version == MPEG1)
+        return "48 kHz";
+      else if (h_version == MPEG2_LSF)
+        return "24 kHz";
+      else
+        // SZD
+        return "12 kHz";
+    }
+    return (null);
+  }
+
+  /**
+   * Returns Mode.
+   */
+  public String mode_string() {
+    switch (h_mode) {
+    case STEREO:
+      return "Stereo";
+    case JOINT_STEREO:
+      return "Joint stereo";
+    case DUAL_CHANNEL:
+      return "Dual channel";
+    case SINGLE_CHANNEL:
+      return "Single channel";
+    }
+    return null;
+  }
+
+  /**
+   * Returns Version.
+   * 
+   * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF
+   */
+  public String version_string() {
+    switch (h_version) {
+    case MPEG1:
+      return "MPEG-1";
+    case MPEG2_LSF:
+      return "MPEG-2 LSF";
+    case MPEG25_LSF: // SZD
+      return "MPEG-2.5 LSF";
+    }
+    return (null);
+  }
+
+  /**
+   * Returns the number of subbands in the current frame.
+   * 
+   * @return number of subbands
+   */
+  @RETURNLOC("OUT")
+  public int number_of_subbands() {
+    return h_number_of_subbands;
+  }
+
+  /**
+   * Returns Intensity Stereo. (Layer II joint stereo only). Returns the number
+   * of subbands which are in stereo mode, subbands above that limit are in
+   * intensity stereo mode.
+   * 
+   * @return intensity
+   */
+  @RETURNLOC("OUT")
+  public int intensity_stereo_bound() {
+    return h_intensity_stereo_bound;
+  }
+
+  public void setSideInfoBuf(SideInfoBuffer sib) {
+    this.sib = sib;
+  }
+
+  public void setBitReserve(BitReserve br) {
+    this.br = br;
+  }
+
+  public SideInfoBuffer getSideInfoBuffer() {
+    return sib;
+  }
+
+  public BitReserve getBitReserve() {
+    return br;
+  }
+
+}
index 055484bbb5577a2fffcfe1292399633b8172191d..31b71e2b8587abb7449e9e2294bf4d29d7fe5961 100644 (file)
@@ -106,6 +106,9 @@ final class LayerIIIDecoder implements FrameDecoder {
   @LOC("SBI")
   private int sfreq;
 
+  private int part2_start;
+
+
   /**
    * Constructor.
    */
@@ -329,7 +332,7 @@ final class LayerIIIDecoder implements FrameDecoder {
           get_LSF_scale_factors(ch, gr); // no need to care from this side
 
         // here, decoding the compressed audio data
-        huffman_decode(part2_start, ch, gr); // no need to care from this side
+        huffman_decode(ch, gr); // no need to care from this side
         // System.out.println("CheckSum HuffMan = " + CheckSumHuff);
         dequantize_sample(/* ro[ch], */ch, gr); // no need to care from this
                                                 // side
@@ -825,39 +828,29 @@ final class LayerIIIDecoder implements FrameDecoder {
   // @LOC("SI1")
   // int[] w = { 0 };
   @LOC("SI1")
-  int x = 0;
+  int x[] = { 0 };
   @LOC("SI1")
-  int y = 0;
+  int y[] = { 0 };
   @LOC("SI1")
-  int v = 0;
+  int v[] = { 0 };
   @LOC("SI1")
-  int w = 0;
-
-  // @LATTICE("H<I,I<R,R<B1,B1<B,B<THIS,THIS<IN,I*,THISLOC=THIS,GLOBALLOC=IN")
-  @LATTICE("BUF<THIS,BUF*,R,B,B1,H,I,THIS<IN,I*,THISLOC=THIS,GLOBALLOC=THIS")
-  private void huffman_decode(@LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int part2_start,
-      @LOC("THIS,LayerIIIDecoder.CH0") int ch, @LOC("THIS,LayerIIIDecoder.CH0") int gr) {
+  int w[] = { 0 };
 
-    // @LOC("THIS,LayerIIIDecoder.IS1D") int x;
-    // @LOC("THIS,LayerIIIDecoder.IS1D") int y;
-    // @LOC("THIS,LayerIIIDecoder.IS1D") int v;
-    // @LOC("THIS,LayerIIIDecoder.IS1D") int w;
+  private void huffman_decode(int ch, int gr) {
+    x[0] = 0;
+    y[0] = 0;
+    v[0] = 0;
+    w[0] = 0;
 
-    x = 0;
-    y = 0;
-    v = 0;
-    w = 0;
+    int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length;
+    int num_bits;
+    int region1Start;
+    int region2Start;
+    int index;
 
-    @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int part2_3_end =
-        part2_start + si.ch[ch].gr[gr].part2_3_length;
+    int buf, buf1;
 
-    @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int num_bits;
-    @LOC("THIS,LayerIIIDecoder.SI1") int region1Start;
-    @LOC("THIS,LayerIIIDecoder.SI1") int region2Start;
-    @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int index;
-
-    @LOC("THIS,LayerIIIDecoder.SI1") int buf;
-    @LOC("THIS,LayerIIIDecoder.SI1") int buf1;
+    huffcodetab h;
 
     // Find region boundary for short block case
 
@@ -865,8 +858,8 @@ final class LayerIIIDecoder implements FrameDecoder {
 
       // Region2.
       // MS: Extrahandling for 8KHZ
-      region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ =
-                                             // 72
+      region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case
+                                             // 8KHZ = 72
       region2Start = 576; // No Region2 for short block case
 
     } else { // Find region boundary for long block case
@@ -874,72 +867,47 @@ final class LayerIIIDecoder implements FrameDecoder {
       buf = si.ch[ch].gr[gr].region0_count + 1;
       buf1 = buf + si.ch[ch].gr[gr].region1_count + 1;
 
-      if (buf1 > sfBandIndex[sfreq].l.length - 1) {
+      if (buf1 > sfBandIndex[sfreq].l.length - 1)
         buf1 = sfBandIndex[sfreq].l.length - 1;
-      }
 
       region1Start = sfBandIndex[sfreq].l[buf];
       region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */
     }
 
     index = 0;
-    @LOC("THIS,LayerIIIDecoder.SI1") int h;
     // Read bigvalues area
-    for (@LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i +=
-        2) {
-      if (i < region1Start) {
-        // huffcodetab.huffman_decoder(h, x, y, v, w, br);
-        h = si.ch[ch].gr[gr].table_select[0];
-      } else if (i < region2Start) {
-        h = si.ch[ch].gr[gr].table_select[1];
-        // h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
-      } else {
-        h = si.ch[ch].gr[gr].table_select[2];
-        // h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
-      }
-
-      // @LOC("THIS,LayerIIIDecoder.SI2") HuffData huffData =
-      // huffcodetab.huffman_decoder(h, new HuffData(x, y, v, w, br));
-      // x = huffData.x;
-      // y = huffData.y;
-      // v = huffData.v;
-      // w = huffData.w;
-      // br = huffData.br;
-      huffcodetab_huffman_decoder(h);
+    for (int i = 0; i < (si.ch[ch].gr[gr].big_values << 1); i += 2) {
+      if (i < region1Start)
+        h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[0]];
+      else if (i < region2Start)
+        h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
+      else
+        h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
 
+      huffcodetab.huffman_decoder(h, x, y, v, w, br);
       // if (index >= is_1d.length)
       // System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length);
 
-      is_1d[index++] = x;
-      is_1d[index++] = y;
+      is_1d[index++] = x[0];
+      is_1d[index++] = y[0];
 
-      CheckSumHuff = CheckSumHuff + x + y;
+      CheckSumHuff = CheckSumHuff + x[0] + y[0];
       // System.out.println("x = "+x[0]+" y = "+y[0]);
     }
 
     // Read count1 area
-    // h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32];
+    h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select + 32];
     num_bits = br.hsstell();
 
     while ((num_bits < part2_3_end) && (index < 576)) {
 
-      // huffcodetab.huffman_decoder(h, x, y, v, w, br);
-      // @LOC("I") HuffData huffData2 =
-      // huffcodetab.huffman_decoder(si.ch[ch].gr[gr].count1table_select + 32,
-      // new HuffData(x, y,
-      // v, w, br));
-      // x = huffData2.x;
-      // y = huffData2.y;
-      // v = huffData2.v;
-      // w = huffData2.w;
-      // br = huffData2.br;
-      huffcodetab_huffman_decoder(h);
-
-      is_1d[index++] = v;
-      is_1d[index++] = w;
-      is_1d[index++] = x;
-      is_1d[index++] = y;
-      CheckSumHuff = CheckSumHuff + v + w + x + y;
+      huffcodetab.huffman_decoder(h, x, y, v, w, br);
+
+      is_1d[index++] = v[0];
+      is_1d[index++] = w[0];
+      is_1d[index++] = x[0];
+      is_1d[index++] = y[0];
+      CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0];
       // System.out.println("v = "+v[0]+" w = "+w[0]);
       // System.out.println("x = "+x[0]+" y = "+y[0]);
       num_bits = br.hsstell();
index 51f7eebf133c98ff57a7f213c9246df54f24d7e6..bd623697e0aea58ef3f4e724599371672d1d1719 100644 (file)
@@ -14,6 +14,7 @@ public class MP3Player {
     if (args.length == 1) {
       filename = args[0];
     }
+    play();
   }
 
   /**
@@ -34,9 +35,7 @@ public class MP3Player {
       player.play();
     } catch (IOException ex) {
       throw new JavaLayerException("Problem playing file " + filename, ex);
-    } catch (Exception ex) {
-      throw new JavaLayerException("Problem playing file " + filename, ex);
-    }
+    } 
   }
 
 }
\ No newline at end of file
index 75d5863b5e07491e711e22bbcef88f301a7777d1..14db695e2616bc5f207bab2cd4f2937ce24fe8cd 100644 (file)
@@ -1,3 +1,4 @@
+\r
 /*\r
  * 11/19/04            1.0 moved to LGPL.\r
  * 29/01/00            Initial version. mdm@techie.com\r
@@ -19,8 +20,6 @@
  */\r
 \r
 \r
-//import java.io.InputStream;\r
-\r
        \r
 /**\r
  * The <code>Player</code> class implements a simple player for playback\r
@@ -113,11 +112,13 @@ public class Player
        public boolean play(@LOC("IN") int frames) throws JavaLayerException\r
        {\r
            @LOC("IN") boolean ret = true;\r
-           \r
-            SSJAVA:\r
+         \r
+         \r
+           SSJAVA:\r
                while (frames-- > 0 && ret)\r
                {\r
-                        ret = decodeFrame();\r
+                 System.out.println("DECODE");\r
+                  ret = decodeFrame();\r
                }\r
                /*\r
                if (!ret)\r
@@ -219,7 +220,15 @@ public class Player
                                \r
                        // sample buffer set when decoder constructed\r
                        @LOC("O") SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);\r
-                                                                                                                                                                                                                                                                                                       \r
+                                                                                                               \r
+                 // eom debug\r
+               short[] outbuf = output.getBuffer();\r
+               for (int i = 0; i < outbuf.length; i++) {\r
+//                 bw.write(outbuf[i]);\r
+                 System.out.println(outbuf[i]);\r
+               }\r
+               //\r
+               \r
                        //synchronized (this)\r
                        //{\r
                        //      out = audio;\r
index caf5ca25d81337dec848f1bd9a0b9f497e569baf..7aec4ccc4042be457c8e686d7680605a112d01d3 100644 (file)
@@ -500,6 +500,121 @@ final class huffcodetab {
     VAL = null;\r
     treelen = TREELEN;\r
   }\r
+  \r
+  /**\r
+   * Do the huffman-decoding.\r
+   * note! for counta,countb -the 4 bit value is returned in y,\r
+   * discard x.\r
+   */\r
+  public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br)\r
+  {\r
+     // array of all huffcodtable headers\r
+     // 0..31 Huffman code table 0..31\r
+     // 32,33 count1-tables\r
+\r
+     int dmask = 1 << ((4 * 8) - 1);\r
+     int hs    = 4 * 8;\r
+     int level;\r
+     int point = 0;\r
+     int error = 1;\r
+     level = dmask;\r
+\r
+     if (h.val == null) return 2;\r
+\r
+     /* table 0 needs no bits */\r
+     if ( h.treelen == 0)\r
+      { \r
+        x[0] = y[0] = 0;\r
+        return 0;\r
+     }\r
+\r
+     /* Lookup in Huffman table. */\r
+\r
+      /*int bitsAvailable = 0;      \r
+      int bitIndex = 0;\r
+      \r
+      int bits[] = bitbuf;*/\r
+      do \r
+      {\r
+         if (h.val[point][0]==0)\r
+          {   /*end of tree*/\r
+             x[0] = h.val[point][1] >>> 4;\r
+             y[0] = h.val[point][1] & 0xf;\r
+             error = 0;\r
+             break;\r
+         }\r
+         \r
+          // hget1bit() is called thousands of times, and so needs to be\r
+          // ultra fast. \r
+          /*\r
+          if (bitIndex==bitsAvailable)\r
+          {\r
+               bitsAvailable = br.readBits(bits, 32);            \r
+               bitIndex = 0;\r
+          }\r
+          */\r
+          //if (bits[bitIndex++]!=0)\r
+          if (br.hget1bit()!=0)\r
+          {\r
+             while (h.val[point][1] >= MXOFF) point += h.val[point][1];\r
+             point += h.val[point][1];\r
+         }\r
+         else\r
+          {\r
+             while (h.val[point][0] >= MXOFF) point += h.val[point][0];\r
+             point += h.val[point][0];\r
+         }\r
+         level >>>= 1;\r
+          // MDM: ht[0] is always 0;\r
+      } while ((level !=0 )  || (point < 0 /*ht[0].treelen*/) );\r
+          \r
+          // put back any bits not consumed\r
+     /*   \r
+      int unread = (bitsAvailable-bitIndex);\r
+          if (unread>0)\r
+               br.rewindNbits(unread);\r
+      */\r
+       /* Process sign encodings for quadruples tables. */\r
+      // System.out.println(h.tablename);\r
+       if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3'))\r
+       {\r
+          v[0] = (y[0]>>3) & 1;\r
+          w[0] = (y[0]>>2) & 1;\r
+          x[0] = (y[0]>>1) & 1;\r
+          y[0] = y[0] & 1;\r
+\r
+         /* v, w, x and y are reversed in the bitstream.\r
+            switch them around to make test bistream work. */\r
+\r
+          if (v[0]!=0)\r
+            if (br.hget1bit() != 0) v[0] = -v[0];\r
+          if (w[0]!=0)\r
+            if (br.hget1bit() != 0) w[0] = -w[0];\r
+          if (x[0]!=0)\r
+            if (br.hget1bit() != 0) x[0] = -x[0];\r
+          if (y[0]!=0)\r
+            if (br.hget1bit() != 0) y[0] = -y[0];\r
+       }\r
+        else\r
+        {\r
+            // Process sign and escape encodings for dual tables.\r
+            // x and y are reversed in the test bitstream.\r
+            // Reverse x and y here to make test bitstream work.\r
+\r
+           if (h.linbits != 0)\r
+             if ((h.xlen-1) == x[0])\r
+               x[0] += br.hgetbits(h.linbits);\r
+            if (x[0] != 0)\r
+                 if (br.hget1bit() != 0) x[0] = -x[0];\r
+            if (h.linbits != 0)\r
+                if ((h.ylen-1) == y[0])\r
+                    y[0] += br.hgetbits(h.linbits);\r
+            if (y[0] != 0)\r
+                 if (br.hget1bit() != 0) y[0] = -y[0];\r
+        }\r
+        return error;\r
+  }\r
+  \r
 \r
   /**\r
    * Do the huffman-decoding. note! for counta,countb -the 4 bit value is\r
@@ -623,7 +738,7 @@ final class huffcodetab {
     return data;\r
 //    return error;\r
   }\r
-\r
+  \r
   public static void inithuff() {\r
 \r
     if (ht != null)\r