summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/javax
diff options
context:
space:
mode:
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 23:20:01 +0000
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 23:20:01 +0000
commit3b3101d8b5ae4f08a16c0b7111da6cad41bbd282 (patch)
treea5eb7cf42a51869cc8aa1fad7ad6a90cca47fdd8 /libjava/classpath/gnu/javax
parent7e55c49d7d91ef9f09e93c1100119b1ab3652446 (diff)
downloadppe42-gcc-3b3101d8b5ae4f08a16c0b7111da6cad41bbd282.tar.gz
ppe42-gcc-3b3101d8b5ae4f08a16c0b7111da6cad41bbd282.zip
Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107049 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/gnu/javax')
-rw-r--r--libjava/classpath/gnu/javax/crypto/DiffieHellmanImpl.java159
-rw-r--r--libjava/classpath/gnu/javax/crypto/GnuDHPrivateKey.java90
-rw-r--r--libjava/classpath/gnu/javax/crypto/RSACipherImpl.java311
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java169
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPException.java47
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java128
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java153
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java123
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java201
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java104
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java108
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java96
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java77
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java92
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java90
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java176
-rw-r--r--libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java143
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/CorbaInput.java297
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/CorbaOutput.java219
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/DefaultWriteObjectTester.java85
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/DelegateFactory.java76
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java352
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/RmiUtilities.java946
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/StubDelegateImpl.java262
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/TieTargetRecord.java (renamed from libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerImpl.java)73
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/UtilDelegateImpl.java714
-rw-r--r--libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java163
-rw-r--r--libjava/classpath/gnu/javax/rmi/PortableServer.java141
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java130
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java216
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java519
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java131
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java153
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java173
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java745
35 files changed, 7321 insertions, 341 deletions
diff --git a/libjava/classpath/gnu/javax/crypto/DiffieHellmanImpl.java b/libjava/classpath/gnu/javax/crypto/DiffieHellmanImpl.java
new file mode 100644
index 00000000000..4797af7cf79
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/DiffieHellmanImpl.java
@@ -0,0 +1,159 @@
+/* DiffieHellmanImpl.java -- implementation of the Diffie-Hellman key agreement.
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.crypto;
+
+import gnu.java.security.provider.GnuDHPublicKey;
+
+import java.math.BigInteger;
+
+import java.security.Key;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * The Diffie-Hellman key agreement.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public final class DiffieHellmanImpl extends KeyAgreementSpi
+{
+
+ /** The private key being used for this agreement. */
+ private DHPrivateKey key;
+
+ /** The current result. */
+ private BigInteger result;
+
+ /** True if the caller told us we are done. */
+ private boolean last_phase_done;
+
+ /** Trivial default constructor. */
+ public DiffieHellmanImpl ()
+ {
+ key = null;
+ result = null;
+ last_phase_done = false;
+ }
+
+ // KeyAgreementSpi methods.
+
+ protected Key engineDoPhase (final Key incoming, final boolean lastPhase)
+ throws InvalidKeyException
+ {
+ if (key == null)
+ throw new IllegalStateException ("not initialized");
+ if (last_phase_done)
+ throw new IllegalStateException ("last phase already done");
+
+ if (!(incoming instanceof DHPublicKey))
+ throw new InvalidKeyException ("expecting javax.crypto.interfaces.DHPublicKey");
+ DHPublicKey pub = (DHPublicKey) incoming;
+ DHParameterSpec s1 = key.getParams();
+ DHParameterSpec s2 = pub.getParams();
+ if (!s1.getG().equals (s2.getG())
+ || !s1.getP().equals (s2.getP())
+ || s1.getL() != s2.getL())
+ throw new InvalidKeyException ("supplied key is not compatible");
+
+ result = pub.getY().modPow (key.getX(), s1.getP());
+ if (lastPhase)
+ {
+ last_phase_done = true;
+ return null;
+ }
+
+ throw new IllegalArgumentException ("only supports two-party Diffie Hellman");
+ }
+
+ protected byte[] engineGenerateSecret ()
+ {
+ if (result == null || !last_phase_done)
+ throw new IllegalStateException ("not finished");
+
+ byte[] buf = result.toByteArray ();
+ if (buf[0] == 0x00)
+ {
+ byte[] buf2 = new byte[buf.length - 1];
+ System.arraycopy (buf, 1, buf2, 0, buf2.length);
+ buf = buf2;
+ }
+ return buf;
+ }
+
+ protected int engineGenerateSecret (final byte[] secret, final int offset)
+ {
+ byte[] s = engineGenerateSecret();
+ System.arraycopy (s, 0, secret, offset, s.length);
+ return s.length;
+ }
+
+ protected SecretKey engineGenerateSecret (final String algorithm)
+ throws InvalidKeyException
+ {
+ byte[] s = engineGenerateSecret();
+ return new SecretKeySpec (s, algorithm);
+ }
+
+ protected void engineInit (final Key key, final SecureRandom random)
+ throws InvalidKeyException
+ {
+ if (!(key instanceof DHPrivateKey))
+ throw new InvalidKeyException ("not a javax.crypto.interfaces.DHPrivateKey");
+ this.key = (DHPrivateKey) key;
+ result = null;
+ last_phase_done = false;
+ }
+
+ protected void engineInit (final Key key, final AlgorithmParameterSpec params,
+ final SecureRandom random)
+ throws InvalidKeyException
+ {
+ engineInit (key, random);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/crypto/GnuDHPrivateKey.java b/libjava/classpath/gnu/javax/crypto/GnuDHPrivateKey.java
new file mode 100644
index 00000000000..f70cd7d2aec
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/GnuDHPrivateKey.java
@@ -0,0 +1,90 @@
+/* GnuDHPrivateKey.java -- a Diffie-Hellman private key.
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.crypto;
+
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.DHKey;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+
+/**
+ * A Diffie-Hellman private key.
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class GnuDHPrivateKey implements DHPrivateKey
+{
+
+ private final BigInteger x;
+ private final DHParameterSpec params;
+
+ public GnuDHPrivateKey (final BigInteger x, final DHParameterSpec params)
+ {
+ x.getClass ();
+ params.getClass ();
+ this.x = x;
+ this.params = params;
+ }
+
+ public DHParameterSpec getParams()
+ {
+ return params;
+ }
+
+ public String getAlgorithm()
+ {
+ return "DiffieHellman";
+ }
+
+ public String getFormat ()
+ {
+ return "NONE";
+ }
+
+ public byte[] getEncoded ()
+ {
+ return null;
+ }
+
+ public BigInteger getX ()
+ {
+ return x;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java b/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java
new file mode 100644
index 00000000000..0a4c29db6f1
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java
@@ -0,0 +1,311 @@
+/* DiffieHellmanImpl.java -- implementation of the Diffie-Hellman key agreement.
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.crypto;
+
+import gnu.classpath.ByteArray;
+import gnu.classpath.debug.Component;
+import gnu.classpath.debug.SystemLogger;
+
+import java.math.BigInteger;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPublicKey;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import java.util.logging.Logger;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+public class RSACipherImpl extends CipherSpi
+{
+ private static final Logger logger = SystemLogger.SYSTEM;
+
+ private static final byte[] EMPTY = new byte[0];
+ private int opmode = -1;
+ private RSAPrivateKey decipherKey = null;
+ private RSAPublicKey blindingKey = null;
+ private RSAPublicKey encipherKey = null;
+ private SecureRandom random = null;
+ private byte[] dataBuffer = null;
+ private int pos = 0;
+
+ protected void engineSetMode (String mode) throws NoSuchAlgorithmException
+ {
+ throw new NoSuchAlgorithmException ("only one mode available");
+ }
+
+ protected void engineSetPadding (String pad) throws NoSuchPaddingException
+ {
+ throw new NoSuchPaddingException ("only one padding available");
+ }
+
+ protected int engineGetBlockSize ()
+ {
+ return 1;
+ }
+
+ protected int engineGetOutputSize (int inputLen)
+ {
+ int outputLen = 0;
+ if (decipherKey != null)
+ {
+ outputLen = (decipherKey.getModulus ().bitLength () + 7) / 8;
+ }
+ else if (encipherKey != null)
+ {
+ outputLen = (encipherKey.getModulus ().bitLength () + 7) / 8;
+ }
+ else
+ throw new IllegalStateException ("not initialized");
+ if (inputLen > outputLen)
+ throw new IllegalArgumentException ("not configured to encode " + inputLen
+ + "bytes; at most " + outputLen);
+ return outputLen;
+ }
+
+ protected int engineGetKeySize (final Key key) throws InvalidKeyException
+ {
+ if (!(key instanceof RSAKey))
+ throw new InvalidKeyException ("not an RSA key");
+ return ((RSAKey) key).getModulus ().bitLength ();
+ }
+
+ protected byte[] engineGetIV ()
+ {
+ return null;
+ }
+
+ protected AlgorithmParameters engineGetParameters()
+ {
+ return null;
+ }
+
+ protected void engineInit (int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException
+ {
+ int outputLen = 0;
+ if (opmode == Cipher.ENCRYPT_MODE)
+ {
+ if (!(key instanceof RSAPublicKey))
+ throw new InvalidKeyException ("expecting a RSAPublicKey");
+ encipherKey = (RSAPublicKey) key;
+ decipherKey = null;
+ blindingKey = null;
+ outputLen = (encipherKey.getModulus ().bitLength () + 7) / 8;
+ }
+ else if (opmode == Cipher.DECRYPT_MODE)
+ {
+ if (key instanceof RSAPrivateKey)
+ {
+ decipherKey = (RSAPrivateKey) key;
+ encipherKey = null;
+ blindingKey = null;
+ outputLen = (decipherKey.getModulus ().bitLength () + 7) / 8;
+ }
+ else if (key instanceof RSAPublicKey)
+ {
+ if (decipherKey == null)
+ throw new IllegalStateException ("must configure decryption key first");
+ if (!decipherKey.getModulus ().equals (((RSAPublicKey) key).getModulus ()))
+ throw new InvalidKeyException ("blinding key is not compatible");
+ blindingKey = (RSAPublicKey) key;
+ return;
+ }
+ else
+ throw new InvalidKeyException ("expecting either an RSAPrivateKey or an RSAPublicKey (for blinding)");
+ }
+ else
+ throw new IllegalArgumentException ("only encryption and decryption supported");
+ this.random = random;
+ this.opmode = opmode;
+ pos = 0;
+ dataBuffer = new byte[outputLen];
+ }
+
+ protected void engineInit (int opmode, Key key, AlgorithmParameterSpec spec, SecureRandom random)
+ throws InvalidKeyException
+ {
+ engineInit (opmode, key, random);
+ }
+
+ protected void engineInit (int opmode, Key key, AlgorithmParameters params, SecureRandom random)
+ throws InvalidKeyException
+ {
+ engineInit (opmode, key, random);
+ }
+
+ protected byte[] engineUpdate (byte[] in, int offset, int length)
+ {
+ if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE)
+ throw new IllegalStateException ("not initialized");
+ System.arraycopy (in, offset, dataBuffer, pos, length);
+ pos += length;
+ return EMPTY;
+ }
+
+ protected int engineUpdate (byte[] in, int offset, int length, byte[] out, int outOffset)
+ {
+ engineUpdate (in, offset, length);
+ return 0;
+ }
+
+ protected byte[] engineDoFinal (byte[] in, int offset, int length)
+ throws IllegalBlockSizeException, BadPaddingException
+ {
+ engineUpdate (in, offset, length);
+ if (opmode == Cipher.DECRYPT_MODE)
+ {
+ if (pos < dataBuffer.length)
+ throw new IllegalBlockSizeException ("expecting exactly " + dataBuffer.length + " bytes");
+ BigInteger enc = new BigInteger (1, dataBuffer);
+ byte[] dec = rsaDecrypt (enc);
+ logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}",
+ new ByteArray (dec));
+ if (dec[0] != 0x02)
+ throw new BadPaddingException ("expected padding type 2");
+ int i;
+ for (i = 1; i < dec.length && dec[i] != 0x00; i++);
+ int len = dec.length - i;
+ byte[] result = new byte[len];
+ System.arraycopy (dec, i, result, 0, len);
+ pos = 0;
+ return result;
+ }
+ else
+ {
+ offset = dataBuffer.length - pos;
+ if (offset < 3)
+ throw new IllegalBlockSizeException ("input is too large to encrypt");
+ byte[] dec = new byte[dataBuffer.length];
+ dec[0] = 0x02;
+ if (random == null)
+ random = new SecureRandom ();
+ byte[] pad = new byte[offset - 2];
+ random.nextBytes (pad);
+ for (int i = 0; i < pad.length; i++)
+ if (pad[i] == 0)
+ pad[i] = 1;
+ System.arraycopy (pad, 0, dec, 1, pad.length);
+ dec[dec.length - pos] = 0x00;
+ System.arraycopy (dataBuffer, 0, dec, offset, pos);
+ logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}",
+ new ByteArray (dec));
+ BigInteger x = new BigInteger (1, dec);
+ BigInteger y = x.modPow (encipherKey.getPublicExponent (),
+ encipherKey.getModulus ());
+ byte[] enc = y.toByteArray ();
+ if (enc[0] == 0x00)
+ {
+ byte[] tmp = new byte[enc.length - 1];
+ System.arraycopy (enc, 1, tmp, 0, tmp.length);
+ enc = tmp;
+ }
+ pos = 0;
+ return enc;
+ }
+ }
+
+ protected int engineDoFinal (byte[] out, int offset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
+ {
+ byte[] result = engineDoFinal (EMPTY, 0, 0);
+ if (out.length - offset < result.length)
+ throw new ShortBufferException ("need " + result.length + ", have "
+ + (out.length - offset));
+ System.arraycopy (result, 0, out, offset, result.length);
+ return result.length;
+ }
+
+ protected int engineDoFinal (final byte[] input, final int offset, final int length,
+ final byte[] output, final int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
+ {
+ byte[] result = engineDoFinal (input, offset, length);
+ if (output.length - outputOffset < result.length)
+ throw new ShortBufferException ("need " + result.length + ", have "
+ + (output.length - outputOffset));
+ System.arraycopy (result, 0, output, outputOffset, result.length);
+ return result.length;
+ }
+
+ /**
+ * Decrypts the ciphertext, employing RSA blinding if possible.
+ */
+ private byte[] rsaDecrypt (BigInteger enc)
+ {
+ if (random == null)
+ random = new SecureRandom ();
+ BigInteger n = decipherKey.getModulus ();
+ BigInteger r = null;
+ BigInteger pubExp = null;
+ if (blindingKey != null)
+ pubExp = blindingKey.getPublicExponent ();
+ if (pubExp != null && (decipherKey instanceof RSAPrivateCrtKey))
+ pubExp = ((RSAPrivateCrtKey) decipherKey).getPublicExponent ();
+ if (pubExp != null)
+ {
+ r = new BigInteger (n.bitLength () - 1, random);
+ enc = r.modPow (pubExp, n).multiply (enc).mod (n);
+ }
+
+ BigInteger dec = enc.modPow (decipherKey.getPrivateExponent (), n);
+
+ if (pubExp != null)
+ {
+ dec = dec.multiply (r.modInverse (n)).mod (n);
+ }
+
+ return dec.toByteArray ();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java
new file mode 100644
index 00000000000..c4a582bfa20
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java
@@ -0,0 +1,169 @@
+/* BMPDecoder.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.BufferedImage;
+
+public abstract class BMPDecoder {
+
+ protected BMPInfoHeader infoHeader;
+ protected BMPFileHeader fileHeader;
+ protected long offset;
+
+ public BMPDecoder(BMPFileHeader fh, BMPInfoHeader ih){
+ fileHeader = fh;
+ infoHeader = ih;
+ offset = BMPFileHeader.SIZE + BMPInfoHeader.SIZE;
+ }
+
+ /**
+ * Determines the coding type of the bitmap and returns the corresponding
+ * decoder.
+ */
+ public static BMPDecoder getDecoder(BMPFileHeader fh, BMPInfoHeader ih){
+ switch(ih.getCompression()){
+ case BMPInfoHeader.BI_RGB: // uncompressed RGB
+ switch(ih.getBitCount()){
+ case 32:
+ return new DecodeBF32(fh, ih, true);
+
+ case 24:
+ return new DecodeRGB24(fh, ih);
+
+ case 16:
+ return new DecodeBF16(fh, ih, true);
+
+ case 8:
+ return new DecodeRGB8(fh, ih);
+
+ case 4:
+ return new DecodeRGB4(fh, ih);
+
+ case 1:
+ return new DecodeRGB1(fh, ih);
+
+ default:
+ return null;
+ }
+
+ case BMPInfoHeader.BI_RLE8:
+ return new DecodeRLE8(fh, ih);
+
+ case BMPInfoHeader.BI_RLE4:
+ return new DecodeRLE4(fh, ih);
+
+ case BMPInfoHeader.BI_BITFIELDS:
+ switch(ih.getBitCount()){
+ case 16:
+ return new DecodeBF16(fh, ih, false);
+
+ case 32:
+ return new DecodeBF32(fh, ih, false);
+
+ default:
+ return null;
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * The image decoder.
+ */
+ public abstract BufferedImage decode(ImageInputStream in)
+ throws IOException, BMPException;
+
+ /**
+ * Reads r,g,b bit masks from an inputstream
+ */
+ protected int[] readBitMasks(ImageInputStream in) throws IOException {
+ int[] bitmasks = new int[3];
+ byte[] temp = new byte[12];
+ if(in.read(temp) != 12)
+ throw new IOException("Couldn't read bit masks.");
+ offset += 12;
+
+ ByteBuffer buf = ByteBuffer.wrap(temp);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ bitmasks[0] = buf.getInt();
+ bitmasks[1] = buf.getInt();
+ bitmasks[2] = buf.getInt();
+ return bitmasks;
+ }
+
+ /**
+ * Reads an N-color palette from an inputstream in RGBQUAD format and
+ * returns an equivalent ColorModel object
+ */
+ protected IndexColorModel readPalette(ImageInputStream in) throws IOException {
+ int N = infoHeader.getNumberOfPaletteEntries();
+ byte[] r = new byte[N];
+ byte[] g = new byte[N];
+ byte[] b = new byte[N];
+ for(int i=0;i<N;i++){
+ byte[] RGBquad = new byte[4];
+ if(in.read(RGBquad) != 4)
+ throw new IOException("Error reading palette information.");
+ // RGBQUAD structure is b,g,r,0
+ r[i] = RGBquad[2];
+ g[i] = RGBquad[1];
+ b[i] = RGBquad[0];
+ }
+
+ offset += 4*N;
+ return new IndexColorModel(8, N, r, g, b);
+ }
+
+ /**
+ * Read bytes to the start of the image data
+ */
+ protected void skipToImage(ImageInputStream in) throws IOException {
+ byte[] d = new byte[1];
+ long n = fileHeader.getOffset() - offset;
+ for(int i=0;i<n;i++)
+ in.read(d);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java
new file mode 100644
index 00000000000..d3c62e7597e
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java
@@ -0,0 +1,47 @@
+/* BMPException.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import javax.imageio.IIOException;
+
+public class BMPException extends IIOException {
+
+ public BMPException(String message){
+ super(message);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java
new file mode 100644
index 00000000000..246e0eacfeb
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java
@@ -0,0 +1,128 @@
+/* BMPFileHeader.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class BMPFileHeader {
+ /** Header signature, always 'BM' */
+ private final static short bfType = 0x424d;
+
+ /** Bitmap file size, in bytes. */
+ private long bfSize;
+
+ /** Offset from the beginning of the file to the bitmap data */
+ private long bfOffBits;
+
+ /** BITMAPFILEHEADER is 14 bytes */
+ public static final int SIZE = 14;
+
+ /**
+ * Creates the header from an input stream, which is not closed.
+ * @throws IOException if an I/O error occured.
+ * @throws BMPException if the header was invalid
+ */
+ public BMPFileHeader(ImageInputStream in) throws IOException, BMPException {
+ byte[] data = new byte[SIZE];
+
+ if (in.read(data) != SIZE)
+ throw new IOException("Couldn't read header.");
+ ByteBuffer buf = ByteBuffer.wrap(data);
+
+ if(buf.getShort(0) != bfType)
+ throw new BMPException("Not a BMP file.");
+
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+
+ // get size (keep unsigned)
+ bfSize = ((long)buf.getInt(2) & (0xFFFFFFFF));
+
+ // Two reserved shorts are here, and should be zero,
+ // perhaps they should be tested to be zero, but I don't
+ // feel this strictness is necessary.
+
+ bfOffBits = ((long)buf.getInt(10) & (0xFFFFFFFF));
+ }
+
+ /**
+ * Writes the header to an output stream, which is not closed or flushed.
+ * @throws IOException if an I/O error occured.
+ */
+ public void write(OutputStream out) throws IOException {
+ ByteBuffer buf = ByteBuffer.allocate(SIZE);
+ buf.putShort(0, bfType); // ID
+ buf.putInt(2, (int)(bfSize & (0xFFFFFFFF))); // size
+ buf.putInt(6, 0); // 4 reserved bytes set to zero
+ buf.putInt(2, (int)(bfOffBits & (0xFFFFFFFF))); // size
+ out.write(buf.array());
+ }
+
+ /**
+ * Sets the file size
+ */
+ public void setSize(long size){
+ bfSize = size;
+ }
+
+ /**
+ * Sets the bitmap offset within the file
+ */
+ public void setOffset(long offset){
+ bfOffBits = offset;
+ }
+
+ /**
+ * Gets the file size
+ */
+ public long getSize(){
+ return bfSize;
+ }
+
+ /**
+ * Gets the bitmap offset within the file
+ */
+ public long getOffset(){
+ return bfOffBits;
+ }
+}
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java
new file mode 100644
index 00000000000..3341d4b4aed
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java
@@ -0,0 +1,153 @@
+/* BMPImageReader.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.*;
+import javax.imageio.spi.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.ImageInputStream;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class BMPImageReader extends ImageReader {
+ private BMPInfoHeader infoHeader;
+ private BMPFileHeader fileHeader;
+ private BMPDecoder decoder;
+
+ protected BMPImageReader(ImageReaderSpi originatingProvider){
+ super(originatingProvider);
+ infoHeader = null;
+ fileHeader = null;
+ decoder = null;
+ }
+
+ private void validateIndex(int imageIndex)
+ throws IndexOutOfBoundsException {
+ if (imageIndex != 0)
+ throw new IndexOutOfBoundsException("Invalid image index.");
+ }
+
+ public void setInput(Object input) {
+ super.setInput(input);
+ }
+
+ public void setInput(Object input,
+ boolean seekForwardOnly,
+ boolean ignoreMetadata) {
+ super.setInput(input, seekForwardOnly, ignoreMetadata);
+ }
+
+ public void setInput(Object input, boolean isStreamable) {
+ super.setInput(input, isStreamable);
+
+ if (!(input instanceof ImageInputStream))
+ throw new IllegalArgumentException("Input not an ImageInputStream.");
+ }
+
+ private void checkStream() throws IOException {
+ if (!(input instanceof ImageInputStream))
+ throw new IllegalStateException("Input not an ImageInputStream.");
+ if(input == null)
+ throw new IllegalStateException("No input stream.");
+
+ }
+
+ private void readHeaders() throws IOException, IIOException {
+ if(fileHeader != null)
+ return;
+
+ checkStream();
+
+ fileHeader = new BMPFileHeader((ImageInputStream)input);
+ infoHeader = new BMPInfoHeader((ImageInputStream)input);
+ decoder = BMPDecoder.getDecoder(fileHeader, infoHeader);
+ }
+
+ public int getWidth(int imageIndex) throws IOException {
+ validateIndex(imageIndex);
+ readHeaders();
+ return infoHeader.getWidth();
+ }
+
+ public int getHeight(int imageIndex) throws IOException {
+ validateIndex(imageIndex);
+ readHeaders();
+ return infoHeader.getHeight();
+ }
+
+ public Iterator getImageTypes(int imageIndex){
+ validateIndex(imageIndex);
+ return null;
+ }
+
+ /**
+ * Returns the number of images. BMP files can only contain a single one.
+ */
+ public int getNumImages(boolean allowSearch){
+ return 1;
+ }
+
+
+ // FIXME: Support metadata
+ public IIOMetadata getImageMetadata(int imageIndex){
+ validateIndex(imageIndex);
+ return null;
+ }
+
+ // FIXME: Support metadata
+ public IIOMetadata getStreamMetadata(){
+ return null;
+ }
+
+ /**
+ * Reads the image indexed by imageIndex and returns it as
+ * a complete BufferedImage, using a supplied ImageReadParam.
+ */
+ public BufferedImage read(int imageIndex, ImageReadParam param)
+ throws IOException, IIOException {
+ validateIndex(imageIndex);
+ readHeaders();
+ return decoder.decode((ImageInputStream)input);
+ }
+
+
+}
+
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java
new file mode 100644
index 00000000000..b175c7d076b
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java
@@ -0,0 +1,123 @@
+/* BMPImageReaderSpi.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+
+public class BMPImageReaderSpi extends ImageReaderSpi {
+
+ static final String vendorName = "GNU";
+ static final String version = "0.1";
+ static final String readerClassName =
+ "gnu.javax.imageio.bmp.BMPImageReader";
+ static final String[] names = { "Microsoft Windows BMP" };
+ static final String[] suffixes = { ".bmp", ".bm" };
+ static final String[] MIMETypes = {
+ "image/bmp",
+ "image/x-windows-bmp"};
+
+ static final String[] writerSpiNames = null;
+ //{"com.mycompany.imageio.MyFormatImageWriterSpi" };
+
+ static final boolean supportsStandardStreamMetadataFormat = false;
+ static final String nativeStreamMetadataFormatName = null;
+ static final String nativeStreamMetadataFormatClassName = null;
+ static final String[] extraStreamMetadataFormatNames = null;
+ static final String[] extraStreamMetadataFormatClassNames = null;
+ static final boolean supportsStandardImageMetadataFormat = false;
+ static final String nativeImageMetadataFormatName = null;
+ static final String nativeImageMetadataFormatClassName = null;
+ static final String[] extraImageMetadataFormatNames = null;
+ static final String[] extraImageMetadataFormatClassNames = null;
+
+ public BMPImageReaderSpi() {
+ super(vendorName, version,
+ names, suffixes, MIMETypes,
+ readerClassName,
+ STANDARD_INPUT_TYPE, // Accept ImageImageInputStreams
+ writerSpiNames,
+ supportsStandardStreamMetadataFormat,
+ nativeStreamMetadataFormatName,
+ nativeStreamMetadataFormatClassName,
+ extraStreamMetadataFormatNames,
+ extraStreamMetadataFormatClassNames,
+ supportsStandardImageMetadataFormat,
+ nativeImageMetadataFormatName,
+ nativeImageMetadataFormatClassName,
+ extraImageMetadataFormatNames,
+ extraImageMetadataFormatClassNames);
+ }
+
+ public String getDescription(Locale locale) {
+ return "Microsoft BMP v3";
+ }
+
+ public boolean canDecodeInput(Object input)
+ throws IOException {
+ if (!(input instanceof ImageInputStream))
+ return false;
+
+ ImageInputStream in = (ImageInputStream)input;
+ boolean retval;
+
+ in.mark();
+ try {
+ new BMPFileHeader(in);
+ retval = true;
+ } catch(BMPException e){
+ retval = false;
+ }
+ in.reset();
+
+ return retval;
+ }
+
+ public ImageReader createReaderInstance(Object extension) {
+ return new BMPImageReader(this);
+ }
+}
+
+
+
+
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java
new file mode 100644
index 00000000000..edcb4e644cc
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java
@@ -0,0 +1,201 @@
+/* BMPInfoHeader.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.awt.Dimension;
+
+public class BMPInfoHeader {
+ /** Size of the bitmap info header*/
+ private int biSize;
+
+ /** Pixel width of the bitmap */
+ private int biWidth;
+
+ /** Pixel height of the bitmap */
+ private int biHeight;
+
+ /** Number of bitplanes = 1 */
+ private short biPlanes;
+
+ /** Number of bpp = 1,4,8,24 */
+ private short biBitCount;
+
+ /** Compression type, RGB8, RLE8, RLE4, BITFIELDS */
+ private int biCompression;
+
+ /** Byte size of the uncompressed bitmap, can be 0. */
+ private int biSizeImage;
+
+ /** X resolution, dots per meter */
+ private int biXPelsPerMeter;
+
+ /** Y resolution, dots per meter */
+ private int biYPelsPerMeter;
+
+ /** Number of colors used (palette only, can be 0 for all) */
+ private int biClrUsed;
+
+ /** Number of 'important' colors, 0 for all */
+ private int biClrImportant;
+
+ /** BITMAPINFOHEADER is 40 bytes */
+ public static final int SIZE = 40;
+
+ /**
+ * Compression types
+ */
+ public static final int BI_RGB = 0;
+ public static final int BI_RLE8 = 1;
+ public static final int BI_RLE4 = 2;
+ public static final int BI_BITFIELDS = 3;
+
+ /**
+ * Creates the header from an input stream, which is not closed.
+ * @throws IOException if an I/O error occured.
+ * @throws BMPException if the header was invalid
+ */
+ public BMPInfoHeader(ImageInputStream in) throws IOException, BMPException {
+ byte[] data = new byte[SIZE];
+
+ if (in.read(data) != SIZE)
+ throw new IOException("Couldn't read header.");
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+
+ int n;
+ if((n=buf.getInt()) != SIZE)
+ throw new BMPException("Invalid BITMAPINFOHEADER size: "+n);
+
+ biWidth = buf.getInt();
+ biHeight = buf.getInt();
+ biPlanes = buf.getShort();
+ setBitCount(buf.getShort());
+ setCompression(buf.getInt());
+ biSizeImage = buf.getInt();
+ biXPelsPerMeter = buf.getInt();
+ biYPelsPerMeter = buf.getInt();
+ biClrUsed = buf.getInt();
+ biClrImportant = buf.getInt();
+ }
+
+ public void setBitCount(short bitcount) throws BMPException {
+ switch(bitcount){
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ biBitCount = bitcount;
+ break;
+
+ default:
+ throw new BMPException("Invalid number of bits per pixel: "+
+ bitcount);
+ }
+ }
+
+ public short getBitCount() { return biBitCount; }
+
+ public void setCompression(int compression) throws BMPException {
+ switch(compression){
+ case BI_RLE8:
+ if(getBitCount() != 8)
+ throw new BMPException("Invalid number of bits per pixel.");
+ biCompression = compression;
+ break;
+ case BI_RLE4:
+ if(getBitCount() != 4)
+ throw new BMPException("Invalid number of bits per pixel.");
+ biCompression = compression;
+ break;
+
+ case BI_RGB:
+ case BI_BITFIELDS:
+ biCompression = compression;
+ break;
+
+ default:
+ throw new BMPException("Unknown bitmap compression type.");
+ }
+ }
+
+ public int getNumberOfPaletteEntries(){
+ if(biClrUsed == 0)
+ switch(biBitCount){
+ case 1:
+ return 2;
+ case 4:
+ return 16;
+ case 8:
+ return 256;
+
+ default: // should not happen
+ return 0;
+ }
+
+ return biClrUsed;
+ }
+
+ public int getCompression(){
+ return biCompression;
+ }
+
+ public Dimension getSize(){
+ return new Dimension(biWidth, biHeight);
+ }
+
+ public int getWidth(){
+ return biWidth;
+ }
+
+ public int getHeight(){
+ return biHeight;
+ }
+
+ public void setSize(Dimension d){
+ biWidth = (int)d.getWidth();
+ biHeight = (int)d.getHeight();
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java
new file mode 100644
index 00000000000..702c93ab3ca
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java
@@ -0,0 +1,104 @@
+/* DecodeBF16.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeBF16 extends BMPDecoder {
+ private int[] bitmasks;
+ private boolean useDefaultMasks;
+
+ public DecodeBF16(BMPFileHeader fh, BMPInfoHeader ih,
+ boolean udm){
+ super(fh,ih);
+
+ useDefaultMasks = udm;
+ if(useDefaultMasks) // 5-6-5 mask, B,G,R
+ bitmasks = new int[] { 0x00F800, 0x0007E0, 0x00001F };
+ }
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ if(!useDefaultMasks)
+ bitmasks = readBitMasks(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+
+ // BMP scanlines are padded to dword offsets
+ int scansize = (w + (w&1)) << 1;
+ short[] data = new short[w*h];
+
+ for(int y=h-1;y>=0;y--){
+ byte[] scanline = new byte[scansize];
+ if(in.read(scanline) != scansize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<w;x++)
+ data[x + y*w] = (short)((scanline[x*2] & (0xFF)) |
+ ((scanline[x*2+1] & (0xFF)) << 8));
+ }
+
+ ColorModel cm = new DirectColorModel(16,
+ bitmasks[0], bitmasks[1], bitmasks[2]);
+ SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT,
+ w, h,
+ bitmasks);
+ DataBuffer db = new DataBufferUShort(data, w*h, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+ return new BufferedImage(cm, raster, false, null);
+ }
+
+}
+
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java
new file mode 100644
index 00000000000..ee64f4b0eac
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java
@@ -0,0 +1,108 @@
+/* DecodeBF32.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeBF32 extends BMPDecoder {
+ private int[] bitmasks;
+ private boolean useDefaultMasks;
+
+ public DecodeBF32(BMPFileHeader fh, BMPInfoHeader ih,
+ boolean udm){
+ super(fh,ih);
+
+ useDefaultMasks = udm;
+ if(useDefaultMasks)
+ bitmasks = new int[] { 0x00FF0000, 0x0000FF00, 0x000000FF };
+ }
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ if(!useDefaultMasks)
+ bitmasks = readBitMasks(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+
+ // BMP scanlines are padded to dword offsets
+ int scansize = w << 2;
+ int[] data = new int[w*h];
+
+
+ for(int y=h-1;y>=0;y--){
+ byte[] scanline = new byte[scansize];
+ if(in.read(scanline) != scansize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<w;x++)
+ data[x + y*w] = ((scanline[x<<2] & (0xFF)) |
+ ((scanline[(x<<2)+1] & (0xFF)) << 8) |
+ ((scanline[(x<<2)+2] & (0xFF)) << 16) |
+ ((scanline[(x<<2)+3] & (0xFF)) << 24));
+ }
+
+ ColorModel cm = new DirectColorModel(32,
+ bitmasks[0], bitmasks[1], bitmasks[2]);
+ SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
+ w, h,
+ bitmasks);
+ DataBuffer db = new DataBufferInt(data, w*h);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(cm, raster, false, null);
+ }
+
+}
+
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java
new file mode 100644
index 00000000000..9ca82d9ee4a
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java
@@ -0,0 +1,96 @@
+/* DecodeRGB1.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeRGB1 extends BMPDecoder {
+
+ public DecodeRGB1(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ public BufferedImage decode(ImageInputStream in)
+ throws IOException, BMPException {
+
+ IndexColorModel palette = readPalette(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+ int size = (w*h)>>3;
+
+ int scansize = w>>3;
+ byte[] data = new byte[size];
+
+ for(int y=h-1;y>=0;y--){
+ // Scanlines are padded to dword boundries
+ int readsize = scansize;
+ if((readsize & 3) != 0) readsize += (4 - (scansize & 3));
+
+ byte[] scanline = new byte[readsize];
+ if(in.read(scanline) != readsize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<scansize;x++)
+ data[x + y*scansize] = scanline[x];
+ }
+
+ SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ w, h, 1);
+
+ DataBuffer db = new DataBufferByte(data, size, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(palette, raster, false, null);
+ }
+
+}
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java
new file mode 100644
index 00000000000..2a910cb3063
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java
@@ -0,0 +1,77 @@
+/* DecodeRGB24.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.Dimension;
+
+public class DecodeRGB24 extends BMPDecoder {
+
+ public DecodeRGB24(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+ BufferedImage image = new BufferedImage(w, h,
+ BufferedImage.TYPE_INT_RGB);
+ // BMP scanlines are padded to dword offsets
+ int scansize = ((w*3 & 3) != 0)? w*3 + 4 - (w*3 & 3): w*3;
+ int[] data = new int[w*h];
+
+ for(int y=h-1;y>=0;y--){
+ byte[] scanline = new byte[scansize];
+ if(in.read(scanline) != scansize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<w;x++)
+ data[x + y*w] = scanline[x*3] +
+ (scanline[x*3+1] << 8) +
+ (scanline[x*3+2] << 16);
+ }
+ image.setRGB(0, 0, w, h, data, 0, w);
+ return image;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java
new file mode 100644
index 00000000000..a10d390ab82
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java
@@ -0,0 +1,92 @@
+/* DecodeRGB4.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeRGB4 extends BMPDecoder {
+
+ public DecodeRGB4(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ IndexColorModel palette = readPalette(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+ int size = (w*h) >> 1;
+
+ // Scanline padded to dword offsets
+ int wbytes = (w + (w & 1)) >> 1;
+ int scansize = ((wbytes & 3) != 0)? (wbytes + 4 - (wbytes&3)) : wbytes;
+
+ byte[] data = new byte[wbytes*h];
+
+ for(int y=h-1;y>=0;y--){
+ byte[] scanline = new byte[scansize];
+ if(in.read(scanline) != scansize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<wbytes;x++)
+ data[x + y*wbytes] = scanline[x];
+ }
+ SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ w, h, 4);
+
+ DataBuffer db = new DataBufferByte(data, w*h, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(palette, raster, false, null);
+ }
+
+}
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java
new file mode 100644
index 00000000000..dfe4a19e8be
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java
@@ -0,0 +1,90 @@
+/* DecodeRGB8.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeRGB8 extends BMPDecoder {
+
+ public DecodeRGB8(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ IndexColorModel palette = readPalette(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+
+ // BMP scanlines are padded to dword offsets
+ int scansize = ((w & 3) != 0)? w + 4 - (w & 3): w;
+ byte[] data = new byte[w*h];
+
+ for(int y=h-1;y>=0;y--){
+ byte[] scanline = new byte[scansize];
+ if(in.read(scanline) != scansize)
+ throw new IOException("Couldn't read image data.");
+
+ for(int x=0;x<w;x++)
+ data[x + y*w] = scanline[x];
+ }
+
+ SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ w, h,
+ new int[] {0xFF});
+ DataBuffer db = new DataBufferByte(data, w*h, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(palette, raster, false, null);
+ }
+
+}
+
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java
new file mode 100644
index 00000000000..55d314f05f1
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java
@@ -0,0 +1,176 @@
+/* DecodeRLE4.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeRLE4 extends BMPDecoder {
+
+ public DecodeRLE4(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ /**
+ * RLE control codes
+ */
+ private static final byte ESCAPE = (byte)0;
+ private static final byte EOL = (byte)0; // end of line
+ private static final byte EOB = (byte)1; // end of bitmap
+ private static final byte DELTA = (byte)2; // delta
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ IndexColorModel palette = readPalette(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+
+ byte[] data = uncompress(w, h, in);
+ SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ w, h, 4);
+
+ DataBuffer db = new DataBufferByte(data, w*h, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(palette, raster, false, null);
+ }
+
+ private byte[] uncompress(int w, int h, ImageInputStream in)
+ throws BMPException, IOException {
+ byte[] cmd = new byte[2];
+ byte[] data = new byte[w*h>>1];
+ int offIn = 0;
+ int x=0,y=0;
+
+ // width in bytes
+ w += (w&1);
+ w = w >> 1;
+
+ try {
+ while(((x>>1) + y*w) < w*h){
+ if(in.read(cmd) != 2)
+ throw new IOException("Error reading compressed data.");
+
+ if(cmd[0] == ESCAPE){
+ switch(cmd[1]){
+ case EOB: // end of bitmap
+ return data;
+ case EOL: // end of line
+ x = 0;
+ y++;
+ break;
+ case DELTA: // delta
+ if(in.read(cmd) != 2)
+ throw new IOException("Error reading compressed data.");
+ int dx = cmd[0] & (0xFF);
+ int dy = cmd[1] & (0xFF);
+ x += dx;
+ y += dy;
+ break;
+
+ default:
+ // decode a literal run
+ int length = cmd[1] & (0xFF);
+
+ // size of run, which is word aligned.
+ int bytesize = length;
+ bytesize += (bytesize & 1);
+ bytesize >>= 1;
+ bytesize += (bytesize & 1);
+
+ byte[] run = new byte[bytesize];
+ if(in.read(run) != bytesize)
+ throw new IOException("Error reading compressed data.");
+
+ if((x&1) == 0){
+ length += (length&1);
+ length >>= 1;
+ System.arraycopy(run, 0, data, ((x>>1) + w*(h-y-1)),
+ length);
+ } else {
+ for(int i=0;i<length;i++){
+ if((i&1) == 0) // copy high to low
+ data[((x+i)>>1) + w*(h-y-1)]
+ |= ((run[i>>1]&0xF0) >> 4);
+ else // copy low to high
+ data[((x+i)>>1) + w*(h-y-1)]
+ |= ((run[i>>1]&0x0F) << 4);
+ }
+ }
+ x += cmd[1] & (0xFF);
+ break;
+ }
+ } else {
+ // decode a byte run
+ int length = cmd[0] & (0xFF);
+ if((x&1) == 0){
+ length += (length&1);
+ length >>= 1;
+ for(int i=0;i<length;i++)
+ data[(h-y-1)*w + i + (x >> 1)] = cmd[1];
+ } else {
+ for(int i=0;i<length;i++){
+ if((i&1) == 0) // copy high to low
+ data[((x+i)>>1) + w*(h-y-1)]
+ |= ((cmd[1]&0xF0) >> 4);
+ else // copy low to high
+ data[((x+i)>>1) + w*(h-y-1)]
+ |= ((cmd[1]&0x0F) << 4);
+ }
+ }
+ x += cmd[0] & (0xFF);
+ }
+ }
+ return data;
+ } catch(ArrayIndexOutOfBoundsException e){
+ throw new BMPException("Invalid RLE data.");
+ }
+ }
+}
+
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java
new file mode 100644
index 00000000000..1d00e6751d0
--- /dev/null
+++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java
@@ -0,0 +1,143 @@
+/* DecodeRLE8.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.imageio.bmp;
+
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.Dimension;
+
+public class DecodeRLE8 extends BMPDecoder {
+
+ public DecodeRLE8(BMPFileHeader fh, BMPInfoHeader ih){
+ super(fh, ih);
+ }
+
+ /**
+ * RLE control codes
+ */
+ private static final byte ESCAPE = (byte)0;
+ private static final byte EOL = (byte)0; // end of line
+ private static final byte EOB = (byte)1; // end of bitmap
+ private static final byte DELTA = (byte)2; // delta
+
+ public BufferedImage decode(ImageInputStream in) throws IOException, BMPException {
+ IndexColorModel palette = readPalette(in);
+ skipToImage(in);
+
+ Dimension d = infoHeader.getSize();
+ int h = (int)d.getHeight();
+ int w = (int)d.getWidth();
+
+ byte[] data = uncompress(w, h, in);
+ SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ w, h,
+ new int[] {0xFF});
+ DataBuffer db = new DataBufferByte(data, w*h, 0);
+ WritableRaster raster = Raster.createWritableRaster(sm, db, null);
+
+ return new BufferedImage(palette, raster, false, null);
+ }
+
+ private byte[] uncompress(int w, int h, ImageInputStream in)
+ throws BMPException, IOException {
+ byte[] cmd = new byte[2];
+ byte[] data = new byte[w*h];
+ int offIn = 0;
+ int x=0,y=0;
+
+ try {
+ while((x + y*w) < w*h){
+ if(in.read(cmd) != 2)
+ throw new IOException("Error reading compressed data.");
+
+ if(cmd[0] == ESCAPE){
+ switch(cmd[1]){
+ case EOB: // end of bitmap
+ return data;
+ case EOL: // end of line
+ x = 0;
+ y++;
+ break;
+ case DELTA: // delta
+ if(in.read(cmd) != 2)
+ throw new IOException("Error reading compressed data.");
+ int dx = cmd[0] & (0xFF);
+ int dy = cmd[1] & (0xFF);
+ x += dx;
+ y += dy;
+ break;
+
+ default:
+ // decode a literal run
+ int length = cmd[1] & (0xFF);
+ int copylength = length;
+
+ // absolute mode must be word-aligned
+ length += (length & 1);
+
+ byte[] run = new byte[length];
+ if(in.read(run) != length)
+ throw new IOException("Error reading compressed data.");
+
+ System.arraycopy(run, 0, data, (x+w*(h-y-1)),
+ copylength);
+ x += copylength;
+ break;
+ }
+ } else {
+ // decode a byte run
+ int length = cmd[0] & (0xFF);
+ for(int i=0;i<length;i++)
+ data[(h-y-1)*w + x++] = cmd[1];
+ }
+ }
+ return data;
+ } catch(ArrayIndexOutOfBoundsException e){
+ throw new BMPException("Invalid RLE data.");
+ }
+ }
+}
+
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/CorbaInput.java b/libjava/classpath/gnu/javax/rmi/CORBA/CorbaInput.java
new file mode 100644
index 00000000000..e80cabf6b2b
--- /dev/null
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/CorbaInput.java
@@ -0,0 +1,297 @@
+/* CorbaInput.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.rmi.CORBA;
+
+import gnu.CORBA.CDR.gnuRuntime;
+
+import org.omg.CORBA_2_3.portable.InputStream;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * Converts calls on java ObjectOutputStream to calls on CORBA OutputStream. A
+ * class to substitute for objects using readObject method.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class CorbaInput
+ extends ObjectInputStream
+ implements ObjectInput
+{
+
+ /**
+ * The underlying CORBA stream from where the actual input is taken.
+ */
+ public InputStream stream;
+
+ /**
+ * The utility class to write the object fields in default way.
+ */
+ final RmiUtilities util;
+
+ /**
+ * The object currently being read.
+ */
+ Object current;
+
+ /**
+ * The offset of the object currently being read.
+ */
+ int offset;
+
+ /**
+ * The repository id of the object currently being read.
+ */
+ String rid;
+
+ /**
+ * The runtime, related to the object currently being read.
+ */
+ gnuRuntime runtime;
+
+ /**
+ * Create an instance, delegating calls to the given CORBA stream.
+ */
+ public CorbaInput(InputStream an_input, Object firstObject,
+ RmiUtilities an_util, int an_offset, String a_rid,
+ gnuRuntime a_runtime)
+ throws Exception
+ {
+ stream = an_input;
+ current = firstObject;
+ util = an_util;
+
+ offset = an_offset;
+ rid = a_rid;
+ runtime = a_runtime;
+ }
+
+ /** @inheritDoc */
+ public int available()
+ throws IOException
+ {
+ return stream.available();
+ }
+
+ /**
+ * No action.
+ */
+ public void close()
+ throws IOException
+ {
+ }
+
+ /** @inheritDoc */
+ public void defaultReadObject()
+ throws IOException, ClassNotFoundException
+ {
+ util.readFields(offset, rid, (Serializable) current, stream, runtime);
+ }
+
+ /** @inheritDoc */
+ public void mark(int readlimit)
+ {
+ stream.mark(readlimit);
+ }
+
+ /** @inheritDoc */
+ public boolean markSupported()
+ {
+ return stream.markSupported();
+ }
+
+ /** @inheritDoc */
+ public int read()
+ throws IOException
+ {
+ return stream.read();
+ }
+
+ /** @inheritDoc */
+ public int read(byte[] buf, int off, int len)
+ throws IOException
+ {
+ return stream.read(buf, off, len);
+ }
+
+ /** @inheritDoc */
+ public int read(byte[] b)
+ throws IOException
+ {
+ return stream.read(b);
+ }
+
+ /** @inheritDoc */
+ public boolean readBoolean()
+ throws IOException
+ {
+ return stream.read_boolean();
+ }
+
+ /** @inheritDoc */
+ public byte readByte()
+ throws IOException
+ {
+ return (byte) stream.read();
+ }
+
+ /** @inheritDoc */
+ public char readChar()
+ throws IOException
+ {
+ return stream.read_char();
+ }
+
+ /** @inheritDoc */
+ public double readDouble()
+ throws IOException
+ {
+ return stream.read_double();
+ }
+
+ /** @inheritDoc */
+ public float readFloat()
+ throws IOException
+ {
+ return stream.read_float();
+ }
+
+ /** @inheritDoc */
+ public void readFully(byte[] buf, int off, int len)
+ throws IOException
+ {
+ // This class only reads from the buffered streams.
+ stream.read(buf, off, len);
+ }
+
+ /** @inheritDoc */
+ public void readFully(byte[] buf)
+ throws IOException
+ {
+ // This class only reads from the buffered streams.
+ stream.read(buf);
+ }
+
+ /** @inheritDoc */
+ public int readInt()
+ throws IOException
+ {
+ return stream.read_long();
+ }
+
+ /** @inheritDoc */
+ public String readLine()
+ throws IOException
+ {
+ return new DataInputStream(this).readLine();
+ }
+
+ /** @inheritDoc */
+ public long readLong()
+ throws IOException
+ {
+ return stream.read_longlong();
+ }
+
+ /** @inheritDoc */
+ public short read_short()
+ throws IOException
+ {
+ return stream.read_short();
+ }
+
+ /** @inheritDoc */
+ public int readUnsignedByte()
+ throws IOException
+ {
+ return (stream.read() & 0xFF);
+ }
+
+ /** @inheritDoc */
+ public int readUnsignedShort()
+ throws IOException
+ {
+ return (stream.read_short() & 0xFFFF);
+ }
+
+ /**
+ * Read as wide string (not as UTF).
+ */
+ public String readUTF()
+ throws IOException
+ {
+ return stream.read_wstring();
+ }
+
+ /** @inheritDoc */
+ public void reset()
+ throws IOException
+ {
+ stream.reset();
+ }
+
+ /** @inheritDoc */
+ public long skip(long n)
+ throws IOException
+ {
+ return stream.skip(n);
+ }
+
+ /** @inheritDoc */
+ public int skipBytes(int len)
+ throws IOException
+ {
+ return (int) stream.skip(len);
+ }
+
+ /**
+ * Objects are read as abstract interfaces.
+ */
+ protected Object readObjectOverride()
+ throws IOException, ClassNotFoundException
+ {
+ current = stream.read_abstract_interface();
+ return current;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/CorbaOutput.java b/libjava/classpath/gnu/javax/rmi/CORBA/CorbaOutput.java
new file mode 100644
index 00000000000..1c723407980
--- /dev/null
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/CorbaOutput.java
@@ -0,0 +1,219 @@
+/* CorbaOutput.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.rmi.CORBA;
+
+import org.omg.CORBA_2_3.portable.OutputStream;
+
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * A class to substitute as an ObjectOutputStream for objects using writeObject
+ * method.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class CorbaOutput
+ extends ObjectOutputStream
+ implements ObjectOutput
+{
+ /**
+ * A CORBA stream where the output is forwarded.
+ */
+ final OutputStream stream;
+
+ /**
+ * The utility class to write the object fields in default way.
+ */
+ final RmiUtilities util;
+
+ /**
+ * The object currently being written.
+ */
+ Object current;
+
+ /**
+ * Create an instance, delegating calls to the given CORBA stream.
+ */
+ public CorbaOutput(OutputStream an_output, Object firstObject,
+ RmiUtilities an_util)
+ throws Exception
+ {
+ stream = an_output;
+ current = firstObject;
+ util = an_util;
+ }
+
+ /**
+ * No action.
+ */
+ public void close()
+ throws IOException
+ {
+ }
+
+ /** @inheritDoc */
+ public void flush()
+ throws IOException
+ {
+ stream.flush();
+ }
+
+ /** @inheritDoc */
+ public void write(byte[] buf, int off, int len)
+ throws IOException
+ {
+ stream.write(buf, off, len);
+ }
+
+ /** @inheritDoc */
+ public void write(byte[] buf)
+ throws IOException
+ {
+ stream.write(buf);
+ }
+
+ /** @inheritDoc */
+ public void write(int val)
+ throws IOException
+ {
+ stream.write(val);
+ }
+
+ /** @inheritDoc */
+ public void writeBoolean(boolean val)
+ throws IOException
+ {
+ stream.write_boolean(val);
+ }
+
+ /** @inheritDoc */
+ public void writeByte(int val)
+ throws IOException
+ {
+ stream.write(val);
+ }
+
+ /** @inheritDoc */
+ public void writeBytes(String str)
+ throws IOException
+ {
+ stream.write_string(str);
+ }
+
+ /** @inheritDoc */
+ public void writeChar(int val)
+ throws IOException
+ {
+ stream.write_wchar((char) val);
+ }
+
+ /** @inheritDoc */
+ public void writeChars(String str)
+ throws IOException
+ {
+ stream.write_char_array(str.toCharArray(), 0, str.length());
+ }
+
+ /** @inheritDoc */
+ public void writeDouble(double val)
+ throws IOException
+ {
+ stream.write_double(val);
+ }
+
+ /** @inheritDoc */
+ public void writeFloat(float val)
+ throws IOException
+ {
+ stream.write_float(val);
+ }
+
+ /** @inheritDoc */
+ public void writeInt(int val)
+ throws IOException
+ {
+ stream.write_long(val);
+ }
+
+ /** @inheritDoc */
+ public void writeLong(long val)
+ throws IOException
+ {
+ stream.write_longlong(val);
+ }
+
+ /**
+ * Objects are written as abstract interfaces.
+ */
+ protected void writeObjectOverride(Object obj)
+ throws IOException
+ {
+ current = obj;
+ stream.write_abstract_interface(obj);
+ }
+
+ /** @inheritDoc */
+ public void writeShort(int val)
+ throws IOException
+ {
+ stream.write_short((short) val);
+ }
+
+ /**
+ * Such strings are written as wide strings, not as UTF.
+ */
+ public void writeUTF(String str)
+ throws IOException
+ {
+ stream.write_wstring(str);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public void defaultWriteObject()
+ throws IOException
+ {
+ util.writeFields(stream, (Serializable) current);
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/DefaultWriteObjectTester.java b/libjava/classpath/gnu/javax/rmi/CORBA/DefaultWriteObjectTester.java
new file mode 100644
index 00000000000..5bdf7dac933
--- /dev/null
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/DefaultWriteObjectTester.java
@@ -0,0 +1,85 @@
+/* DefaultWriteObjectTester.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.rmi.CORBA;
+
+import gnu.CORBA.CDR.BufferedCdrOutput;
+
+import java.io.IOException;
+
+/**
+ * Tests if the defaultWriteObject method has been called.
+ * This information is required by RMI-IIOP header.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class DefaultWriteObjectTester
+ extends CorbaOutput
+{
+ /**
+ * The flag, indicating, that the defaultWriteObject method was called.
+ */
+ public boolean dwo_called;
+
+ /**
+ * Create an instance, delegating calls to the given CORBA stream.
+ */
+ public DefaultWriteObjectTester(Object firstObject)
+ throws Exception
+ {
+ super(new BufferedCdrOutput(), firstObject, null);
+ }
+
+ /**
+ * Set the flag that defaultWriteObject was called.
+ */
+ public void defaultWriteObject()
+ throws IOException
+ {
+ dwo_called = true;
+ }
+
+ /**
+ * Do not write other objects.
+ */
+ protected void writeObjectOverride(Object obj)
+ throws IOException
+ {
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/DelegateFactory.java b/libjava/classpath/gnu/javax/rmi/CORBA/DelegateFactory.java
index d71546d7561..0607c9f9626 100644
--- a/libjava/classpath/gnu/javax/rmi/CORBA/DelegateFactory.java
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/DelegateFactory.java
@@ -1,5 +1,5 @@
/* DelegateFactory.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,38 +38,70 @@ exception statement from your version. */
package gnu.javax.rmi.CORBA;
-import java.util.HashMap;
+import gnu.CORBA.ObjectCreator;
+
+/**
+ * This class produces delegates, using the system properties. If not
+ * corresponding property is specified, returns default implementations.
+ *
+ * @author Wu Gansha (gansha.wu@intel.com)
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
public class DelegateFactory
{
- private static HashMap cache = new HashMap(4);
-
- public static synchronized Object getInstance(String type)
- throws GetDelegateInstanceException
+ /**
+ * The name to get a stub delegate.
+ */
+ public static final String STUB = "Stub";
+
+ /**
+ * The name to get the util delegate.
+ */
+ public static final String UTIL = "Util";
+
+ /**
+ * The name to get the ValueHandler delegate.
+ */
+ public static final String VALUEHANDLER = "ValueHandler";
+
+ /**
+ * The name to get the PortableRemoteObject delegate.
+ */
+ public static final String PORTABLE_REMOTE_OBJECT = "PortableRemoteObject";
+
+ /**
+ * Get an instance of the given delegate. As in all cases the singleton
+ * instance is used, the caching here would be redundant.
+ *
+ * @param type a delegate type.
+ *
+ * @return the associated delegate.
+ *
+ * @throws InternalError if the delegate class, indicated in the system
+ * properties, cannot be instantiated.
+ */
+ public static Object getInstance(String type)
+ throws InternalError
{
- Object r = cache.get(type);
- if (r != null)
- return r;
- String dcname = System.getProperty("javax.rmi.CORBA." + type + "Class");
+ String propertyName = "javax.rmi.CORBA." + type + "Class";
+ String dcname = System.getProperty(propertyName);
if (dcname == null)
{
- //throw new DelegateException
- // ("no javax.rmi.CORBA.XXXClass property sepcified.");
- dcname = "gnu.javax.rmi.CORBA." + type + "DelegateImpl";
+ // // No javax.rmi.CORBA.XXXClass property sepcified.
+ dcname = "gnu.javax.rmi.CORBA." + type + "DelegateImpl";
}
try
{
- Class dclass = Class.forName(dcname,
- true,
- Thread.currentThread().getContextClassLoader());
- r = dclass.newInstance();
- cache.put(type, r);
- return r;
+ Class dclass = ObjectCreator.forName(dcname);
+ return dclass.newInstance();
}
- catch(Exception e)
+ catch (Exception e)
{
- throw new GetDelegateInstanceException
- ("Exception when trying to get delegate instance:" + dcname, e);
+ InternalError ierr = new InternalError("Exception when trying to get "
+ + type + "delegate instance:" + dcname);
+ ierr.initCause(e);
+ throw ierr;
}
}
}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java b/libjava/classpath/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java
index 6a7e6b74622..ea4f73811f0 100644
--- a/libjava/classpath/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java
@@ -1,5 +1,5 @@
/* PortableRemoteObjectDelegateImpl.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,99 +38,325 @@ exception statement from your version. */
package gnu.javax.rmi.CORBA;
-import gnu.javax.rmi.PortableServer;
+import gnu.CORBA.SimpleDelegate;
+import gnu.CORBA.Unexpected;
+import gnu.CORBA.Poa.LocalDelegate;
+import gnu.CORBA.Poa.ORB_1_4;
+import gnu.CORBA.Poa.AOM;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
+import java.rmi.server.RMIClassLoader;
import javax.rmi.CORBA.PortableRemoteObjectDelegate;
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.portable.Delegate;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAHelper;
+import org.omg.PortableServer.Servant;
+import org.omg.PortableServer.POAManagerPackage.State;
+
+/**
+ * Implements PortableRemoteObjectDelegate.
+ *
+ * @author Wu Gansha (gansha.wu@intel.com) (stub)
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
+ */
public class PortableRemoteObjectDelegateImpl
implements PortableRemoteObjectDelegate
{
-
- public PortableRemoteObjectDelegateImpl()
- {
- }
-
- public void connect(Remote remote, Remote remote1)
+ /**
+ * <p>
+ * Makes the remote object <code>a_target</code> ready for remote
+ * communication using the same communications runtime as for the passed
+ * <code>a_source</code> parameter. The a_target is connected to the same
+ * ORB (and, if applicable, to the same POA) as the a_source.
+ *
+ * @param a_target the target to connect to ORB, must be an instance of either
+ * {@link ObjectImpl} (Stubs and old-style ties) or {@link Servant} (POA-bases
+ * ties).
+ *
+ * @param a_source the object, providing the connection information, must be
+ * an instance of either {@link ObjectImpl} (Stubs and old-style ties) or
+ * {@link Servant} (POA-bases ties).
+ *
+ * @throws RemoteException if the target is already connected to another ORB.
+ */
+ public void connect(Remote a_target, Remote a_source)
throws RemoteException
{
- throw new Error("Not implemented for PortableRemoteObjectDelegateImpl");
- }
-
- public void exportObject(Remote obj)
- throws RemoteException
- {
- PortableServer.exportObject(obj);
+ ORB orb = null;
+ POA poa = null;
+ boolean ok = false;
+
+ try
+ {
+ if (a_source instanceof Servant)
+ {
+ Servant s = (Servant) a_source;
+ orb = s._orb();
+ poa = s._poa();
+ ok = true;
+ }
+
+ if (!ok && a_source instanceof ObjectImpl)
+ {
+ ObjectImpl o = (ObjectImpl) a_source;
+ orb = o._orb();
+ ok = true;
+ try
+ {
+ if (orb instanceof ORB_1_4)
+ {
+ // POA information available.
+ ORB_1_4 xorb = (ORB_1_4) orb;
+ Delegate d = o._get_delegate();
+
+ if (d instanceof LocalDelegate)
+ {
+ LocalDelegate l = (LocalDelegate) d;
+ poa = l.poa;
+ }
+ else if (d instanceof SimpleDelegate)
+ {
+ byte[] ior_key = ((SimpleDelegate) d).getIor().key;
+ AOM.Obj ref = xorb.rootPOA.findIorKey(ior_key);
+ if (ref != null)
+ poa = ref.poa;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ // OK, POA info is not available, but as ORB is available, we
+ // will connect in a default way.
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ RuntimeException rex = new RuntimeException("Unable to get info from "
+ + a_source);
+ rex.initCause(ex);
+ throw rex;
+ }
+
+ if (!ok && a_source instanceof Tie)
+ {
+ Tie t = (Tie) a_source;
+ orb = t.orb();
+ poa = null;
+ ok = true;
+ }
+
+ if (orb == null)
+ throw new RemoteException("Unable to determine ORB from " + a_source);
+
+ if (a_target instanceof Stub)
+ {
+ StubDelegateImpl.connect((Stub) a_target, orb, poa);
+ }
+ else if (a_target instanceof Servant)
+ {
+ try
+ {
+ if (poa == null)
+ {
+ poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
+ // Activate if not active.
+ if (poa.the_POAManager().get_state().value() == State._HOLDING)
+ poa.the_POAManager().activate();
+ }
+ poa.servant_to_reference((Servant) a_target);
+ }
+ catch (Exception ex)
+ {
+ throw new Unexpected(ex);
+ }
+ }
+ else if (a_target instanceof org.omg.CORBA.Object)
+ {
+ // Connect as object.
+ orb.connect((org.omg.CORBA.Object) a_target);
+ }
+ else if (a_target instanceof Tie)
+ {
+ // We avoid calling this because it will aways connect to the root poa.
+ ((Tie) a_target).orb(orb);
+ }
}
+ /**
+ * Narrow the given object to the instance of the given class. The currently
+ * supported narrowing types are:
+ *
+ * 1. Simple widening conversion.<br>
+ * 2. ObjectImpl -> RMI interface.<br>
+ * 3. ObjectImpl -> ObjectImpl.<br>
+ * 4. Tie -> Remote (implementation)<br>
+ * 5. Remote (implementation) -> Tie.<br>
+ *
+ * The narrowing has sense only for derived classes.
+ */
public Object narrow(Object narrowFrom, Class narrowTo)
throws ClassCastException
{
if (narrowTo == null)
throw new ClassCastException("Can't narrow to null class");
- if (narrowFrom == null)
+ else if (narrowFrom == null)
return null;
+ else
+ // Simple narrowing case.
+ if (narrowTo.isAssignableFrom(narrowFrom.getClass()))
+ return narrowFrom;
+ else if (narrowTo.isInterface() || narrowFrom instanceof ObjectImpl)
+ {
+ // Narrow CORBA object to passed interface.
+
+ String interf = narrowTo.getName();
+ String stubClassName;
- Class fromClass = narrowFrom.getClass();
- Object result = null;
-
+ stubClassName = getStubClassName(interf);
+
+ try
+ {
+ // Replace the interface class by the stub class.
+ narrowTo = Util.loadClass(stubClassName, null,
+ narrowTo.getClassLoader());
+ }
+ catch (ClassNotFoundException e)
+ {
+ ClassCastException cex = new ClassCastException("Class not found: "
+ + stubClassName);
+ cex.initCause(e);
+ throw cex;
+ }
+ }
+ else if (narrowFrom instanceof Tie)
+ {
+ // Try to substitute the return tie target as a return value.
+ Remote target = ((Tie) narrowFrom).getTarget();
+ if (target != null && narrowTo.isAssignableFrom(target.getClass()))
+ return target;
+ }
+
+ Object narrowed;
try
{
- if (narrowTo.isAssignableFrom(fromClass))
- result = narrowFrom;
- else
- {
- System.out.println("We still haven't implement this case: narrow "
- + narrowFrom + " of type " + fromClass + " to "
- + narrowTo);
- Class[] cs = fromClass.getInterfaces();
- for (int i = 0; i < cs.length; i++)
- System.out.println(cs[i]);
- Exception e1 = new Exception();
- try
- {
- throw e1;
- }
- catch(Exception ee)
- {
- ee.printStackTrace();
- }
- System.exit(2);
- //throw new Error("We still haven't implement this case: narrow "
- // + narrowFrom + " of type " + fromClass + " to "
- // + narrowTo);
- /*
- ObjectImpl objimpl = (ObjectImpl)narrowFrom;
- if(objimpl._is_a(PortableServer.getTypeName(narrowTo)))
- result = PortableServer.getStubFromObjectImpl(objimpl, narrowTo);
- */
- }
- }
- catch(Exception e)
- {
- result = null;
- }
-
- if (result == null)
- throw new ClassCastException("Can't narrow from "
- + fromClass + " to " + narrowTo);
-
- return result;
+ narrowed = narrowTo.newInstance();
+ }
+ catch (Exception e)
+ {
+ ClassCastException cex = new ClassCastException("Cannot instantiate "
+ + narrowTo.getName());
+ cex.initCause(e);
+ throw cex;
+ }
+
+ if (narrowed instanceof ObjectImpl)
+ {
+ // This also works for the instances of the Stub.
+ ObjectImpl target = (ObjectImpl) narrowed;
+ // Set the delegate, as is done in *Helper.narrow(..).
+ target._set_delegate(((ObjectImpl) narrowFrom)._get_delegate());
+ }
+ else if (narrowed instanceof Tie && narrowFrom instanceof Remote)
+ {
+ // Try to set the narrowing object as a target for the Tie.
+ ((Tie) narrowed).setTarget((Remote) narrowFrom);
+ }
+ else
+ throw new ClassCastException("Narrowing of " + narrowFrom.getClass()
+ + " to " + narrowTo + " is either not possible or not implemented.");
+
+ return narrowed;
}
-
- public Remote toStub(Remote obj)
+
+ /**
+ * Get the Stub class name for the name, representing the given interface.
+ */
+ static String getStubClassName(String interf)
+ {
+ String stubClassName;
+ int p = interf.lastIndexOf('.');
+
+ if (p < 0)
+ // The interface is defined in the default package.
+ stubClassName = "_" + interf + "_Stub";
+ else
+ stubClassName = interf.substring(0, p + 1) + "_"
+ + interf.substring(p + 1) + "_Stub";
+ return stubClassName;
+ }
+
+ /**
+ * Get stub for the given implementation, searching by class name pattern. The
+ * found stub must implement Remote for this method to succeed.
+ */
+ public Remote toStub(Remote ObjImpl)
throws NoSuchObjectException
{
- return PortableServer.toStub(obj);
+ String icn = ObjImpl.getClass().getName();
+ if (!icn.endsWith("Impl"))
+ throw new BAD_PARAM("Invalid class name '" + icn
+ + "', must end with 'Impl'");
+
+ String sn = "_" + icn.substring(0, icn.length() - "Impl".length())
+ + "_Stub";
+
+ Class stubClass;
+ Object o_stub;
+
+ try
+ {
+ stubClass = RMIClassLoader.loadClass(sn);
+ o_stub = stubClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ NoSuchObjectException n = new NoSuchObjectException(sn);
+ n.initCause(e);
+ throw n;
+ }
+
+ if (!Remote.class.isAssignableFrom(stubClass))
+ throw new ClassCastException(stubClass.getName()
+ + " exists but cannot be returned as it does not inherit from "
+ + Remote.class.getName());
+
+ return (Remote) o_stub;
}
+ /**
+ * If the object tie is no longer in use, disconnet it from the orb.
+ */
public void unexportObject(Remote obj)
throws NoSuchObjectException
{
- PortableServer.unexportObject(obj);
+ Util.unexportObject(obj);
+ }
+
+ /**
+ * Find or create a tie for this target and mark it as being used by the given
+ * object.
+ */
+ public void exportObject(Remote obj)
+ throws RemoteException
+ {
+ if (obj instanceof Stub)
+ Util.registerTarget(StubDelegateImpl.getTieFromStub((Stub) obj), obj);
+ else if (obj instanceof Tie)
+ {
+ Tie t = (Tie) obj;
+ Util.registerTarget(t, null);
+ }
}
}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/RmiUtilities.java b/libjava/classpath/gnu/javax/rmi/CORBA/RmiUtilities.java
new file mode 100644
index 00000000000..91bfa3776dc
--- /dev/null
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/RmiUtilities.java
@@ -0,0 +1,946 @@
+/* RmiUtilities.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.rmi.CORBA;
+
+import gnu.CORBA.OrbFunctional;
+import gnu.CORBA.Minor;
+import gnu.CORBA.Unexpected;
+import gnu.CORBA.CDR.Vio;
+import gnu.CORBA.CDR.gnuRuntime;
+import gnu.CORBA.CDR.gnuValueStream;
+import gnu.CORBA.CDR.HeadlessInput;
+
+import org.omg.CORBA.MARSHAL;
+import org.omg.CORBA.StringValueHelper;
+import org.omg.CORBA.WStringValueHelper;
+import org.omg.CORBA.portable.Delegate;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ValueBase;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAHelper;
+import org.omg.PortableServer.Servant;
+import org.omg.PortableServer.POAManagerPackage.State;
+import org.omg.SendingContext.RunTime;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.rmi.Remote;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.WeakHashMap;
+
+import javax.rmi.PortableRemoteObject;
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+
+/**
+ * Defines methods that must be accessible in several derived classes.
+ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
+ */
+public class RmiUtilities
+{
+ /**
+ * The currently used RMI-IIOP version format.
+ */
+ public static byte VERSION = 1;
+
+ /**
+ * The non - writable class fields.
+ */
+ static final int NON_WRITABLE = Modifier.STATIC | Modifier.TRANSIENT;
+
+ /**
+ * The standard String repository Id.
+ */
+ public static final String RMI_STRING_ID = StringValueHelper.id();
+
+ /**
+ * The standard Class repository Id.
+ */
+ public static final String RMI_CLASS_ID = "RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B";
+
+ /**
+ * The standard string array repository Id.
+ */
+ public static final String RMI_STRING_ARRAY_ID = "RMI:[Ljava.lang.String;:071DA8BE7F971128:A0F0A4387A3BB342";
+
+ /**
+ * An instance of the wide string value helper for writing strings.
+ */
+ static WStringValueHelper wStringValueHelper = new WStringValueHelper();
+
+ /**
+ * Set of serializable classes that have .writeObject and .readObject defined.
+ * Contains weak references to ensure that the classes will be unloadable.
+ */
+ WeakHashMap io_format = new WeakHashMap();
+
+ /**
+ * The standard IO format with no .writeObject and .readObject defined.
+ */
+ static final Object STANDARD = new Object();
+
+ /**
+ * The custom IO format with .writeObject and .readObject defined,
+ * defaultWriteObject called.
+ */
+ static final Object CUSTOM_DWO = new Object();
+
+ /**
+ * The custom IO format with .writeObject and .readObject defined,
+ * defaultWriteObject has not been called.
+ */
+ static final Object CUSTOM_NO_DWO = new Object();
+
+ /**
+ * The arguments for readObject.
+ */
+ static final Class[] READ_OBJECT_ARGS = new Class[] { ObjectInputStream.class };
+
+ /**
+ * The arguments for writeObject.
+ */
+ static final Class[] WRITE_OBJECT_ARGS = new Class[] { ObjectOutputStream.class };
+
+ /**
+ * The undocumented field that is heading the Sun's object data, written with
+ * writeObject.
+ */
+ static final int S_X = 16908034;
+
+ /**
+ * Write all fields of the passed value.
+ */
+ void writeFields(OutputStream an_output, Serializable object)
+ {
+ org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
+ try
+ {
+ Class o_class = object.getClass();
+ Field[] fields = getWritableFields(o_class);
+ Field f;
+
+ Class fc;
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ f = fields[i];
+ fc = f.getType();
+ Object v = f.get(object);
+
+ if (fc == String.class)
+ {
+ output.write_value((Serializable) v, wStringValueHelper);
+ }
+ else if (fc == int.class)
+ output.write_long(((Integer) v).intValue());
+ else if (fc == long.class)
+ output.write_longlong(((Number) v).longValue());
+ else if (fc == double.class)
+ output.write_double(((Number) v).doubleValue());
+ else if (fc == float.class)
+ output.write_float(((Number) v).floatValue());
+ else if (fc == boolean.class)
+ output.write_boolean(((Boolean) v).booleanValue());
+ else if (fc == short.class)
+ output.write_short(((Number) v).shortValue());
+ else if (fc == byte.class)
+ output.write_octet(((Number) v).byteValue());
+ else if (fc == char.class)
+ output.write_wchar(((Character) v).charValue());
+ else
+ {
+ if (!fc.isInterface() && Remote.class.isAssignableFrom(fc))
+ fc = getExportedInterface(fc);
+ writeMember(output, v, fc);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MARSHAL m = new MARSHAL("Cannot write " + object);
+ m.minor = Minor.ValueFields;
+ m.initCause(ex);
+ throw m;
+ }
+ }
+
+ /**
+ * Write a memeber (field) of the data structure.
+ */
+ void writeMember(org.omg.CORBA_2_3.portable.OutputStream output,
+ Object object, Class xClass)
+ {
+ if (output instanceof gnuValueStream)
+ {
+ gnuRuntime g = ((gnuValueStream) output).getRunTime();
+ // Reset the target as we are already beyond the critical point
+ // where is must have the value being written.
+ if (g != null)
+ g.target = null;
+ }
+ if (Serializable.class.isAssignableFrom(xClass)
+ || Remote.class.isAssignableFrom(xClass))
+ {
+ // Object handles null reference on its own.
+ if (org.omg.CORBA.Object.class.isAssignableFrom(xClass)
+ || Remote.class.isAssignableFrom(xClass))
+ {
+ if (object == null)
+ output.write_Object(null);
+ else if (isTieRequired(object))
+ exportTie(output, object, xClass);
+ else
+ writeValue(output, (Serializable) object);
+ }
+ else
+ output.write_value((Serializable) object, xClass);
+ }
+ else
+ {
+ MARSHAL m = new MARSHAL(xClass + " is not Serializable");
+ m.minor = Minor.NonSerializable;
+ throw m;
+ }
+ }
+
+ /**
+ * Check if the object must be wrapped into Tie, connected to the ORB and then
+ * the corresponding Stub be written.
+ */
+ public boolean isTieRequired(Object object)
+ {
+ return object instanceof Remote && !(object instanceof Stub);
+ }
+
+ /**
+ * Get the interface under that the class of this object must be exposed. The
+ * interface must be derived from Remote.
+ */
+ Class getExportedInterface(Object object)
+ throws MARSHAL
+ {
+ Class fc = null;
+ Class[] interfaces = object.getClass().getInterfaces();
+ for (int i = 0; i < interfaces.length; i++)
+ {
+ if (!Remote.class.equals(interfaces[i]))
+ if (Remote.class.isAssignableFrom(interfaces[i]))
+ {
+ if (fc == null)
+ fc = interfaces[i];
+ else
+ {
+ MARSHAL m = new MARSHAL("Both " + fc + " and " + interfaces[i]
+ + " extends Remote");
+ m.minor = Minor.TargetConversion;
+ throw m;
+ }
+ }
+ }
+ if (fc == null)
+ {
+ MARSHAL m = new MARSHAL(object.getClass()
+ + " does not implement any interface, derived from Remote");
+ m.minor = Minor.TargetConversion;
+ throw m;
+ }
+ return fc;
+ }
+
+ /**
+ * Get the persistent hash code for the given class, as defined by OMG
+ * standard. The inheritance, field names and types (but not the visibility)
+ * are taken into consideration as well as the presence of the writeObject
+ * method are taken into consideration. The class name and methods, if any,
+ * are not taken into consideration.
+ */
+ public static long getHashCode(Class c)
+ {
+ Class of = c.isArray() ? c.getComponentType() : null;
+ if (c.isArray()
+ && ((!Serializable.class.isAssignableFrom(of) || of.isPrimitive() || Remote.class.isAssignableFrom(of))))
+ return 0;
+ if (!Serializable.class.isAssignableFrom(c))
+ return 0;
+ try
+ {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ DataOutputStream out = new DataOutputStream(bout);
+
+ Class superClass = c.getSuperclass();
+ if (superClass != null)
+ out.writeLong(getHashCode(superClass));
+
+ int writeObjectPresentCode;
+ try
+ {
+ c.getDeclaredMethod("writeObject",
+ new Class[] { ObjectOutputStream.class });
+ writeObjectPresentCode = 2; // Exists.
+ }
+ catch (NoSuchMethodException e)
+ {
+ writeObjectPresentCode = 1; // Missing.
+ }
+ out.writeInt(writeObjectPresentCode);
+
+ Field[] fields = c.getDeclaredFields();
+
+ Arrays.sort(fields, new Comparator()
+ {
+ public int compare(Object a, Object b)
+ {
+ Field fa = (Field) a;
+ Field fb = (Field) b;
+ return fa.getName().compareTo(fb.getName());
+ }
+ });
+
+ Field f;
+ for (int i = 0; i < fields.length; i++)
+ {
+ f = fields[i];
+ if ((f.getModifiers() & NON_WRITABLE) == 0)
+ {
+ out.writeUTF(f.getName());
+ out.writeUTF(getDescriptor(f.getType()));
+ }
+ }
+
+ out.flush();
+ out.close();
+ MessageDigest shaDigest;
+ try
+ {
+ shaDigest = MessageDigest.getInstance("SHA");
+ }
+ catch (Exception ex)
+ {
+ throw new InternalError("SHA digesting algorithm is not available");
+ }
+
+ // Return the digest value to the calling
+ // method as an array of bytes.
+ byte[] sha = shaDigest.digest(bout.toByteArray());
+
+ long hash = 0;
+ for (int i = 0; i < Math.min(8, sha.length); i++)
+ {
+ hash += (long) (sha[i] & 255) << (i * 8);
+ }
+ return hash;
+ }
+ catch (IOException ioex)
+ {
+ throw new Unexpected(ioex);
+ }
+ }
+
+ /**
+ * Converts to hexadecimal string, supplementing leading zeros.
+ */
+ public static String toHex(long l)
+ {
+ StringBuffer b = new StringBuffer();
+ b.append(Long.toHexString(l).toUpperCase());
+ while (b.length() < 16)
+ b.insert(0, '0');
+ return b.toString();
+ }
+
+ /**
+ * Returns a <code>String</code> representing the type-encoding of a class.
+ */
+ static String getDescriptor(Class type)
+ {
+ if (type.equals(boolean.class))
+ return "Z";
+ if (type.equals(byte.class))
+ return "B";
+ if (type.equals(short.class))
+ return "S";
+ if (type.equals(char.class))
+ return "C";
+ if (type.equals(int.class))
+ return "I";
+ if (type.equals(long.class))
+ return "J";
+ if (type.equals(float.class))
+ return "F";
+ if (type.equals(double.class))
+ return "D";
+ if (type.equals(void.class))
+ return "V";
+ else if (type.isArray())
+ {
+ StringBuffer l = new StringBuffer("[");
+ Class component = type.getComponentType();
+
+ while (component.isArray())
+ {
+ l.append('[');
+ component = component.getComponentType();
+ }
+
+ l.append('L');
+ l.append(component.getName().replace('.', '/'));
+ l.append(';');
+ return l.toString();
+ }
+ else
+ return "L" + type.getName().replace('.', '/') + ';';
+ }
+
+ public static Field[] getWritableFields(Class c)
+ {
+ TreeSet set = new TreeSet(new Comparator()
+ {
+ public int compare(Object a, Object b)
+ {
+ return ((Field) a).getName().compareTo(((Field) b).getName());
+ }
+ });
+
+ while (!c.equals(Object.class))
+ {
+ Field[] f = c.getDeclaredFields();
+ for (int i = 0; i < f.length; i++)
+ {
+ if ((f[i].getModifiers() & NON_WRITABLE) == 0)
+ {
+ f[i].setAccessible(true);
+ set.add(f[i]);
+ }
+ }
+ c = c.getSuperclass();
+ }
+
+ Field[] r = new Field[set.size()];
+ int p = 0;
+ Iterator it = set.iterator();
+ while (it.hasNext())
+ {
+ r[p++] = (Field) it.next();
+ }
+ return r;
+ }
+
+ /**
+ * The method is called for Remotes that are not Stubs. It is assumed, that
+ * the Remote is an implementation. The method searches for the suitable tie
+ * and, if found, exports it by creating and connecting the stub. Such export
+ * is supported since jdk 1.5.
+ */
+ void exportTie(org.omg.CORBA_2_3.portable.OutputStream output,
+ Object implementation, Class interfaceClass)
+ {
+ try
+ {
+ // Remote, but non - stub class (implementation)
+ // must be replaced by stub.
+ Tie t = Util.getTie((Remote) implementation);
+ if (t instanceof Servant)
+ {
+ POA rootPoa = POAHelper.narrow(output.orb().resolve_initial_references(
+ "RootPOA"));
+ org.omg.CORBA.Object co = rootPoa.servant_to_reference((Servant) t);
+ Stub stub = (Stub) PortableRemoteObject.narrow(co, interfaceClass);
+ writeRemoteObject(output, stub);
+
+ if (rootPoa.the_POAManager().get_state().value() == State._HOLDING)
+ rootPoa.the_POAManager().activate();
+ }
+ else if (t instanceof org.omg.CORBA.Object)
+ {
+ org.omg.CORBA.Object co = (org.omg.CORBA.Object) t;
+ output.orb().connect(co);
+
+ Stub stub = (Stub) PortableRemoteObject.narrow(co, interfaceClass);
+ writeRemoteObject(output, stub);
+ }
+ }
+ catch (Exception ex)
+ {
+ MARSHAL m = new MARSHAL("Unable to export " + implementation);
+ m.minor = Minor.TargetConversion;
+ m.initCause(ex);
+ throw m;
+ }
+ }
+
+ /**
+ * Start the ORB, if it is not already runnning.
+ */
+ void ensureOrbRunning(org.omg.CORBA_2_3.portable.OutputStream output)
+ {
+ // Ensure ORB is running.
+ if (output.orb() instanceof OrbFunctional)
+ {
+ ((OrbFunctional) output.orb()).ensureRunning();
+ }
+ }
+
+ /**
+ * Write data to the CORBA output stream. Writes the object contents only; the
+ * header must be already written. For object, containing objects, may be
+ * called recursively.
+ *
+ * @param an_output a stream to write to, must be
+ * org.omg.CORBA_2_3.portable.OutputStream
+ * @param object an object to write.
+ */
+ public void writeRemoteObject(OutputStream an_output, Object object)
+ {
+ org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
+
+ if (isTieRequired(object))
+ {
+ // Find the interface that is implemented by the object and extends
+ // Remote.
+ Class fc = getExportedInterface(object);
+ exportTie(output, object, fc);
+ }
+ else if (object instanceof org.omg.CORBA.Object)
+ {
+ ensureOrbRunning(output);
+ an_output.write_Object((org.omg.CORBA.Object) object);
+ }
+ else if (object != null && object instanceof Serializable)
+ writeFields(an_output, (Serializable) object);
+ }
+
+ /**
+ * Write data to the CORBA output stream. Writes the object contents only; the
+ * header must be already written. For object, containing objects, may be
+ * called recursively.
+ *
+ * @param an_output a stream to write to, must be
+ * org.omg.CORBA_2_3.portable.OutputStream
+ * @param object an object to write.
+ */
+ public void writeValue(OutputStream an_output, Serializable object)
+ {
+ org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
+
+ if (isTieRequired(object))
+ {
+ // Find the interface that is implemented by the object and extends
+ // Remote.
+ Class fc = getExportedInterface(object);
+ exportTie(output, object, fc);
+ }
+ else if (object instanceof org.omg.CORBA.Object)
+ {
+ ensureOrbRunning(output);
+ an_output.write_Object((org.omg.CORBA.Object) object);
+ }
+ else if (object instanceof Externalizable)
+ {
+ try
+ {
+ ObjectOutputStream stream = new CorbaOutput(output, object,
+ this);
+ stream.write(VERSION);
+ ((Externalizable) object).writeExternal(stream);
+ }
+ catch (Exception ex)
+ {
+ MARSHAL m = new MARSHAL("writeExternal failed");
+ m.minor = Minor.Value;
+ m.initCause(ex);
+ throw m;
+ }
+ }
+ else if (object instanceof Serializable)
+ {
+ Object mode = null;
+ synchronized (io_format)
+ {
+ mode = io_format.get(object.getClass());
+ if (mode == STANDARD)
+ {
+ writeFields(an_output, (Serializable) object);
+ return;
+ }
+ }
+ try
+ {
+ Method m = object.getClass().getDeclaredMethod("writeObject",
+ WRITE_OBJECT_ARGS);
+ m.setAccessible(true); // May be private.
+
+ try
+ {
+ ObjectOutputStream stream = new CorbaOutput(output,
+ object, this);
+
+ // Write version.
+ stream.write(VERSION);
+
+ if (mode == CUSTOM_DWO)
+ // Write true, supposing that the defaultWriteObject
+ // has been called.
+ stream.write(1);
+ else if (mode == CUSTOM_NO_DWO)
+ // Write false (has not been called)
+ stream.write(0);
+ else
+ {
+ // Measure.
+ DefaultWriteObjectTester tester = new DefaultWriteObjectTester(object);
+ m.invoke(object, new Object[] { tester });
+
+ synchronized (io_format)
+ {
+ io_format.put(object.getClass(),
+ tester.dwo_called ? CUSTOM_DWO : CUSTOM_NO_DWO);
+ stream.write(tester.dwo_called ? 1 : 0);
+ }
+ }
+
+ m.invoke(object, new Object[] { stream });
+ stream.flush();
+ }
+ catch (Exception ex)
+ {
+ MARSHAL mx = new MARSHAL(object.getClass().getName()
+ + ".writeObject failed");
+ mx.initCause(ex);
+ throw mx;
+ }
+ }
+ catch (NoSuchMethodException e)
+ {
+ // Write in a standard way.
+ writeFields(an_output, (Serializable) object);
+ synchronized (io_format)
+ {
+ io_format.put(object.getClass(), STANDARD);
+ }
+ }
+ }
+ }
+
+ /**
+ * Read data from the CDR input stream. Reads the object contents only; the
+ * header must be already read (the repository id or ids ara passed). For
+ * object, containing objects, may be called recursively.
+ *
+ * @param an_input the stream to read from, must be
+ * org.omg.CORBA_2_3.portable.InputStream
+ * @param object the instance of the object being read.
+ * @param id the repository Id from the stream in the case when single id was
+ * specified.
+ * @param ids the repository Ids from the stream in the case when multiple ids
+ * were specified.
+ * @param codebase the codebase, if it was included in the header of the value
+ * type. Null if not codebase was included.
+ *
+ * @return the object, extracted from the stream.
+ */
+ /**
+ * Read value from the input stream in the case when the value is not
+ * Streamable or CustomMarshalled.
+ */
+ public Serializable readValue(InputStream in, int offset, Class clz,
+ String repositoryID, RunTime sender)
+ {
+ if (in instanceof HeadlessInput)
+ ((HeadlessInput) in).subsequentCalls = true;
+
+ gnuRuntime g;
+ Serializable object = null;
+
+ try
+ {
+ g = (gnuRuntime) sender;
+ object = g.target;
+ }
+ catch (ClassCastException e)
+ {
+ // Working with the other CORBA implementation.
+ g = null;
+ }
+
+ org.omg.CORBA_2_3.portable.InputStream input = (org.omg.CORBA_2_3.portable.InputStream) in;
+
+ if (Remote.class.isAssignableFrom(clz)
+ || ValueBase.class.isAssignableFrom(clz))
+ {
+ // Interface is narrowed into Stub.
+ if (clz.isInterface())
+ try
+ {
+ clz = Util.loadClass(
+ PortableRemoteObjectDelegateImpl.getStubClassName(clz.getName()),
+ null, clz.getClassLoader());
+ }
+ catch (ClassNotFoundException e)
+ {
+ MARSHAL m = new MARSHAL("Cannot get stub from interface "
+ + clz.getClass().getName());
+ m.minor = Minor.TargetConversion;
+ m.initCause(e);
+ throw m;
+ }
+
+ // Remote needs special handling.
+ if (ObjectImpl.class.isAssignableFrom(clz))
+ {
+ // First read CORBA object reference.
+ Object ro = input.read_Object();
+
+ ObjectImpl obj = (ObjectImpl) ro;
+ if (obj == null)
+ return null;
+
+ Delegate delegate = obj._get_delegate();
+ object = instantiate(offset, clz, g);
+ ((ObjectImpl) object)._set_delegate(delegate);
+ }
+ // The object - specific data follows.
+ }
+ else if (org.omg.CORBA.Object.class.isAssignableFrom(clz))
+ object = (Serializable) input.read_Object();
+
+ if (object == null)
+ object = instantiate(offset, clz, g);
+
+ // The sentence below prevents attempt to read the internal fields of the
+ // ObjectImpl (or RMI Stub) that might follow the object definition.
+ // Sun's jre 1.5 does not write this information. The stubs, generated
+ // by rmic, does not contain such fields.
+ if (object instanceof ObjectImpl)
+ return object;
+
+ if (object instanceof Externalizable)
+ {
+ try
+ {
+ CorbaInput stream = new CorbaInput(input, object, this,
+ offset, repositoryID, g);
+
+ byte version = stream.readByte();
+ if (version != 1)
+ throw new MARSHAL("Unsuported RMI-IIOP version " + version);
+
+ ((Externalizable) object).readExternal(stream);
+ }
+ catch (Exception ex)
+ {
+ MARSHAL m = new MARSHAL("readExternal failed");
+ m.initCause(ex);
+ throw m;
+ }
+ }
+ else
+ {
+ Object mode = null;
+ synchronized (io_format)
+ {
+ mode = io_format.get(object.getClass());
+ }
+
+ if (mode == STANDARD)
+ {
+ readFields(offset, repositoryID, object, input, g);
+ }
+ else
+ {
+ try
+ {
+ Method m = object.getClass().getDeclaredMethod("readObject",
+ READ_OBJECT_ARGS);
+ try
+ {
+ m.setAccessible(true); // May be private.
+
+ CorbaInput stream = new CorbaInput(input,
+ object, this, offset, repositoryID, g);
+
+ byte version = stream.readByte();
+ if (version != 1)
+ throw new MARSHAL("Unsuported RMI-IIOP version "
+ + version);
+
+ // This would indicate is defaultWriteObject has been
+ // called,
+ // but the readObject method normally takes care about this.
+ boolean dwo = stream.readByte() != 0;
+
+ m.invoke(object, new Object[] { stream });
+ synchronized (io_format)
+ {
+ io_format.put(object.getClass(), dwo ? CUSTOM_DWO
+ : CUSTOM_NO_DWO);
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ MARSHAL mx = new MARSHAL(object.getClass().getName()
+ + ".readObject failed");
+ mx.initCause(ex);
+ throw mx;
+ }
+ }
+ catch (NoSuchMethodException e)
+ {
+ // Read in a standard way.
+ synchronized (io_format)
+ {
+ io_format.put(object.getClass(), STANDARD);
+ readFields(offset, repositoryID, object, input, g);
+ }
+ }
+ }
+ }
+ return object;
+ }
+
+ /**
+ * Create an instance.
+ */
+ Serializable instantiate(int offset, Class clz, gnuRuntime g)
+ throws MARSHAL
+ {
+ Serializable object;
+ try
+ {
+ object = (Serializable) Vio.instantiateAnyWay(clz);
+ g.objectWritten(object, offset);
+ }
+ catch (Exception e)
+ {
+ MARSHAL m = new MARSHAL("Unable to instantiate " + clz);
+ m.minor = Minor.Instantiation;
+ m.initCause(e);
+ throw m;
+ }
+ return object;
+ }
+
+ /**
+ * Read fields of the object.
+ */
+ void readFields(int offset, String repositoryID, Serializable object,
+ org.omg.CORBA_2_3.portable.InputStream input, gnuRuntime r)
+ throws MARSHAL
+ {
+ Field f = null;
+ Class o_class = object.getClass();
+
+ try
+ {
+ // The returned field array must already be in canonical order.
+ Field[] fields = getWritableFields(o_class);
+
+ Class fc;
+
+ for (int i = 0; i < fields.length; i++)
+ {
+ // Full value type header expected ahead.
+ if (input instanceof HeadlessInput)
+ ((HeadlessInput) input).subsequentCalls = true;
+
+ f = fields[i];
+ fc = f.getType();
+
+ Object v;
+
+ if (fc == String.class)
+ {
+ v = input.read_value(wStringValueHelper);
+ }
+ else if (fc == int.class)
+ v = new Integer(input.read_long());
+ else if (fc == long.class)
+ v = new Long(input.read_longlong());
+ else if (fc == double.class)
+ v = new Double(input.read_double());
+ else if (fc == float.class)
+ v = new Float(input.read_float());
+ else if (fc == boolean.class)
+ v = input.read_boolean() ? Boolean.TRUE : Boolean.FALSE;
+ else if (fc == short.class)
+ v = new Short(input.read_short());
+ else if (fc == byte.class)
+ v = new Byte(input.read_octet());
+ else if (fc == char.class)
+ v = new Character(input.read_char());
+ else if (org.omg.CORBA.Object.class.isAssignableFrom(fc)
+ || Remote.class.isAssignableFrom(fc))
+ {
+ v = readValue(input, offset, fc, null, r);
+ }
+ else
+ {
+ v = Vio.read(input, fc);
+ }
+
+ f.set(object, v);
+ }
+ }
+ catch (Exception ex)
+ {
+ MARSHAL m = new MARSHAL("Cannot read " + o_class.getName() + " field "
+ + f);
+ m.initCause(ex);
+ m.minor = Minor.ValueFields;
+ throw m;
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/StubDelegateImpl.java b/libjava/classpath/gnu/javax/rmi/CORBA/StubDelegateImpl.java
index 998d59e3379..afc254ddb49 100644
--- a/libjava/classpath/gnu/javax/rmi/CORBA/StubDelegateImpl.java
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/StubDelegateImpl.java
@@ -1,5 +1,5 @@
-/* StubDelegateImpl.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* StubDelegateImpl.java --
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,67 +38,273 @@ exception statement from your version. */
package gnu.javax.rmi.CORBA;
+import gnu.CORBA.ObjectCreator;
+import gnu.CORBA.Unexpected;
+import gnu.CORBA.CDR.BufferredCdrInput;
+import gnu.CORBA.CDR.BufferedCdrOutput;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.rmi.Remote;
import java.rmi.RemoteException;
+
+import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.StubDelegate;
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.portable.Delegate;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAHelper;
+import org.omg.PortableServer.Servant;
+import org.omg.PortableServer.POAManagerPackage.State;
+
+/**
+ * The default stub delegate.
+ *
+ * @author Wu Gansha (gansha.wu@intel.com) (stub)
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
+ */
public class StubDelegateImpl
implements StubDelegate
{
-
- private int hashCode;
-
- public StubDelegateImpl(){
- hashCode = 0;
+ /**
+ * <p>
+ * Finds the suitable {@link Tie} for this Stub and connects it to the given
+ * ORB. The tie is found by the name pattern. If the found tie is derived from
+ * {@link org.omg.CORBA.PortableServer.Servant}, it is connected to the root
+ * POA, also activating it (if not already active).
+ * </p>
+ * <p>
+ * This method does not allow to specify, to which POA the found Tie must be
+ * connected and requires to use the deprecated method {@link ORB#connect}.
+ * Many useful POA features remain unaccessible. A better alternative it might
+ * be to generate a {@link org.omg.CORBA.PortableServer.Servant} - derived Tie
+ * (-poa key in rmic) and connect it to POA in one of the many ways, listed in
+ * the description of the {@link orb.omg.PortableServer} package). The
+ * obtained CORBA object can be narrowed into stub using
+ * {@link PortableRemoteObject#narrow}.
+ * </p>
+ *
+ * @param orb the ORB where the Stub must be connected.
+ *
+ * @throws RemoteException if the stub is already connected to some other ORB.
+ * If the stub is already connected to the ORB that was passed as parameter,
+ * the method returns without action.
+ *
+ * @throws BAD_PARAM if the name of this stub does not match the stub name
+ * pattern, "_*_Stub" or if the Tie class, "_*Impl_Tie", does not exists or an
+ * instance of this class cannot be instantiated.
+ */
+ public void connect(Stub self, ORB orb)
+ throws RemoteException
+ {
+ connect(self, orb, null);
}
- // XXX javax.rmi.ORB -> org.omg.CORBA.ORB
- public void connect(Stub self, javax.rmi.ORB orb)
+
+ /**
+ * Connect when the POA is specified.
+ */
+ public static void connect(Stub self, ORB orb, POA poa)
throws RemoteException
{
- throw new Error("Not implemented for StubDelegate");
+ ORB oorb = null;
+ try
+ {
+ Delegate d = self._get_delegate();
+ if (d != null)
+ oorb = d.orb(self);
+ }
+ catch (Exception e)
+ {
+ // Failed to get Delegate or ORB.
+ // (possible ony for user-written Stubs).
+ }
+
+ if (oorb != null)
+ {
+ if (!oorb.equals(orb))
+ throw new RemoteException("Stub " + self
+ + " is connected to another ORB, " + orb);
+ else
+ return;
+ }
+
+ Tie t = null;
+ if (self instanceof Remote)
+ t = Util.getTie((Remote) self);
+
+ // Find by name pattern.
+ if (t == null)
+ t = getTieFromStub(self);
+
+ Delegate delegate;
+
+ if (t instanceof Servant)
+ {
+ try
+ {
+ if (poa == null)
+ {
+ poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
+ // Activate if not active.
+ if (poa.the_POAManager().get_state().value() == State._HOLDING)
+ poa.the_POAManager().activate();
+ }
+
+ ObjectImpl obj = (ObjectImpl) poa.servant_to_reference((Servant) t);
+ delegate = obj._get_delegate();
+ }
+ catch (Exception ex)
+ {
+ throw new Unexpected(ex);
+ }
+ }
+ else if (t instanceof ObjectImpl)
+ {
+ ObjectImpl o = (ObjectImpl) t;
+ orb.connect(o);
+ delegate = o._get_delegate();
+ }
+ else
+ throw new BAD_PARAM("The Tie must be either Servant or ObjectImpl");
+
+ self._set_delegate(delegate);
}
- public boolean equals(Stub self, Object obj)
+ /**
+ * Locate a tie class, appropriate to the given stub class, by the name
+ * pattern.
+ */
+ public static Tie getTieFromStub(java.lang.Object self)
{
- if(self == null || obj == null)
- return self == obj;
- if(!(obj instanceof Stub))
- return false;
- return self.hashCode() == ((Stub)obj).hashCode();
+ Tie t;
+ String sn = self.getClass().getName();
+ if (!sn.endsWith("_Stub"))
+ throw new BAD_PARAM("The stub name, " + sn
+ + ", does not match _*_Stub pattern");
+
+ String tn = sn.substring(0, sn.length() - "_Stub".length()) + "Impl_Tie";
+ Class tieClass = null;
+
+ try
+ {
+ tieClass = ObjectCreator.forName(tn);
+ t = (Tie) tieClass.newInstance();
+ if (self instanceof Remote)
+ Util.registerTarget(t, (Remote) self);
+ }
+ catch (Exception e)
+ {
+ BAD_PARAM bad = new BAD_PARAM("Unable to instantiate '" + tn + "'");
+ bad.initCause(e);
+ throw bad;
+ }
+ return t;
+ }
+
+ /**
+ * Compare two stubs for equality.
+ */
+ public boolean equals(Stub self, java.lang.Object obj)
+ {
+ if (obj instanceof ObjectImpl)
+ {
+ ObjectImpl other = (ObjectImpl) obj;
+ Delegate d1 = other._get_delegate();
+ Delegate d2 = self._get_delegate();
+ if (d1 == null || d2 == null)
+ return d1 == d2;
+ else
+ return d1.equals(d2);
+ }
+ else return false;
}
+ /**
+ * Get the hash code (from IOR reference).
+ */
public int hashCode(Stub self)
{
- //FIX ME
- return hashCode;
+ Delegate d = self._get_delegate();
+ return d==null?0:d.hashCode();
}
+ /**
+ * Returns the IOR reference of the connected ORB.
+ *
+ * @see ORB#object_to_string(org.omg.CORBA.Object);
+ */
public String toString(Stub self)
{
try
{
- return self._orb().object_to_string(self);
+ return self._orb().object_to_string(self);
}
- // XXX javax.rmi.BAD_OPERATION -> org.omg.CORBA.BAD_OPERATION
- catch(javax.rmi.BAD_OPERATION bad_operation)
+ catch (Exception ex)
{
- return null;
+ return null;
}
}
- public void readObject(Stub self, ObjectInputStream s)
+ /**
+ * This should never be called. The ORB must be supplied.
+ *
+ * @see #connect
+ */
+ public void readObject(Stub self, ObjectInputStream input)
throws IOException, ClassNotFoundException
{
- throw new Error("Not implemented for StubDelegate");
+ readObject(self, input, null);
}
- public void writeObject(Stub self, ObjectOutputStream s)
+ /**
+ * Read as CORBA object when the ORB is known. The ORB must be set under the
+ * previous call of Stub.connect. The Stub is automatically registered with
+ * this ORB.
+ */
+ public void readObject(Stub self, ObjectInputStream input, ORB orb)
+ throws IOException, ClassNotFoundException
+ {
+ byte[] b = (byte[]) input.readObject();
+ BufferredCdrInput in = new BufferredCdrInput(b);
+
+ if (orb != null)
+ in.setOrb(orb);
+
+ ObjectImpl r = (ObjectImpl) in.read_Object();
+
+ self._set_delegate(r._get_delegate());
+ }
+
+ /**
+ * Write as CORBA object. The ORB is taken from the
+ * org.omg.CORBA.portable.Delegate. The Stub is automatically registered with
+ * this ORB (if not already done).
+ */
+ public void writeObject(Stub self, ObjectOutputStream output)
+ throws IOException
+ {
+ writeObject(self, output, null);
+ }
+
+ /**
+ * Write as CORBA object. The ORB must be either set under the previous call
+ * of Stub.connect or it is taken from the org.omg.CORBA.portable.Delegate.
+ * The Stub is automatically registered with this ORB (if not already done).
+ */
+ public void writeObject(Stub self, ObjectOutputStream output, ORB orb)
throws IOException
{
- throw new Error("Not implemented for StubDelegate");
+ BufferedCdrOutput out = new BufferedCdrOutput();
+ out.setOrb(orb == null ? self._orb() : orb);
+ out.write_Object(self);
+
+ output.writeObject(out.buffer.toByteArray());
}
-
-}
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerImpl.java b/libjava/classpath/gnu/javax/rmi/CORBA/TieTargetRecord.java
index 906381fe478..70e751a6f2c 100644
--- a/libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerImpl.java
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/TieTargetRecord.java
@@ -1,5 +1,5 @@
-/* ValueHandlerImpl.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+/* TieTargetRecord.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,45 +38,56 @@ exception statement from your version. */
package gnu.javax.rmi.CORBA;
-import java.io.*;
-//import org.omg.CORBA.portable.InputStream;
-//import org.omg.CORBA.portable.OutputStream;
-//import org.omg.SendingContext.RunTime;
-import javax.rmi.CORBA.ValueHandler;
+import java.util.HashSet;
-public class ValueHandlerImpl
- implements ValueHandler
+import javax.rmi.CORBA.Tie;
+
+/**
+ * Represents a Tie, connected to possibly multiple invocation targets.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class TieTargetRecord
{
+ /**
+ * The associated Tie.
+ */
+ public final Tie tie;
- public String getRMIRepositoryID(Class clz)
- {
- throw new Error("Not implemented for ValueHandler");
- }
+ /**
+ * The objects, exposing the tie.
+ */
+ public HashSet targets = new HashSet();
- // XXX - Runtime -> RunTime
- public Runtime getRunTimeCodeBase()
+ /**
+ * Create a new record.
+ */
+ public TieTargetRecord(Tie a_tie)
{
- throw new Error("Not implemented for ValueHandler");
+ tie = a_tie;
}
-
- public boolean isCustomMarshaled(Class clz)
- {
- throw new Error("Not implemented for ValueHandler");
- }
-
- // XXX - Runtime -> RunTime
- public Serializable readValue(InputStream in, int offset, Class clz, String repositoryID, Runtime sender)
+
+ /**
+ * Add a target.
+ */
+ public void add(Object target)
{
- throw new Error("Not implemented for ValueHandler");
+ targets.add(target);
}
-
- public Serializable writeReplace(Serializable value)
+
+ /**
+ * Remove target.
+ */
+ public void remove(Object target)
{
- throw new Error("Not implemented for ValueHandler");
+ targets.remove(target);
}
-
- public void writeValue(OutputStream out, Serializable value)
+
+ /**
+ * Return true if the tie has no associated invocation targets.
+ */
+ public boolean unused()
{
- throw new Error("Not implemented for ValueHandler");
+ return targets.size() == 0;
}
}
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/UtilDelegateImpl.java b/libjava/classpath/gnu/javax/rmi/CORBA/UtilDelegateImpl.java
index 7bed2aa22dc..66a4e24ff18 100644
--- a/libjava/classpath/gnu/javax/rmi/CORBA/UtilDelegateImpl.java
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/UtilDelegateImpl.java
@@ -1,5 +1,5 @@
-/* UtilDelegateImpl.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+/* UtilDelegateImpl.java --
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,115 +38,717 @@ exception statement from your version. */
package gnu.javax.rmi.CORBA;
+import gnu.CORBA.Minor;
+import gnu.CORBA.ObjectCreator;
+import gnu.CORBA.Poa.ORB_1_4;
+import gnu.CORBA.Poa.AOM;
+import gnu.CORBA.Poa.gnuPOA;
+import gnu.CORBA.typecodes.GeneralTypeCode;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.COMM_FAILURE;
+import org.omg.CORBA.CompletionStatus;
+import org.omg.CORBA.INVALID_TRANSACTION;
+import org.omg.CORBA.INV_OBJREF;
+import org.omg.CORBA.MARSHAL;
+import org.omg.CORBA.NO_PERMISSION;
+import org.omg.CORBA.OBJECT_NOT_EXIST;
+import org.omg.CORBA.OMGVMCID;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TRANSACTION_REQUIRED;
+import org.omg.CORBA.TRANSACTION_ROLLEDBACK;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UNKNOWN;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.rmi.AccessException;
+import java.rmi.MarshalException;
+import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
+import java.rmi.ServerError;
+import java.rmi.ServerException;
+import java.rmi.UnexpectedException;
import java.rmi.server.RMIClassLoader;
-import java.net.MalformedURLException;
-import java.io.*;
-//import org.omg.CORBA.ORB;
-//import org.omg.CORBA.SystemException;
-//import org.omg.CORBA.portable.InputStream;
-//import org.omg.CORBA.portable.OutputStream;
-import javax.rmi.CORBA.*;
+import java.util.Hashtable;
+
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+import javax.rmi.CORBA.UtilDelegate;
+import javax.rmi.CORBA.ValueHandler;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.TransactionRequiredException;
+import javax.transaction.TransactionRolledbackException;
+/**
+ * The implementation of UtilDelegate.
+ *
+ * @author Wu Gansha (gansha.wu@intel.com) (stub)
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
+ */
public class UtilDelegateImpl
+ extends RmiUtilities
implements UtilDelegate
{
- // XXX javax.rmi.ORB -> org.omg.CORBA.ORB
- public Object copyObject(Object obj, javax.rmi.ORB orb)
+ /**
+ * The instance of the value handler, requested once.
+ */
+ static ValueHandler m_ValueHandler;
+
+ /**
+ * The global map of all ties to they records.
+ */
+ static Hashtable m_Ties = new Hashtable();
+
+ /**
+ * The global map of all targets to they records.
+ */
+ static Hashtable m_Targets = new Hashtable();
+
+ /**
+ * The standard package for that the exception names are omitted.
+ */
+ static final String m_StandardPackage = "org.omg.CORBA.";
+
+ /**
+ * Make a deep copy of the object.
+ */
+ public Object copyObject(Object obj, ORB orb)
throws RemoteException
{
- throw new Error("Not implemented for UtilDelegate");
+ // Strings are immutable, can be shared.
+ if (obj instanceof String)
+ return obj;
+ else if (obj == null)
+ return null;
+ else if (obj instanceof String[] || obj instanceof String[][]
+ || obj instanceof String[][][])
+ {
+ // String arrays can be just cloned.
+ return ((Object[]) obj).clone();
+ }
+ else if (obj instanceof Serializable)
+ {
+ try
+ {
+ ByteArrayOutputStream a = new ByteArrayOutputStream();
+ ObjectOutputStream ou = new ObjectOutputStream(a);
+ ou.writeObject(obj);
+ ou.close();
+ ObjectInputStream input = new ObjectInputStream(
+ new ByteArrayInputStream(a.toByteArray()));
+ return input.readObject();
+ }
+ catch (Exception ex)
+ {
+ RemoteException rex = new RemoteException("Cannot copy " + obj);
+ throw rex;
+ }
+ }
+ else
+ return obj;
}
- // XXX javax.rmi.ORB -> org.omg.CORBA.ORB
- public Object[] copyObjects(Object obj[], javax.rmi.ORB orb)
+ /**
+ * Make a deep copy of the object array.
+ */
+ public Object[] copyObjects(Object[] obj, ORB orb)
throws RemoteException
{
- throw new Error("Not implemented for UtilDelegate");
+ return (Object[]) copyObject(obj, orb);
}
public ValueHandler createValueHandler()
{
- throw new Error("Not implemented for UtilDelegate");
+ if (m_ValueHandler == null)
+ m_ValueHandler = (ValueHandler) DelegateFactory.getInstance(DelegateFactory.VALUEHANDLER);
+ return m_ValueHandler;
}
-
+
+ /**
+ * Returns the codebase of the given class.
+ */
public String getCodebase(Class clz)
{
- throw new Error("Not implemented for UtilDelegate");
+ return RMIClassLoader.getClassAnnotation(clz);
}
-
+
+ /**
+ * Get the Tie that handles invocations on the given target. If the target/Tie
+ * pair has not been previously registered using {@link #registerTarget},
+ * this method tries to locate a tie class by the name pattern. If this
+ * succeeds, the tie-target pair is also registered.
+ *
+ * @return the Tie.
+ */
public Tie getTie(Remote target)
{
- throw new Error("Not implemented for UtilDelegate");
+ synchronized (m_Targets)
+ {
+ Tie tie;
+ TieTargetRecord r = ((TieTargetRecord) m_Targets.get(target));
+ if (r == null)
+ {
+ if (target instanceof Stub)
+ {
+ tie = StubDelegateImpl.getTieFromStub(target);
+ registerTarget(tie, target);
+ }
+ else
+ {
+ // Treat this as implementation.
+ String tieClassName = getTieClassName(target.getClass().getName());
+ try
+ {
+ Class tieClass = Util.loadClass(tieClassName, null,
+ target.getClass().getClassLoader());
+ tie = (Tie) tieClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ MARSHAL m = new MARSHAL("Unable to instantiate "
+ + tieClassName);
+ m.minor = Minor.TargetConversion;
+ m.initCause(e);
+ throw m;
+ }
+ tie.setTarget(target);
+ registerTarget(tie, target);
+ }
+ }
+ else
+ tie = r.tie;
+ return tie;
+ }
+ }
+
+ /**
+ * Get the Stub class name for the name, representing the given interface.
+ */
+ private String getTieClassName(String interf)
+ {
+ String stubClassName;
+ int p = interf.lastIndexOf('.');
+
+ if (p < 0)
+ // The interface is defined in the default package.
+ stubClassName = "_" + interf + "_Tie";
+ else
+ stubClassName = interf.substring(0, p + 1) + "_"
+ + interf.substring(p + 1) + "_Tie";
+ return stubClassName;
}
-
+
+ /**
+ * Register the Tie-target pair. As the Tie is a Servant, it can potentially
+ * be connected to several objects and hence may be registered with several
+ * targets.
+ */
+ public void registerTarget(Tie tie, Remote target)
+ {
+ synchronized (m_Ties)
+ {
+ synchronized (m_Targets)
+ {
+ TieTargetRecord r = (TieTargetRecord) m_Ties.get(tie);
+ if (r == null)
+ {
+ // First registration for this Tie.
+ r = new TieTargetRecord(tie);
+ m_Ties.put(tie, r);
+ }
+ if (target != null)
+ {
+ r.add(target);
+ m_Targets.put(target, r);
+ }
+ }
+ }
+ }
+
+ /**
+ * Deactivate the associated Tie, if it is found and is not connected to other
+ * registered targets. Independing from the POA policies, the transparent
+ * reactivation will not be possible.
+ */
+ public void unexportObject(Remote target)
+ throws NoSuchObjectException
+ {
+ synchronized (m_Ties)
+ {
+ synchronized (m_Targets)
+ {
+ TieTargetRecord r = ((TieTargetRecord) m_Targets.get(target));
+ if (r != null)
+ {
+ if (target instanceof org.omg.CORBA.Object)
+ r.tie.orb().disconnect((org.omg.CORBA.Object) target);
+
+ if (r.unused())
+ {
+ m_Targets.remove(target);
+ m_Ties.remove(r.tie);
+ r.tie.deactivate();
+
+ if (r.tie.orb() instanceof ORB_1_4)
+ {
+ // Standard case, when more deep cleanup is possible.
+ // Independing from the POA policies, the object will
+ // not be activable transparently.
+ ORB_1_4 orb = (ORB_1_4) r.tie.orb();
+
+ if (target instanceof org.omg.CORBA.Object)
+ {
+ AOM.Obj record = orb.rootPOA.findObject((org.omg.CORBA.Object) target);
+
+ if (record != null && record.servant == r.tie
+ && record.poa instanceof gnuPOA)
+ {
+ ((gnuPOA) record.poa).aom.remove(record.key);
+ record.deactivated = true;
+ record.servant = null;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if the given stub is local.
+ *
+ * @param stub a stub to check.
+ * @return true if the stub is local, false otherwise.
+ */
public boolean isLocal(Stub stub)
throws RemoteException
{
- throw new Error("Not implemented for UtilDelegate");
+ try
+ {
+ return stub._is_local();
+ }
+ catch (SystemException e)
+ {
+ RemoteException rex = new RemoteException();
+ rex.initCause(e);
+ throw rex;
+ }
}
+ /**
+ * Load the class. The method uses class loaders from the call stact first. If
+ * this fails, the further behaviour depends on the System Property
+ * "java.rmi.server.useCodebaseOnly" with default value "false".
+ *
+ * <ul>
+ * <li>Try the current thread context class loader first.</li>
+ * <li>If remoteCodebase is non-null and useCodebaseOnly is "false" then call
+ * java.rmi.server.RMIClassLoader.loadClass (remoteCodebase, className)</li>
+ * <li> If remoteCodebase is null or useCodebaseOnly is true then call
+ * java.rmi.server.RMIClassLoader.loadClass(className)</li>
+ * <li>If a class is still not successfully loaded and the loader != null
+ * then try Class.forName(className, false, loader). </li>
+ * </ul>
+ *
+ * @param className the name of the class.
+ * @param remoteCodebase the codebase.
+ * @param loader the class loader.
+ * @return the loaded class.
+ *
+ * @throws ClassNotFoundException of the class cannot be loaded.
+ */
public Class loadClass(String className, String remoteCodebase,
- ClassLoader loader)
+ ClassLoader loader)
throws ClassNotFoundException
{
- try{
- if (remoteCodebase == null)
- return RMIClassLoader.loadClass(className);
- else
- return RMIClassLoader.loadClass(remoteCodebase, className);
- }
- catch (MalformedURLException e1)
+ if (loader == null)
+ loader = Thread.currentThread().getContextClassLoader();
+
+ String p_useCodebaseOnly = System.getProperty("java.rmi.server.useCodebaseOnly");
+
+ boolean useCodebaseOnly = p_useCodebaseOnly != null
+ && p_useCodebaseOnly.trim().equalsIgnoreCase("true");
+
+ try
{
- throw new ClassNotFoundException(className, e1);
+ if (remoteCodebase != null && !useCodebaseOnly)
+ return RMIClassLoader.loadClass(remoteCodebase, className);
}
- catch(ClassNotFoundException e2)
+ catch (Exception e)
{
- if(loader != null)
- return loader.loadClass(className);
- else
- return null;
+ // This failed but try others.
}
+
+ try
+ {
+ if (remoteCodebase == null || useCodebaseOnly)
+ return RMIClassLoader.loadClass(remoteCodebase, className);
+ }
+ catch (Exception e)
+ {
+ // This failed but try others.
+ }
+
+ if (loader != null)
+ return Class.forName(className, true, loader);
+
+ throw new ClassNotFoundException(className + " at " + remoteCodebase);
}
+ /**
+ * Converts CORBA {@link SystemException} into RMI {@link RemoteException}.
+ * The exception is converted as defined in the following table:
+ * <p>
+ * <table border = "1">
+ * <tr>
+ * <th>CORBA Exception</th>
+ * <th>RMI Exception</th>
+ * </tr>
+ * <tr>
+ * <td>{@link COMM_FAILURE}</td>
+ * <td>{@link MarshalException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link INV_OBJREF}</td>
+ * <td>{@link NoSuchObjectException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link NO_PERMISSION}</td>
+ * <td>{@link AccessException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link MARSHAL}</td>
+ * <td>{@link MarshalException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link BAD_PARAM} (all other cases)</td>
+ * <td>{@link MarshalException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link OBJECT_NOT_EXIST}</td>
+ * <td>{@link NoSuchObjectException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link TRANSACTION_REQUIRED}</td>
+ * <td>{@link TransactionRequiredException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link TRANSACTION_ROLLEDBACK}</td>
+ * <td>{@link TransactionRolledbackException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link INVALID_TRANSACTION}</td>
+ * <td>{@link InvalidTransactionException}</td>
+ * </tr>
+ * <tr>
+ * <td bgcolor="lightgray">Any other {@link SystemException}</td>
+ * <td bgcolor="lightgray">{@link RemoteException}</td>
+ * </tr>
+ * </table>
+ * </p>
+ * <p>
+ * The exception detailed message always consists of
+ * <ol>
+ * <li>the string "CORBA "</li>
+ * <li>the CORBA name of the system exception</li>
+ * <li>single space</li>
+ * <li>the hexadecimal value of the system exception's minor code, preceeded
+ * by 0x (higher bits contain {@link OMGVMCID}).</li>
+ * <li>single space</li>
+ * <li>the {@link CompletionStatus} of the exception: "Yes", "No" or "Maybe".</li>
+ * </ol>
+ * <p>
+ * For instance, if the Internet connection was refused:
+ * </p>
+ * <p>
+ * <pre>
+ * <code>CORBA COMM_FAILURE 0x535500C9 No</code>
+ * </p>
+ * <p>
+ * The original CORBA exception is set as the cause of the RemoteException
+ * being created.
+ * </p>
+ */
public RemoteException mapSystemException(SystemException ex)
{
- throw new Error("Not implemented for UtilDelegate");
+ RemoteException rex;
+
+ String status;
+
+ switch (ex.completed.value())
+ {
+ case CompletionStatus._COMPLETED_MAYBE:
+ status = "Maybe";
+ break;
+
+ case CompletionStatus._COMPLETED_NO:
+ status = "No";
+ break;
+
+ case CompletionStatus._COMPLETED_YES:
+ status = "Yes";
+ break;
+
+ default:
+ status = "Unexpected completion status " + ex.completed.value();
+ }
+
+ String name = ex.getClass().getName();
+
+ if (name.startsWith(m_StandardPackage))
+ name = name.substring(m_StandardPackage.length());
+
+ String message = "CORBA " + name + " 0x" + Integer.toHexString(ex.minor)
+ + " " + status;
+
+ if (ex instanceof COMM_FAILURE)
+ rex = new MarshalException(message, ex);
+ else if (ex instanceof INV_OBJREF)
+ {
+ rex = new NoSuchObjectException(message);
+ rex.detail = ex;
+ }
+ else if (ex instanceof NO_PERMISSION)
+ rex = new AccessException(message, ex);
+ else if (ex instanceof MARSHAL)
+ rex = new MarshalException(message, ex);
+ else if (ex instanceof BAD_PARAM)
+ rex = new MarshalException(message, ex);
+ else if (ex instanceof OBJECT_NOT_EXIST)
+ {
+ rex = new NoSuchObjectException(message);
+ rex.detail = ex;
+ }
+ else if (ex instanceof TRANSACTION_REQUIRED)
+ {
+ rex = new TransactionRequiredException(message);
+ rex.detail = ex;
+ }
+ else if (ex instanceof TRANSACTION_ROLLEDBACK)
+ {
+ rex = new TransactionRolledbackException(message);
+ rex.detail = ex;
+ }
+ else if (ex instanceof INVALID_TRANSACTION)
+ {
+ rex = new InvalidTransactionException(message);
+ rex.detail = ex;
+ }
+ else if (ex instanceof UNKNOWN)
+ rex = wrapException(ex.getCause());
+ else
+ rex = new RemoteException(message, ex);
+
+ return rex;
}
- public Object readAny(InputStream in)
+ /**
+ * Converts the exception that was thrown by the implementation method on a
+ * server side into RemoteException that can be transferred and re-thrown on a
+ * client side. The method converts exceptions as defined in the following
+ * table: <table border = "1">
+ * <tr>
+ * <th>Exception to map (or subclass)</th>
+ * <th>Maps into</th>
+ * </tr>
+ * <tr>
+ * <td>{@link Error}</td>
+ * <td>{@link ServerError}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link RemoteException}</td>
+ * <td>{@link ServerException}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link SystemException}</td>
+ * <td>wrapException({@link #mapSystemException})</td>
+ * </tr>
+ * <tr>
+ * <td>{@link RuntimeException}</td>
+ * <td><b>rethrows</b></td>
+ * </tr>
+ * <tr>
+ * <td>Any other exception</td>
+ * <td>{@link UnexpectedException}</td>
+ * </tr>
+ * </table>
+ *
+ * @param ex an exception that was thrown on a server side implementation.
+ *
+ * @return the corresponding RemoteException unless it is a RuntimeException.
+ *
+ * @throws RuntimeException the passed exception if it is an instance of
+ * RuntimeException.
+ *
+ * @specnote It is the same behavior, as in Suns implementations 1.4.0-1.5.0.
+ */
+ public RemoteException wrapException(Throwable ex)
+ throws RuntimeException
{
- throw new Error("Not implemented for UtilDelegate");
+ if (ex instanceof RuntimeException)
+ throw (RuntimeException) ex;
+ else if (ex instanceof Error)
+ return new ServerError(ex.getMessage(), (Error) ex);
+ else if (ex instanceof RemoteException)
+ return new ServerException(ex.getMessage(), (Exception) ex);
+ else if (ex instanceof SystemException)
+ return wrapException(mapSystemException((SystemException) ex));
+ else
+ return new UnexpectedException("Unexpected", (Exception) ex);
}
- public void registerTarget(Tie tie, Remote target)
+ /**
+ * Write abstract interface to the CORBA output stream. The write format is
+ * matching CORBA abstract interface. Remotes and CORBA objects are written as
+ * objects, other classes are supposed to be value types and are written as
+ * such. {@link Remote}s are processed as defined in
+ * {@link #writeRemoteObject}. The written data contains discriminator,
+ * defining, that was written. Another method that writes the same content is
+ * {@link org.omg.CORBA_2_3.portable.OutputStream#write_abstract_interface(java.lang.Object)}.
+ *
+ * @param output a stream to write to, must be
+ * {@link org.omg.CORBA_2_3.portable.OutputStream}.
+ *
+ * @param object an object to write, must be CORBA object, Remote
+ */
+ public void writeAbstractObject(OutputStream output, Object object)
{
- throw new Error("Not implemented for UtilDelegate");
+ ((org.omg.CORBA_2_3.portable.OutputStream) output).write_abstract_interface(object);
}
-
- public void unexportObject(Remote target)
+
+ /**
+ * Write the passed java object to the output stream in the form of the CORBA
+ * {@link Any}. This includes creating an writing the object {@link TypeCode}
+ * first. Such Any can be later read by a non-RMI-IIOP CORBA implementation
+ * and manipulated, for instance, by means, provided in
+ * {@link org.omg.DynamicAny.DynAny}. Depending from the passed value, this
+ * method writes CORBA object, value type or value box. For value types Null
+ * is written with the abstract interface, its typecode having repository id
+ * "IDL:omg.org/CORBA/AbstractBase:1.0" and the empty string name.
+ *
+ * @param output the object to write.
+ * @param object the java object that must be written in the form of the CORBA
+ * {@link Any}.
+ */
+ public void writeAny(OutputStream output, Object object)
{
- throw new Error("Not implemented for UtilDelegate");
+ Any any = output.orb().create_any();
+ if (object == null)
+ {
+ GeneralTypeCode t = new GeneralTypeCode(TCKind.tk_abstract_interface);
+ t.setId("IDL:omg.org/CORBA/AbstractBase:1.0");
+ t.setName("");
+ any.type(t);
+ output.write_any(any);
+ return;
+ }
+ else if (object instanceof org.omg.CORBA.Object
+ && !(object instanceof Remote))
+ {
+ // Write as value type.
+ boolean inserted = ObjectCreator.insertWithHelper(any, object);
+ if (inserted)
+ {
+ output.write_any(any);
+ return;
+ }
+ }
+
+ if (object instanceof org.omg.CORBA.Object)
+ writeAnyAsRemote(output, object);
+ else if (object instanceof Serializable)
+ {
+ any.insert_Value((Serializable) object);
+ output.write_any(any);
+ }
+ else
+ {
+ MARSHAL m = new MARSHAL(object.getClass().getName()
+ + " must be CORBA Object, Remote or Serializable");
+ m.minor = Minor.NonSerializable;
+ throw m;
+ }
}
-
- public RemoteException wrapException(Throwable orig)
+
+ /**
+ * Write Any as for remote object.
+ */
+ void writeAnyAsRemote(OutputStream output, Object object)
{
- throw new Error("Not implemented for UtilDelegate");
+ GeneralTypeCode t = new GeneralTypeCode(TCKind.tk_objref);
+ t.setId(m_ValueHandler.getRMIRepositoryID(object.getClass()));
+ t.setName(object.getClass().getName());
+
+ // Writing Any (typecode, followed by value).
+ output.write_TypeCode(t);
+ writeRemoteObject(output, object);
}
-
- public void writeAbstractObject(OutputStream out, Object obj)
+
+ /**
+ * Get the class name excluding the package name.
+ */
+ String getName(String n)
{
- throw new Error("Not implemented for UtilDelegate");
+ int p = n.lastIndexOf('.');
+ if (p < 0)
+ return n;
+ else
+ return n.substring(p + 1);
}
-
- public void writeAny(OutputStream out, Object obj)
+
+ /**
+ * Read Any from the input stream.
+ */
+ public Object readAny(InputStream input)
{
- throw new Error("Not implemented for UtilDelegate");
+ return input.read_any();
}
- public void writeRemoteObject(OutputStream out, Object obj)
+ /**
+ * Write the passed parameter to the output stream as CORBA object. If the
+ * parameter is an instance of Remote and not an instance of Stub, the method
+ * instantiates a suitable Tie, connects the parameter to this Tie and then
+ * connects that Tie to the ORB that is requested from the output stream. Then
+ * the object reference is written to the stream, making remote invocations
+ * possible. This method is used in write_value(..) method group in
+ * {@link org.omg.CORBA_2_3.portable.OutputStream} and also may be called
+ * directly from generated Stubs and Ties.
+ *
+ * @param output a stream to write to, must be
+ * org.omg.CORBA_2_3.portable.OutputStream
+ * @param object an object to write.
+ */
+ public void writeRemoteObject(OutputStream an_output, Object object)
{
- throw new Error("Not implemented for UtilDelegate");
+ org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
+ if (object == null)
+ an_output.write_Object(null);
+ else if (isTieRequired(object))
+ {
+ // Find the interface that is implemented by the object and extends
+ // Remote.
+ Class fc = getExportedInterface(object);
+ exportTie(output, object, fc);
+ }
+ else if (object instanceof org.omg.CORBA.Object)
+ {
+ ensureOrbRunning(output);
+ an_output.write_Object((org.omg.CORBA.Object) object);
+ }
+ else if (object != null && object instanceof Serializable)
+ writeFields(an_output, (Serializable) object);
}
-}
+
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java b/libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java
new file mode 100644
index 00000000000..dc3b3cd6ee8
--- /dev/null
+++ b/libjava/classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java
@@ -0,0 +1,163 @@
+/* ValueHandlerDelegateImpl.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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.rmi.CORBA;
+
+import gnu.CORBA.CDR.gnuRuntime;
+
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.CustomMarshal;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.Streamable;
+import org.omg.SendingContext.RunTime;
+
+import java.io.Externalizable;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.rmi.Remote;
+
+import javax.rmi.CORBA.ValueHandler;
+import javax.rmi.CORBA.ValueHandlerMultiFormat;
+
+/**
+ * Implementation of the ValueHandler.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
+ */
+public class ValueHandlerDelegateImpl
+ extends RmiUtilities
+ implements ValueHandler, ValueHandlerMultiFormat
+{
+ /**
+ * Return the maximal supported stream format version. We currently
+ * support the version 1.
+ *
+ * TODO Support the version 2.
+ */
+ public byte getMaximumStreamFormatVersion()
+ {
+ return 1;
+ }
+
+ /**
+ * Write value using the given stream format version.
+ */
+ public void writeValue(OutputStream output, Serializable value, byte version)
+ {
+ if (version!=1)
+ throw new BAD_PARAM("Unsupported stream format version "+version);
+ else
+ writeValue(output, value);
+ }
+
+ /**
+ * This implementation associates RunTime with stream rather than with the
+ * value handler and this method is not used in the implementation. It is
+ * implemented just for the sake of compatibility.
+ */
+ public RunTime getRunTimeCodeBase()
+ {
+ return new gnuRuntime(null, null);
+ }
+
+ /**
+ * Checks if an instance of this class can write its fields itself.
+ */
+ public boolean isCustomMarshaled(Class clz)
+ {
+ return CustomMarshal.class.isAssignableFrom(clz)
+ || Streamable.class.isAssignableFrom(clz);
+ }
+
+ /**
+ * No replacement, returns the passed parameter.
+ */
+ public Serializable writeReplace(Serializable value)
+ {
+ return value;
+ }
+
+ /**
+ * Compute the repository id in the RMI hashed format.
+ */
+ public String getRMIRepositoryID(final Class cx)
+ {
+ long hash = 0;
+ Class of = cx.isArray() ? cx.getComponentType() : null;
+
+ if (cx.equals(String[].class))
+ return RMI_STRING_ARRAY_ID;
+ else if (cx.equals(String.class))
+ return RMI_STRING_ID;
+ else if (cx.equals(Class.class))
+ return RMI_CLASS_ID;
+ else if (Remote.class.isAssignableFrom(cx)
+ || !Serializable.class.isAssignableFrom(cx)
+ || cx.isInterface()
+ || (cx.isArray() && (!Serializable.class.isAssignableFrom(of)
+ || of.isPrimitive() || Remote.class.isAssignableFrom(of)))
+
+ )
+ // Some classes that have zero hash code and serial no version id
+ // included.
+ return "RMI:" + cx.getName() + ":" + toHex(hash);
+ else if (cx.isArray())
+ // Arrays have the same hashcode and uid as they components.
+ return "RMI:" + cx.getName() + ":" + toHex(getHashCode(of)) + ":"
+ + toHex(getSid(of));
+ else
+ {
+ if (Externalizable.class.isAssignableFrom(cx))
+ hash = 1;
+ else
+ hash = getHashCode(cx);
+
+ return "RMI:" + cx.getName() + ":" + toHex(hash) + ":"
+ + toHex(getSid(cx));
+ }
+ }
+
+ /**
+ * Get the class serial version UID.
+ */
+ long getSid(Class cx)
+ {
+ ObjectStreamClass osc = ObjectStreamClass.lookup(cx);
+ return osc.getSerialVersionUID();
+ }
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/rmi/PortableServer.java b/libjava/classpath/gnu/javax/rmi/PortableServer.java
deleted file mode 100644
index 4a841387dd7..00000000000
--- a/libjava/classpath/gnu/javax/rmi/PortableServer.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/* PortableServer.java --
- Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 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.javax.rmi;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.server.RemoteStub;
-import java.util.Hashtable;
-
-import javax.rmi.CORBA.*;
-
-/**
- * The relationship of PortableRemoteObjectImpl with PortableServer
- * is like that of UnicastRemoteObject with UnicastServer
- */
-public class PortableServer
-{
- static private Hashtable tieCache = new Hashtable();
- static private Object NO_TIE = new Object();
-
- public static final synchronized void exportObject(Remote obj)
- throws RemoteException
- {
- if(Util.getTie(obj) != null)
- return;
-
- Tie tie = getTieFromRemote(obj);
- if (tie != null)
- Util.registerTarget(tie, obj);
- else
- UnicastRemoteObject.exportObject(obj);
- }
-
- public static final void unexportObject(Remote obj)
- {
- if (Util.getTie(obj) != null)
- Util.unexportObject(obj);
- if (tieCache.get(obj) != null) //??
- tieCache.remove(obj);
- }
-
- public static final Remote toStub(Remote obj)
- throws NoSuchObjectException
- {
- if (obj instanceof Stub || obj instanceof RemoteStub)
- return obj;
-
- Tie tie = Util.getTie(obj);
- Remote stub;
- if (tie != null)
- stub = getStubFromTie(tie);
- else
- throw new NoSuchObjectException("Can't toStub an unexported object");
- return stub;
- }
-
- static synchronized Tie getTieFromRemote(Remote obj)
- {
- Object tie = tieCache.get(obj);
- if (tie == null)
- {
- tie = getTieFromClass(obj.getClass());
- if(tie == null)
- tieCache.put(obj, NO_TIE);
- else
- tieCache.put(obj, tie);
- }
- else
- if(tie != NO_TIE)
- {
- try
- {
- tie = obj.getClass().newInstance();
- }
- catch(Exception _)
- {
- tie = null;
- }
- }
- else //NO_TIE
- tie = null;
-
- return (Tie)tie;
- }
-
- static synchronized Tie getTieFromClass(Class clz)
- {
- //FIX ME
- return null;
- }
-
- public static Remote getStubFromTie(Tie tie)
- {
- //FIX ME
- return null;
- }
-
- public static Remote getStubFromObjectImpl(ObjectImpl objimpl, Class toClass)
- {
- //FIX ME
- return null;
- }
-}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java
new file mode 100644
index 00000000000..fb9e684d096
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaInputPortDevice.java
@@ -0,0 +1,130 @@
+/* AlsaInputPortDevice.java -- ALSA MIDI In Port
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.alsa;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+/**
+ * ALSA MIDI In Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaInputPortDevice extends AlsaPortDevice
+{
+
+ AlsaInputPortDevice (AlsaPortInfo info)
+ {
+ super(info);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ return new AlsaTransmitter();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java
new file mode 100644
index 00000000000..4951be6059c
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiDeviceProvider.java
@@ -0,0 +1,216 @@
+/* AlsaMidiDeviceProvider.java -- The ALSA MIDI Device Provider
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.alsa;
+
+import gnu.classpath.Configuration;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * Provide ALSA MIDI devices.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaMidiDeviceProvider extends MidiDeviceProvider
+{
+ /**
+ * Abstract base for ALSA specific MIDI device info.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static abstract class AlsaInfo extends Info
+ {
+ /**
+ * Create an ALSA specific MIDI device info object.
+ *
+ * @param name the device name
+ * @param description the device description
+ */
+ public AlsaInfo(String name, String description)
+ {
+ super(name, "Alsa", description, "0.0");
+ }
+
+ abstract MidiDevice getDevice ();
+ }
+
+ /**
+ * ALSA MIDI Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public static abstract class AlsaPortInfo extends AlsaInfo
+ {
+ long client;
+ long port;
+
+ /**
+ * Create ALSA MIDI In Port.
+ *
+ * @param name the device name
+ * @param description the device description
+ * @param client the client ID
+ * @param port the port ID
+ */
+ public AlsaPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description);
+ this.client = client;
+ this.port = port;
+ }
+ }
+
+ /**
+ * ALSA Sequencer specific info.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaSequencerInfo extends AlsaInfo
+ {
+ public AlsaSequencerInfo(String name, String description)
+ {
+ super(name, description);
+ }
+
+ MidiDevice getDevice()
+ {
+ return AlsaMidiSequencerDevice.getInstance();
+ }
+ }
+
+ /**
+ * ALSA MIDI In Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaInputPortInfo extends AlsaPortInfo
+ {
+ public AlsaInputPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description, client, port);
+ }
+
+ MidiDevice getDevice()
+ {
+ return new AlsaInputPortDevice(this);
+ }
+ }
+
+ /**
+ * ALSA MIDI Out Port.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class AlsaOutputPortInfo extends AlsaPortInfo
+ {
+ public AlsaOutputPortInfo(String name, String description, long client, long port)
+ {
+ super(name, description, client, port);
+ }
+
+ MidiDevice getDevice()
+ {
+ return new AlsaOutputPortDevice(this);
+ }
+ }
+
+ private static AlsaInfo[] infos;
+
+ private static native AlsaInfo[] getInputDeviceInfo_();
+ private static native AlsaInfo[] getOutputDeviceInfo_();
+
+ /**
+ * Initialize the ALSA system
+ */
+ private static native void init_();
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gjsmalsa");
+ }
+
+ init_();
+
+ AlsaInfo inputs[] = getInputDeviceInfo_();
+ AlsaInfo outputs[] = getOutputDeviceInfo_();
+
+ infos = new AlsaInfo[inputs.length + outputs.length + 1];
+ infos[0] = new AlsaSequencerInfo ("/dev/snd/seq", "ALSA Sequencer");
+ System.arraycopy(inputs, 0, infos, 1, inputs.length);
+ System.arraycopy(outputs, 0, infos, 1 + inputs.length, outputs.length);
+ }
+
+ public AlsaMidiDeviceProvider()
+ {
+ // Nothing.
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDeviceInfo()
+ */
+ public Info[] getDeviceInfo()
+ {
+ return infos;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDevice(javax.sound.midi.MidiDevice.Info)
+ */
+ public MidiDevice getDevice(Info info)
+ {
+ for (int i = 0; i < infos.length; i++)
+ {
+ if (info.equals(infos[i]))
+ {
+ return infos[i].getDevice();
+ }
+ }
+ throw new IllegalArgumentException("Don't recognize MIDI device " + info);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
new file mode 100644
index 00000000000..c91f1e39851
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
@@ -0,0 +1,519 @@
+/* AlsaMidiSequencerDevice.java -- The ALSA MIDI sequencer device
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.alsa;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.midi.ControllerEventListener;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.MetaEventListener;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
+import javax.sound.midi.Track;
+import javax.sound.midi.Transmitter;
+
+// FIXME: These next two imports are only required by gcj it seems.
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.Sequencer.SyncMode;
+
+/**
+ * The ALSA MIDI sequencer device. This is a singleton device.
+ *
+ * @author green@redhat.com
+ *
+ */
+public class AlsaMidiSequencerDevice implements Sequencer
+{
+ // The singleton instance.
+ public final static AlsaMidiSequencerDevice instance = new AlsaMidiSequencerDevice();
+
+ // A pointer to a native chunk of memory
+ private long nativeState;
+
+ // The sequence to process
+ private Sequence sequence;
+
+ /**
+ * A private constructor. There should only be one instance of this
+ * device.
+ */
+ private AlsaMidiSequencerDevice()
+ {
+ super();
+ }
+
+ /**
+ * Return the sequencer singleton.
+ *
+ * @return the sequencer singleton
+ */
+ public static AlsaMidiSequencerDevice getInstance()
+ {
+ return instance;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSequence(javax.sound.midi.Sequence)
+ */
+ public void setSequence(Sequence seq) throws InvalidMidiDataException
+ {
+ sequence = seq;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSequence(java.io.InputStream)
+ */
+ public void setSequence(InputStream istream) throws IOException,
+ InvalidMidiDataException
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSequence()
+ */
+ public Sequence getSequence()
+ {
+ return sequence;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#start()
+ */
+ public void start()
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#stop()
+ */
+ public void stop()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#isRunning()
+ */
+ public boolean isRunning()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#startRecording()
+ */
+ public void startRecording()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#stopRecording()
+ */
+ public void stopRecording()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#isRecording()
+ */
+ public boolean isRecording()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#recordEnable(javax.sound.midi.Track, int)
+ */
+ public void recordEnable(Track track, int channel)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#recordDisable(javax.sound.midi.Track)
+ */
+ public void recordDisable(Track track)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoInBPM()
+ */
+ public float getTempoInBPM()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoInBPM(float)
+ */
+ public void setTempoInBPM(float bpm)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoInMPQ()
+ */
+ public float getTempoInMPQ()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoInMPQ(float)
+ */
+ public void setTempoInMPQ(float mpq)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTempoFactor(float)
+ */
+ public void setTempoFactor(float factor)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTempoFactor()
+ */
+ public float getTempoFactor()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTickLength()
+ */
+ public long getTickLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTickPosition()
+ */
+ public long getTickPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTickPosition(long)
+ */
+ public void setTickPosition(long tick)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMicrosecondLength()
+ */
+ public long getMicrosecondLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setMicrosecondPosition(long)
+ */
+ public void setMicrosecondPosition(long microsecond)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setMasterSyncMode(javax.sound.midi.Sequencer.SyncMode)
+ */
+ public void setMasterSyncMode(SyncMode sync)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMasterSyncMode()
+ */
+ public SyncMode getMasterSyncMode()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getMasterSyncModes()
+ */
+ public SyncMode[] getMasterSyncModes()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setSlaveSyncMode(javax.sound.midi.Sequencer.SyncMode)
+ */
+ public void setSlaveSyncMode(SyncMode sync)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSlaveSyncMode()
+ */
+ public SyncMode getSlaveSyncMode()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getSlaveSyncModes()
+ */
+ public SyncMode[] getSlaveSyncModes()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTrackMute(int, boolean)
+ */
+ public void setTrackMute(int track, boolean mute)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTrackMute(int)
+ */
+ public boolean getTrackMute(int track)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#setTrackSolo(int, boolean)
+ */
+ public void setTrackSolo(int track, boolean solo)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#getTrackSolo(int)
+ */
+ public boolean getTrackSolo(int track)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#addMetaEventListener(javax.sound.midi.MetaEventListener)
+ */
+ public boolean addMetaEventListener(MetaEventListener listener)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#removeMetaEventListener(javax.sound.midi.MetaEventListener)
+ */
+ public void removeMetaEventListener(MetaEventListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#addControllerEventListener(javax.sound.midi.ControllerEventListener, int[])
+ */
+ public int[] addControllerEventListener(ControllerEventListener listener,
+ int[] controllers)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Sequencer#removeControllerEventListener(javax.sound.midi.ControllerEventListener, int[])
+ */
+ public int[] removeControllerEventListener(ControllerEventListener listener,
+ int[] controllers)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getDeviceInfo()
+ */
+ public Info getDeviceInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ synchronized(this)
+ {
+ // Check to see if we're open already.
+ if (nativeState != 0)
+ return;
+
+ nativeState = open_();
+ }
+ }
+
+ /**
+ * Allocate the native state object, and open the sequencer.
+ *
+ * @return a long representation of a pointer to the nativeState.
+ */
+ private native long open_();
+
+ /**
+ * Close the sequencer and free the native state object.
+ */
+ private native void close_(long nativeState);
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ synchronized(this)
+ {
+ close_(nativeState);
+ nativeState = 0;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ synchronized(this)
+ {
+ return (nativeState != 0);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java
new file mode 100644
index 00000000000..bc5a5593967
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaOutputPortDevice.java
@@ -0,0 +1,131 @@
+/* AlsaOutputPortDevice.java -- ALSA MIDI Output Port Device
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.alsa;
+
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+/**
+ * ALSA MIDI Out Device
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class AlsaOutputPortDevice extends AlsaPortDevice
+{
+ AlsaOutputPortDevice (AlsaPortInfo info)
+ {
+ super(info);
+ }
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
new file mode 100644
index 00000000000..d666be1f1ba
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
@@ -0,0 +1,153 @@
+/* AlsaPortDevice.java -- ALSA MIDI Port Devices
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.alsa;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+// FIXME: This next import is only rquired for gcj it seems.
+import javax.sound.midi.MidiDevice.Info;
+
+import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
+
+/**
+ * ALSA Port Device
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public abstract class AlsaPortDevice implements MidiDevice
+{
+ /**
+ * The ALSA Receiver class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public class AlsaReceiver implements Receiver
+ {
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
+ */
+ public void send(MidiMessage message, long timeStamp)
+ throws IllegalStateException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ AlsaMidiDeviceProvider.AlsaPortInfo info;
+
+ public AlsaPortDevice (AlsaPortInfo info)
+ {
+ this.info = info;
+ }
+
+ public Info getDeviceInfo()
+ {
+ return info;
+ }
+
+ native void run_receiver_thread_ (long client, long port, Receiver receiver);
+
+ /**
+ * The ALSA Transmitter class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ protected class AlsaTransmitter implements Transmitter, Runnable
+ {
+ private Receiver receiver;
+
+ public void run()
+ {
+ run_receiver_thread_ (info.client, info.port, receiver);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#setReceiver(javax.sound.midi.Receiver)
+ */
+ public void setReceiver(Receiver receiver)
+ {
+ synchronized (this)
+ {
+ this.receiver = receiver;
+ }
+
+ // Create the processing thread
+ new Thread(this).start();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#getReceiver()
+ */
+ public Receiver getReceiver()
+ {
+ synchronized (this)
+ {
+ return receiver;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Transmitter#close()
+ */
+ public void close()
+ {
+ synchronized (this)
+ {
+ receiver.close();
+ receiver = null;
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java
new file mode 100644
index 00000000000..baf61732d18
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSIMidiDeviceProvider.java
@@ -0,0 +1,173 @@
+/* DSSIMidiDeviceProvider.java -- DSSI Device Provider
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.dssi;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.FilenameFilter;
+
+import gnu.classpath.Configuration;
+import gnu.javax.sound.midi.alsa.AlsaMidiSequencerDevice;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * A DSSI MIDI device provider.
+ *
+ * DSSI (pronounced "dizzy") is an API for audio plugins, with particular
+ * application for software synthesis plugins with native user interfaces.
+ *
+ * Read about DSSI at http://dssi.sourceforge.net
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class DSSIMidiDeviceProvider extends MidiDeviceProvider
+{
+ /**
+ * The MidiDevice.Info specialized for DSSI synthesizers.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ private static class DSSIInfo extends Info
+ {
+ String soname;
+ long index;
+
+ public DSSIInfo(String name, String vendor, String description,
+ String version, String soname, long index)
+ {
+ super(name, vendor, description, version);
+ this.soname = soname;
+ this.index = index;
+ }
+ }
+
+ static native long dlopen_(String soname);
+ static native void dlclose_(long sohandle);
+ static native long getDSSIHandle_(long sohandle, long index);
+ static native String getDSSIName_(long handle);
+ static native String getDSSICopyright_(long handle);
+ static native String getDSSIVendor_(long handle);
+ static native String getDSSILabel_(long handle);
+
+ private static List examineLibrary(String soname)
+ {
+ List list = new ArrayList();
+ long index = 0;
+ long handle;
+
+ long sohandle = dlopen_(soname);
+ if (sohandle == 0)
+ return list;
+ do
+ {
+ handle = getDSSIHandle_(sohandle, index);
+ if (handle == 0)
+ break;
+ String name = getDSSILabel_(handle);
+ String copyright = getDSSICopyright_(handle);
+ String label = getDSSIName_(handle);
+ String vendor = getDSSIVendor_(handle);
+ list.add(new DSSIInfo(name, vendor, label,
+ "DSSI-1", soname, index));
+ index++;
+ } while (true);
+
+ // Close the library and free memory
+ dlclose_(sohandle);
+
+ return list;
+ }
+
+ private static DSSIInfo[] infos;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("gjsmdssi");
+
+ File dssidir = new File("/usr/lib/dssi/");
+ String sofiles[] = dssidir.list(new FilenameFilter()
+ {
+ public boolean accept(File dir, String n)
+ {
+ return n.endsWith(".so");
+ }
+ });
+ List ilist = new ArrayList();
+ for (int i = 0; i < sofiles.length; i++)
+ ilist.addAll(examineLibrary(new File(dssidir, sofiles[i]).getAbsolutePath()));
+ infos = (DSSIInfo[]) ilist.toArray(new DSSIInfo[ilist.size()]);
+ }
+
+ public DSSIMidiDeviceProvider()
+ {
+ // Empty.
+ }
+
+ /* Return the Info array.
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDeviceInfo()
+ */
+ public Info[] getDeviceInfo()
+ {
+ return infos;
+ }
+
+ /* Get a MIDI Device for info.
+ * @see javax.sound.midi.spi.MidiDeviceProvider#getDevice(javax.sound.midi.MidiDevice.Info)
+ */
+ public MidiDevice getDevice(Info info)
+ {
+ for (int i = 0; i < infos.length; i++)
+ {
+ if (info.equals(infos[i]))
+ {
+ return new DSSISynthesizer(infos[i],
+ infos[i].soname,
+ infos[i].index);
+ }
+ }
+ throw new IllegalArgumentException("Don't recognize MIDI device " + info);
+ }
+}
diff --git a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
new file mode 100644
index 00000000000..ca09b305078
--- /dev/null
+++ b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
@@ -0,0 +1,745 @@
+/* DSSISynthesizer.java -- DSSI Synthesizer Provider
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.javax.sound.midi.dssi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.midi.Synthesizer;
+import javax.sound.midi.Transmitter;
+import javax.sound.midi.VoiceStatus;
+
+// FIXME: This import in only required for gcj it seems.
+import javax.sound.midi.MidiDevice.Info;
+
+/**
+ * DSSI soft-synth support.
+ *
+ * All DSSI soft-synths are expected to be installed in /usr/lib/dssi.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+public class DSSISynthesizer implements Synthesizer
+{
+ /**
+ * The DSSI Instrument class.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSIInstrument extends Instrument
+ {
+ DSSIInstrument (Soundbank soundbank, Patch patch, String name)
+ {
+ super (soundbank, patch, name, null);
+ }
+
+ /* @see javax.sound.midi.SoundbankResource#getData()
+ */
+ public Object getData()
+ {
+ return null;
+ }
+
+ }
+
+/**
+ * DSSISoundbank holds all instruments.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSISoundbank implements Soundbank
+ {
+ private String name;
+ private String description;
+ private List instruments = new ArrayList();
+ private List resources = new ArrayList();
+ private String vendor;
+ private String version;
+
+ public DSSISoundbank(String name, String description, String vendor, String version)
+ {
+ this.name = name;
+ this.description = description;
+ this.vendor = vendor;
+ this.version = version;
+ }
+
+ void add(Instrument instrument)
+ {
+ instruments.add(instrument);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getName()
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getVersion()
+ */
+ public String getVersion()
+ {
+ return version;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getVendor()
+ */
+ public String getVendor()
+ {
+ return vendor;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getDescription()
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+
+ /* @see javax.sound.midi.Soundbank#getResources()
+ */
+ public SoundbankResource[] getResources()
+ {
+ return (SoundbankResource[])
+ resources.toArray(new SoundbankResource[resources.size()]);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getInstruments()
+ */
+ public Instrument[] getInstruments()
+ {
+ return (Instrument[])
+ instruments.toArray(new Instrument[instruments.size()]);
+ }
+
+ /* @see javax.sound.midi.Soundbank#getInstrument(javax.sound.midi.Patch)
+ */
+ public Instrument getInstrument(Patch patch)
+ {
+ Iterator itr = instruments.iterator();
+
+ while (itr.hasNext())
+ {
+ Instrument i = (Instrument) itr.next();
+ if (i.getPatch().equals(patch))
+ return i;
+ }
+
+ return null;
+ }
+ }
+
+/**
+ * The Receiver class receives all MIDI messages from a connected
+ * Transmitter.
+ *
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ class DSSIReceiver implements Receiver
+ {
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
+ */
+ public void send(MidiMessage message, long timeStamp)
+ throws IllegalStateException
+ {
+ if (message instanceof ShortMessage)
+ {
+ ShortMessage smessage = (ShortMessage) message;
+
+ switch (message.getStatus())
+ {
+ case ShortMessage.NOTE_ON:
+ int velocity = smessage.getData2();
+ if (velocity > 0)
+ channels[smessage.getChannel()].noteOn(smessage.getData1(),
+ smessage.getData2());
+ else
+ channels[smessage.getChannel()].noteOff(smessage.getData1());
+ break;
+ case ShortMessage.CONTROL_CHANGE:
+ channels[smessage.getChannel()].controlChange(smessage.getData1(),
+ smessage.getData2());
+ break;
+ default:
+ System.out.println ("Unhandled message: " + message.getStatus());
+ break;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Receiver#close()
+ */
+ public void close()
+ {
+ // TODO Auto-generated method stub
+ }
+
+ }
+
+ static native void noteOn_(long handle, int channel, int noteNumber, int velocity);
+ static native void noteOff_(long handle, int channel, int noteNumber, int velocity);
+ static native void setPolyPressure_(long handle, int channel, int noteNumber, int pressure);
+ static native int getPolyPressure_(long handle, int channel, int noteNumber);
+ static native void controlChange_(long handle, int channel, int control, int value);
+ static native void open_(long handle);
+ static native void close_(long handle);
+ static native String getProgramName_(long handle, int index);
+ static native int getProgramBank_(long handle, int index);
+ static native int getProgramProgram_(long handle, int index);
+ static native void selectProgram_(long handle, int bank, int program);
+
+ /**
+ * @author Anthony Green (green@redhat.com)
+ *
+ */
+ public class DSSIMidiChannel implements MidiChannel
+ {
+ int channel = 0;
+
+ /**
+ * Default contructor.
+ */
+ public DSSIMidiChannel(int channel)
+ {
+ super();
+ this.channel = channel;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOn(int, int)
+ */
+ public void noteOn(int noteNumber, int velocity)
+ {
+ noteOn_(sohandle, channel, noteNumber, velocity);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOff(int, int)
+ */
+ public void noteOff(int noteNumber, int velocity)
+ {
+ noteOff_(sohandle, channel, noteNumber, velocity);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#noteOff(int)
+ */
+ public void noteOff(int noteNumber)
+ {
+ noteOff_(sohandle, channel, noteNumber, -1);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setPolyPressure(int, int)
+ */
+ public void setPolyPressure(int noteNumber, int pressure)
+ {
+ setPolyPressure_(sohandle, channel, noteNumber, pressure);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getPolyPressure(int)
+ */
+ public int getPolyPressure(int noteNumber)
+ {
+ return getPolyPressure_(sohandle, channel, noteNumber);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setChannelPressure(int)
+ */
+ public void setChannelPressure(int pressure)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getChannelPressure()
+ */
+ public int getChannelPressure()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiChannel#controlChange(int, int) */
+ public void controlChange(int controller, int value)
+ {
+ controlChange_(sohandle, channel, controller, value);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getController(int)
+ */
+ public int getController(int controller)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#programChange(int)
+ */
+ public void programChange(int program)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#programChange(int, int)
+ */
+ public void programChange(int bank, int program)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getProgram()
+ */
+ public int getProgram()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setPitchBend(int)
+ */
+ public void setPitchBend(int bend)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getPitchBend()
+ */
+ public int getPitchBend()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#resetAllControllers()
+ */
+ public void resetAllControllers()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#allNotesOff()
+ */
+ public void allNotesOff()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#allSoundOff()
+ */
+ public void allSoundOff()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#localControl(boolean)
+ */
+ public boolean localControl(boolean on)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setMono(boolean)
+ */
+ public void setMono(boolean on)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getMono()
+ */
+ public boolean getMono()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setOmni(boolean)
+ */
+ public void setOmni(boolean on)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getOmni()
+ */
+ public boolean getOmni()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setMute(boolean)
+ */
+ public void setMute(boolean mute)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getMute()
+ */
+ public boolean getMute()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#setSolo(boolean)
+ */
+ public void setSolo(boolean solo)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiChannel#getSolo()
+ */
+ public boolean getSolo()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+ long sohandle;
+ long handle;
+ private Info info;
+
+ MidiChannel channels[] = new MidiChannel[16];
+
+ // The list of known soundbanks, and the default one.
+ List soundbanks = new ArrayList();
+ DSSISoundbank defaultSoundbank;
+
+ /**
+ * Create a DSSI Synthesizer.
+ *
+ * @param info the DSSIInfo for this soft-synth
+ * @param soname the name of the .so file for this DSSI synth
+ * @param index the DSSI index for this soft-synth
+ */
+ public DSSISynthesizer(Info info, String soname, long index)
+ {
+ super();
+ this.info = info;
+ sohandle = DSSIMidiDeviceProvider.dlopen_(soname);
+ handle = DSSIMidiDeviceProvider.getDSSIHandle_(sohandle, index);
+ channels[0] = new DSSIMidiChannel(0);
+ defaultSoundbank = new DSSISoundbank("name", "description",
+ "vendor", "version");
+ soundbanks.add(defaultSoundbank);
+
+ int i = 0;
+ String name;
+ do
+ {
+ name = getProgramName_(sohandle, i);
+ if (name != null)
+ {
+ defaultSoundbank.
+ add(new DSSIInstrument(defaultSoundbank,
+ new Patch(getProgramBank_(sohandle, i),
+ getProgramProgram_(sohandle, i)),
+ name));
+ i++;
+ }
+ } while (name != null);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getMaxPolyphony()
+ */
+ public int getMaxPolyphony()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getLatency()
+ */
+ public long getLatency()
+ {
+ // DSSI and LADSPA provide no way to determine the latency.
+ // Let's just return 0 for now.
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getChannels()
+ */
+ public MidiChannel[] getChannels()
+ {
+ return channels;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getVoiceStatus()
+ */
+ public VoiceStatus[] getVoiceStatus()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#isSoundbankSupported(javax.sound.midi.Soundbank)
+ */
+ public boolean isSoundbankSupported(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#loadInstrument(javax.sound.midi.Instrument)
+ */
+ public boolean loadInstrument(Instrument instrument)
+ {
+ // FIXME: perhaps this isn't quite right. It can probably
+ // be in any soundbank.
+ if (instrument.getSoundbank() != defaultSoundbank)
+ throw new IllegalArgumentException ("Synthesizer doesn't support this instrument's soundbank");
+
+ Patch patch = instrument.getPatch();
+ selectProgram_(sohandle, patch.getBank(), patch.getProgram());
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadInstrument(javax.sound.midi.Instrument)
+ */
+ public void unloadInstrument(Instrument instrument)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#remapInstrument(javax.sound.midi.Instrument, javax.sound.midi.Instrument)
+ */
+ public boolean remapInstrument(Instrument from, Instrument to)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#getDefaultSoundbank()
+ */
+ public Soundbank getDefaultSoundbank()
+ {
+ return defaultSoundbank;
+ }
+
+ /* @see javax.sound.midi.Synthesizer#getAvailableInstruments()
+ */
+ public Instrument[] getAvailableInstruments()
+ {
+ List instruments = new ArrayList();
+ Iterator itr = soundbanks.iterator();
+ while (itr.hasNext())
+ {
+ Soundbank sb = (Soundbank) itr.next();
+ Instrument ins[] = sb.getInstruments();
+ for (int i = 0; i < ins.length; i++)
+ instruments.add(ins[i]);
+ }
+ return (Instrument[])
+ instruments.toArray(new Instrument[instruments.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#getLoadedInstruments()
+ */
+ public Instrument[] getLoadedInstruments()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#loadAllInstruments(javax.sound.midi.Soundbank)
+ */
+ public boolean loadAllInstruments(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadAllInstruments(javax.sound.midi.Soundbank)
+ */
+ public void unloadAllInstruments(Soundbank soundbank)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#loadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
+ */
+ public boolean loadInstruments(Soundbank soundbank, Patch[] patchList)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.Synthesizer#unloadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
+ */
+ public void unloadInstruments(Soundbank soundbank, Patch[] patchList)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getDeviceInfo()
+ */
+ public Info getDeviceInfo()
+ {
+ return info;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#open()
+ */
+ public void open() throws MidiUnavailableException
+ {
+ open_(sohandle);
+ }
+
+ /* @see javax.sound.midi.MidiDevice#close()
+ */
+ public void close()
+ {
+ close_(sohandle);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#isOpen()
+ */
+ public boolean isOpen()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
+ */
+ public long getMicrosecondPosition()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getMaxReceivers()
+ */
+ public int getMaxReceivers()
+ {
+ return 1;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getMaxTransmitters()
+ */
+ public int getMaxTransmitters()
+ {
+ return 0;
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getReceiver()
+ */
+ public Receiver getReceiver() throws MidiUnavailableException
+ {
+ return new DSSIReceiver();
+ }
+
+ /* @see javax.sound.midi.MidiDevice#getTransmitter()
+ */
+ public Transmitter getTransmitter() throws MidiUnavailableException
+ {
+ return null;
+ }
+}
OpenPOWER on IntegriCloud