diff options
Diffstat (limited to 'gnu')
40 files changed, 3568 insertions, 1044 deletions
diff --git a/gnu/CORBA/CDR/BigEndianInputStream.java b/gnu/CORBA/CDR/BigEndianInputStream.java new file mode 100644 index 000000000..8218b0347 --- /dev/null +++ b/gnu/CORBA/CDR/BigEndianInputStream.java @@ -0,0 +1,61 @@ +/* BigEndianInputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.DataInputStream; +import java.io.InputStream; + +/** + * As java uses Big Endian by default, this class is directly derived + * form DataInputStream. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class BigEndianInputStream + extends DataInputStream + implements abstractDataInputStream +{ + /** + * Delegates to the parent constructor. + */ + public BigEndianInputStream(InputStream in) + { + super(in); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/BigEndianOutputStream.java b/gnu/CORBA/CDR/BigEndianOutputStream.java new file mode 100644 index 000000000..fe80bbc4f --- /dev/null +++ b/gnu/CORBA/CDR/BigEndianOutputStream.java @@ -0,0 +1,62 @@ +/* BigEndianOutputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.DataOutputStream; +import java.io.OutputStream; + +/** + * A stream to read the data in Big Endian format. This class is + * directly derived from DataOutputStream that uses the Big + * Endian. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class BigEndianOutputStream + extends DataOutputStream + implements abstractDataOutputStream +{ + /** + * Delegate functionality to the parent constructor. + */ + public BigEndianOutputStream(OutputStream out) + { + super(out); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/LittleEndianInputStream.java b/gnu/CORBA/CDR/LittleEndianInputStream.java new file mode 100644 index 000000000..412608b0b --- /dev/null +++ b/gnu/CORBA/CDR/LittleEndianInputStream.java @@ -0,0 +1,633 @@ +/* LittleEndianInputStream.java -- + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.DataInput; +import java.io.EOFException; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; + +/** + * This class reads data in the Little Endian format. It reuses + * code from GNU Classpath DataInputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class LittleEndianInputStream + extends FilterInputStream + implements abstractDataInputStream +{ + // Byte buffer, used to make primitive read calls more efficient. + byte[] buf = new byte[ 8 ]; + + /** + * This constructor initializes a new <code>DataInputStream</code> + * to read from the specified subordinate stream. + * + * @param in The subordinate <code>InputStream</code> to read from + */ + public LittleEndianInputStream(InputStream in) + { + super(in); + } + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to fill the buffer completely, but + * may return a short count if there is insufficient data remaining to be + * read to fill the buffer. + * + * @param b The buffer into which bytes will be read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + public int read(byte[] b) + throws IOException + { + return in.read(b, 0, b.length); + } + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to read <code>len</code> bytes and + * will start storing them at position <code>off</code> into the buffer. + * This method can return a short count if there is insufficient data + * remaining to be read to complete the desired read length. + * + * @param b The buffer into which bytes will be read. + * @param off The offset into the buffer 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 reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + public int read(byte[] b, int off, int len) + throws IOException + { + return in.read(b, off, len); + } + + /** + * This method reads a Java boolean value from an input stream. It does + * so by reading a single byte of data. If that byte is zero, then the + * value returned is <code>false</code>. If the byte is non-zero, then + * the value returned is <code>true</code>. + * <p> + * This method can read a <code>boolean</code> written by an object + * implementing the <code>writeBoolean()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>boolean</code> value read + * + * @exception EOFException If end of file is reached before reading + * the boolean + * @exception IOException If any other error occurs + * + * @see DataOutput#writeBoolean + */ + public boolean readBoolean() + throws IOException + { + return convertToBoolean(in.read()); + } + + /** + * This method reads a Java byte value from an input stream. The value + * is in the range of -128 to 127. + * <p> + * This method can read a <code>byte</code> written by an object + * implementing the <code>writeByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>byte</code> value read + * + * @exception EOFException If end of file is reached before reading the byte + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + public byte readByte() + throws IOException + { + return convertToByte(in.read()); + } + + /** + * This method reads a Java <code>char</code> value from an input stream. + * It operates by reading two bytes from the stream and converting them to + * a single 16-bit Java <code>char</code>. The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>char</code> in + * the following manner: + * <p> + * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code> + * <p> + * This method can read a <code>char</code> written by an object + * implementing the <code>writeChar()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>char</code> value read + * + * @exception EOFException If end of file is reached before reading the char + * @exception IOException If any other error occurs + * + * @see DataOutput#writeChar + */ + public char readChar() + throws IOException + { + readFully(buf, 0, 2); + return convertToChar(buf); + } + + /** + * This method reads a Java double value from an input stream. It operates + * by first reading a <code>long</code> value from the stream by calling the + * <code>readLong()</code> method in this interface, then converts + * that <code>long</code> to a <code>double</code> using the + * <code>longBitsToDouble</code> method in the class + * <code>java.lang.Double</code> + * <p> + * This method can read a <code>double</code> written by an object + * implementing the <code>writeDouble()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>double</code> value read + * + * @exception EOFException If end of file is reached before reading + * the double + * @exception IOException If any other error occurs + * + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble + */ + public double readDouble() + throws IOException + { + return Double.longBitsToDouble(readLong()); + } + + /** + * This method reads a Java float value from an input stream. It + * operates by first reading an <code>int</code> value from the + * stream by calling the <code>readInt()</code> method in this + * interface, then converts that <code>int</code> to a + * <code>float</code> using the <code>intBitsToFloat</code> method + * in the class <code>java.lang.Float</code> + * <p> + * This method can read a <code>float</code> written by an object + * implementing the <code>writeFloat()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>float</code> value read + * + * @exception EOFException If end of file is reached before reading the float + * @exception IOException If any other error occurs + * + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat + */ + public float readFloat() + throws IOException + { + return Float.intBitsToFloat(readInt()); + } + + /** + * This method reads raw bytes into the passed array until the array is + * full. Note that this method blocks until the data is available and + * throws an exception if there is not enough data left in the stream to + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. + * + * @param b The buffer into which to read the data + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + public void readFully(byte[] b) + throws IOException + { + readFully(b, 0, b.length); + } + + /** + * This method reads raw bytes into the passed array <code>buf</code> + * starting + * <code>offset</code> bytes into the buffer. The number of bytes read + * will be + * exactly <code>len</code>. Note that this method blocks until the data is + * available and throws an exception if there is not enough data left in + * the stream to read <code>len</code> bytes. Note also that zero length + * buffers are permitted. In this case, the method will return immediately + * without reading any bytes from the stream. + * + * @param buf The buffer into which to read the data + * @param offset The offset into the buffer to start storing data + * @param len The number of bytes to read into the buffer + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + public void readFully(byte[] buf, int offset, int len) + throws IOException + { + if (len < 0) + throw new IndexOutOfBoundsException("Negative length: " + len); + + while (len > 0) + { + // in.read will block until some data is available. + int numread = in.read(buf, offset, len); + if (numread < 0) + throw new EOFException(); + len -= numread; + offset += numread; + } + } + + /** + * This method reads a Java <code>int</code> value from an input stream + * It operates by reading four bytes from the stream and converting them to + * a single Java <code>int</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte4</code> represent + * the first four bytes read from the stream, they will be + * transformed to an <code>int</code> in the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code> + * <p> + * The value returned is in the range of -2147483648 to 2147483647. + * <p> + * This method can read an <code>int</code> written by an object + * implementing the <code>writeInt()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>int</code> value read + * + * @exception EOFException If end of file is reached before reading the int + * @exception IOException If any other error occurs + * + * @see DataOutput#writeInt + */ + public int readInt() + throws IOException + { + readFully(buf, 0, 4); + return convertToInt(buf); + } + + /** + * This method reads the next line of text data from an input + * stream. It operates by reading bytes and converting those bytes + * to <code>char</code> values by treating the byte read as the low + * eight bits of the <code>char</code> and using 0 as the high eight + * bits. Because of this, it does not support the full 16-bit + * Unicode character set. + * <p> + * The reading of bytes ends when either the end of file or a line + * terminator is encountered. The bytes read are then returned as a + * <code>String</code> A line terminator is a byte sequence + * consisting of either <code>\r</code>, <code>\n</code> or + * <code>\r\n</code>. These termination charaters are discarded and + * are not returned as part of the string. + * <p> + * This method can read data that was written by an object implementing the + * <code>writeLine()</code> method in <code>DataOutput</code>. + * + * @return The line read as a <code>String</code> + * + * @exception IOException If an error occurs + * + * @see DataOutput + * + * @deprecated + */ + public String readLine() + throws IOException + { + StringBuffer strb = new StringBuffer(); + + while (true) + { + int c = in.read(); + if (c == -1) // got an EOF + return strb.length() > 0 ? strb.toString() : null; + if (c == '\r') + { + int next_c = in.read(); + if (next_c != '\n' && next_c != -1) + { + if (!(in instanceof PushbackInputStream)) + in = new PushbackInputStream(in); + ((PushbackInputStream) in).unread(next_c); + } + break; + } + if (c == '\n') + break; + strb.append((char) c); + } + + return strb.length() > 0 ? strb.toString() : ""; + } + + /** + * This method reads a Java <code>long</code> value from an input stream + * It operates by reading eight bytes from the stream and converting them to + * a single Java <code>long</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte8</code> represent + * the first eight bytes read from the stream, they will be + * transformed to an <code>long</code> in the following manner: + * <p> + * <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) + * </code> + * <p> + * The value returned is in the range of -9223372036854775808 to + * 9223372036854775807. + * <p> + * This method can read an <code>long</code> written by an object + * implementing the <code>writeLong()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>long</code> value read + * + * @exception EOFException If end of file is reached before reading the long + * @exception IOException If any other error occurs + * + * @see DataOutput#writeLong + */ + public long readLong() + throws IOException + { + readFully(buf, 0, 8); + return convertToLong(buf); + } + + /** + * This method reads a signed 16-bit value into a Java in from the + * stream. It operates by reading two bytes from the stream and + * converting them to a single 16-bit Java <code>short</code>. The + * two bytes are stored most significant byte first (i.e., "big + * endian") regardless of the native host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>short</code>. in + * the following manner: + * <p> + * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of -32768 to 32767. + * <p> + * This method can read a <code>short</code> written by an object + * implementing the <code>writeShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>short</code> value read + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + public short readShort() + throws IOException + { + readFully(buf, 0, 2); + return convertToShort(buf); + } + + /** + * This method reads 8 unsigned bits into a Java <code>int</code> + * value from the stream. The value returned is in the range of 0 to + * 255. + * <p> + * This method can read an unsigned byte written by an object + * implementing the <code>writeUnsignedByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned bytes value read as a Java <code>int</code>. + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + public int readUnsignedByte() + throws IOException + { + return convertToUnsignedByte(in.read()); + } + + /** + * This method reads 16 unsigned bits into a Java int value from the stream. + * It operates by reading two bytes from the stream and converting them to + * a single Java <code>int</code> The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to an <code>int</code> in + * the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of 0 to 65535. + * <p> + * This method can read an unsigned short written by an object + * implementing the <code>writeUnsignedShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned short value read as a Java <code>int</code> + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + public int readUnsignedShort() + throws IOException + { + readFully(buf, 0, 2); + return convertToUnsignedShort(buf); + } + + /** + * This method attempts to skip and discard the specified number of bytes + * in the input stream. It may actually skip fewer bytes than requested. + * This method will not skip any bytes if passed a negative number of bytes + * to skip. + * + * @param n The requested number of bytes to skip. + * + * @return The requested number of bytes to skip. + * + * @exception IOException If an error occurs. + * @specnote The JDK docs claim that this returns the number of bytes + * actually skipped. The JCL claims that this method can throw an + * EOFException. Neither of these appear to be true in the JDK 1.3's + * implementation. This tries to implement the actual JDK behaviour. + */ + public int skipBytes(int n) + throws IOException + { + if (n <= 0) + return 0; + try + { + return (int) in.skip(n); + } + catch (EOFException x) + { + // do nothing. + } + return n; + } + + protected boolean convertToBoolean(int b) + throws EOFException + { + if (b < 0) + throw new EOFException(); + + return (b != 0); + } + + protected byte convertToByte(int i) + throws EOFException + { + if (i < 0) + throw new EOFException(); + + return (byte) i; + } + + protected int convertToUnsignedByte(int i) + throws EOFException + { + if (i < 0) + throw new EOFException(); + + return (i & 0xFF); + } + + /** + * Less significant byte first. + */ + protected char convertToChar(byte[] buf) + { + return (char) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected short convertToShort(byte[] buf) + { + return (short) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected int convertToUnsignedShort(byte[] buf) + { + return (((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected int convertToInt(byte[] buf) + { + return (((buf [ 3 ] & 0xff) << 24) | ((buf [ 2 ] & 0xff) << 16) | + ((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected long convertToLong(byte[] buf) + { + return (((long) (buf [ 7 ] & 0xff) << 56) | + ((long) (buf [ 6 ] & 0xff) << 48) | + ((long) (buf [ 5 ] & 0xff) << 40) | + ((long) (buf [ 4 ] & 0xff) << 32) | + ((long) (buf [ 3 ] & 0xff) << 24) | + ((long) (buf [ 2 ] & 0xff) << 16) | + ((long) (buf [ 1 ] & 0xff) << 8) | ((long) (buf [ 0 ] & 0xff))); + } + + /** + * This should never be called. + * + * @throws InternalError, always. + */ + public String readUTF() + { + throw new InternalError(); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/LittleEndianOutputStream.java b/gnu/CORBA/CDR/LittleEndianOutputStream.java new file mode 100644 index 000000000..7ff8263db --- /dev/null +++ b/gnu/CORBA/CDR/LittleEndianOutputStream.java @@ -0,0 +1,253 @@ +/* LittleEndianOutputStream.java -- + Copyright (C) 1998, 2001, 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * This stream writes data in the Little Endian format + * (less significant byte first). This is opposite to the + * usual data presentation in java platform. + * + * This class reuses code from DataOutputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Tom Tromey (tromey@cygnus.com) + */ +public class LittleEndianOutputStream + extends FilterOutputStream + implements abstractDataOutputStream +{ + /** + * This method initializes an instance of <code>DataOutputStream</code> to + * write its data to the specified underlying <code>OutputStream</code> + * + * @param out The subordinate <code>OutputStream</code> to which this + * object will write + */ + public LittleEndianOutputStream(OutputStream out) + { + super(out); + } + + /** + * This method flushes any unwritten bytes to the underlying stream. + * + * @exception IOException If an error occurs. + */ + public void flush() + throws IOException + { + out.flush(); + } + + /** + * This method writes the specified byte (passed as an <code>int</code>) + * to the underlying output stream. + * + * @param value The <code>byte</code> to write, passed as an <code>int</code>. + * + * @exception IOException If an error occurs. + */ + public synchronized void write(int value) + throws IOException + { + out.write(value); + } + + /** + * This method writes <code>len</code> bytes from the specified byte array + * <code>buf</code> starting at position <code>offset</code> into the + * buffer to the underlying output stream. + * + * @param buf The byte array to write from. + * @param offset The index into the byte array to start writing from. + * @param len The number of bytes to write. + * + * @exception IOException If an error occurs. + */ + public synchronized void write(byte[] buf, int offset, int len) + throws IOException + { + out.write(buf, offset, len); + } + + /** + * This method writes a Java boolean value to an output stream. If + * <code>value</code> is <code>true</code>, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the <code>readBoolean</code> + * method in <code>DataInput</code>. + * + * @param value The <code>boolean</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see DataInput#readBoolean + */ + public void writeBoolean(boolean value) + throws IOException + { + write(value ? 1 : 0); + } + + /** + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * <code>int</code> value passed. + * + * The value written can be read using the <code>readByte</code> or + * <code>readUnsignedByte</code> methods in <code>DataInput</code>. + * + * @param value The <code>byte</code> to write to the stream, passed as + * the low eight bits of an <code>int</code>. + * + * @exception IOException If an error occurs + * + * @see DataInput#readByte + * @see DataInput#readUnsignedByte + */ + public void writeByte(int value) + throws IOException + { + write(value & 0xff); + } + + /** + * This method writes a Java short value to an output stream. + * + * @param value The <code>short</code> value to write to the stream, + * passed as an <code>int</code>. + * + * @exception IOException If an error occurs + */ + public synchronized void writeShort(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + } + + /** + * Writes char in Little Endian. + */ + public synchronized void writeChar(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + } + + /** + * Writes int in Little Endian. + */ + public synchronized void writeInt(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + write((byte) (0xff & (value >> 16))); + write((byte) (0xff & (value >> 24))); + } + + /** + * Writes long in Little Endian. + */ + public synchronized void writeLong(long value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + write((byte) (0xff & (value >> 16))); + write((byte) (0xff & (value >> 24))); + write((byte) (0xff & (value >> 32))); + write((byte) (0xff & (value >> 40))); + write((byte) (0xff & (value >> 48))); + write((byte) (0xff & (value >> 56))); + } + + /** + * This method writes a Java <code>float</code> value to the stream. This + * value is written by first calling the method + * <code>Float.floatToIntBits</code> + * to retrieve an <code>int</code> representing the floating point number, + * then writing this <code>int</code> value to the stream exactly the same + * as the <code>writeInt()</code> method does. + * + * @param value The <code>float</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see writeInt + * @see DataInput#readFloat + * @see Float#floatToIntBits + */ + public void writeFloat(float value) + throws IOException + { + writeInt(Float.floatToIntBits(value)); + } + + /** + * This method writes a Java <code>double</code> value to the stream. This + * value is written by first calling the method + * <code>Double.doubleToLongBits</code> + * to retrieve an <code>long</code> representing the floating point number, + * then writing this <code>long</code> value to the stream exactly the same + * as the <code>writeLong()</code> method does. + * + * @param value The <code>double</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see writeLong + * @see DataInput#readDouble + * @see Double#doubleToLongBits + */ + public void writeDouble(double value) + throws IOException + { + writeLong(Double.doubleToLongBits(value)); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/abstractDataInputStream.java b/gnu/CORBA/CDR/abstractDataInputStream.java new file mode 100644 index 000000000..4da48bb27 --- /dev/null +++ b/gnu/CORBA/CDR/abstractDataInputStream.java @@ -0,0 +1,392 @@ +/* abstractDataInputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * Some data input stream that can be either Big or + * Little Endian. + * + * This class reuses code from GNU Classpath DataInputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface abstractDataInputStream +{ + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to fill the buffer completely, but + * may return a short count if there is insufficient data remaining to be + * read to fill the buffer. + * + * @param b The buffer into which bytes will be read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b) + throws IOException; + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to read <code>len</code> bytes and + * will start storing them at position <code>off</code> into the buffer. + * This method can return a short count if there is insufficient data + * remaining to be read to complete the desired read length. + * + * @param b The buffer into which bytes will be read. + * @param off The offset into the buffer 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 reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b, int off, int len) + throws IOException; + + /** + * This method reads a Java boolean value from an input stream. It does + * so by reading a single byte of data. If that byte is zero, then the + * value returned is <code>false</code>. If the byte is non-zero, then + * the value returned is <code>true</code>. + * <p> + * This method can read a <code>boolean</code> written by an object + * implementing the <code>writeBoolean()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>boolean</code> value read + * + * @exception EOFException If end of file is reached before reading + * the boolean + * @exception IOException If any other error occurs + * + * @see DataOutput#writeBoolean + */ + boolean readBoolean() + throws IOException; + + /** + * This method reads a Java byte value from an input stream. The value + * is in the range of -128 to 127. + * <p> + * This method can read a <code>byte</code> written by an object + * implementing the <code>writeByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>byte</code> value read + * + * @exception EOFException If end of file is reached before reading the byte + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + byte readByte() + throws IOException; + + /** + * This method reads a Java <code>char</code> value from an input stream. + * It operates by reading two bytes from the stream and converting them to + * a single 16-bit Java <code>char</code>. The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>char</code> in + * the following manner: + * <p> + * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code> + * <p> + * This method can read a <code>char</code> written by an object + * implementing the <code>writeChar()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>char</code> value read + * + * @exception EOFException If end of file is reached before reading the char + * @exception IOException If any other error occurs + * + * @see DataOutput#writeChar + */ + char readChar() + throws IOException; + + /** + * This method reads a Java double value from an input stream. It operates + * by first reading a <code>long</code> value from the stream by calling the + * <code>readLong()</code> method in this interface, then converts + * that <code>long</code> to a <code>double</code> using the + * <code>longBitsToDouble</code> method in the class + * <code>java.lang.Double</code> + * <p> + * This method can read a <code>double</code> written by an object + * implementing the <code>writeDouble()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>double</code> value read + * + * @exception EOFException If end of file is reached before reading + * the double + * @exception IOException If any other error occurs + * + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble + */ + double readDouble() + throws IOException; + + /** + * This method reads a Java float value from an input stream. It + * operates by first reading an <code>int</code> value from the + * stream by calling the <code>readInt()</code> method in this + * interface, then converts that <code>int</code> to a + * <code>float</code> using the <code>intBitsToFloat</code> method + * in the class <code>java.lang.Float</code> + * <p> + * This method can read a <code>float</code> written by an object + * implementing the <code>writeFloat()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>float</code> value read + * + * @exception EOFException If end of file is reached before reading the float + * @exception IOException If any other error occurs + * + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat + */ + float readFloat() + throws IOException; + + /** + * This method reads raw bytes into the passed array until the array is + * full. Note that this method blocks until the data is available and + * throws an exception if there is not enough data left in the stream to + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. + * + * @param b The buffer into which to read the data + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + void readFully(byte[] b) + throws IOException; + + /** + * This method reads a Java <code>int</code> value from an input stream + * It operates by reading four bytes from the stream and converting them to + * a single Java <code>int</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte4</code> represent + * the first four bytes read from the stream, they will be + * transformed to an <code>int</code> in the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code> + * <p> + * The value returned is in the range of -2147483648 to 2147483647. + * <p> + * This method can read an <code>int</code> written by an object + * implementing the <code>writeInt()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>int</code> value read + * + * @exception EOFException If end of file is reached before reading the int + * @exception IOException If any other error occurs + * + * @see DataOutput#writeInt + */ + int readInt() + throws IOException; + + /** + * This method reads a Java <code>long</code> value from an input stream + * It operates by reading eight bytes from the stream and converting them to + * a single Java <code>long</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte8</code> represent + * the first eight bytes read from the stream, they will be + * transformed to an <code>long</code> in the following manner: + * <p> + * <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) + * </code> + * <p> + * The value returned is in the range of -9223372036854775808 to + * 9223372036854775807. + * <p> + * This method can read an <code>long</code> written by an object + * implementing the <code>writeLong()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>long</code> value read + * + * @exception EOFException If end of file is reached before reading the long + * @exception IOException If any other error occurs + * + * @see DataOutput#writeLong + */ + long readLong() + throws IOException; + + /** + * This method reads a signed 16-bit value into a Java in from the + * stream. It operates by reading two bytes from the stream and + * converting them to a single 16-bit Java <code>short</code>. The + * two bytes are stored most significant byte first (i.e., "big + * endian") regardless of the native host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>short</code>. in + * the following manner: + * <p> + * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of -32768 to 32767. + * <p> + * This method can read a <code>short</code> written by an object + * implementing the <code>writeShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>short</code> value read + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + short readShort() + throws IOException; + + /** + * This method reads 8 unsigned bits into a Java <code>int</code> + * value from the stream. The value returned is in the range of 0 to + * 255. + * <p> + * This method can read an unsigned byte written by an object + * implementing the <code>writeUnsignedByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned bytes value read as a Java <code>int</code>. + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + int readUnsignedByte() + throws IOException; + + /** + * This method reads 16 unsigned bits into a Java int value from the stream. + * It operates by reading two bytes from the stream and converting them to + * a single Java <code>int</code> The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to an <code>int</code> in + * the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of 0 to 65535. + * <p> + * This method can read an unsigned short written by an object + * implementing the <code>writeUnsignedShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned short value read as a Java <code>int</code> + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + int readUnsignedShort() + throws IOException; + + /** + * Read a single byte. + * + * @return a byte, extracted from the stream or -1 if + * EOF has been reached. + * @throws IOException + */ + public int read() + throws IOException; + + /** + * This method attempts to skip and discard the specified number of bytes + * in the input stream. It may actually skip fewer bytes than requested. + * This method will not skip any bytes if passed a negative number of bytes + * to skip. + * + * @param n The requested number of bytes to skip. + * + * @return The requested number of bytes to skip. + * + * @exception IOException If an error occurs. + * @specnote The JDK docs claim that this returns the number of bytes + * actually skipped. The JCL claims that this method can throw an + * EOFException. Neither of these appear to be true in the JDK 1.3's + * implementation. This tries to implement the actual JDK behaviour. + */ + int skipBytes(int n) + throws IOException; +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/abstractDataOutputStream.java b/gnu/CORBA/CDR/abstractDataOutputStream.java new file mode 100644 index 000000000..b54dc0f7f --- /dev/null +++ b/gnu/CORBA/CDR/abstractDataOutputStream.java @@ -0,0 +1,185 @@ +/* abstractDataOutputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * An abstract data output stream that could write data in either + * Big Endian or Little Endian format. + * + * This class reuses code from GNU Classpath DataOutputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface abstractDataOutputStream +{ + /** + * This method flushes any unwritten bytes to the underlying stream. + * + * @exception IOException If an error occurs. + */ + void flush() + throws IOException; + + /** + * This method writes the specified byte (passed as an <code>int</code>) + * to the underlying output stream. + * + * @param value The <code>byte</code> to write, passed as an <code>int</code>. + * + * @exception IOException If an error occurs. + */ + void write(int value) + throws IOException; + + /** + * This method writes <code>len</code> bytes from the specified byte array + * <code>buf</code> starting at position <code>offset</code> into the + * buffer to the underlying output stream. + * + * @param buf The byte array to write from. + * @param offset The index into the byte array to start writing from. + * @param len The number of bytes to write. + * + * @exception IOException If an error occurs. + */ + void write(byte[] buf, int offset, int len) + throws IOException; + + /** + * Write the complete byte array. + * @throws IOException + */ + void write(byte[] buf) + throws IOException; + + /** + * This method writes a Java boolean value to an output stream. If + * <code>value</code> is <code>true</code>, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the <code>readBoolean</code> + * method in <code>DataInput</code>. + * + * @param value The <code>boolean</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeBoolean(boolean value) + throws IOException; + + /** + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * <code>int</code> value passed. + * + * The value written can be read using the <code>readByte</code> or + * <code>readUnsignedByte</code> methods in <code>DataInput</code>. + * + * @param value The <code>byte</code> to write to the stream, passed as + * the low eight bits of an <code>int</code>. + * + * @exception IOException If an error occurs + */ + void writeByte(int value) + throws IOException; + + /** + * This method writes a Java short value to an output stream. The + * char to be written will be in the lowest 16 bits of the <code>int</code> + * value passed. + * + * @exception IOException If an error occurs + */ + void writeShort(int value) + throws IOException; + + /** + * This method writes a Java char value to an output stream. The + * char to be written will be in the lowest 16 bits of the <code>int</code> + * value passed. + * + * @exception IOException If an error occurs + */ + void writeChar(int value) + throws IOException; + + /** + * This method writes a Java int value to an output stream. + * + * @param value The <code>int</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeInt(int value) + throws IOException; + + /** + * This method writes a Java long value to an output stream. + * + * @param value The <code>long</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeLong(long value) + throws IOException; + + /** + * This method writes a Java <code>float</code> value to the stream. + * @param value The <code>float</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeFloat(float value) + throws IOException; + + /** + * This method writes a Java <code>double</code> value to the stream. + * + * @param value The <code>double</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeDouble(double value) + throws IOException; +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/aligningInputStream.java b/gnu/CORBA/CDR/aligningInputStream.java index 798b3acea..c29a52cfa 100644 --- a/gnu/CORBA/CDR/aligningInputStream.java +++ b/gnu/CORBA/CDR/aligningInputStream.java @@ -106,7 +106,9 @@ public class aligningInputStream } catch (Exception ex) { - throw new BAD_PARAM("Unable to align at " + alignment); + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; } } diff --git a/gnu/CORBA/CDR/aligningOutputStream.java b/gnu/CORBA/CDR/aligningOutputStream.java index b4a96f8bb..f4009c47c 100644 --- a/gnu/CORBA/CDR/aligningOutputStream.java +++ b/gnu/CORBA/CDR/aligningOutputStream.java @@ -100,7 +100,9 @@ public class aligningOutputStream } catch (Exception ex) { - throw new BAD_PARAM("Unable to align at " + alignment); + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; } } diff --git a/gnu/CORBA/CDR/cdrInput.java b/gnu/CORBA/CDR/cdrInput.java index 03be3363b..644e01930 100644 --- a/gnu/CORBA/CDR/cdrInput.java +++ b/gnu/CORBA/CDR/cdrInput.java @@ -62,6 +62,7 @@ import org.omg.CORBA.TypeCodePackage.Bounds; import org.omg.CORBA.portable.InputStream; import org.omg.CORBA.portable.ObjectImpl; +import java.io.DataInput; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; @@ -93,7 +94,13 @@ public abstract class cdrInput * This instance is used to convert primitive data types into the * byte sequences. */ - protected DataInputStream b; + protected abstractDataInputStream b; + + /** + * The input stream, from where the data are actually + * being read. + */ + protected java.io.InputStream actual_stream; /** * The associated orb, if any. @@ -137,7 +144,16 @@ public abstract class cdrInput private boolean wide_native; /** - * Creates the stream. + * If true, the stream expect + * the multi-byte data in the form "less significant byte + * first" (Little Endian). This is the opposite to the + * java standard (Big Endian). + */ + private boolean little_endian; + + /** + * Creates the stream. The stream reads Big Endian by + * default. * * @param readFrom a stream to read CORBA input from. */ @@ -157,13 +173,33 @@ public abstract class cdrInput } /** + * Set the Big Endian or Little Endian encoding. + * The stream reads Big Endian by default. + * + * @param use_little_endian if true, the stream expect + * the multi-byte data in the form "less significant byte + * first" (Little Endian). This is the opposite to the + * java standard (Big Endian). + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setInputStream(actual_stream); + } + + /** * Set the input stream that receives the CORBA input. * * @param readFrom the stream. */ public void setInputStream(java.io.InputStream readFrom) { - b = new DataInputStream(readFrom); + if (little_endian) + b = new LittleEndianInputStream(readFrom); + else + b = new BigEndianInputStream(readFrom); + + actual_stream = readFrom; } /** @@ -209,7 +245,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) { @@ -230,7 +268,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -260,7 +300,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } } @@ -276,7 +318,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } } @@ -292,7 +336,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } } @@ -344,7 +390,9 @@ public abstract class cdrInput } catch (IOException ex) { - throw new BAD_OPERATION(ex.toString()); + BAD_OPERATION bad = new BAD_OPERATION(); + bad.initCause(ex); + throw bad; } } @@ -394,7 +442,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) { @@ -416,7 +466,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -436,11 +488,13 @@ public abstract class cdrInput if (narrow_native) return (char) b.read(); else - return (char) new InputStreamReader(b, narrow_charset).read(); + return (char) new InputStreamReader((InputStream) b, narrow_charset).read(); } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -463,13 +517,16 @@ public abstract class cdrInput } else { - InputStreamReader reader = new InputStreamReader(b, narrow_charset); + InputStreamReader reader = + new InputStreamReader((InputStream) b, narrow_charset); reader.read(x, offset, length); } } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -490,7 +547,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -514,7 +573,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -524,8 +585,10 @@ public abstract class cdrInput } /** - * Read the encapsulated stream. The endian flag is already extracted from - * the returned stream. + * Read the encapsulated stream. + * If the encapsulated sequence appears to be in the + * Little endian format, the flag of the returned stream + * is set to read Little endian. */ public cdrBufInput read_encapsulation() { @@ -538,7 +601,7 @@ public abstract class cdrInput reading: while (n < r.length) { - n = read(r, n, r.length - n); + n += read(r, n, r.length - n); } cdrBufInput capsule = new cdrBufInput(r); @@ -546,17 +609,18 @@ public abstract class cdrInput int endian = capsule.read_octet(); - // TODO FIXME implement little endian. if (endian != 0) { - throw new NO_IMPLEMENT("Little endian not supported."); + capsule.setBigEndian(false); } return capsule; } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -578,7 +642,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -599,7 +665,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -623,7 +691,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -644,7 +714,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -668,7 +740,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -713,7 +787,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -733,7 +809,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -753,7 +831,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -780,7 +860,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -801,7 +883,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -825,7 +909,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -860,7 +946,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -944,11 +1032,13 @@ public abstract class cdrInput if (wide_native) return (char) b.readShort(); else - return (char) new InputStreamReader(b, wide_charset).read(); + return (char) new InputStreamReader((InputStream) b, wide_charset).read(); } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) { @@ -974,13 +1064,16 @@ public abstract class cdrInput } else { - InputStreamReader reader = new InputStreamReader(b, wide_charset); + InputStreamReader reader = + new InputStreamReader((InputStream) b, wide_charset); reader.read(x, offset, length); } } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -1001,7 +1094,7 @@ public abstract class cdrInput public String read_wstring() { // Native encoding or word oriented data. - if (wide_charset == null || giop.until_inclusive(1, 1)) + if (wide_native || giop.until_inclusive(1, 1)) return read_wstring_UTF_16(); try { @@ -1015,7 +1108,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -1069,7 +1164,9 @@ public abstract class cdrInput } catch (EOFException ex) { - throw new MARSHAL(UNEXP_EOF); + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.initCause(ex); + throw t; } catch (IOException ex) @@ -1126,4 +1223,4 @@ public abstract class cdrInput { return read_Object(); } -} +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/cdrOutput.java b/gnu/CORBA/CDR/cdrOutput.java index e675d7d6c..30efaa854 100644 --- a/gnu/CORBA/CDR/cdrOutput.java +++ b/gnu/CORBA/CDR/cdrOutput.java @@ -88,7 +88,7 @@ public abstract class cdrOutput * This instance is used to convert primitive data types into the * byte sequences. */ - protected DataOutputStream b; + protected abstractDataOutputStream b; /** * The associated orb, if any. @@ -131,6 +131,17 @@ public abstract class cdrOutput private boolean wide_native; /** + * If true, the Little Endian encoding is used to write the + * data. Otherwise, the Big Endian encoding is used. + */ + private boolean little_endian; + + /** + * The stream whre the data are actually written. + */ + private java.io.OutputStream actual_stream; + + /** * Creates the stream. * * @param writeTo a stream to write CORBA output to. @@ -193,7 +204,12 @@ public abstract class cdrOutput */ public void setOutputStream(java.io.OutputStream writeTo) { - b = new DataOutputStream(writeTo); + if (little_endian) + b = new LittleEndianOutputStream(writeTo); + else + b = new BigEndianOutputStream(writeTo); + + actual_stream = writeTo; } /** @@ -206,6 +222,19 @@ public abstract class cdrOutput } /** + * Specify if the stream should use the Big Endian (usual for java) + * or Little Encoding. The default is Big Endian. + * + * @param use_big_endian if true, use Big Endian, if false, + * use Little Endian. + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setOutputStream(actual_stream); + } + + /** * Align the curretn position at the given natural boundary. */ public abstract void align(int boundary); @@ -219,11 +248,14 @@ public abstract class cdrOutput * It is not allowed to write to the current stream directly * before the encapsulation stream is closed. * + * The encoding (Big/Little Endian) inside the encapsulated + * sequence is the same as used into the parent stream. + * * @return the encapsulated stream. */ public cdrOutput createEncapsulation() { - return new encapsulatedOutput(this); + return new encapsulatedOutput(this, !little_endian); } /** @@ -407,7 +439,8 @@ public abstract class cdrOutput b.write(x); else { - OutputStreamWriter ow = new OutputStreamWriter(b, narrow_charset); + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); ow.write(x); ow.flush(); } @@ -438,7 +471,8 @@ public abstract class cdrOutput } else { - OutputStreamWriter ow = new OutputStreamWriter(b, narrow_charset); + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); ow.write(chars, offset, length); ow.flush(); } @@ -672,7 +706,9 @@ public abstract class cdrOutput } catch (IOException ex) { - throw new MARSHAL("IOException while writing the data"); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } @@ -691,7 +727,9 @@ public abstract class cdrOutput } catch (IOException ex) { - throw new MARSHAL("IOException while writing the data"); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } @@ -835,7 +873,8 @@ public abstract class cdrOutput b.writeShort(x); else { - OutputStreamWriter ow = new OutputStreamWriter(b, wide_charset); + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, wide_charset); ow.write(x); ow.flush(); } @@ -872,7 +911,8 @@ public abstract class cdrOutput } else { - OutputStreamWriter ow = new OutputStreamWriter(b, wide_charset); + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, wide_charset); ow.write(chars, offset, length); ow.flush(); } @@ -920,4 +960,4 @@ public abstract class cdrOutput Unexpected.error(ex); } } -} +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/encapsulatedOutput.java b/gnu/CORBA/CDR/encapsulatedOutput.java index 656bf066f..e4673b099 100644 --- a/gnu/CORBA/CDR/encapsulatedOutput.java +++ b/gnu/CORBA/CDR/encapsulatedOutput.java @@ -57,6 +57,11 @@ public class encapsulatedOutput public static final byte BIG_ENDIAN = 0; /** + * The Little Endian (least siginificant byte first flag). + */ + public static final byte LITTLE_ENDIAN = 1; + + /** * The byte buffer. */ public final aligningOutputStream buffer; @@ -67,16 +72,17 @@ public class encapsulatedOutput public final org.omg.CORBA.portable.OutputStream parent; /** - * Create the EncapsulationOutput with the default buffer size - * and the given parent stream. - */ - public encapsulatedOutput(org.omg.CORBA.portable.OutputStream _parent) + * Create the EncapsulationOutput with the given parent stream + * and the specified encoding. + */ + public encapsulatedOutput(org.omg.CORBA.portable.OutputStream _parent, + boolean use_big_endian) { super(); buffer = new aligningOutputStream(); setOutputStream(buffer); parent = _parent; - write(BIG_ENDIAN); + write(use_big_endian?BIG_ENDIAN:LITTLE_ENDIAN); } /** @@ -109,7 +115,9 @@ public class encapsulatedOutput } catch (IOException ex) { - throw new InternalError(); + InternalError err = new InternalError(); + err.initCause(ex); + throw err; } } diff --git a/gnu/java/awt/peer/gtk/GtkOffScreenImage.java b/gnu/CORBA/CDR/uncObjectInputStream.java index 786c4b449..b912f5d2c 100644 --- a/gnu/java/awt/peer/gtk/GtkOffScreenImage.java +++ b/gnu/CORBA/CDR/uncObjectInputStream.java @@ -1,5 +1,5 @@ -/* GtkOffScreenImage.java - Copyright (C) 1999 Free Software Foundation, Inc. +/* uncObjectInputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,58 +36,35 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -package gnu.java.awt.peer.gtk; +package gnu.CORBA.CDR; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.image.ImageObserver; -import java.awt.image.ImageProducer; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; -public class GtkOffScreenImage extends Image +/** + * An object input stream that cannot be closed. Used in cases where + * it represents only part of the input data. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class uncObjectInputStream + extends ObjectInputStream { - int width, height; - ImageProducer source; - Graphics g; - - public GtkOffScreenImage (ImageProducer source, Graphics g, - int width, int height) + /** + * Delegate call to super class constructor. + */ + public uncObjectInputStream(InputStream in) + throws IOException { - this.width = width; - this.height = height; - - this.source = source; - this.g = g; - } - - public int getWidth (ImageObserver observer) - { - return width; - } - - public int getHeight (ImageObserver observer) - { - return height; - } - - public ImageProducer getSource () - { - return source; - } - - public Graphics getGraphics () - { - if (g instanceof GdkGraphics2D) - return new GdkGraphics2D ((GdkGraphics2D) this.g); - else - return new GdkGraphics ((GdkGraphics) this.g); - } - - public Object getProperty (String name, ImageObserver observer) - { - return Image.UndefinedProperty; + super(in); } - public void flush () + /** + * Do not close the stream, return without action. + */ + public void close() { + // Do nothing. } -} +}
\ No newline at end of file diff --git a/gnu/CORBA/CDR/uncObjectOutputStream.java b/gnu/CORBA/CDR/uncObjectOutputStream.java new file mode 100644 index 000000000..3aa8582bb --- /dev/null +++ b/gnu/CORBA/CDR/uncObjectOutputStream.java @@ -0,0 +1,73 @@ +/* uncObjectOutputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +/** + * The Uncloseable Object Output Stream is used in cases when + * it is necessary to write the data and leave the stream opened. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class uncObjectOutputStream + extends ObjectOutputStream +{ + /** + * Delegate call to super class constructor. + */ + public uncObjectOutputStream(OutputStream out) + throws IOException + { + super(out); + } + + /** + * Do not close, just flush. + * + * @throws IOException if the flush() throws it. + */ + public void close() + throws IOException + { + flush(); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/DefinitionKindHolder.java b/gnu/CORBA/DefinitionKindHolder.java new file mode 100644 index 000000000..dc6dcc0be --- /dev/null +++ b/gnu/CORBA/DefinitionKindHolder.java @@ -0,0 +1,91 @@ +/* DefinitionKindHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA; + +import org.omg.CORBA.DefinitionKind; +import org.omg.CORBA.DefinitionKindHelper; + + +/** + * The definition kind holder. This class is not included in the original + * API specification, so we place it outside the org.omg namespace. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class DefinitionKindHolder + implements org.omg.CORBA.portable.Streamable +{ + /** + * The stored value. + */ + public DefinitionKind value; + + /** + * Create the initialised instance. + * @param initialValue + */ + public DefinitionKindHolder(DefinitionKind initialValue) + { + value = initialValue; + } + + /** + * Read from the CDR stream. + */ + public void _read(org.omg.CORBA.portable.InputStream in) + { + value = DefinitionKindHelper.read(in); + } + + /** + * Get the typecode. + */ + public org.omg.CORBA.TypeCode _type() + { + return DefinitionKindHelper.type(); + } + + /** + * Write into the CDR stream. + */ + public void _write(org.omg.CORBA.portable.OutputStream out) + { + DefinitionKindHelper.write(out, value); + } +} diff --git a/gnu/CORBA/Functional_ORB.java b/gnu/CORBA/Functional_ORB.java index b26b5aa8c..437f420c4 100644 --- a/gnu/CORBA/Functional_ORB.java +++ b/gnu/CORBA/Functional_ORB.java @@ -103,6 +103,11 @@ public class Functional_ORB extends Thread { /** + * The number of the currently running parallel threads. + */ + private int running_threads; + + /** * The port on that this portServer is listening for requests. */ int s_port; @@ -113,6 +118,12 @@ public class Functional_ORB ServerSocket service; /** + * True if the serving node must shutdown due + * call of the close_now(). + */ + boolean terminated; + + /** * Create a new portServer, serving on specific port. */ portServer(int _port) @@ -127,30 +138,32 @@ public class Functional_ORB */ public void run() { - boolean terminated; - try { service = new ServerSocket(s_port); } catch (IOException ex) { - throw new BAD_OPERATION("Unable to open the server socket."); + BAD_OPERATION bad = + new BAD_OPERATION("Unable to open the server socket."); + bad.initCause(ex); + throw bad; } while (running) { try { - serve(service); + serve(this, service); } catch (SocketException ex) { - // Thrown when the service is closed by + // May be thrown when the service is closed by // the close_now(). - return; + if (terminated) + return; } - catch (IOException iex) + catch (Exception iex) { // Wait 5 seconds. Do not terminate the // service due potentially transient error. @@ -172,6 +185,7 @@ public class Functional_ORB { try { + terminated = true; service.close(); } catch (Exception ex) @@ -217,11 +231,73 @@ public class Functional_ORB public static final String NAME_SERVICE = "NameService"; /** + * The if the client has once opened a socket, it should start sending + * the message header in a given time. Otherwise the server will close the + * socket. This prevents server hang when the client opens the socket, + * but does not send any message, usually due crash on the client side. + */ + public static String START_READING_MESSAGE = + "gnu.classpath.CORBA.TOUT_START_READING_MESSAGE"; + + /** + * If the client has started to send the request message, the socket time + * out changes to the specified value. + */ + public static String WHILE_READING = "gnu.classpath.CORBA.TOUT_WHILE_READING"; + + /** + * If the message body is received, the time out changes to the + * specifice value. This must be longer, as includes time, required to + * process the received task. We make it 40 minutes. + */ + public static String AFTER_RECEIVING = + "gnu.classpath.CORBA.TOUT_AFTER_RECEIVING"; + + /** * The address of the local host. */ public final String LOCAL_HOST; /** + * The if the client has once opened a socket, it should start sending + * the message header in a given time. Otherwise the server will close the + * socket. This prevents server hang when the client opens the socket, + * but does not send any message, usually due crash on the client side. + */ + private int TOUT_START_READING_MESSAGE = 20 * 1000; + + // (Here and below, we use * to make meaning of the constant clearler). + + /** + * If the client has started to send the request message, the socket time + * out changes to the specified value. + */ + private int TOUT_WHILE_READING = 2 * 60 * 1000; + + /** + * If the message body is received, the time out changes to the + * specifice value. This must be longer, as includes time, required to + * process the received task. We make it 40 minutes. + */ + private int TOUT_AFTER_RECEIVING = 40 * 60 * 1000; + + /** + * Some clients tend to submit multiple requests over the + * same socket. The server waits for the next request on + * the same socket for the duration, specified + * below. The default time is seven seconds. + */ + public int TANDEM_REQUESTS = 7000; + + /** + * If the maximal number of threads per object is reached, + * the server waits for the given time interval before checking + * again maybe some threads are already complete. + * Thr default time is 0.5 second. + */ + public int PAUSE_ON_THREAD_OVERLOAD = 500; + + /** * The map of the already conncted objects. */ protected final Connected_objects connected_objects = new Connected_objects(); @@ -280,6 +356,14 @@ public class Functional_ORB protected LinkedList freed_ports = new LinkedList(); /** + * The maximal allowed number of the currently running parallel + * threads per object. For security reasons, this is made private and + * unchangeable. After exceeding this limit, the NO_RESOURCES + * is thrown back to the client. + */ + private int MAX_RUNNING_THREADS = 256; + + /** * Create the instance of the Functional ORB. */ public Functional_ORB() @@ -290,7 +374,10 @@ public class Functional_ORB } catch (UnknownHostException ex) { - throw new BAD_OPERATION("Unable to resolve the local host address."); + BAD_OPERATION bad = + new BAD_OPERATION("Unable to open the server socket."); + bad.initCause(ex); + throw bad; } } @@ -329,6 +416,7 @@ public class Functional_ORB throws BAD_OPERATION { ServerSocket s; + int a_port; try { @@ -349,14 +437,14 @@ public class Functional_ORB // OK then, use a new port. } - for (int i = Port; i < Port + 20; i++) + for (a_port = Port; a_port < Port + 20; a_port++) { try { - s = new ServerSocket(i); + s = new ServerSocket(a_port); s.close(); - Port = i + 1; - return s.getLocalPort(); + Port = a_port + 1; + return a_port; } catch (IOException ex) { @@ -368,12 +456,16 @@ public class Functional_ORB { // Try any port. s = new ServerSocket(); + a_port = s.getLocalPort(); s.close(); - return s.getLocalPort(); + return a_port; } - catch (IOException ex1) + catch (IOException ex) { - throw new NO_RESOURCES("Unable to open the server socket"); + NO_RESOURCES bad = + new NO_RESOURCES("Unable to open the server socket."); + bad.initCause(ex); + throw bad; } } @@ -508,16 +600,16 @@ public class Functional_ORB { Delegate delegate = ((ObjectImpl) object)._get_delegate(); if (delegate instanceof Simple_delegate) - { - byte[] key = ((Simple_delegate) delegate).getIor().key; - rmKey = connected_objects.get(key); - } + { + byte[] key = ((Simple_delegate) delegate).getIor().key; + rmKey = connected_objects.get(key); + } } // Try to find and disconned the object that is not an instance of the // object implementation. if (rmKey == null) - rmKey = connected_objects.getKey(object); + rmKey = connected_objects.getKey(object); // Disconnect the object on any success. if (rmKey != null) @@ -646,7 +738,9 @@ public class Functional_ORB } catch (Exception ex) { - throw new InvalidName(name + ":" + ex.getMessage()); + InvalidName err = new InvalidName(name); + err.initCause(ex); + throw err; } if (object != null) return object; @@ -784,7 +878,7 @@ public class Functional_ORB protected org.omg.CORBA.Object find_connected_object(byte[] key) { Connected_objects.cObject ref = connected_objects.get(key); - return ref==null?null:ref.object; + return ref == null ? null : ref.object; } /** @@ -820,6 +914,15 @@ public class Functional_ORB if (para [ i ] [ 0 ].equals(NS_HOST)) ns_host = para [ i ] [ 1 ]; + if (para [ i ] [ 0 ].equals(START_READING_MESSAGE)) + TOUT_START_READING_MESSAGE = Integer.parseInt(para [ i ] [ 1 ]); + + if (para [ i ] [ 0 ].equals(WHILE_READING)) + TOUT_WHILE_READING = Integer.parseInt(para [ i ] [ 1 ]); + + if (para [ i ] [ 0 ].equals(AFTER_RECEIVING)) + TOUT_AFTER_RECEIVING = Integer.parseInt(para [ i ] [ 1 ]); + try { if (para [ i ] [ 0 ].equals(NS_PORT)) @@ -827,10 +930,13 @@ public class Functional_ORB } catch (NumberFormatException ex) { - throw new BAD_PARAM("Invalid " + NS_PORT + - "property, unable to parse '" + - props.getProperty(NS_PORT) + "'" - ); + BAD_PARAM bad = + new BAD_PARAM("Invalid " + NS_PORT + + "property, unable to parse '" + + props.getProperty(NS_PORT) + "'" + ); + bad.initCause(ex); + throw bad; } } } @@ -991,6 +1097,7 @@ public class Functional_ORB handler.getBuffer().buffer.writeTo(out); MessageHeader msh_reply = new MessageHeader(); + msh_reply.version = msh_request.version; msh_reply.message_type = MessageHeader.REPLY; msh_reply.message_size = out.buffer.size(); @@ -1002,127 +1109,205 @@ public class Functional_ORB } /** - * Contains a single servicing step. + * Contains a single servicing task. + * + * Normally, each task matches a single remote invocation. + * However under frequent tandem submissions the same + * task may span over several invocations. * * @param serverSocket the ORB server socket. * * @throws MARSHAL * @throws IOException */ - private void serve(ServerSocket serverSocket) + private void serve(final portServer p, ServerSocket serverSocket) throws MARSHAL, IOException { - Socket service = null; - try - { - service = serverSocket.accept(); - service.setKeepAlive(true); + final Socket service; + service = serverSocket.accept(); - InputStream in = service.getInputStream(); - - MessageHeader msh_request = new MessageHeader(); - msh_request.read(in); + // Tell the server there are no more resources. + while (p.running_threads >= MAX_RUNNING_THREADS) + { + serveStep(service, true); + } - if (max_version != null) - if (!msh_request.version.until_inclusive(max_version.major, - max_version.minor - ) - ) + new Thread() + { + public void run() + { + try { - OutputStream out = service.getOutputStream(); - new ErrorMessage(max_version).write(out); - service.close(); - return; + synchronized (p) + { + p.running_threads++; + } + serveStep(service, false); } + finally + { + synchronized (p) + { + p.running_threads--; + } + } + } + }.start(); + } - byte[] r = new byte[ msh_request.message_size ]; - - int n = 0; - - reading: - while (n < r.length) - { - n = in.read(r, n, r.length - n); - } - - if (msh_request.message_type == MessageHeader.REQUEST) + /** + * A single servicing step, when the client socket is alrady open. + * + * Normally, each task matches a single remote invocation. + * However under frequent tandem submissions the same + * task may span over several invocations. + * + * @param service the opened client socket. + * @param no_resources if true, the "NO RESOURCES" exception + * is thrown to the client. + */ + private void serveStep(Socket service, boolean no_resources) + { + try + { + Serving: + while (true) { - RequestHeader rh_request; - - cdrBufInput cin = new cdrBufInput(r); - cin.setOrb(this); - cin.setVersion(msh_request.version); - cin.setOffset(msh_request.getHeaderSize()); - - rh_request = msh_request.create_request_header(); + InputStream in = service.getInputStream(); + service.setSoTimeout(TOUT_START_READING_MESSAGE); - // Read header and auto set the charset. - rh_request.read(cin); + MessageHeader msh_request = new MessageHeader(); - // in 1.2 and higher, align the current position at - // 8 octet boundary. - if (msh_request.version.since_inclusive(1, 2)) - cin.align(8); + try + { + msh_request.read(in); + } + catch (MARSHAL ex) + { + // This exception may be thrown due closing the connection. + return; + } - // find the target object. - InvokeHandler target = - (InvokeHandler) find_connected_object(rh_request.object_key); + if (max_version != null) + if (!msh_request.version.until_inclusive(max_version.major, + max_version.minor + ) + ) + { + OutputStream out = service.getOutputStream(); + new ErrorMessage(max_version).write(out); + return; + } - // Prepare the reply header. This must be done in advance, - // as the size must be known for handler to set alignments - // correctly. - ReplyHeader rh_reply = msh_request.create_reply_header(); + byte[] r = new byte[ msh_request.message_size ]; - // TODO log errors about not existing objects and methods. - bufferedResponseHandler handler = - new bufferedResponseHandler(this, msh_request, rh_reply); + int n = 0; - SystemException sysEx = null; + service.setSoTimeout(TOUT_WHILE_READING); - try - { - if (target == null) - throw new OBJECT_NOT_EXIST(); - target._invoke(rh_request.operation, cin, handler); - } - catch (SystemException ex) + reading: + while (n < r.length) { - sysEx = ex; - - org.omg.CORBA.portable.OutputStream ech = - handler.createExceptionReply(); - ObjectCreator.writeSystemException(ech, ex); + n += in.read(r, n, r.length - n); } - catch (Exception except) - { - sysEx = - new UNKNOWN("Unknown", 2, CompletionStatus.COMPLETED_MAYBE); - org.omg.CORBA.portable.OutputStream ech = - handler.createExceptionReply(); + service.setSoTimeout(TOUT_AFTER_RECEIVING); - ObjectCreator.writeSystemException(ech, sysEx); + if (msh_request.message_type == MessageHeader.REQUEST) + { + RequestHeader rh_request; + + cdrBufInput cin = new cdrBufInput(r); + cin.setOrb(this); + cin.setVersion(msh_request.version); + cin.setOffset(msh_request.getHeaderSize()); + cin.setBigEndian(msh_request.isBigEndian()); + + rh_request = msh_request.create_request_header(); + + // Read header and auto set the charset. + rh_request.read(cin); + + // in 1.2 and higher, align the current position at + // 8 octet boundary. + if (msh_request.version.since_inclusive(1, 2)) + cin.align(8); + + // find the target object. + InvokeHandler target = + (InvokeHandler) find_connected_object(rh_request.object_key); + + // Prepare the reply header. This must be done in advance, + // as the size must be known for handler to set alignments + // correctly. + ReplyHeader rh_reply = msh_request.create_reply_header(); + + // TODO log errors about not existing objects and methods. + bufferedResponseHandler handler = + new bufferedResponseHandler(this, msh_request, rh_reply); + + SystemException sysEx = null; + + try + { + if (no_resources) + throw new NO_RESOURCES(); + if (target == null) + throw new OBJECT_NOT_EXIST(); + target._invoke(rh_request.operation, cin, handler); + } + catch (SystemException ex) + { + sysEx = ex; + + org.omg.CORBA.portable.OutputStream ech = + handler.createExceptionReply(); + ObjectCreator.writeSystemException(ech, ex); + } + catch (Exception except) + { + sysEx = + new UNKNOWN("Unknown", 2, CompletionStatus.COMPLETED_MAYBE); + + org.omg.CORBA.portable.OutputStream ech = + handler.createExceptionReply(); + + ObjectCreator.writeSystemException(ech, sysEx); + } + + // Write the response. + if (rh_request.isResponseExpected()) + { + OutputStream sou = service.getOutputStream(); + respond_to_client(sou, msh_request, rh_request, handler, + sysEx + ); + } } + else + ; - // Write the response. - if (rh_request.isResponseExpected()) + // TODO log error: "Not a request message." + if (service != null && !service.isClosed()) { - respond_to_client(service.getOutputStream(), msh_request, - rh_request, handler, sysEx - ); + // Wait for the subsequent invocations on the + // same socket for 2 minutes. + service.setSoTimeout(TANDEM_REQUESTS); } + else + return; } - else - ; - - // TODO log error: "Not a request message." } - finally + catch (SocketException ex) { - if (service != null && !service.isClosed()) - { - service.close(); - } + // OK. + return; + } + catch (IOException ioex) + { + // Network error, probably transient. + // TODO log it. + return; } } @@ -1140,6 +1325,18 @@ public class Functional_ORB { if (props.containsKey(NS_PORT)) ns_port = Integer.parseInt(props.getProperty(NS_PORT)); + + if (props.containsKey(START_READING_MESSAGE)) + TOUT_START_READING_MESSAGE = + Integer.parseInt(props.getProperty(START_READING_MESSAGE)); + + if (props.containsKey(WHILE_READING)) + TOUT_WHILE_READING = + Integer.parseInt(props.getProperty(WHILE_READING)); + + if (props.containsKey(AFTER_RECEIVING)) + TOUT_AFTER_RECEIVING = + Integer.parseInt(props.getProperty(AFTER_RECEIVING)); } catch (NumberFormatException ex) { @@ -1240,6 +1437,4 @@ public class Functional_ORB running = false; super.finalize(); } -} - - +}
\ No newline at end of file diff --git a/gnu/CORBA/GIOP/ErrorMessage.java b/gnu/CORBA/GIOP/ErrorMessage.java index fdba54f4b..0da5f649c 100644 --- a/gnu/CORBA/GIOP/ErrorMessage.java +++ b/gnu/CORBA/GIOP/ErrorMessage.java @@ -89,7 +89,9 @@ public class ErrorMessage } catch (IOException ex) { - throw new MARSHAL(ex.toString()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } } diff --git a/gnu/CORBA/GIOP/MessageHeader.java b/gnu/CORBA/GIOP/MessageHeader.java index aef00e37a..7640b6bfd 100644 --- a/gnu/CORBA/GIOP/MessageHeader.java +++ b/gnu/CORBA/GIOP/MessageHeader.java @@ -38,16 +38,23 @@ exception statement from your version. */ package gnu.CORBA.GIOP; +import gnu.CORBA.CDR.BigEndianOutputStream; +import gnu.CORBA.CDR.LittleEndianInputStream; +import gnu.CORBA.CDR.LittleEndianOutputStream; +import gnu.CORBA.CDR.abstractDataOutputStream; import gnu.CORBA.Version; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.IDLEntity; + import java.io.DataInputStream; -import java.io.DataOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.Arrays; - -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.portable.IDLEntity; +import gnu.CORBA.CDR.BigEndianInputStream; +import gnu.CORBA.CDR.abstractDataInputStream; +import java.io.InputStream; /** * The GIOP message header. @@ -142,7 +149,7 @@ public class MessageHeader */ public MessageHeader() { - version = new Version(1,0); + version = new Version(1, 0); } /** @@ -166,6 +173,20 @@ public class MessageHeader } /** + * Set the encoding to use. + * + * @param use_big_endian if true (default), the Big Endian + * encoding is used. If false, the Little Endian encoding is used. + */ + public void setBigEndian(boolean use_big_endian) + { + if (use_big_endian) + flags = (byte) (flags & ~1); + else + flags = (byte) (flags | 1); + } + + /** * Get the size of the message header itself. So far, it is always 12 bytes. */ public int getHeaderSize() @@ -250,27 +271,32 @@ public class MessageHeader { try { - DataInputStream din = new DataInputStream(istream); - byte[] xMagic = new byte[ MAGIC.length ]; - din.read(xMagic); + istream.read(xMagic); if (!Arrays.equals(xMagic, MAGIC)) throw new MARSHAL("Not a GIOP message"); - version = Version.read_version(din); + version = Version.read_version(istream); - flags = (byte) din.read(); + abstractDataInputStream din; - /** TODO implement support for the little endian. */ - if (!isBigEndian()) - throw new MARSHAL("Little endian unsupported."); + flags = (byte) istream.read(); + + // This checks the bit in the byte we have just received. + if (isBigEndian()) + din = new BigEndianInputStream(istream); + else + din = new LittleEndianInputStream(istream); message_type = (byte) din.read(); + message_size = din.readInt(); } catch (IOException ex) { - throw new MARSHAL(ex.toString()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } @@ -295,22 +321,30 @@ public class MessageHeader { try { - DataOutputStream dout = new DataOutputStream(out); + abstractDataOutputStream dout; + + if (isBigEndian()) + dout = new BigEndianOutputStream(out); + else + dout = new LittleEndianOutputStream(out); // Write magic sequence. dout.write(MAGIC); // Write version number. - version.write(dout); + version.write((OutputStream) dout); dout.write(flags); dout.write(message_type); + dout.writeInt(message_size); } catch (IOException ex) { - throw new MARSHAL(ex.toString()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } -} +}
\ No newline at end of file diff --git a/gnu/CORBA/GIOP/cxCodeSet.java b/gnu/CORBA/GIOP/cxCodeSet.java index 487a134a7..0fbf00bfe 100644 --- a/gnu/CORBA/GIOP/cxCodeSet.java +++ b/gnu/CORBA/GIOP/cxCodeSet.java @@ -160,7 +160,9 @@ public class cxCodeSet } catch (IOException ex) { - throw new InternalError(); + InternalError t = new InternalError(); + t.initCause(ex); + throw t; } } diff --git a/gnu/CORBA/GIOP/v1_2/RequestHeader.java b/gnu/CORBA/GIOP/v1_2/RequestHeader.java index 081bfcaf0..184893bb3 100644 --- a/gnu/CORBA/GIOP/v1_2/RequestHeader.java +++ b/gnu/CORBA/GIOP/v1_2/RequestHeader.java @@ -163,7 +163,9 @@ public class RequestHeader } catch (IOException ex) { - throw new MARSHAL(ex.toString()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } diff --git a/gnu/CORBA/IOR.java b/gnu/CORBA/IOR.java index 08f79f57b..056009f06 100644 --- a/gnu/CORBA/IOR.java +++ b/gnu/CORBA/IOR.java @@ -64,9 +64,6 @@ import java.io.IOException; * decoding the IOR information from/to the stringified references, * usually returned by {@link org.omg.CORBA.ORB#String object_to_string()}. * - * TODO the current implementation supports the IOP version 1.0 only. - * TODO Little Endian (lower byte first) encoding, if anybody needs it. - * * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) * * @see org.mog.CORBA.Object.object_to_string(Object forObject) @@ -276,6 +273,14 @@ public class IOR public byte[] key; /** + * True if the profile was encoded using the Big Endian or + * the encoding is not known. + * + * false if it was encoded using the Little Endian. + */ + public boolean Big_Endian = true; + + /** * Create an empty instance, initialising the code sets to default * values. */ @@ -345,10 +350,6 @@ public class IOR * * @param c a stream to read from. * @throws IOException if the stream throws it. - * @throws BAD_PARAM, minor code 10, if the stream contents - * requires to switch into currently unsupported Little Endian mode. - * - * FIXME TODO Implement Little Endian mode. */ public void _read(cdrInput c) throws IOException, BAD_PARAM @@ -357,9 +358,10 @@ public class IOR endian = c.read_long(); if (endian != 0) - throw new BAD_PARAM("Little endian is not yet supported", FAILED, - CompletionStatus.COMPLETED_NO - ); + { + Big_Endian = false; + c.setBigEndian(false); + } _read_no_endian(c); } @@ -371,8 +373,6 @@ public class IOR * * @param c a stream to read from. * @throws IOException if the stream throws it. - * @throws BAD_PARAM, minor code 10, if the stream contents - * requires to switch into currently unsupported Little Endian mode. */ public void _read_no_endian(cdrInput c) throws IOException, BAD_PARAM @@ -402,7 +402,8 @@ public class IOR try { - n_components = profile.read_long(); + if (Internet.version.since_inclusive(1, 1)) + n_components = profile.read_long(); for (int t = 0; t < n_components; t++) { @@ -487,6 +488,10 @@ public class IOR b.append(Id); b.append(" at "); b.append(Internet); + + if (!Big_Endian) + b.append(" (Little endian) "); + b.append(" Key "); for (int i = 0; i < key.length; i++) @@ -526,4 +531,4 @@ public class IOR return b.toString(); } -} +}
\ No newline at end of file diff --git a/gnu/CORBA/IOR_Delegate.java b/gnu/CORBA/IOR_Delegate.java index 799704dc5..5b02fc2db 100644 --- a/gnu/CORBA/IOR_Delegate.java +++ b/gnu/CORBA/IOR_Delegate.java @@ -211,7 +211,9 @@ public class IOR_Delegate } catch (IOException ex) { - throw new MARSHAL(ex + " while reading the forwarding info"); + MARSHAL t = new MARSHAL("Cant read forwarding info"); + t.initCause(ex); + throw t; } request.request.setIor(forwarded); diff --git a/gnu/CORBA/ServiceRequestAdapter.java b/gnu/CORBA/ServiceRequestAdapter.java new file mode 100644 index 000000000..f584eb7a3 --- /dev/null +++ b/gnu/CORBA/ServiceRequestAdapter.java @@ -0,0 +1,159 @@ +/* ServiceRequestConverter.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.cdrBufOutput; + +import org.omg.CORBA.ARG_IN; +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ServerRequest; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.Streamable; + +/** + * This class exists to handle obsolete invocation style using + * ServerRequest. + * + * @deprecated The method {@link ObjectImpl#_invoke} is much faster. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ServiceRequestAdapter + implements ResponseHandler +{ + /** + * A buffer for writing the response. + */ + cdrBufOutput reply = new cdrBufOutput(); + + /** + * If set to true, an exception has been thrown during the invocation. + */ + boolean isException; + + public OutputStream createExceptionReply() + { + isException = true; + return reply; + } + + public OutputStream createReply() + { + isException = false; + return reply; + } + + /** + * The old style invocation using the currently deprecated server + * request class. + * + * @param request a server request, containg the invocation information. + * @param target the invocation target + * @param result the result holder with the set suitable streamable to read + * the result or null for void. + */ + public static void invoke(ServerRequest request, InvokeHandler target, + Streamable result + ) + { + try + { + int IN = ARG_IN.value; + int OUT = ARG_OUT.value; + + // Write all arguments to the buffer output stream. + cdrBufOutput buffer = new cdrBufOutput(); + gnuNVList args = new gnuNVList(); + request.arguments(args); + + for (int i = 0; i < args.count(); i++) + { + if ((args.item(i).flags() & IN) != 0) + { + args.item(i).value().write_value(buffer); + } + } + + ServiceRequestAdapter h = new ServiceRequestAdapter(); + + target._invoke(request.operation(), buffer.create_input_stream(), h); + + InputStream in = h.reply.create_input_stream(); + + if (h.isException) + { + // Write the exception information + gnuAny exc = new gnuAny(); + universalHolder uku = new universalHolder(h.reply); + exc.insert_Streamable(uku); + request.set_exception(exc); + } + else + { + if (result != null) + { + result._read(in); + gnuAny r = new gnuAny(); + r.insert_Streamable(result); + request.set_result(r); + }; + + // Unpack the arguments + for (int i = 0; i < args.count(); i++) + { + if ((args.item(i).flags() & OUT) != 0) + { + Any a = args.item(i).value(); + a.read_value(in, a.type()); + } + } + } + } + catch (Bounds ex) + { + throw new InternalError(); + } + } +}
\ No newline at end of file diff --git a/gnu/CORBA/SetOverrideTypeHolder.java b/gnu/CORBA/SetOverrideTypeHolder.java new file mode 100644 index 000000000..d1fcc18f3 --- /dev/null +++ b/gnu/CORBA/SetOverrideTypeHolder.java @@ -0,0 +1,90 @@ +/* SetOverrideTypeHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.CORBA; + +import org.omg.CORBA.SetOverrideType; +import org.omg.CORBA.SetOverrideTypeHelper; + +/** + * The holder for SetOverrideType. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class SetOverrideTypeHolder + implements org.omg.CORBA.portable.Streamable +{ + /** + * The stored SetOverrideType value. + */ + public SetOverrideType value; + + /** + * Create the initialised instance. + * + * @param initialValue the initial value. + */ + public SetOverrideTypeHolder(SetOverrideType initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + */ + public void _read(org.omg.CORBA.portable.InputStream in) + { + value = SetOverrideTypeHelper.read(in); + } + + /** + * Get the typecode of the SetOverrideType. + */ + public org.omg.CORBA.TypeCode _type() + { + return SetOverrideTypeHelper.type(); + } + + /** + * Write the stored value into the CDR stream. + */ + public void _write(org.omg.CORBA.portable.OutputStream out) + { + SetOverrideTypeHelper.write(out, value); + } +}
\ No newline at end of file diff --git a/gnu/CORBA/Simple_delegate.java b/gnu/CORBA/Simple_delegate.java index 9d6aab060..662dfef18 100644 --- a/gnu/CORBA/Simple_delegate.java +++ b/gnu/CORBA/Simple_delegate.java @@ -238,13 +238,12 @@ public class Simple_delegate } /** - * Not implemented for this delegate. + * This should never be called this type delegate. * - * @throws NO_IMPLEMENT, always. + * @throws InternalError, always. */ public Request request(org.omg.CORBA.Object target, String operation) { - /**@todo Implement this org.omg.CORBA.portable.Delegate abstract method*/ - throw new java.lang.UnsupportedOperationException("Method request() not yet implemented."); + throw new InternalError(); } } diff --git a/gnu/CORBA/binaryReply.java b/gnu/CORBA/binaryReply.java index 44d9e8dc8..6d3c19291 100644 --- a/gnu/CORBA/binaryReply.java +++ b/gnu/CORBA/binaryReply.java @@ -89,6 +89,7 @@ class binaryReply in.setOffset(header.getHeaderSize()); in.setVersion(header.version); in.setOrb(orb); + in.setBigEndian(header.isBigEndian()); return in; } } diff --git a/gnu/CORBA/gnuNVList.java b/gnu/CORBA/gnuNVList.java index f61afd7a6..e423df3b4 100644 --- a/gnu/CORBA/gnuNVList.java +++ b/gnu/CORBA/gnuNVList.java @@ -74,13 +74,13 @@ public class gnuNVList /** {@inheritDoc} */ public NamedValue add(int a_flags) { - return add_value(null, null, a_flags); + return add_value(null, new gnuAny(), a_flags); } /** {@inheritDoc} */ public NamedValue add_item(String a_name, int a_flags) { - return add_value(a_name, null, a_flags); + return add_value(a_name, new gnuAny(), a_flags); } /** {@inheritDoc} */ @@ -93,17 +93,17 @@ public class gnuNVList list.add(n); return n; } - + /** * Add the given named value to the list directly. - * + * * @param value the named vaue to add. */ public void add(NamedValue value) { list.add(value); - } - + } + /** {@inheritDoc} */ public int count() diff --git a/gnu/CORBA/gnuRequest.java b/gnu/CORBA/gnuRequest.java index 0665e919b..745b350d5 100644 --- a/gnu/CORBA/gnuRequest.java +++ b/gnu/CORBA/gnuRequest.java @@ -69,6 +69,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import org.omg.CORBA.UnknownUserException; /** * The implementation of the CORBA request. @@ -172,13 +173,26 @@ public class gnuRequest private ORB orb; /** + * The encoding, used to send the message. + * + * The default encoding is inherited from the set IOR + * (that string reference can be encoded in either Big or + * Little endian). If the IOR encoding is not known + * (for example, by obtaining the reference from the naming + * service), the Big Endian is used. + */ + private boolean Big_endian = true; + + /** * Set the IOR data, sufficient to find the invocation target. + * This also sets default endian encoding for invocations. * * @see IOR.parse(String) */ public void setIor(IOR an_ior) { ior = an_ior; + setBigEndian(ior.Big_Endian); } /** @@ -200,6 +214,22 @@ public class gnuRequest } /** + * Set the encoding that will be used to send the message. + * The default encoding is inherited from the set IOR + * (that string reference can be encoded in either Big or + * Little endian). If the IOR encoding is not known + * (for example, by obtaining the reference from the naming + * service), the Big Endian is used. + * + * @param use_big_endian true to use the Big Endian, false + * to use the Little Endian encoding. + */ + public void setBigEndian(boolean use_big_endian) + { + Big_endian = use_big_endian; + } + + /** * The the method name to invoke. * * @param operation the method name. @@ -220,6 +250,7 @@ public class gnuRequest m_parameter_buffer.setVersion(ior.Internet.version); m_parameter_buffer.setCodeSet(cxCodeSet.negotiate(ior.CodeSets)); m_parameter_buffer.setOrb(orb); + m_parameter_buffer.setBigEndian(Big_endian); return m_parameter_buffer; } @@ -574,6 +605,8 @@ public class gnuRequest { gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader(); + header.setBigEndian(Big_endian); + // The byte order will be Big Endian by default. header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST; header.version = useVersion(ior.Internet.version); @@ -590,6 +623,7 @@ public class gnuRequest request_part.setVersion(header.version); request_part.setCodeSet(cxCodeSet.negotiate(ior.CodeSets)); request_part.setOrb(orb); + request_part.setBigEndian(header.isBigEndian()); // This also sets the stream encoding to the encoding, specified // in the header. @@ -638,7 +672,7 @@ public class gnuRequest reading: while (n < r.length) { - n = socketInput.read(r, n, r.length - n); + n += socketInput.read(r, n, r.length - n); } socketInput.close(); return new binaryReply(orb, response_header, r); @@ -786,17 +820,15 @@ public class gnuRequest input.align(8); align = false; } - input.mark(2000); - String uxId = input.read_string(); - input.reset(); + // Prepare an Any that will hold the exception. + gnuAny exc = new gnuAny(); + + exc.insert_Streamable(new streamReadyHolder(input)); - UserException uex = ObjectCreator.readUserException(uxId, input); + UnknownUserException unuex = new UnknownUserException(exc); + m_environment.exception(unuex); - if (uex == null) - m_environment.exception(new UserException(uxId)); - else - m_environment.exception(uex); break; case ReplyHeader.LOCATION_FORWARD_PERM : diff --git a/gnu/CORBA/streamReadyHolder.java b/gnu/CORBA/streamReadyHolder.java new file mode 100644 index 000000000..db35495c0 --- /dev/null +++ b/gnu/CORBA/streamReadyHolder.java @@ -0,0 +1,120 @@ +/* streamReadyHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + +package gnu.CORBA; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +import java.io.IOException; + +/** + * A holder that stores the input stream, from that the holder data + * can be read. There is no way to write the data into this holder. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class streamReadyHolder + implements Streamable +{ + /** + * The stream, holding the data for this holder. + */ + protected final InputStream stream; + + /** + * Create a holder that will read from the given stream. + * + * @param a_stream a stream. + */ + public streamReadyHolder(InputStream a_stream) + { + stream = a_stream; + } + + /** + * This method is not in use, should never be called. + */ + public TypeCode _type() + { + throw new NO_IMPLEMENT(); + } + + /** + * Writes the data from the stored stream into the provided + * output stream till the end of the input stream is reached. + * + * @throws MARSHAL if the IOException is thrown during operation. + */ + public void _write(OutputStream output) + { + try + { + int d = stream.read(); + + while (d >= 0) + { + output.write(d); + d = stream.read(); + } + } + catch (IOException ex) + { + throw new MARSHAL(ex + ":" + ex.getMessage()); + } + } + + /** + * This method is not in use, should never be called. + */ + public void _read(InputStream input) + { + throw new NO_IMPLEMENT(); + } + + /** + * Get the input stream that has been passed in constructor. + */ + InputStream getInputStream() + { + return stream; + } +}
\ No newline at end of file diff --git a/gnu/CORBA/universalHolder.java b/gnu/CORBA/universalHolder.java index 6cfab80d2..1a5226c3e 100644 --- a/gnu/CORBA/universalHolder.java +++ b/gnu/CORBA/universalHolder.java @@ -109,7 +109,9 @@ class universalHolder } catch (IOException ex) { - throw new MARSHAL(ex.getClass().getName() + ":" + ex.getMessage()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } @@ -139,7 +141,9 @@ class universalHolder } catch (IOException ex) { - throw new MARSHAL(ex.getClass().getName() + ":" + ex.getMessage()); + MARSHAL t = new MARSHAL(); + t.initCause(ex); + throw t; } } diff --git a/gnu/java/awt/GradientPaintContext.java b/gnu/java/awt/GradientPaintContext.java new file mode 100644 index 000000000..6073917cd --- /dev/null +++ b/gnu/java/awt/GradientPaintContext.java @@ -0,0 +1,164 @@ +/* GradientPaintContext.java -- + Copyright (C) 2005, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + +package gnu.java.awt; + +import java.awt.geom.Point2D; +import java.awt.image.ColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.PaintContext; +import java.awt.Color; + +/** + * A {@link PaintContext} used by the {@link GradientPaint} class. + */ +public class GradientPaintContext implements PaintContext +{ + + // This implementation follows the technique described in + // "Java(tm) 2D Graphics" by Jonathan Knudsen (O'Reilly 1999). + + /** The x-coordinate of the anchor point for color 1. */ + private final float x1; + + /** The y-coordinate of the anchor point for color 1. */ + private final float y1; + + /** Color 1. */ + private final Color c1; + + /** The x-coordinate of the anchor point for color 2. */ + private final float x2; + + /** The y-coordinate of the anchor point for color 2. */ + private final float y2; + + /** Color 2. */ + private final Color c2; + + /** A flag indicating whether the gradient is cyclic or acyclic. */ + private final boolean cyclic; + + /** The length of the gradient line - computed from the two anchor points. */ + private final double length; + + /** + * Creates a new instance. + * + * @param x1 the x-coordinate for the anchor point for color 1. + * @param y1 the y-coordinate for the anchor point for color 1. + * @param c1 color 1. + * @param x2 the x-coordinate for the anchor point for color 2. + * @param y2 the y-coordinate for the anchor point for color 2. + * @param c2 color 2. + * @param cyclic a flag that determines whether the gradient is cyclic + * or acyclic. + */ + public GradientPaintContext(float x1, float y1, Color c1, + float x2, float y2, Color c2, boolean cyclic) + { + this.x1 = x1; + this.y1 = y1; + this.c1 = c1; + this.x2 = x2; + this.y2 = y2; + this.c2 = c2; + this.cyclic = cyclic; + length = Point2D.distance(x1, y1, x2, y2); + } + + /** + * Return the color model of this context. It may be different from the + * hint specified during createContext, as not all contexts can generate + * color patterns in an arbitrary model. + * + * @return the context color model + */ + public ColorModel getColorModel() + { + return ColorModel.getRGBdefault(); + } + + /** + * Return a raster containing the colors for the graphics operation. + * + * @param x the x-coordinate, in device space + * @param y the y-coordinate, in device space + * @param w the width, in device space + * @param h the height, in device space + * @return a raster for the given area and color + */ + public Raster getRaster(int x, int y, int w, int h) { + ColorModel cm = getColorModel(); + WritableRaster raster = cm.createCompatibleWritableRaster(w, h); + int[] data = new int[w * h * 4]; + double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + for (int r = 0; r < h; r++) { + for (int c = 0; c < w; c++) { + double u = 0.0; + if (pd2 != 0) + u = (((x + c) - x1) * (x2 - x1) + ((y + r) - y1) * (y2 - y1)) + / Math.sqrt(pd2); + double ratio = u / length; + if (cyclic) + ratio = Math.abs(ratio - Math.floor((ratio + 1.0) / 2.0) * 2.0); + else + ratio = Math.max(0.0, Math.min(1.0, ratio)); + int base = (r * w + c) * 4; + data[base] = (int) (c1.getRed() + ratio * (c2.getRed() - c1.getRed())); + data[base + 1] + = (int) (c1.getGreen() + ratio * (c2.getGreen() - c1.getGreen())); + data[base + 2] + = (int) (c1.getBlue() + ratio * (c2.getBlue() - c1.getBlue())); + data[base + 3] + = (int) (c1.getAlpha() + ratio * (c2.getAlpha() - c1.getAlpha())); + } + } + raster.setPixels(0, 0, w, h, data); + return raster; + } + + /** + * Release the resources allocated for the paint (none in this + * implementation). + */ + public void dispose() { + // nothing to do + } + +} diff --git a/gnu/java/awt/peer/gtk/GdkGraphics.java b/gnu/java/awt/peer/gtk/GdkGraphics.java index 70b3abca7..c870dc1d4 100644 --- a/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -58,6 +58,7 @@ public class GdkGraphics extends Graphics GtkComponentPeer component; Font font; Rectangle clip; + GtkImage image; int xOffset = 0; int yOffset = 0; @@ -66,6 +67,7 @@ public class GdkGraphics extends Graphics native void initState (GtkComponentPeer component); native void initState (int width, int height); + native void initFromImage (GtkImage image); native void copyState (GdkGraphics g); GdkGraphics (GdkGraphics g) @@ -87,10 +89,21 @@ public class GdkGraphics extends Graphics font = new Font ("Dialog", Font.PLAIN, 12); } + GdkGraphics (GtkImage image) + { + this.image = image; + initFromImage (image); + color = Color.black; + clip = new Rectangle (0, 0, + image.getWidth(null), image.getHeight(null)); + font = new Font ("Dialog", Font.PLAIN, 12); + } + GdkGraphics (GtkComponentPeer component) { this.component = component; font = component.awtComponent.getFont (); + color = Color.black; if (component.isRealized ()) initComponentGraphics (); @@ -129,169 +142,57 @@ public class GdkGraphics extends Graphics public native void dispose(); - native void copyPixmap (Graphics g, int x, int y, int width, int height); - native void copyAndScalePixmap (Graphics g, boolean flip_x, boolean flip_y, - int src_x, int src_y, - int src_width, int src_height, - int dest_x, int dest_y, - int dest_width, int dest_height); public boolean drawImage (Image img, int x, int y, Color bgcolor, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (img instanceof GtkOffScreenImage) - { - int width = img.getWidth (null); - int height = img.getHeight (null); - copyPixmap (img.getGraphics (), - x, y, width, height); - return true; - } - - GtkImage image = (GtkImage) img; - new GtkImagePainter (image, this, x, y, -1, -1, bgcolor, observer); - return image.isLoaded (); + return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), + bgcolor, observer); } public boolean drawImage (Image img, int x, int y, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (img instanceof GtkOffScreenImage) - { - int width = img.getWidth (null); - int height = img.getHeight (null); - copyPixmap (img.getGraphics (), - x, y, width, height); - return true; - } - - if (component != null) - return drawImage (img, x, y, component.getBackground (), observer); - else - return drawImage (img, x, y, SystemColor.window, observer); + return drawImage (img, x, y, null, observer); } public boolean drawImage (Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (img instanceof GtkOffScreenImage) - { - copyAndScalePixmap (img.getGraphics (), false, false, - 0, 0, img.getWidth (null), img.getHeight (null), - x, y, width, height); - return true; - } - - GtkImage image = (GtkImage) img; - new GtkImagePainter (image, this, x, y, width, height, bgcolor, observer); - return image.isLoaded (); + if (img instanceof GtkImage) + return ((GtkImage)img).drawImage (this, x, y, width, height, + bgcolor, observer); + else + return (new GtkImage(img.getSource())).drawImage (this, x, y, + width, height, + bgcolor, observer); } public boolean drawImage (Image img, int x, int y, int width, int height, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (component != null) - return drawImage (img, x, y, width, height, component.getBackground (), - observer); - else - return drawImage (img, x, y, width, height, SystemColor.window, - observer); + return drawImage (img, x, y, width, height, null, observer); } public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (img instanceof GtkOffScreenImage) - { - int dx_start, dy_start, d_width, d_height; - int sx_start, sy_start, s_width, s_height; - boolean x_flip = false; - boolean y_flip = false; - - if (dx1 < dx2) - { - dx_start = dx1; - d_width = dx2 - dx1; - } - else - { - dx_start = dx2; - d_width = dx1 - dx2; - x_flip ^= true; - } - if (dy1 < dy2) - { - dy_start = dy1; - d_height = dy2 - dy1; - } - else - { - dy_start = dy2; - d_height = dy1 - dy2; - y_flip ^= true; - } - if (sx1 < sx2) - { - sx_start = sx1; - s_width = sx2 - sx1; - } - else - { - sx_start = sx2; - s_width = sx1 - sx2; - x_flip ^= true; - } - if (sy1 < sy2) - { - sy_start = sy1; - s_height = sy2 - sy1; - } - else - { - sy_start = sy2; - s_height = sy1 - sy2; - y_flip ^= true; - } - - copyAndScalePixmap (img.getGraphics (), x_flip, y_flip, - sx_start, sy_start, s_width, s_height, - dx_start, dy_start, d_width, d_height); - return true; - } - - GtkImage image = (GtkImage) img; - new GtkImagePainter (image, this, dx1, dy1, dx2, dy2, - sx1, sy1, sx2, sy2, bgcolor, observer); - return image.isLoaded (); + if (img instanceof GtkImage) + return ((GtkImage)img).drawImage(this, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, bgcolor, observer); + else + return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, + dx2, dy2, + sx1, sy1, sx2, sy2, + bgcolor, observer); } public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - if (component != null && ! component.isRealized ()) - return false; - - if (component != null) - return drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, - component.getBackground (), observer); - else - return drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, - SystemColor.window, observer); + return drawImage (img, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, + null, observer); } public native void drawLine(int x1, int y1, int x2, int y2); diff --git a/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 6c04f7834..0ddc1c7a8 100644 --- a/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -510,21 +510,22 @@ public class GdkGraphics2D extends Graphics2D if (img == null) return false; - if (img instanceof GtkOffScreenImage - && img.getGraphics() instanceof GdkGraphics2D - && (xform == null || xform.getType() == AffineTransform.TYPE_IDENTITY - || xform.getType() == AffineTransform.TYPE_TRANSLATION)) - { - // we are being asked to flush a double buffer from Gdk - GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics(); - gdkDrawDrawable(g2, (int) xform.getTranslateX(), - (int) xform.getTranslateY()); - - updateBufferedImage(); - - return true; - } - else + // FIXME: I'll fix this, /Sven +// if (img instanceof GtkOffScreenImage +// && img.getGraphics() instanceof GdkGraphics2D +// && (xform == null || xform.getType() == AffineTransform.TYPE_IDENTITY +// || xform.getType() == AffineTransform.TYPE_TRANSLATION)) +// { +// // we are being asked to flush a double buffer from Gdk +// GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics(); +// gdkDrawDrawable(g2, (int) xform.getTranslateX(), +// (int) xform.getTranslateY()); + +// updateBufferedImage(); + +// return true; +// } +// else { // In this case, xform is an AffineTransform that transforms bounding // box of the specified image from image space to user space. However diff --git a/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/gnu/java/awt/peer/gtk/GtkComponentPeer.java index e3e7afb19..3a1bf8b66 100644 --- a/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -198,33 +198,21 @@ public class GtkComponentPeer extends GtkGenericPeer public int checkImage (Image image, int width, int height, ImageObserver observer) { - GtkImage i = (GtkImage) image; - return i.checkImage (); + return getToolkit().checkImage(image, width, height, observer); } public Image createImage (ImageProducer producer) { - GtkImage image = new GtkImage (producer, null); - producer.startProduction (image); - return image; + return new GtkImage (producer); } public Image createImage (int width, int height) { - Graphics g; - if (GtkToolkit.useGraphics2D ()) - { - Graphics2D g2 = new GdkGraphics2D (width, height); - g2.setBackground (getBackground ()); - g = g2; - } - else - g = new GdkGraphics (width, height); - + GtkImage image = new GtkImage (width, height); + Graphics g = image.getGraphics(); g.setColor(getBackground()); g.fillRect(0, 0, width, height); - - return new GtkOffScreenImage (null, g, width, height); + return image; } public void disable () @@ -353,29 +341,7 @@ public class GtkComponentPeer extends GtkGenericPeer public boolean prepareImage (Image image, int width, int height, ImageObserver observer) { - GtkImage i = (GtkImage) image; - - if (i.isLoaded ()) return true; - - class PrepareImage extends Thread - { - GtkImage image; - ImageObserver observer; - - PrepareImage (GtkImage image, ImageObserver observer) - { - this.image = image; - image.setObserver (observer); - } - - public void run () - { - image.source.startProduction (image); - } - } - - new PrepareImage (i, observer).start (); - return false; + return getToolkit().prepareImage(image, width, height, observer); } public void print (Graphics g) diff --git a/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/gnu/java/awt/peer/gtk/GtkContainerPeer.java index 61551835e..e4aea64c9 100644 --- a/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -115,9 +115,14 @@ public class GtkContainerPeer extends GtkComponentPeer Component[] components = ((Container) awtComponent).getComponents(); for (int i = 0; i < components.length; i++) { - GtkComponentPeer peer = (GtkComponentPeer) components[i].getPeer(); - if (peer != null && ! peer.awtComponent.isFontSet()) - peer.setFont(f); + if (components[i].isLightweight ()) + components[i].setFont (f); + else + { + GtkComponentPeer peer = (GtkComponentPeer) components[i].getPeer(); + if (peer != null && ! peer.awtComponent.isFontSet()) + peer.setFont(f); + } } } diff --git a/gnu/java/awt/peer/gtk/GtkFramePeer.java b/gnu/java/awt/peer/gtk/GtkFramePeer.java index b22a25e88..53e06bc08 100644 --- a/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -166,36 +166,17 @@ public class GtkFramePeer extends GtkWindowPeer setIconImage(frame.getIconImage()); } - native void nativeSetIconImageFromDecoder (GdkPixbufDecoder decoder); - native void nativeSetIconImageFromData (int[] pixels, int width, int height); + native void nativeSetIconImage (GtkImage image); + public void setIconImage (Image image) { - if (image != null && image instanceof GtkImage) - { - GtkImage img = (GtkImage) image; - // FIXME: Image should be loaded, but if not, do image loading here. - if (img.isLoaded()) - { - if (img.getSource() instanceof GdkPixbufDecoder) - { - nativeSetIconImageFromDecoder((GdkPixbufDecoder) img.getSource()); - } - else - { - int[] pixels = img.getPixelCache(); - ColorModel model = img.getColorModel(); - int[] data = new int[pixels.length * 4]; - for (int i = 0; i < pixels.length; i++) - { - data[i * 4] = model.getRed(pixels[i]); - data[i * 4 + 1] = model.getGreen(pixels[i]); - data[i * 4 + 2] = model.getBlue(pixels[i]); - data[i * 4 + 3] = model.getAlpha(pixels[i]); - } - nativeSetIconImageFromData(data, img.getWidth(null), img.getHeight(null)); - } - } - } + if (image != null) + { + if (image instanceof GtkImage) + nativeSetIconImage((GtkImage) image); + else + nativeSetIconImage(new GtkImage(image.getSource())); + } } public Graphics getGraphics () diff --git a/gnu/java/awt/peer/gtk/GtkImage.java b/gnu/java/awt/peer/gtk/GtkImage.java index 510646c5a..9b794b4aa 100644 --- a/gnu/java/awt/peer/gtk/GtkImage.java +++ b/gnu/java/awt/peer/gtk/GtkImage.java @@ -1,5 +1,5 @@ /* GtkImage.java - Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,306 +39,420 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Graphics; +import java.awt.Color; import java.awt.Image; import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; +import java.io.File; +import java.io.IOException; import java.util.Hashtable; import java.util.Vector; - -public class GtkImage extends Image implements ImageConsumer +import gnu.classpath.RawData; + +/** + * GtkImage - wraps a GdkPixbuf or GdkPixmap. + * + * The constructor GtkImage(int, int) creates an 'off-screen' GdkPixmap, + * this can be drawn to (it's a GdkDrawable), and correspondingly, you can + * create a GdkGraphics object for it. + * + * This corresponds to the Image implementation returned by + * Component.createImage(int, int). + * + * A GdkPixbuf is 'on-screen' and the gdk cannot draw to it, + * this is used for the other constructors (and other createImage methods), and + * corresponds to the Image implementations returned by the Toolkit.createImage + * methods, and is basically immutable. + * + * @author Sven de Marothy + */ +public class GtkImage extends Image { int width = -1, height = -1; - Hashtable props = null; - boolean isLoaded = false; - boolean isCacheable = true; - boolean loading = false; - - Vector widthObservers = new Vector (); - Vector heightObservers = new Vector (); - Vector propertyObservers = new Vector (); + /** + * Properties. + */ + Hashtable props; + + /** + * Loaded or not flag, for asynchronous compatibility. + */ + boolean isLoaded; + + /** + * Pointer to the GdkPixbuf + */ + RawData pixmap; + + /** + * Observer queue. + */ + Vector observers; + + /** + * If offScreen is set, a GdkBitmap is wrapped and not a Pixbuf. + */ + boolean offScreen; + + /** + * Original source, if created from an ImageProducer. + */ ImageProducer source; - ImageObserver observer; - Graphics g; - - /* Variables in which we stored cached data, if possible. - An image is cached if the following properties are true: - 1. The ColorModel passed into setColorModel is the same ColorModel - passed to all invocations of setPixels. - 2. The image contains a single frame. - - */ - int[] pixelCache; - ColorModel model; - - public - GtkImage (ImageProducer producer, Graphics g) + /* + * The 32-bit AABBGGRR format the GDK uses. + */ + static ColorModel nativeModel = new DirectColorModel(32, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); + + /** + * Returns a copy of the pixel data as a java array. + */ + private native int[] getPixels(); + + /** + * Sets the pixel data from a java array. + */ + private native void setPixels(int[] pixels); + + /** + * Loads an image using gdk-pixbuf. + */ + private native boolean loadPixbuf(String name); + + /** + * Allocates a Gtk Pixbuf or pixmap + */ + private native void createPixmap(); + + /** + * Frees the above. + */ + private native void freePixmap(); + + /** + * Sets the pixmap to scaled copy of src image. hints are rendering hints. + */ + private native void createScaledPixmap(GtkImage src, int hints); + + /** + * Draws the image, optionally scaled and composited. + */ + private native void drawPixelsScaled (GdkGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, int width, int height, + boolean composite); + + /** + * Draws the image, optionally scaled flipped and composited. + */ + private native void drawPixelsScaledFlipped (GdkGraphics gc, + int bg_red, int bg_green, + int bg_blue, + boolean flipX, boolean flipY, + int srcX, int srcY, + int srcWidth, int srcHeight, + int dstX, int dstY, + int dstWidth, int dstHeight, + boolean composite); + + /** + * Constructs a GtkImage from an ImageProducer. Asynchronity is handled in + * the following manner: + * A GtkImageConsumer gets the image data, and calls setImage() when + * completely finished. The GtkImage is not considered loaded until the + * GtkImageConsumer is completely finished. We go for all "all or nothing". + */ + public GtkImage (ImageProducer producer) { + isLoaded = false; + observers = new Vector(); source = producer; - this.g = g; + source.startProduction(new GtkImageConsumer(this, source)); + offScreen = false; + } - if (source != null) - source.addConsumer (this); + /** + * Constructs a GtkImage by loading a given file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public GtkImage (String filename) + { + File f = new File(filename); + try + { + if (loadPixbuf(f.getCanonicalPath()) != true) + throw new IllegalArgumentException("Couldn't load image: "+filename); + } + catch(IOException e) + { + throw new IllegalArgumentException("Couldn't load image: "+filename); + } + + isLoaded = true; + observers = null; + offScreen = false; + props = new Hashtable(); } - public void setObserver (ImageObserver observer) + /** + * Constructs an empty GtkImage. + */ + public GtkImage (int width, int height) { - this.observer = observer; + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + observers = null; + offScreen = true; + createPixmap(); } - public synchronized int[] - getPixelCache () + /** + * Constructs a scaled version of the src bitmap, using the GDK. + */ + private GtkImage (GtkImage src, int width, int height, int hints) { - return pixelCache; + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + observers = null; + offScreen = false; + + // Use the GDK scaling method. + createScaledPixmap(src, hints); } - public synchronized ColorModel - getColorModel () + /** + * Callback from the image consumer. + */ + public void setImage(int width, int height, + int[] pixels, Hashtable properties) { - return model; + this.width = width; + this.height = height; + props = (properties != null) ? properties : new Hashtable(); + isLoaded = true; + deliver(); + createPixmap(); + setPixels(pixels); } - public synchronized int - getWidth (ImageObserver observer) + // java.awt.Image methods //////////////////////////////////////////////// + + public synchronized int getWidth (ImageObserver observer) { - if (width == -1) - widthObservers.addElement (observer); - + if (addObserver(observer)) + return -1; + return width; } - public synchronized int - getHeight (ImageObserver observer) + public synchronized int getHeight (ImageObserver observer) { - if (height == -1) - heightObservers.addElement (observer); + if (addObserver(observer)) + return -1; return height; } - - public ImageProducer - getSource () - { - return source; - } - public Graphics - getGraphics () - { - return g; - } - - public synchronized Object - getProperty (String name, ImageObserver observer) + public synchronized Object getProperty (String name, ImageObserver observer) { - if (props == null) - { - propertyObservers.addElement (observer); - return null; - } + if (addObserver(observer)) + return UndefinedProperty; Object value = props.get (name); return (value == null) ? UndefinedProperty : value; } - public synchronized void - flush () + /** + * Returns the source of this image. + */ + public ImageProducer getSource () { - isLoaded = false; - isCacheable = true; - width = height = -1; - props = null; - pixelCache = null; - model = null; - - if (source != null) - { - source.removeConsumer (this); - source.addConsumer (this); - } + return new MemoryImageSource(width, height, nativeModel, getPixels(), + 0, width); } - public boolean - isLoaded () + /** + * Creates a GdkGraphics context for this pixmap. + */ + public Graphics getGraphics () { - return isLoaded; + if (!isLoaded) + return null; + if (offScreen) + return new GdkGraphics(this); + else + throw new IllegalAccessError("This method only works for off-screen" + +" Images."); } - - /* ImageConsumer methods */ - - public synchronized void - setDimensions (int width, int height) + + /** + * Returns a scaled instance of this pixmap. + */ + public Image getScaledInstance(int width, + int height, + int hints) { - pixelCache = new int[width*height]; + if (width <= 0 || height <= 0) + throw new IllegalArgumentException("Width and height of scaled bitmap"+ + "must be >= 0"); - this.width = width; - this.height = height; - - for (int i = 0; i < widthObservers.size (); i++) - { - ImageObserver io = (ImageObserver) widthObservers.elementAt (i); - if (io != null) - io.imageUpdate (this, ImageObserver.WIDTH, -1, -1, width, height); - } - - for (int i = 0; i < heightObservers.size (); i++) - { - ImageObserver io = (ImageObserver) heightObservers.elementAt (i); - if (io != null) - io.imageUpdate (this, ImageObserver.HEIGHT, -1, -1, width, height); - } - - if (observer != null) - observer.imageUpdate (this, - (ImageObserver.WIDTH - | ImageObserver.HEIGHT), - -1, -1, width, height); + return new GtkImage(this, width, height, hints); } - public synchronized void - setProperties (Hashtable props) + /** + * If the image is loaded and comes from an ImageProducer, + * regenerate the image from there. + * + * I have no idea if this is ever actually used. Since GtkImage can't be + * instantiated directly, how is the user to know if it was created from + * an ImageProducer or not? + */ + public synchronized void flush () { - this.props = props; - - for (int i = 0; i < propertyObservers.size (); i++) + if (isLoaded && source != null) { - ImageObserver io = (ImageObserver) propertyObservers.elementAt (i); - if (io != null) - io.imageUpdate (this, ImageObserver.PROPERTIES, -1, -1, width, height); + observers = new Vector(); + isLoaded = false; + freePixmap(); + source.startProduction(new GtkImageConsumer(this, source)); } } - public synchronized void - setColorModel (ColorModel model) - { - if (this.model == null || this.model.equals(model)) - this.model = model; - else - isCacheable = false; - } - - public synchronized void - setHints (int flags) + public void finalize() { + if (isLoaded) + freePixmap(); } - public synchronized void - setPixels (int x, int y, int width, int height, ColorModel cm, byte[] pixels, - int offset, int scansize) + /** + * Returns the image status, used by GtkToolkit + */ + public int checkImage (ImageObserver observer) { - setPixels (x, y, width, height, cm, convertPixels (pixels), offset, - scansize); + if (addObserver(observer)) + return 0; - if (observer != null) - observer.imageUpdate (this, - ImageObserver.SOMEBITS, - x, y, width, height); + return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT; } - public synchronized void - setPixels (int x, int y, int width, int height, ColorModel cm, int[] pixels, - int offset, int scansize) - { - loading = true; + // Drawing methods //////////////////////////////////////////////// - if (!isCacheable) - return; - - if (!cm.equals(model) || pixelCache == null) + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (GdkGraphics g, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + boolean flipX = (dx1 > dx2)^(sx1 > sx2); + boolean flipY = (dy1 > dy2)^(sy1 > sy2); + int dstWidth = Math.abs (dx2 - dx1); + int dstHeight = Math.abs (dy2 - dy1); + int srcWidth = Math.abs (sx2 - sx1); + int srcHeight = Math.abs (sy2 - sy1); + int srcX = (sx1 < sx2) ? sx1 : sx2; + int srcY = (sy1 < sy2) ? sy1 : sy2; + int dstX = (dx1 < dx2) ? dx1 : dx2; + int dstY = (dy1 < dy2) ? dy1 : dy2; + + // Clipping. This requires the dst to be scaled as well, + if (srcWidth + srcX > width) { - isCacheable = false; - return; - } + dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth); + srcWidth = width - srcX; + } - if (scansize == width && height == 1) - { - // Copy contents of pixels array into pixel cache. - System.arraycopy (pixels, offset, - pixelCache, y * this.width + x, - pixels.length - offset); - } - else // skip over scansize-width for each row + if (srcHeight + srcY > height) { - for (int i = 0; i < height; i++) - System.arraycopy (pixels, offset + (i * scansize), - pixelCache, (y + i) * this.width + x, - width); + dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight); + srcHeight = height - srcY; } + + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + return true; } - public synchronized void - imageComplete (int status) + /** + * Draws an image to the GdkGraphics context, at (x,y) scaled to + * width and height, with optional compositing with a background color. + */ + public boolean drawImage (GdkGraphics g, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { - if (status == ImageConsumer.STATICIMAGEDONE && isCacheable) - isLoaded = true; + if (addObserver(observer)) + return false; - if (status == ImageConsumer.SINGLEFRAME) - isCacheable = false; - - if (observer != null) - { - if (status == ImageConsumer.IMAGEERROR) - observer.imageUpdate (null, - ImageObserver.ERROR, - -1, -1, -1, -1); - else - observer.imageUpdate (null, - ImageObserver.ALLBITS, - -1, -1, -1, -1); - } + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); - if (source != null && status != ImageConsumer.SINGLEFRAME) - source.removeConsumer (this); + return true; } - public synchronized void - startProduction (GtkImagePainter painter) - { - if (isLoaded) - { - painter.setDimensions (width, height); - painter.setPixels (0, 0, width, height, model, pixelCache, 0, width); - } - else - { - if (source != null) - { - source.startProduction (painter); - source.removeConsumer (painter); - } - } - } + // Private methods //////////////////////////////////////////////// - private int[] - convertPixels (byte[] pixels) + /** + * Delivers notifications to all queued observers. + */ + private void deliver() { - int ret[] = new int[pixels.length]; + int flags = ImageObserver.HEIGHT | + ImageObserver.WIDTH | + ImageObserver.PROPERTIES | + ImageObserver.ALLBITS; - for (int i = 0; i < pixels.length; i++) - ret[i] = pixels[i]; - - return ret; - } + for(int i=0; i < observers.size(); i++) + ((ImageObserver)observers.elementAt(i)). + imageUpdate(this, flags, 0, 0, width, height); - synchronized int - checkImage () + observers = null; + } + + /** + * Adds an observer, if we need to. + * @return true if an observer was added. + */ + private boolean addObserver(ImageObserver observer) { - int bits = 0; - - if (width != -1) - bits |= ImageObserver.WIDTH; - if (height != -1) - bits |= ImageObserver.HEIGHT; - if (props != null) - bits |= ImageObserver.PROPERTIES; - if (loading) - bits |= ImageObserver.SOMEBITS; - if (isLoaded) - bits |= ImageObserver.ALLBITS; - - return bits; + if (!isLoaded) + { + if(observer != null) + if (!observers.contains (observer)) + observers.addElement (observer); + return true; + } + return false; } } diff --git a/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/gnu/java/awt/peer/gtk/GtkImageConsumer.java new file mode 100644 index 000000000..93743fe1a --- /dev/null +++ b/gnu/java/awt/peer/gtk/GtkImageConsumer.java @@ -0,0 +1,155 @@ +/* GtkImageConsumer.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +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. */ + + +package gnu.java.awt.peer.gtk; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Helper class to GtkImage. Sits and gathers pixels for a GtkImage and then + * calls GtkImage.setImage(). + * + * @author Sven de Marothy + */ +public class GtkImageConsumer implements ImageConsumer +{ + private GtkImage target; + private int width, height; + private Hashtable properties; + private int[] pixelCache = null; + private ImageProducer source; + + public GtkImageConsumer(GtkImage target, ImageProducer source) + { + this.target = target; + this.source = source; + } + + public synchronized void imageComplete (int status) + { + source.removeConsumer(this); + target.setImage(width, height, pixelCache, properties); + } + + public synchronized void setColorModel (ColorModel model) + { + // This method is to inform on what the most used color model + // in the image is, for optimization reasons. We ignore this + // information. + } + + public synchronized void setDimensions (int width, int height) + { + pixelCache = new int[width*height]; + + this.width = width; + this.height = height; + } + + public synchronized void setHints (int flags) + { + // This method informs us in which order the pixels are + // delivered, for progressive-loading support, etc. + // Since we wait until it's all loaded, we can ignore the hints. + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, byte[] pixels, + int offset, int scansize) + { + setPixels (x, y, width, height, cm, convertPixels (pixels), offset, + scansize); + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, int[] pixels, + int offset, int scansize) + { + if (pixelCache == null) + return; // Not sure this should ever happen. + + if (cm.equals(GtkImage.nativeModel)) + for (int i = 0; i < height; i++) + System.arraycopy (pixels, offset + (i * scansize), + pixelCache, (y + i) * this.width + x, + width); + else + { + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + { + // get in AARRGGBB and convert to AABBGGRR + int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]); + byte b = (byte)(pix & 0xFF); + byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF); + pix &= 0xFF00FF00; + pix |= ((b & 0xFF) << 16); + pix |= (r & 0xFF); + pixelCache[(y + i) * this.width + x + j] = pix; + } + } + } + + /** + * This is an old method, no idea if it's correct. + */ + private int[] convertPixels (byte[] pixels) + { + int ret[] = new int[pixels.length]; + + for (int i = 0; i < pixels.length; i++) + ret[i] = pixels[i] & 0xFF; + + return ret; + } + + public synchronized void setProperties (Hashtable props) + { + this.properties = props; + } +} + + diff --git a/gnu/java/awt/peer/gtk/GtkImagePainter.java b/gnu/java/awt/peer/gtk/GtkImagePainter.java deleted file mode 100644 index 9f2ecb7dc..000000000 --- a/gnu/java/awt/peer/gtk/GtkImagePainter.java +++ /dev/null @@ -1,267 +0,0 @@ -/* GtkImagePainter.java - Copyright (C) 1999, 2000 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -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. */ - - -package gnu.java.awt.peer.gtk; - -import java.awt.Color; -import java.awt.Rectangle; -import java.awt.image.ColorModel; -import java.awt.image.ImageConsumer; -import java.awt.image.ImageObserver; -import java.util.Hashtable; - -public class GtkImagePainter implements Runnable, ImageConsumer -{ - GtkImage image; - GdkGraphics gc; - int startX, startY; - int redBG; - int greenBG; - int blueBG; - double affine[]; - int width, height; - boolean flipX, flipY; - Rectangle clip; - int s_width, s_height; - ImageObserver observer; - - public - GtkImagePainter (GtkImage image, GdkGraphics gc, int x, int y, - int width, int height, Color bgcolor, ImageObserver o) - { - this.image = image; - this.gc = (GdkGraphics) gc.create (); - startX = x; - startY = y; - redBG = bgcolor.getRed (); - greenBG = bgcolor.getGreen (); - blueBG = bgcolor.getBlue (); - this.width = width; - this.height = height; - flipX = flipY = false; - s_width = s_height = 0; - clip = null; - observer = o; - - run (); - } - - public - GtkImagePainter (GtkImage image, GdkGraphics gc, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, ImageObserver o) - { - this.image = image; - this.gc = (GdkGraphics) gc.create (); - startX = (dx1 < dx2) ? dx1 : dx2; - startY = dy1; - redBG = bgcolor.getRed (); - greenBG = bgcolor.getGreen (); - blueBG = bgcolor.getBlue (); - observer = o; - - this.width = Math.abs (dx2 - dx1); - this.height = Math.abs (dy2 - dy1); - - flipX = ((dx1 > dx2 && sx2 > sx1) - || (dx1 < dx2 && sx2 < sx1)); - - flipY = ((dy1 > dy2 && sy2 > sy1) - || (dy1 < dy2 && sy2 < sy1)); - - s_width = Math.abs (sx2 - sx1); - s_height = Math.abs (sy2 - sy1); - clip = new Rectangle (sx1, sy1, s_width, s_height); - - run (); - } - - public void - run () - { - image.startProduction (this); - gc.dispose (); - } - - /* Convert pixel data into a format that gdkrgb can understand */ - static int[] - convertPixels (int[] pixels, ColorModel model) - { - if (pixels == null || model == null) - { - return null; - } - - if (model.equals (ColorModel.getRGBdefault ())) - return pixels; - - int ret[] = new int[pixels.length]; - - for (int i = 0; i < pixels.length; i++) - ret[i] = model.getRGB (pixels[i]); - - return ret; - } - - static int[] - convertPixels (byte[] pixels, ColorModel model) - { - if (pixels == null || model == null) - { - return null; - } - - int ret[] = new int[pixels.length]; - - for (int i = 0; i < pixels.length; i++) - ret[i] = model.getRGB (pixels[i]); - - return ret; - } - - native void - drawPixels (GdkGraphics gc, int bg_red, int bg_green, int bg_blue, - int x, int y, int width, int height, int[] pixels, int offset, - int scansize, double affine[]); - - - public void - setPixels (int x, int y, int width, int height, ColorModel model, - int[] pixels, int offset, int scansize) - { - if (clip != null) - { - Rectangle r; - r = clip.intersection (new Rectangle (x, y, width, height)); - if (r.width == 0 && r.height == 0) - return; - - offset += r.y * scansize + r.x; - - width = r.width; - height = r.height; - x = r.x; - y = r.y; - } - - drawPixels (gc, redBG, greenBG, blueBG, - startX + x, startY + y, - width, height, convertPixels (pixels, model), offset, - scansize, affine); - } - - public void - setPixels (int x, int y, int width, int height, ColorModel model, - byte[] pixels, int offset, int scansize) - { - setPixels (x, y, width, height, ColorModel.getRGBdefault(), - convertPixels (pixels, model), offset, scansize); - } - - public void - setDimensions (int width, int height) - { - if (!flipX && !flipY && - ((this.width == -1 && this.height == -1) - || (this.width == width && this.height == height))) - return; - - affine = new double[6]; - affine[1] = affine[2] = affine[4] = affine[5] = 0; - - if (clip != null) - { - affine[0] = this.width / (double) s_width; - affine[3] = this.height / (double) s_height; - } - else - { - affine[0] = this.width / (double) width; - affine[3] = this.height / (double) height; - } - - if (flipX) - { - affine[0] = -affine[0]; - affine[4] = this.width; - } - - if (flipY) - { - affine[3] = -affine[3]; - affine[5] = this.height; - } - - if (affine[0] == 1 && affine[3] == 1) - affine = null; - } - - public void - setProperties (Hashtable props) - { - } - - public void - setColorModel (ColorModel model) - { - } - - public void - setHints (int flags) - { - } - - public void - imageComplete (int status) - { - image.imageComplete(status); - - if (observer != null) - { - if (status == ImageConsumer.IMAGEERROR) - observer.imageUpdate (null, - ImageObserver.ERROR, - -1, -1, -1, -1); - else - observer.imageUpdate (null, - ImageObserver.ALLBITS, - -1, -1, -1, -1); - } - } -} diff --git a/gnu/java/awt/peer/gtk/GtkToolkit.java b/gnu/java/awt/peer/gtk/GtkToolkit.java index 3bbbe27ac..5c0ab5438 100644 --- a/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -53,6 +53,7 @@ import java.awt.font.FontRenderContext; import java.awt.im.InputMethodHighlight; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; @@ -140,9 +141,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit | ImageObserver.HEIGHT; if (image instanceof GtkImage) - { - status = ((GtkImage) image).checkImage (); - } + return ((GtkImage) image).checkImage (observer); if (observer != null) observer.imageUpdate (image, status, @@ -250,12 +249,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit if (useGraphics2D()) return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (filename)); else - { - GdkPixbufDecoder d = new GdkPixbufDecoder (filename); - GtkImage image = new GtkImage (d, null); - d.startProduction (image); - return image; - } + return new GtkImage (filename); } public Image createImage (URL url) @@ -265,8 +259,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit else { GdkPixbufDecoder d = new GdkPixbufDecoder (url); - GtkImage image = new GtkImage (d, null); - d.startProduction (image); + GtkImage image = new GtkImage (d); return image; } } @@ -276,11 +269,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit if (useGraphics2D()) return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (producer)); else - { - GtkImage image = new GtkImage (producer, null); - producer.startProduction (image); - return image; - } + return new GtkImage (producer); } public Image createImage (byte[] imagedata, int imageoffset, @@ -295,8 +284,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit GdkPixbufDecoder d = new GdkPixbufDecoder (imagedata, imageoffset, imagelength); - GtkImage image = new GtkImage (d, null); - d.startProduction (image); + GtkImage image = new GtkImage (d); return image; } } @@ -312,9 +300,18 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit return new GdkPixbufDecoder(url); } + /** + * Returns the native color model (which isn't the same as the default + * ARGB color model, but doesn't have to be). + */ public ColorModel getColorModel () { - return ColorModel.getRGBdefault (); + /* Return the GDK-native ABGR format */ + return new DirectColorModel(32, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); } public String[] getFontList () @@ -410,34 +407,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public boolean prepareImage (Image image, int width, int height, ImageObserver observer) { + /* GtkImages are always prepared, as long as they're loaded. */ if (image instanceof GtkImage) - { - GtkImage i = (GtkImage) image; - - if (i.isLoaded ()) return true; - - class PrepareImage extends Thread - { - GtkImage image; - ImageObserver observer; - - PrepareImage (GtkImage image, ImageObserver observer) - { - this.image = image; - image.setObserver (observer); - } - - public void run () - { - image.source.startProduction (image); - } - } - - new PrepareImage (i, observer).start (); - return false; - } - else - return true; + return ((((GtkImage)image).checkImage (observer) & + ImageObserver.ALLBITS) != 0); + + /* Assume anything else is too */ + return true; } public native void sync(); diff --git a/gnu/java/nio/channels/FileChannelImpl.java b/gnu/java/nio/channels/FileChannelImpl.java index 715e80a2f..664e93c87 100644 --- a/gnu/java/nio/channels/FileChannelImpl.java +++ b/gnu/java/nio/channels/FileChannelImpl.java @@ -97,12 +97,17 @@ public final class FileChannelImpl extends FileChannel private int mode; - public FileChannelImpl () + /* Open a file. MODE is a combination of the above mode flags. */ + /* This is a static factory method, so that VM implementors can decide + * substitute subclasses of FileChannelImpl. */ + public static FileChannelImpl create(File file, int mode) + throws FileNotFoundException { + return new FileChannelImpl(file, mode); } - /* Open a file. MODE is a combination of the above mode flags. */ - public FileChannelImpl (File file, int mode) throws FileNotFoundException + private FileChannelImpl(File file, int mode) + throws FileNotFoundException { final String path = file.getPath(); fd = open (path, mode); |