From: yeom Date: Mon, 15 Aug 2011 01:27:45 +0000 (+0000) Subject: changes. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=IRC.git;a=commitdiff_plain;h=3d3fdbcd196fc83cfc9a73cb8b5777c4b50c0621 changes. --- diff --git a/Robust/src/ClassLibrary/SSJava/BufferedInputStream.java b/Robust/src/ClassLibrary/SSJava/BufferedInputStream.java index ead2f26f..e1144a3f 100644 --- a/Robust/src/ClassLibrary/SSJava/BufferedInputStream.java +++ b/Robust/src/ClassLibrary/SSJava/BufferedInputStream.java @@ -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 FilterInputStream buffers input from an + * This subclass of FilterInputStream 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. *

- * 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 Integer.MAX_VALUE + * 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 Integer.MAX_VALUE *

- * Please note that this class does not properly handle character - * encodings. Consider using the BufferedReader class which - * does. - * + * Please note that this class does not properly handle character encodings. + * Consider using the BufferedReader class which does. + * * @author Aaron M. Renn (arenn@urbanophile.com) * @author Warren Levy (warrenl@cygnus.com) * @author Jeroen Frijters (jeroen@frijters.net) */ @LATTICE("BUFpos == count, the buffer is empty. + * The index of the next character that will by read from the buffer. When + * pos == count, the buffer is empty. */ - @LOC("C") protected int pos; + @LOC("C") + protected int pos; /** * The value of pos when the mark() 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 mark() before the mark can be discarded. - * After this may bytes are read, the reset() method - * may not be called successfully. + * This is the maximum number of bytes than can be read after a call to + * mark() before the mark can be discarded. After this may bytes + * are read, the reset() 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 BufferedInputStream 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 BufferedInputStream 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. *

- * 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 buf to null. - * - * @exception IOException If an error occurs. + * This method closes the underlying input stream and frees any resources + * associated with it. Sets buf to null. + * + * @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 reset() method. The parameter - * readlimit is the number of bytes that can be read from the - * stream after setting the mark before the mark becomes invalid. For - * example, if mark() is called with a read limit of 10, then - * when 11 bytes of data are read from the stream before the - * reset() method is called, then the mark is invalid and the - * stream object instance is not required to remember the mark. + * "reset" by calling the reset() method. The parameter + * readlimit is the number of bytes that can be read from the + * stream after setting the mark before the mark becomes invalid. For example, + * if mark() is called with a read limit of 10, then when 11 + * bytes of data are read from the stream before the reset() + * method is called, then the mark is invalid and the stream object instance + * is not required to remember the mark. *

- * 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 true to indicate that this class - * supports mark/reset functionality. - * + * This method returns true to indicate that this class supports + * mark/reset functionality. + * * @return true 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. *

* 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 off - * into the buffer and attempts to read len 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 off into + * the buffer and attempts to read len 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. *

* 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 off or - * len are negative, or when off + len - * is larger then the size of b, + * + * @exception IOException + * If an error occurs. + * @exception IndexOutOfBoundsException + * when off or len are negative, or + * when off + len is larger then the size of + * b, */ - 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 mark() - * 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. *

- * This method will throw an IOException if the number of bytes read from - * the stream since the call to mark() exceeds the mark limit - * passed when establishing the mark. - * - * @exception IOException If mark() was never called or more - * then marklimit bytes were read since the last - * call to mark() + * This method will throw an IOException if the number of bytes read from the + * stream since the call to mark() exceeds the mark limit passed + * when establishing the mark. + * + * @exception IOException + * If mark() was never called or more then + * marklimit bytes were read since the last call to + * mark() */ - 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 true when at least one additional byte was read - * into buf, false otherwise (at EOF). + * + * @return true when at least one additional byte was read into + * buf, false 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 index 00000000..e8da9fec --- /dev/null +++ b/Robust/src/ClassLibrary/SSJava/Enumeration.java @@ -0,0 +1,13 @@ +public class Enumeration { + + public Enumeration() { + } + + public boolean hasMoreElements() { + return false; + } + + public Object nextElement() { + return null; + } +} diff --git a/Robust/src/ClassLibrary/SSJava/FileInputStream.java b/Robust/src/ClassLibrary/SSJava/FileInputStream.java index c5b608dc..be3c76f4 100644 --- a/Robust/src/ClassLibrary/SSJava/FileInputStream.java +++ b/Robust/src/ClassLibrary/SSJava/FileInputStream.java @@ -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 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); } } diff --git a/Robust/src/ClassLibrary/SSJava/FilterInputStream.java b/Robust/src/ClassLibrary/SSJava/FilterInputStream.java index 0508e4bd..38550de6 100644 --- a/Robust/src/ClassLibrary/SSJava/FilterInputStream.java +++ b/Robust/src/ClassLibrary/SSJava/FilterInputStream.java @@ -86,7 +86,6 @@ public class FilterInputStream extends InputStream protected FilterInputStream(@LOC("IN") InputStream in) { this.in = in; - in = null; } /** diff --git a/Robust/src/ClassLibrary/SSJava/PushbackInputStream.java b/Robust/src/ClassLibrary/SSJava/PushbackInputStream.java index c9910732..904ab203 100644 --- a/Robust/src/ClassLibrary/SSJava/PushbackInputStream.java +++ b/Robust/src/ClassLibrary/SSJava/PushbackInputStream.java @@ -38,64 +38,67 @@ exception statement from your version. */ //package java.io; /** - * This subclass of FilterInputStream 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. - *

- * The default pushback buffer size one byte, but this can be overridden - * by the creator of the stream. - *

- * - * @author Aaron M. Renn (arenn@urbanophile.com) - * @author Warren Levy (warrenl@cygnus.com) - */ + * This subclass of FilterInputStream 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. + *

+ * The default pushback buffer size one byte, but this can be overridden by the + * creator of the stream. + *

+ * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Warren Levy (warrenl@cygnus.com) + */ @LATTICE("INbuf[buf.length - 1] to buf[0]. Thus when - * pos is 0 the buffer is full and buf.length 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 + * buf[buf.length - 1] to buf[0]. Thus when + * pos is 0 the buffer is full and buf.length when * it is empty */ - @LOC("POS") protected int pos; + @LOC("POS") + protected int pos; /** - * This method initializes a PushbackInputStream to - * read from the specified subordinate InputStream - * with a default pushback buffer size of 1. - * - * @param in The subordinate stream to read from + * This method initializes a PushbackInputStream to read from the + * specified subordinate InputStream 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 PushbackInputStream to - * read from the specified subordinate InputStream with - * the specified buffer size - * - * @param in The subordinate InputStream to read from - * @param size The pushback buffer size to use + * This method initializes a PushbackInputStream to read from the + * specified subordinate InputStream with the specified buffer + * size + * + * @param in + * The subordinate InputStream 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. *

- * 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 false to indicate that it does - * not support mark/reset functionality. - * - * @return This method returns false to indicate that - * this class does not support mark/reset functionality + * This method returns false to indicate that it does not support + * mark/reset functionality. + * + * @return This method returns false 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. *

* 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 - * offset into the buffer and attempts to read - * len 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 offset into the + * buffer and attempts to read len 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. - *

+ *

* This method will block until some data can be 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 - * + * 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("OUT0"); + 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. *

* If the pushback buffer is full, this method throws an exception. *

- * The argument to this method is an int. 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 int. 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 - * b[0] followed by b[1], 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 b[0] + * followed by b[1], etc. *

- * 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 b[offset] to - * b[offset + len] are pushed in reverse order so that - * the next byte read from the stream after this operation will be - * b[offset] followed by b[offset + 1], - * etc. + * This method pushed back bytes from the passed in array into the pushback + * buffer. The bytes from b[offset] to + * b[offset + len] are pushed in reverse order so that the next + * byte read from the stream after this operation will be + * b[offset] followed by b[offset + 1], etc. *

- * 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. *

* This method first discards bytes from the buffer, then calls the - * skip method on the underlying InputStream to - * skip additional bytes if necessary. - * - * @param n The requested number of bytes to skip - * + * skip method on the underlying InputStream 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; } diff --git a/Robust/src/ClassLibrary/SSJava/String.java b/Robust/src/ClassLibrary/SSJava/String.java index 4fcfb6cb..ddacb966 100644 --- a/Robust/src/ClassLibrary/SSJava/String.java +++ b/Robust/src/ClassLibrary/SSJava/String.java @@ -1,20 +1,29 @@ -import Object; -import String; -import StringBuffer; -import System; +import Vector; -@LATTICE("V(str.length-offset)) length=str.length-offset; char charstr[]=new char[length]; for(int i=0; i(str.length-offset)) + length=str.length-offset; + char charstr[]=new char[length]; + for(int i=0; ithis.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; i0; 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='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='A'&&x<='Z') { + x=(char) ((x-'A')+'a'); + } + buffer[i]=x; } - int len = srcEnd - srcBegin; - int j = dstBegin; - for(int i=srcBegin; ifromIndex) + 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) || (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='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 0) || (len < count))?substring(st, len):this; + } + + public boolean matches(String regex) { + System.println("String.matches() is not fully supported"); + return this.equals(regex); + } } diff --git a/Robust/src/ClassLibrary/SSJava/System.java b/Robust/src/ClassLibrary/SSJava/System.java index 4c773f08..3d18547e 100644 --- a/Robust/src/ClassLibrary/SSJava/System.java +++ b/Robust/src/ClassLibrary/SSJava/System.java @@ -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 index 00000000..adcd4efa --- /dev/null +++ b/Robust/src/ClassLibrary/SSJava/Vector.java @@ -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) { + System.printString("Illegal Vector.elementAt\n"); + System.exit(-1); + return null; + } + return array[index]; + } + + public void setElementAt(Object obj, int index) { + if (index array.length) { + int newsize; + if (capacityIncrement<=0) + newsize=array.length*2; + else + newsize=array.length+capacityIncrement; + if (newsizesize) { + 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>> 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(); - } - } 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 0) && (cf == lf)) { offset[cf] = - * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; } - */ - } - } - - /** - * 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; - } - -} +/* + * 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>> 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 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; + } + +} diff --git a/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java b/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java index 055484bb..31b71e2b 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java +++ b/Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java @@ -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 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(); diff --git a/Robust/src/Tests/ssJava/mp3decoder/MP3Player.java b/Robust/src/Tests/ssJava/mp3decoder/MP3Player.java index 51f7eebf..bd623697 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/MP3Player.java +++ b/Robust/src/Tests/ssJava/mp3decoder/MP3Player.java @@ -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 diff --git a/Robust/src/Tests/ssJava/mp3decoder/Player.java b/Robust/src/Tests/ssJava/mp3decoder/Player.java index 75d5863b..14db695e 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/Player.java +++ b/Robust/src/Tests/ssJava/mp3decoder/Player.java @@ -1,3 +1,4 @@ + /* * 11/19/04 1.0 moved to LGPL. * 29/01/00 Initial version. mdm@techie.com @@ -19,8 +20,6 @@ */ -//import java.io.InputStream; - /** * The Player class implements a simple player for playback @@ -113,11 +112,13 @@ public class Player public boolean play(@LOC("IN") int frames) throws JavaLayerException { @LOC("IN") boolean ret = true; - - SSJAVA: + + + SSJAVA: while (frames-- > 0 && ret) { - ret = decodeFrame(); + System.out.println("DECODE"); + ret = decodeFrame(); } /* if (!ret) @@ -219,7 +220,15 @@ public class Player // sample buffer set when decoder constructed @LOC("O") SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream); - + + // eom debug + short[] outbuf = output.getBuffer(); + for (int i = 0; i < outbuf.length; i++) { +// bw.write(outbuf[i]); + System.out.println(outbuf[i]); + } + // + //synchronized (this) //{ // out = audio; diff --git a/Robust/src/Tests/ssJava/mp3decoder/huffcodetab.java b/Robust/src/Tests/ssJava/mp3decoder/huffcodetab.java index caf5ca25..7aec4ccc 100644 --- a/Robust/src/Tests/ssJava/mp3decoder/huffcodetab.java +++ b/Robust/src/Tests/ssJava/mp3decoder/huffcodetab.java @@ -500,6 +500,121 @@ final class huffcodetab { VAL = null; treelen = TREELEN; } + + /** + * Do the huffman-decoding. + * note! for counta,countb -the 4 bit value is returned in y, + * discard x. + */ + public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br) + { + // array of all huffcodtable headers + // 0..31 Huffman code table 0..31 + // 32,33 count1-tables + + int dmask = 1 << ((4 * 8) - 1); + int hs = 4 * 8; + int level; + int point = 0; + int error = 1; + level = dmask; + + if (h.val == null) return 2; + + /* table 0 needs no bits */ + if ( h.treelen == 0) + { + x[0] = y[0] = 0; + return 0; + } + + /* Lookup in Huffman table. */ + + /*int bitsAvailable = 0; + int bitIndex = 0; + + int bits[] = bitbuf;*/ + do + { + if (h.val[point][0]==0) + { /*end of tree*/ + x[0] = h.val[point][1] >>> 4; + y[0] = h.val[point][1] & 0xf; + error = 0; + break; + } + + // hget1bit() is called thousands of times, and so needs to be + // ultra fast. + /* + if (bitIndex==bitsAvailable) + { + bitsAvailable = br.readBits(bits, 32); + bitIndex = 0; + } + */ + //if (bits[bitIndex++]!=0) + if (br.hget1bit()!=0) + { + while (h.val[point][1] >= MXOFF) point += h.val[point][1]; + point += h.val[point][1]; + } + else + { + while (h.val[point][0] >= MXOFF) point += h.val[point][0]; + point += h.val[point][0]; + } + level >>>= 1; + // MDM: ht[0] is always 0; + } while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) ); + + // put back any bits not consumed + /* + int unread = (bitsAvailable-bitIndex); + if (unread>0) + br.rewindNbits(unread); + */ + /* Process sign encodings for quadruples tables. */ + // System.out.println(h.tablename); + if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3')) + { + v[0] = (y[0]>>3) & 1; + w[0] = (y[0]>>2) & 1; + x[0] = (y[0]>>1) & 1; + y[0] = y[0] & 1; + + /* v, w, x and y are reversed in the bitstream. + switch them around to make test bistream work. */ + + if (v[0]!=0) + if (br.hget1bit() != 0) v[0] = -v[0]; + if (w[0]!=0) + if (br.hget1bit() != 0) w[0] = -w[0]; + if (x[0]!=0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (y[0]!=0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + else + { + // Process sign and escape encodings for dual tables. + // x and y are reversed in the test bitstream. + // Reverse x and y here to make test bitstream work. + + if (h.linbits != 0) + if ((h.xlen-1) == x[0]) + x[0] += br.hgetbits(h.linbits); + if (x[0] != 0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (h.linbits != 0) + if ((h.ylen-1) == y[0]) + y[0] += br.hgetbits(h.linbits); + if (y[0] != 0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + return error; + } + /** * Do the huffman-decoding. note! for counta,countb -the 4 bit value is @@ -623,7 +738,7 @@ final class huffcodetab { return data; // return error; } - + public static void inithuff() { if (ht != null)