diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
commit | f911ba985aa7fe0096c386c5be385ac5825ea527 (patch) | |
tree | a0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/gnu/java | |
parent | 6f4434b39b261de5317dc81ddfdd94d2e1d62b11 (diff) | |
download | gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.zip gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.gz gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.bz2 |
Initial revision
From-SVN: r102074
Diffstat (limited to 'libjava/classpath/gnu/java')
429 files changed, 69704 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java new file mode 100644 index 0000000..a02d1c4 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java @@ -0,0 +1,321 @@ +/* AWTUtilities.java -- Common utility methods for AWT and Swing. + 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.java.awt; + +import java.awt.Component; +import java.awt.Container; +import java.util.AbstractSequentialList; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.WeakHashMap; + +/** + * This class provides utility methods that are commonly used in AWT + * (and Swing). + */ +public class AWTUtilities +{ + + /** + * This List implementation wraps the Component[] returned by + * {@link Container#getComponents()} and iterates over the visible Components + * in that array. This class is used in {@link #getVisibleChildren}. + */ + static class VisibleComponentList extends AbstractSequentialList + { + /** + * The ListIterator for this List. + */ + class VisibleComponentIterator implements ListIterator + { + /** The current index in the Component[]. */ + int index; + + /** The index in the List of visible Components. */ + int listIndex; + + /** + * Creates a new VisibleComponentIterator that starts at the specified + * <code>listIndex</code>. The array of Components is searched from + * the beginning to find the matching array index. + * + * @param listIndex the index from where to begin iterating + */ + VisibleComponentIterator(int listIndex) + { + this.listIndex = listIndex; + int visibleComponentsFound = 0; + for (index = 0; visibleComponentsFound != listIndex; index++) + { + if (components[index].isVisible()) + visibleComponentsFound++; + } + } + + /** + * Returns <code>true</code> if there are more visible components in the + * array, <code>false</code> otherwise. + * + * @return <code>true</code> if there are more visible components in the + * array, <code>false</code> otherwise + */ + public boolean hasNext() + { + boolean hasNext = false; + for (int i = index; i < components.length; i++) + { + if (components[i].isVisible()) + { + hasNext = true; + break; + } + } + return hasNext; + } + + /** + * Returns the next visible <code>Component</code> in the List. + * + * @return the next visible <code>Component</code> in the List + * + * @throws if there is no next element + */ + public Object next() + { + Object o = null; + for (; index < components.length; index++) + { + if (components[index].isVisible()) + { + o = components[index]; + break; + } + } + if (o != null) + { + index++; + listIndex++; + return o; + } + else + throw new NoSuchElementException(); + } + + /** + * Returns <code>true</code> if there are more visible components in the + * array in the reverse direction, <code>false</code> otherwise. + * + * @return <code>true</code> if there are more visible components in the + * array in the reverse direction, <code>false</code> otherwise + */ + public boolean hasPrevious() + { + boolean hasPrevious = false; + for (int i = index - 1; i >= 0; i--) + { + if (components[i].isVisible()) + { + hasPrevious = true; + break; + } + } + return hasPrevious; + } + + /** + * Returns the previous visible <code>Component</code> in the List. + * + * @return the previous visible <code>Component</code> in the List + * + * @throws NoSuchElementException if there is no previous element + */ + public Object previous() + { + Object o = null; + for (index--; index >= 0; index--) + { + if (components[index].isVisible()) + { + o = components[index]; + break; + } + } + if (o != null) + { + listIndex--; + return o; + } + else + throw new NoSuchElementException(); + } + + /** + * Returns the index of the next element in the List. + * + * @return the index of the next element in the List + */ + public int nextIndex() + { + return listIndex + 1; + } + + /** + * Returns the index of the previous element in the List. + * + * @return the index of the previous element in the List + */ + public int previousIndex() + { + return listIndex - 1; + } + + /** + * This operation is not supported because the List is immutable. + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void remove() + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + + /** + * This operation is not supported because the List is immutable. + * + * @param o not used here + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void set(Object o) + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + + /** + * This operation is not supported because the List is immutable. + * + * @param o not used here + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void add(Object o) + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + } + + /** + * The components over which we iterate. Only the visible components + * are returned by this List. + */ + Component[] components; + + /** + * Creates a new instance of VisibleComponentList that wraps the specified + * <code>Component[]</code>. + * + * @param c the <code>Component[]</code> to be wrapped. + */ + VisibleComponentList(Component[] c) + { + components = c; + } + + /** + * Returns a {@link ListIterator} for iterating over this List. + * + * @return a {@link ListIterator} for iterating over this List + */ + public ListIterator listIterator(int index) + { + return new VisibleComponentIterator(index); + } + + /** + * Returns the number of visible components in the wrapped Component[]. + * + * @return the number of visible components + */ + public int size() + { + int visibleComponents = 0; + for (int i = 0; i < components.length; i++) + if (components[i].isVisible()) + visibleComponents++; + return visibleComponents; + } + } + + /** + * The cache for our List instances. We try to hold one instance of + * VisibleComponentList for each Component[] that is requested. Note + * that we use a WeakHashMap for caching, so that the cache itself + * does not keep the array or the List from beeing garbage collected + * if no other objects hold references to it. + */ + static WeakHashMap visibleChildrenCache = new WeakHashMap(); + + /** + * Returns the visible children of a {@link Container}. This method is + * commonly needed in LayoutManagers, because they only have to layout + * the visible children of a Container. + * + * @param c the Container from which to extract the visible children + * + * @return the visible children of <code>c</code> + */ + public static List getVisibleChildren(Container c) + { + Component[] children = c.getComponents(); + Object o = visibleChildrenCache.get(children); + VisibleComponentList visibleChildren = null; + if (o == null) + { + visibleChildren = new VisibleComponentList(children); + visibleChildrenCache.put(children, visibleChildren); + } + else + visibleChildren = (VisibleComponentList) o; + + return visibleChildren; + } +} diff --git a/libjava/classpath/gnu/java/awt/BitMaskExtent.java b/libjava/classpath/gnu/java/awt/BitMaskExtent.java new file mode 100644 index 0000000..2813499 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/BitMaskExtent.java @@ -0,0 +1,79 @@ +/* Copyright (C) 2000, 2002 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt; + +/** + * Simple transparent utility class that can be used to perform bit + * mask extent calculations. + */ +public final class BitMaskExtent +{ + /** The number of the least significant bit of the bit mask extent. */ + public byte leastSignificantBit; + + /** The number of bits in the bit mask extent. */ + public byte bitWidth; + + /** + * Set the bit mask. This will calculate and set the leastSignificantBit + * and bitWidth fields. + * + * @see #leastSignificantBit + * @see #bitWidth + */ + public void setMask(long mask) + { + leastSignificantBit = 0; + bitWidth = 0; + if (mask == 0) return; + long shiftMask = mask; + for (; (shiftMask&1) == 0; shiftMask >>>=1) leastSignificantBit++; + for (; (shiftMask&1) != 0; shiftMask >>>=1) bitWidth++; + + if (shiftMask != 0) + throw new IllegalArgumentException("mask must be continuous"); + } + + /** + * Calculate the bit mask based on the values of the + * leastSignificantBit and bitWidth fields. + */ + public long toMask() + { + return ((1<<bitWidth)-1) << leastSignificantBit; + } +} diff --git a/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java b/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java new file mode 100644 index 0000000..b568e11 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java @@ -0,0 +1,295 @@ +/* BitwiseXORComposite.java -- Composite for emulating old-style XOR. + Copyright (C) 2003, 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.java.awt; + +import java.awt.Color; +import java.awt.Composite; +import java.awt.CompositeContext; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + + +/** + * A composite for emulating traditional bitwise XOR of pixel values. + * Please note that this composite does <i>not</i> implement the Porter-Duff + * XOR operator, but an exclusive or of overlapping subpixel regions. + * + * <p><img src="doc-files/BitwiseXORComposite-1.png" width="545" + * height="138" alt="A screen shot of BitwiseXORComposite in action" + * /> + * + * <p>The above screen shot shows the result of applying six different + * BitwiseXORComposites. They were constructed with the colors colors + * white, blue, black, orange, green, and brown, respectively. Each + * composite was used to paint a fully white rectangle on top of the + * blue bar in the background. + * + * <p>The purpose of this composite is to support the {@link + * Graphics#setXORMode(Color)} method in composite-aware graphics + * implementations. Applications typically would use + * <code>setXORMode</code> for drawing “highlights” such + * as text selections or cursors by inverting colors temporarily and + * then inverting them back. + * + * <p>A concrete <code>Graphics</code> implementation may contain + * the following code: + * + * <p><pre> public void setXORMode(Color xorColor) + * { + * setComposite(new gnu.java.awt.BitwiseXORComposite(xorColor)); + * } + * + * public void setPaintMode() + * { + * setComposite(java.awt.AlphaComposite.SrcOver); + * }</pre> + * + * @author Graydon Hoare (graydon@redhat.com) + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class BitwiseXORComposite + implements Composite +{ + /** + * The color whose RGB value is xor-ed with the values of each + * pixel. + */ + protected Color xorColor; + + + /** + * Constructs a new composite for xor-ing the pixel value. + * + * @param xorColor the color whose pixel value will be bitwise + * xor-ed with the source and destination pixels. + */ + public BitwiseXORComposite(Color xorColor) + { + this.xorColor = xorColor; + } + + + /** + * Creates a context object for performing the compositing + * operation. Several contexts may co-exist for one composite; each + * context may simultaneously be called from concurrent threads. + * + * @param srcColorModel the color model of the source. + * @param dstColorModel the color model of the destination. + * @param hints hints for choosing between rendering alternatives. + */ + public CompositeContext createContext(ColorModel srcColorModel, + ColorModel dstColorModel, + RenderingHints hints) + { + if (IntContext.isSupported(srcColorModel, dstColorModel, hints)) + return new IntContext(srcColorModel, xorColor); + + return new GeneralContext(srcColorModel, dstColorModel, xorColor); + } + + + /** + * A fallback CompositeContext that performs bitwise XOR of pixel + * values with the pixel value of the specified <code>xorColor</code>. + * + * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of + * <code>TYPE_INT_RGB</code> took 611 ms on a lightly loaded 2.4 GHz + * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux + * 2.4.20. The timing is the average of ten runs on the same + * BufferedImage. Since the measurements were taken with {@link + * System#currentTimeMillis()}, they are rather inaccurate. + * + * @author Graydon Hoare (graydon@redhat.com) + */ + private static class GeneralContext + implements CompositeContext + { + ColorModel srcColorModel; + ColorModel dstColorModel; + Color xorColor; + + public GeneralContext(ColorModel srcColorModel, + ColorModel dstColorModel, + Color xorColor) + { + this.srcColorModel = srcColorModel; + this.dstColorModel = dstColorModel; + this.xorColor = xorColor; + } + + + public void compose(Raster src, Raster dstIn, WritableRaster dstOut) + { + Rectangle srcRect = src.getBounds(); + Rectangle dstInRect = dstIn.getBounds(); + Rectangle dstOutRect = dstOut.getBounds(); + + int xp = xorColor.getRGB(); + int w = Math.min(Math.min(srcRect.width, dstOutRect.width), + dstInRect.width); + int h = Math.min(Math.min(srcRect.height, dstOutRect.height), + dstInRect.height); + + Object srcPix = null, dstPix = null, rpPix = null; + + // Re-using the rpPix object saved 1-2% of execution time in + // the 1024x1024 pixel benchmark. + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + srcPix = src.getDataElements(x + srcRect.x, y + srcRect.y, srcPix); + dstPix = dstIn.getDataElements(x + dstInRect.x, y + dstInRect.y, + dstPix); + int sp = srcColorModel.getRGB(srcPix); + int dp = dstColorModel.getRGB(dstPix); + int rp = sp ^ xp ^ dp; + dstOut.setDataElements(x + dstOutRect.x, y + dstOutRect.y, + dstColorModel.getDataElements(rp, rpPix)); + } + } + } + + + /** + * Disposes any cached resources. The default implementation does + * nothing because no resources are cached. + */ + public void dispose() + { + } + } + + + /** + * An optimized CompositeContext that performs bitwise XOR of + * <code>int</code> pixel values with the pixel value of a specified + * <code>xorColor</code>. This CompositeContext working only for + * rasters whose transfer format is {@link DataBuffer#TYPE_INT}. + * + * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of + * <code>TYPE_INT_RGB</code> took 69 ms on a lightly loaded 2.4 GHz + * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux + * 2.4.20. The timing is the average of ten runs on the same + * BufferedImage. Since the measurements were taken with {@link + * System#currentTimeMillis()}, they are rather inaccurate. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ + private static class IntContext + extends GeneralContext + { + public IntContext(ColorModel colorModel, Color xorColor) + { + super(colorModel, colorModel, xorColor); + } + + + public void compose(Raster src, Raster dstIn, + WritableRaster dstOut) + { + int aX, bX, dstX, aY, bY, dstY, width, height; + int xorPixel; + int[] srcLine, dstLine; + + aX = src.getMinX(); + aY = src.getMinY(); + bX = dstIn.getMinX(); + bY = dstIn.getMinY(); + dstX = dstOut.getMinX(); + dstY = dstOut.getMinY(); + width = Math.min(Math.min(src.getWidth(), dstIn.getWidth()), + dstOut.getWidth()); + height = Math.min(Math.min(src.getHeight(), dstIn.getHeight()), + dstOut.getHeight()); + if ((width < 1) || (height < 1)) + return; + + srcLine = new int[width]; + dstLine = new int[width]; + + /* We need an int[] array with at least one element here; + * srcLine is as good as any other. + */ + srcColorModel.getDataElements(this.xorColor.getRGB(), srcLine); + xorPixel = srcLine[0]; + + for (int y = 0; y < height; y++) + { + src.getDataElements(aX, y + aY, width, 1, srcLine); + dstIn.getDataElements(bX, y + bY, width, 1, dstLine); + + for (int x = 0; x < width; x++) + dstLine[x] ^= srcLine[x] ^ xorPixel; + + dstOut.setDataElements(dstX, y + dstY, width, 1, dstLine); + } + } + + + /** + * Determines whether an instance of this CompositeContext would + * be able to process the specified color models. + */ + public static boolean isSupported(ColorModel srcColorModel, + ColorModel dstColorModel, + RenderingHints hints) + { + // FIXME: It would be good if someone could review these checks. + // They probably need to be more restrictive. + + int transferType; + + transferType = srcColorModel.getTransferType(); + if (transferType != dstColorModel.getTransferType()) + return false; + + if (transferType != DataBuffer.TYPE_INT) + return false; + + return true; + } + } +} diff --git a/libjava/classpath/gnu/java/awt/Buffers.java b/libjava/classpath/gnu/java/awt/Buffers.java new file mode 100644 index 0000000..c6ccf91 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/Buffers.java @@ -0,0 +1,243 @@ +/* Buffers.java -- + Copyright (C) 2000, 2002, 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt; + +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferDouble; +import java.awt.image.DataBufferFloat; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.DataBufferUShort; + +/** + * Utility class for creating and accessing data buffers of arbitrary + * data types. + */ +public final class Buffers +{ + /** + * Create a data buffer of a particular type. + * + * @param dataType the desired data type of the buffer. + * @param data an array containing data, or null + * @param size the size of the data buffer bank + */ + public static DataBuffer createBuffer(int dataType, Object data, + int size) + { + if (data == null) return createBuffer(dataType, size, 1); + + return createBufferFromData(dataType, data, size); + } + + + /** + * Create a data buffer of a particular type. + * + * @param dataType the desired data type of the buffer. + * @param size the size of the data buffer bank + */ + public static DataBuffer createBuffer(int dataType, int size) { + return createBuffer(dataType, size, 1); + } + + /** + * Create a data buffer of a particular type. + * + * @param dataType the desired data type of the buffer. + * @param size the size of the data buffer bank + * @param numBanks the number of banks the buffer should have + */ + public static DataBuffer createBuffer(int dataType, int size, int numBanks) + { + switch (dataType) + { + case DataBuffer.TYPE_BYTE: + return new DataBufferByte(size, numBanks); + case DataBuffer.TYPE_SHORT: + return new DataBufferShort(size, numBanks); + case DataBuffer.TYPE_USHORT: + return new DataBufferUShort(size, numBanks); + case DataBuffer.TYPE_INT: + return new DataBufferInt(size, numBanks); + case DataBuffer.TYPE_FLOAT: + return new DataBufferFloat(size, numBanks); + case DataBuffer.TYPE_DOUBLE: + return new DataBufferDouble(size, numBanks); + default: + throw new UnsupportedOperationException(); + } + } + + /** + * Create a data buffer of a particular type. + * + * @param dataType the desired data type of the buffer + * @param data an array containing the data + * @param size the size of the data buffer bank + */ + public static DataBuffer createBufferFromData(int dataType, Object data, + int size) + { + switch (dataType) + { + case DataBuffer.TYPE_BYTE: + return new DataBufferByte((byte[]) data, size); + case DataBuffer.TYPE_SHORT: + return new DataBufferShort((short[]) data, size); + case DataBuffer.TYPE_USHORT: + return new DataBufferUShort((short[]) data, size); + case DataBuffer.TYPE_INT: + return new DataBufferInt((int[]) data, size); + case DataBuffer.TYPE_FLOAT: + return new DataBufferFloat((float[]) data, size); + case DataBuffer.TYPE_DOUBLE: + return new DataBufferDouble((double[]) data, size); + default: + throw new UnsupportedOperationException(); + } + } + + /** + * Return the data array of a data buffer, regardless of the data + * type. + * + * @return an array of primitive values. The actual array type + * depends on the data type of the buffer. + */ + public static Object getData(DataBuffer buffer) + { + if (buffer instanceof DataBufferByte) + return ((DataBufferByte) buffer).getData(); + + if (buffer instanceof DataBufferShort) + return ((DataBufferShort) buffer).getData(); + + if (buffer instanceof DataBufferUShort) + return ((DataBufferUShort) buffer).getData(); + + if (buffer instanceof DataBufferInt) + return ((DataBufferInt) buffer).getData(); + + if (buffer instanceof DataBufferFloat) + return ((DataBufferFloat) buffer).getData(); + + if (buffer instanceof DataBufferDouble) + return ((DataBufferDouble) buffer).getData(); + + throw new ClassCastException("Unknown data buffer type"); + } + + + /** + * Copy data from array contained in data buffer, much like + * System.arraycopy. Create a suitable destination array if the + * given destination array is null. + */ + public static Object getData(DataBuffer src, int srcOffset, + Object dest, int destOffset, + int length) + { + Object from; + if (src instanceof DataBufferByte) + { + from = ((DataBufferByte) src).getData(); + if (dest == null) dest = new byte[length+destOffset]; + } + else if (src instanceof DataBufferShort) + { + from = ((DataBufferShort) src).getData(); + if (dest == null) dest = new short[length+destOffset]; + } + else if (src instanceof DataBufferUShort) + { + from = ((DataBufferUShort) src).getData(); + if (dest == null) dest = new short[length+destOffset]; + } + else if (src instanceof DataBufferInt) + { + from = ((DataBufferInt) src).getData(); + if (dest == null) dest = new int[length+destOffset]; + } + else if (src instanceof DataBufferFloat) + { + from = ((DataBufferFloat) src).getData(); + if (dest == null) dest = new float[length+destOffset]; + } + else if (src instanceof DataBufferDouble) + { + from = ((DataBufferDouble) src).getData(); + if (dest == null) dest = new double[length+destOffset]; + } + else + { + throw new ClassCastException("Unknown data buffer type"); + } + + System.arraycopy(from, srcOffset, dest, destOffset, length); + return dest; + } + + /** + * @param bits the width of a data element measured in bits + * + * @return the smallest data type that can store data elements of + * the given number of bits, without any truncation. + */ + public static int smallestAppropriateTransferType(int bits) + { + if (bits <= 8) + { + return DataBuffer.TYPE_BYTE; + } + else if (bits <= 16) + { + return DataBuffer.TYPE_USHORT; + } + else if (bits <= 32) + { + return DataBuffer.TYPE_INT; + } + else + { + return DataBuffer.TYPE_UNDEFINED; + } + } +} diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java new file mode 100644 index 0000000..5fb444f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java @@ -0,0 +1,379 @@ +/* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits. + Copyright (C) 2003, 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.java.awt; + +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.EmbeddedWindowPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; + +import java.awt.AWTException; +import java.awt.Dimension; +import java.awt.DisplayMode; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.image.ColorModel; +import java.awt.image.ImageProducer; +import java.awt.peer.RobotPeer; +import java.io.File; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.AttributedString; +import java.util.HashMap; +import java.util.Map; + +import javax.imageio.spi.IIORegistry; + +/** + * An abstract superclass for Classpath toolkits. + * + * <p>There exist some parts of AWT and Java2D that are specific to + * the underlying platform, but for which the {@link Toolkit} class + * does not provide suitable abstractions. Examples include some + * methods of {@link Font} or {@link GraphicsEnvironment}. Those + * methods use ClasspathToolkit as a central place for obtaining + * platform-specific functionality. + * + * <p>In addition, ClasspathToolkit implements some abstract methods + * of {@link java.awt.Toolkit} that are not really platform-specific, + * such as the maintenance of a cache of loaded images. + * + * <p><b>Thread Safety:</b> The methods of this class may safely be + * called without external synchronization. This also hold for any + * inherited {@link Toolkit} methods. Subclasses are responsible for + * the necessary synchronization. + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class ClasspathToolkit + extends Toolkit +{ + /** + * A map from URLs to previously loaded images, used by {@link + * #getImage(java.net.URL)}. For images that were loaded via a path + * to an image file, the map contains a key with a file URL. + */ + private HashMap imageCache; + + + /** + * Returns a shared instance of the local, platform-specific + * graphics environment. + * + * <p>This method is specific to GNU Classpath. It gets called by + * the Classpath implementation of {@link + * GraphicsEnvironment.getLocalGraphcisEnvironment()}. + */ + public abstract GraphicsEnvironment getLocalGraphicsEnvironment(); + + + /** + * Determines the current size of the default, primary screen. + * + * @throws HeadlessException if the local graphics environment is + * headless, which means that no screen is attached and no user + * interaction is allowed. + */ + public Dimension getScreenSize() + { + DisplayMode mode; + + // getDefaultScreenDevice throws HeadlessException if the + // local graphics environment is headless. + mode = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDisplayMode(); + + return new Dimension(mode.getWidth(), mode.getHeight()); + } + + + /** + * Determines the current color model of the default, primary + * screen. + * + * @see GraphicsEnvironment#getDefaultScreenDevice() + * @see java.awt.GraphicsDevice#getDefaultConfiguration() + * @see java.awt.GraphicsConfiguration#getColorModel() + * + * @throws HeadlessException if the local graphics environment is + * headless, which means that no screen is attached and no user + * interaction is allowed. + */ + public ColorModel getColorModel() + { + // getDefaultScreenDevice throws HeadlessException if the + // local graphics environment is headless. + return GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration() + .getColorModel(); + } + + /** + * Retrieves the metrics for rendering a font on the screen. + * + * @param font the font whose metrics are requested. + */ + public FontMetrics getFontMetrics(Font font) + { + return ((ClasspathFontPeer) font.getPeer ()).getFontMetrics (font); + } + + + /** + * Acquires an appropriate {@link ClasspathFontPeer}, for use in + * classpath's implementation of {@link java.awt.Font}. + * + * @param name The logical name of the font. This may be either a face + * name or a logical font name, or may even be null. A default + * implementation of name decoding is provided in + * {@link ClasspathFontPeer}, but may be overridden in other toolkits. + * + * @param attrs Any extra {@link java.awt.font.TextAttribute} attributes + * this font peer should have, such as size, weight, family name, or + * transformation. + */ + public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs); + + public abstract ClasspathTextLayoutPeer + getClasspathTextLayoutPeer (AttributedString str, FontRenderContext frc); + + + /** + * Creates a {@link Font}, in a platform-specific manner. + * + * The default implementation simply constructs a {@link Font}, but some + * toolkits may wish to override this, to return {@link Font} subclasses which + * implement {@link java.awt.font.OpenType} or + * {@link java.awt.font.MultipleMaster}. + */ + public Font getFont (String name, Map attrs) + { + return new Font (name, attrs); + } + + + /** + * Creates a font, reading the glyph definitions from a stream. + * + * <p>This method provides the platform-specific implementation for + * the static factory method {@link Font#createFont(int, + * java.io.InputStream)}. + * + * @param format the format of the font data, such as {@link + * Font#TRUETYPE_FONT}. An implementation may ignore this argument + * if it is able to automatically recognize the font format from the + * provided data. + * + * @param stream an input stream from where the font data is read + * in. The stream will be advanced to the position after the font + * data, but not closed. + * + * @throws IllegalArgumentException if <code>format</code> is + * not supported. + * + * @throws FontFormatException if <code>stream</code> does not + * contain data in the expected format, or if required tables are + * missing from a font. + * + * @throws IOException if a problem occurs while reading in the + * contents of <code>stream</code>. + */ + public abstract Font createFont(int format, InputStream stream); + + + /** + * Returns an image from the specified file, which must be in a + * recognized format. The set of recognized image formats may vary + * from toolkit to toolkit. + * + * <p>This method maintains a cache for images. If an image has been + * loaded from the same path before, the cached copy will be + * returned. The implementation may hold cached copies for an + * indefinite time, which can consume substantial resources with + * large images. Users are therefore advised to use {@link + * #createImage(java.lang.String)} instead. + * + * <p>The default implementation creates a file URL for the + * specified path and invokes {@link #getImage(URL)}. + * + * @param path A path to the image file. + * + * @return IllegalArgumentException if <code>path</code> does not + * designate a valid path. + */ + public Image getImage(String path) + { + try + { + return getImage(new File(path).toURL()); + } + catch (MalformedURLException muex) + { + throw (IllegalArgumentException) new IllegalArgumentException(path) + .initCause(muex); + } + } + + + /** + * Loads an image from the specified URL. The image data must be in + * a recognized format. The set of recognized image formats may vary + * from toolkit to toolkit. + * + * <p>This method maintains a cache for images. If an image has been + * loaded from the same URL before, the cached copy will be + * returned. The implementation may hold cached copies for an + * indefinite time, which can consume substantial resources with + * large images. Users are therefore advised to use {@link + * #createImage(java.net.URL)} instead. + * + * @param url the URL from where the image is read. + */ + public Image getImage(URL url) + { + Image result; + + synchronized (this) + { + // Many applications never call getImage. Therefore, we lazily + // create the image cache when it is actually needed. + if (imageCache == null) + imageCache = new HashMap(); + else + { + result = (Image) imageCache.get(url); + if (result != null) + return result; + } + + // The createImage(URL) method, which is specified by + // java.awt.Toolkit, is not implemented by this abstract class + // because it is platform-dependent. Once Classpath has support + // for the javax.imageio package, it might be worth considering + // that toolkits provide native stream readers. Then, the class + // ClasspathToolkit could provide a general implementation that + // delegates the image format parsing to javax.imageio. + result = createImage(url); + + // It is not clear whether it would be a good idea to use weak + // references here. The advantage would be reduced memory + // consumption, since loaded images would not be kept + // forever. But on VMs that frequently perform garbage + // collection (which includes VMs with a parallel or incremental + // collector), the image might frequently need to be re-loaded, + // possibly over a slow network connection. + imageCache.put(url, result); + + return result; + } + } + + + /** + * Returns an image from the specified file, which must be in a + * recognized format. The set of recognized image formats may vary + * from toolkit to toolkit. + * + * <p>A new image is created every time this method gets called, + * even if the same path has been passed before. + * + * <p>The default implementation creates a file URL for the + * specified path and invokes {@link #createImage(URL)}. + * + * @param path A path to the file to be read in. + */ + public Image createImage(String path) + { + try + { + // The abstract method createImage(URL) is defined by + // java.awt.Toolkit, but intentionally not implemented by + // ClasspathToolkit because it is platform specific. + return createImage(new File(path).toURL()); + } + catch (MalformedURLException muex) + { + throw (IllegalArgumentException) new IllegalArgumentException(path) + .initCause(muex); + } + } + + /** + * Creates an ImageProducer from the specified URL. The image is assumed + * to be in a recognised format. If the toolkit does not implement the + * image format or the image format is not recognised, null is returned. + * This default implementation is overriden by the Toolkit implementations. + * + * @param url URL to read image data from. + */ + public ImageProducer createImageProducer(URL url) + { + return null; + } + + public abstract RobotPeer createRobot (GraphicsDevice screen) + throws AWTException; + + /** + * Creates an embedded window peer, and associates it with an + * EmbeddedWindow object. + * + * @param w The embedded window with which to associate a peer. + */ + public abstract EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w); + + /** + * Used to register ImageIO SPIs provided by the toolkit. + */ + + public void registerImageIOSpis(IIORegistry reg) + { + } + + public abstract boolean nativeQueueEmpty(); + public abstract void wakeNativeQueue(); + public abstract void iterateNativeQueue(EventQueue locked, boolean block); +} diff --git a/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java b/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java new file mode 100644 index 0000000..545427e --- /dev/null +++ b/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java @@ -0,0 +1,156 @@ +/* Copyright (C) 2000, 2002, 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt; + +import java.awt.RenderingHints; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.Raster; +import java.awt.image.RasterOp; +import java.awt.image.WritableRaster; + +/** + * This raster copy operation assumes that both source and destination + * sample models are tightly pixel packed and contain the same number + * of bands. + * + * @throws java.lang.ClassCastException if the sample models of the + * rasters are not of type ComponentSampleModel. + * + * @author Rolf W. Rasmussen (rolfwr@ii.uib.no) + */ +public class ComponentDataBlitOp implements RasterOp +{ + public static final ComponentDataBlitOp INSTANCE = new ComponentDataBlitOp(); + + public WritableRaster filter(Raster src, WritableRaster dest) + { + if (dest == null) + dest = createCompatibleDestRaster(src); + + DataBuffer srcDB = src.getDataBuffer(); + DataBuffer destDB = dest.getDataBuffer(); + + ComponentSampleModel srcSM = (ComponentSampleModel) src.getSampleModel(); + ComponentSampleModel destSM = (ComponentSampleModel) dest.getSampleModel(); + + + // Calculate offset to data in the underlying arrays: + + int srcScanlineStride = srcSM.getScanlineStride(); + int destScanlineStride = destSM.getScanlineStride(); + int srcX = src.getMinX() - src.getSampleModelTranslateX(); + int srcY = src.getMinY() - src.getSampleModelTranslateY(); + int destX = dest.getMinX() - dest.getSampleModelTranslateX(); + int destY = dest.getMinY() - dest.getSampleModelTranslateY(); + + int numBands = srcSM.getNumBands(); + + /* We can't use getOffset(x, y) from the sample model since we + don't want the band offset added in. */ + + int srcOffset = + numBands*srcX + srcScanlineStride*srcY + // from sample model + srcDB.getOffset(); // from data buffer + + int destOffset = + numBands*destX + destScanlineStride*destY + // from sample model + destDB.getOffset(); // from data buffer + + // Determine how much, and how many times to blit. + + int rowSize = src.getWidth()*numBands; + int h = src.getHeight(); + + if ((rowSize == srcScanlineStride) && + (rowSize == destScanlineStride)) + { + // collapse scan line blits to one large blit. + rowSize *= h; + h = 1; + } + + + // Do blitting + + Object srcArray = Buffers.getData(srcDB); + Object destArray = Buffers.getData(destDB); + + for (int yd = 0; yd<h; yd++) + { + System.arraycopy(srcArray, srcOffset, + destArray, destOffset, + rowSize); + srcOffset += srcScanlineStride; + destOffset += destScanlineStride; + } + + + return dest; + } + + public Rectangle2D getBounds2D(Raster src) + { + return src.getBounds(); + } + + public WritableRaster createCompatibleDestRaster(Raster src) { + + /* FIXME: Maybe we should explicitly create a raster with a + tightly pixel packed sample model, rather than assuming + that the createCompatibleWritableRaster() method in Raster + will create one. */ + + return src.createCompatibleWritableRaster(); + } + + public Point2D getPoint2D(Point2D srcPoint, Point2D destPoint) + { + if (destPoint == null) + return (Point2D) srcPoint.clone(); + + destPoint.setLocation(srcPoint); + return destPoint; + } + + public RenderingHints getRenderingHints() + { + throw new UnsupportedOperationException("not implemented"); + } +} diff --git a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java new file mode 100644 index 0000000..a85ce74 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java @@ -0,0 +1,139 @@ +/* EmbeddedWindow.java -- + Copyright (C) 2003, 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.java.awt; + +import gnu.java.awt.peer.EmbeddedWindowPeer; +import gnu.java.security.action.SetAccessibleAction; + +import java.awt.Component; +import java.awt.Frame; +import java.awt.Toolkit; +import java.lang.reflect.Field; +import java.security.AccessController; + +/** + * Represents an AWT window that can be embedded into another + * application. + * + * @author Michael Koch (konqueror@gmx.de) + */ +public class EmbeddedWindow extends Frame +{ + private long handle; + + /** + * Creates a window to be embedded into another application. The + * window will only be embedded after its setHandle method has been + * called. + */ + public EmbeddedWindow () + { + super(); + this.handle = 0; + } + + /** + * Creates a window to be embedded into another application. + * + * @param handle the native handle to the screen area where the AWT + * window should be embedded + */ + public EmbeddedWindow (long handle) + { + super(); + this.handle = handle; + } + + /** + * Creates the native peer for this embedded window. + */ + public void addNotify() + { + // Assume we're using ClasspathToolkit + ClasspathToolkit tk = (ClasspathToolkit) getToolkit(); + + // Circumvent the package-privateness of the AWT internal + // java.awt.Component.peer member variable. + try + { + Field peerField = Component.class.getDeclaredField("peer"); + AccessController.doPrivileged(new SetAccessibleAction(peerField)); + peerField.set(this, tk.createEmbeddedWindow (this)); + } + catch (IllegalAccessException e) + { + // This should never happen. + } + catch (NoSuchFieldException e) + { + // This should never happen. + } + + super.addNotify(); + } + + /** + * If the native peer for this embedded window has been created, + * then setHandle will embed the window. If not, setHandle tells + * us where to embed ourselves when our peer is created. + * + * @param handle the native handle to the screen area where the AWT + * window should be embedded + */ + public void setHandle(long handle) + { + if (this.handle != 0) + throw new RuntimeException ("EmbeddedWindow is already embedded"); + + this.handle = handle; + if (getPeer() != null) + ((EmbeddedWindowPeer) getPeer()).embed (this.handle); + } + + /** + * Gets the native handle of the screen area where the window will + * be embedded. + * + * @return The native handle that was passed to the constructor. + */ + public long getHandle() + { + return handle; + } +} diff --git a/libjava/classpath/gnu/java/awt/EventModifier.java b/libjava/classpath/gnu/java/awt/EventModifier.java new file mode 100644 index 0000000..565fcbc --- /dev/null +++ b/libjava/classpath/gnu/java/awt/EventModifier.java @@ -0,0 +1,107 @@ +/* EventModifier.java -- tool for converting modifier bits to 1.4 syle + Copyright (C) 2002 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.java.awt; + +import java.awt.event.InputEvent; + +public class EventModifier +{ + /** The mask for old events. */ + public static final int OLD_MASK = 0x3f; + + /** The mask for new events. */ + public static final int NEW_MASK = 0x3fc0; + + /** + * Non-instantiable. + */ + private EventModifier() + { + throw new InternalError(); + } + + /** + * Converts the old style modifiers (0x3f) to the new style (0xffffffc0). + * + * @param mod the modifiers to convert + * @return the adjusted modifiers + */ + public static int extend(int mod) + { + // Favor what we hope will be the common case. + if ((mod & OLD_MASK) == 0) + return mod; + if ((mod & InputEvent.SHIFT_MASK) != 0) + mod |= InputEvent.SHIFT_DOWN_MASK; + if ((mod & InputEvent.CTRL_MASK) != 0) + mod |= InputEvent.CTRL_DOWN_MASK; + if ((mod & InputEvent.META_MASK) != 0) + mod |= InputEvent.META_DOWN_MASK; + if ((mod & InputEvent.ALT_MASK) != 0) + mod |= InputEvent.ALT_DOWN_MASK; + if ((mod & InputEvent.BUTTON1_MASK) != 0) + mod |= InputEvent.BUTTON1_DOWN_MASK; + if ((mod & InputEvent.ALT_GRAPH_MASK) != 0) + mod |= InputEvent.ALT_GRAPH_DOWN_MASK; + return mod & ~OLD_MASK; + } + + /** + * Converts the new style modifiers (0xffffffc0) to the old style (0x3f). + * + * @param mod the modifiers to convert + * @return the adjusted modifiers + */ + public static int revert(int mod) + { + if ((mod & InputEvent.SHIFT_DOWN_MASK) != 0) + mod |= InputEvent.SHIFT_MASK; + if ((mod & InputEvent.CTRL_DOWN_MASK) != 0) + mod |= InputEvent.CTRL_MASK; + if ((mod & InputEvent.META_DOWN_MASK) != 0) + mod |= InputEvent.META_MASK; + if ((mod & InputEvent.ALT_DOWN_MASK) != 0) + mod |= InputEvent.ALT_MASK; + if ((mod & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) + mod |= InputEvent.ALT_GRAPH_MASK; + if ((mod & InputEvent.BUTTON1_DOWN_MASK) != 0) + mod |= InputEvent.BUTTON1_MASK; + return mod & OLD_MASK; + } +} // class EventModifier diff --git a/libjava/classpath/gnu/java/awt/FocusManager.java b/libjava/classpath/gnu/java/awt/FocusManager.java new file mode 100644 index 0000000..49b40bf --- /dev/null +++ b/libjava/classpath/gnu/java/awt/FocusManager.java @@ -0,0 +1,52 @@ +/* FocusManager.java -- Provide Swing FocusManager API compatibility + 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.java.awt; + +/** + * This is a subclass of the otherwise abstract class + * {@link javax.swing.FocusManager}. Its sole purpose is to make the Swing + * FocusManager usable as a FocusManager in AWT, so that we can provide both + * the new (1.4) KeyboardFocusManager API and still support the older + * Swing FocusManager. + * + * @author Roman Kennke + */ +public class FocusManager + extends javax.swing.FocusManager +{ +} diff --git a/libjava/classpath/gnu/java/awt/GradientPaintContext.java b/libjava/classpath/gnu/java/awt/GradientPaintContext.java new file mode 100644 index 0000000..5e1d62d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/GradientPaintContext.java @@ -0,0 +1,164 @@ +/* GradientPaintContext.java -- + Copyright (C) 2005, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt; + +import java.awt.geom.Point2D; +import java.awt.image.ColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.PaintContext; +import java.awt.Color; + +/** + * A {@link PaintContext} used by the {@link GradientPaint} class. + */ +public class GradientPaintContext implements PaintContext +{ + + // This implementation follows the technique described in + // "Java(tm) 2D Graphics" by Jonathan Knudsen (O'Reilly 1999). + + /** The x-coordinate of the anchor point for color 1. */ + private final float x1; + + /** The y-coordinate of the anchor point for color 1. */ + private final float y1; + + /** Color 1. */ + private final Color c1; + + /** The x-coordinate of the anchor point for color 2. */ + private final float x2; + + /** The y-coordinate of the anchor point for color 2. */ + private final float y2; + + /** Color 2. */ + private final Color c2; + + /** A flag indicating whether the gradient is cyclic or acyclic. */ + private final boolean cyclic; + + /** The length of the gradient line - computed from the two anchor points. */ + private final double length; + + /** + * Creates a new instance. + * + * @param x1 the x-coordinate for the anchor point for color 1. + * @param y1 the y-coordinate for the anchor point for color 1. + * @param c1 color 1. + * @param x2 the x-coordinate for the anchor point for color 2. + * @param y2 the y-coordinate for the anchor point for color 2. + * @param c2 color 2. + * @param cyclic a flag that determines whether the gradient is cyclic + * or acyclic. + */ + public GradientPaintContext(float x1, float y1, Color c1, + float x2, float y2, Color c2, boolean cyclic) + { + this.x1 = x1; + this.y1 = y1; + this.c1 = c1; + this.x2 = x2; + this.y2 = y2; + this.c2 = c2; + this.cyclic = cyclic; + length = Point2D.distance(x1, y1, x2, y2); + } + + /** + * Return the color model of this context. It may be different from the + * hint specified during createContext, as not all contexts can generate + * color patterns in an arbitrary model. + * + * @return the context color model + */ + public ColorModel getColorModel() + { + return ColorModel.getRGBdefault(); + } + + /** + * Return a raster containing the colors for the graphics operation. + * + * @param x the x-coordinate, in device space + * @param y the y-coordinate, in device space + * @param w the width, in device space + * @param h the height, in device space + * @return a raster for the given area and color + */ + public Raster getRaster(int x, int y, int w, int h) { + ColorModel cm = getColorModel(); + WritableRaster raster = cm.createCompatibleWritableRaster(w, h); + int[] data = new int[w * h * 4]; + double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + for (int r = 0; r < h; r++) { + for (int c = 0; c < w; c++) { + double u = 0.0; + if (pd2 != 0) + u = (((x + c) - x1) * (x2 - x1) + ((y + r) - y1) * (y2 - y1)) + / Math.sqrt(pd2); + double ratio = u / length; + if (cyclic) + ratio = Math.abs(ratio - Math.floor((ratio + 1.0) / 2.0) * 2.0); + else + ratio = Math.max(0.0, Math.min(1.0, ratio)); + int base = (r * w + c) * 4; + data[base] = (int) (c1.getRed() + ratio * (c2.getRed() - c1.getRed())); + data[base + 1] + = (int) (c1.getGreen() + ratio * (c2.getGreen() - c1.getGreen())); + data[base + 2] + = (int) (c1.getBlue() + ratio * (c2.getBlue() - c1.getBlue())); + data[base + 3] + = (int) (c1.getAlpha() + ratio * (c2.getAlpha() - c1.getAlpha())); + } + } + raster.setPixels(0, 0, w, h, data); + return raster; + } + + /** + * Release the resources allocated for the paint (none in this + * implementation). + */ + public void dispose() { + // nothing to do + } + +} diff --git a/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java b/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java new file mode 100644 index 0000000..1742805 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java @@ -0,0 +1,73 @@ +/* CieXyzConverter.java -- CieXyz conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * CieXyzConverter - converts to/from a D50-relative CIE XYZ color space. + * + * The sRGB<->CIE XYZ conversions in SrgbConverter are used. + * + * @author Sven de Marothy + */ +public class CieXyzConverter implements ColorSpaceConverter +{ + public float[] toCIEXYZ(float[] in) + { + float[] out = new float[3]; + System.arraycopy(in, 0, out, 0, 3); + return out; + } + + public float[] fromCIEXYZ(float[] in) + { + float[] out = new float[3]; + System.arraycopy(in, 0, out, 0, 3); + return out; + } + + public float[] toRGB(float[] in) + { + return SrgbConverter.XYZtoRGB(in); + } + + public float[] fromRGB(float[] in) + { + return SrgbConverter.RGBtoXYZ(in); + } +} diff --git a/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java b/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java new file mode 100644 index 0000000..bff97cc --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java @@ -0,0 +1,152 @@ +/* ClutProfileConverter.java -- Conversion routines for CLUT-Based profiles + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + +import java.awt.color.ICC_Profile; + + +/** + * ClutProfileConverter - conversions through a CLUT-based profile + * + * @author Sven de Marothy + */ +public class ClutProfileConverter implements ColorSpaceConverter +{ + private ColorLookUpTable toPCS; + private ColorLookUpTable fromPCS; + private int nChannels; + + public ClutProfileConverter(ICC_Profile profile) + { + nChannels = profile.getNumComponents(); + + // Sun does not specifiy which rendering intent should be used, + // neither does the ICC v2 spec really. + // Try intent 0 + try + { + toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag); + } + catch (Exception e) + { + toPCS = null; + } + + try + { + fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag); + } + catch (Exception e) + { + fromPCS = null; + } + + if (toPCS != null || fromPCS != null) + return; + + // If no intent 0 clut is available, look for a intent 1 clut. + try + { + toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB1Tag); + } + catch (Exception e) + { + toPCS = null; + } + + try + { + fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA1Tag); + } + catch (Exception e) + { + fromPCS = null; + } + + if (toPCS != null || fromPCS != null) + return; + + // Last shot.. intent 2 CLUT. + try + { + toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB2Tag); + } + catch (Exception e) + { + toPCS = null; + } + + try + { + fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA2Tag); + } + catch (Exception e) + { + fromPCS = null; + } + + if (toPCS == null && fromPCS == null) + throw new IllegalArgumentException("No CLUTs in profile!"); + } + + public float[] toCIEXYZ(float[] in) + { + if (toPCS != null) + return toPCS.lookup(in); + else + return new float[3]; + } + + public float[] toRGB(float[] in) + { + return SrgbConverter.XYZtoRGB(toCIEXYZ(in)); + } + + public float[] fromCIEXYZ(float[] in) + { + if (fromPCS != null) + return fromPCS.lookup(in); + else + return new float[nChannels]; + } + + public float[] fromRGB(float[] in) + { + return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in)); + } +} diff --git a/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java b/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java new file mode 100644 index 0000000..6b6418b --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java @@ -0,0 +1,429 @@ +/* ColorLookUpTable.java -- ICC v2 CLUT + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.nio.ByteBuffer; + + +/** + * ColorLookUpTable handles color lookups through a color lookup table, + * as defined in the ICC specification. + * Both 'mft2' and 'mft1' (8 and 16-bit) type CLUTs are handled. + * + * This will have to be updated later for ICC 4.0.0 + * + * @author Sven de Marothy + */ +public class ColorLookUpTable +{ + /** + * CIE 1931 D50 white point (in Lab coordinates) + */ + private static float[] D50 = { 0.96422f, 1.00f, 0.82521f }; + + /** + * Number of input/output channels + */ + int nIn; + + /** + * Number of input/output channels + */ + int nOut; + int nInTableEntries; // Number of input table entries + int nOutTableEntries; // Number of output table entries + int gridpoints; // Number of gridpoints + int nClut; // This is nOut*(gridpoints**nIn) + double[][] inTable; // 1D input table ([channel][table]) + short[][] outTable; // 1D input table ([channel][table]) + double[] clut; // The color lookup table + float[][] inMatrix; // input matrix (XYZ only) + boolean useMatrix; // Whether to use the matrix or not. + int[] multiplier; + int[] offsets; // Hypercube offsets + boolean inputLab; // Set if the CLUT input CS is Lab + boolean outputLab; // Set if the CLUT output CS is Lab + + /** + * Constructor + * Requires a profile file to get the CLUT from and the tag of the + * CLUT to create. (icSigXToYZTag where X,Y = [A | B], Z = [0,1,2]) + */ + public ColorLookUpTable(ICC_Profile profile, int tag) + { + useMatrix = false; + + switch (tag) + { + case ICC_Profile.icSigAToB0Tag: + case ICC_Profile.icSigAToB1Tag: + case ICC_Profile.icSigAToB2Tag: + if (profile.getColorSpaceType() == ColorSpace.TYPE_XYZ) + useMatrix = true; + inputLab = false; + outputLab = (profile.getPCSType() == ColorSpace.TYPE_Lab); + break; + case ICC_Profile.icSigBToA0Tag: + case ICC_Profile.icSigBToA1Tag: + case ICC_Profile.icSigBToA2Tag: + if (profile.getPCSType() == ColorSpace.TYPE_XYZ) + useMatrix = true; + inputLab = (profile.getPCSType() == ColorSpace.TYPE_Lab); + outputLab = false; + break; + default: + throw new IllegalArgumentException("Not a clut-type tag."); + } + + byte[] data = profile.getData(tag); + if (data == null) + throw new IllegalArgumentException("Unsuitable profile, does not contain a CLUT."); + + // check 'mft' + if (data[0] != 0x6d || data[1] != 0x66 || data[2] != 0x74) + throw new IllegalArgumentException("Unsuitable profile, invalid CLUT data."); + + if (data[3] == 0x32) + readClut16(data); + else if (data[3] == 0x31) + readClut8(data); + else + throw new IllegalArgumentException("Unknown/invalid CLUT type."); + } + + /** + * Loads a 16-bit CLUT into our data structures + */ + private void readClut16(byte[] data) + { + ByteBuffer buf = ByteBuffer.wrap(data); + + nIn = data[8] & (0xFF); + nOut = data[9] & (0xFF); + nInTableEntries = buf.getShort(48); + nOutTableEntries = buf.getShort(50); + gridpoints = data[10] & (0xFF); + + inMatrix = new float[3][3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + inMatrix[i][j] = ((float) (buf.getInt(12 + (i * 3 + j) * 4))) / 65536.0f; + + inTable = new double[nIn][nInTableEntries]; + for (int channel = 0; channel < nIn; channel++) + for (int i = 0; i < nInTableEntries; i++) + inTable[channel][i] = (double) ((int) buf.getShort(52 + + (channel * nInTableEntries + + i) * 2) + & (0xFFFF)) / 65536.0; + + nClut = nOut; + multiplier = new int[nIn]; + multiplier[nIn - 1] = nOut; + for (int i = 0; i < nIn; i++) + { + nClut *= gridpoints; + if (i > 0) + multiplier[nIn - i - 1] = multiplier[nIn - i] * gridpoints; + } + + int clutOffset = 52 + nIn * nInTableEntries * 2; + clut = new double[nClut]; + for (int i = 0; i < nClut; i++) + clut[i] = (double) ((int) buf.getShort(clutOffset + i * 2) & (0xFFFF)) / 65536.0; + + outTable = new short[nOut][nOutTableEntries]; + for (int channel = 0; channel < nOut; channel++) + for (int i = 0; i < nOutTableEntries; i++) + outTable[channel][i] = buf.getShort(clutOffset + + (nClut + + channel * nOutTableEntries + i) * 2); + + // calculate the hypercube corner offsets + offsets = new int[(1 << nIn)]; + offsets[0] = 0; + for (int j = 0; j < nIn; j++) + { + int factor = 1 << j; + for (int i = 0; i < factor; i++) + offsets[factor + i] = offsets[i] + multiplier[j]; + } + } + + /** + * Loads a 8-bit CLUT into our data structures. + */ + private void readClut8(byte[] data) + { + ByteBuffer buf = ByteBuffer.wrap(data); + + nIn = (data[8] & (0xFF)); + nOut = (data[9] & (0xFF)); + nInTableEntries = 256; // always 256 + nOutTableEntries = 256; // always 256 + gridpoints = (data[10] & (0xFF)); + + inMatrix = new float[3][3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + inMatrix[i][j] = ((float) (buf.getInt(12 + (i * 3 + j) * 4))) / 65536.0f; + + inTable = new double[nIn][nInTableEntries]; + for (int channel = 0; channel < nIn; channel++) + for (int i = 0; i < nInTableEntries; i++) + inTable[channel][i] = (double) ((int) buf.get(48 + + (channel * nInTableEntries + + i)) & (0xFF)) / 255.0; + + nClut = nOut; + multiplier = new int[nIn]; + multiplier[nIn - 1] = nOut; + for (int i = 0; i < nIn; i++) + { + nClut *= gridpoints; + if (i > 0) + multiplier[nIn - i - 1] = multiplier[nIn - i] * gridpoints; + } + + int clutOffset = 48 + nIn * nInTableEntries; + clut = new double[nClut]; + for (int i = 0; i < nClut; i++) + clut[i] = (double) ((int) buf.get(clutOffset + i) & (0xFF)) / 255.0; + + outTable = new short[nOut][nOutTableEntries]; + for (int channel = 0; channel < nOut; channel++) + for (int i = 0; i < nOutTableEntries; i++) + outTable[channel][i] = (short) (buf.get(clutOffset + nClut + + channel * nOutTableEntries + + i) * 257); + + // calculate the hypercube corner offsets + offsets = new int[(1 << nIn)]; + offsets[0] = 0; + for (int j = 0; j < nIn; j++) + { + int factor = 1 << j; + for (int i = 0; i < factor; i++) + offsets[factor + i] = offsets[i] + multiplier[j]; + } + } + + /** + * Performs a lookup through the Color LookUp Table. + * If the CLUT tag type is AtoB the conversion will be from the device + * color space to the PCS, BtoA type goes in the opposite direction. + * + * For convenience, the PCS values for input or output will always be + * CIE XYZ (D50), if the actual PCS is Lab, the values will be converted. + * + * N-dimensional linear interpolation is used. + */ + float[] lookup(float[] in) + { + float[] in2 = new float[in.length]; + if (useMatrix) + { + for (int i = 0; i < 3; i++) + in2[i] = in[0] * inMatrix[i][0] + in[1] * inMatrix[i][1] + + in[2] * inMatrix[i][2]; + } + else if (inputLab) + in2 = XYZtoLab(in); + else + System.arraycopy(in, 0, in2, 0, in.length); + + // input table + for (int i = 0; i < nIn; i++) + { + int index = (int) Math.floor(in2[i] * (double) (nInTableEntries - 1)); // floor in + + // clip values. + if (index >= nInTableEntries - 1) + in2[i] = (float) inTable[i][nInTableEntries - 1]; + else if (index < 0) + in2[i] = (float) inTable[i][0]; + else + { + // linear interpolation + double alpha = in2[i] * ((double) nInTableEntries - 1.0) - index; + in2[i] = (float) (inTable[i][index] * (1 - alpha) + + inTable[i][index + 1] * alpha); + } + } + + // CLUT lookup + double[] output2 = new double[nOut]; + double[] weights = new double[(1 << nIn)]; + double[] clutalpha = new double[nIn]; // interpolation values + int offset = 0; // = gp + for (int i = 0; i < nIn; i++) + { + int index = (int) Math.floor(in2[i] * ((double) gridpoints - 1.0)); + double alpha = in2[i] * ((double) gridpoints - 1.0) - (double) index; + + // clip values. + if (index >= gridpoints - 1) + { + index = gridpoints - 1; + alpha = 1.0; + } + else if (index < 0) + index = 0; + clutalpha[i] = alpha; + offset += index * multiplier[i]; + } + + // Calculate interpolation weights + weights[0] = 1.0; + for (int j = 0; j < nIn; j++) + { + int factor = 1 << j; + for (int i = 0; i < factor; i++) + { + weights[factor + i] = weights[i] * clutalpha[j]; + weights[i] *= (1.0 - clutalpha[j]); + } + } + + for (int i = 0; i < nOut; i++) + output2[i] = weights[0] * clut[offset + i]; + + for (int i = 1; i < (1 << nIn); i++) + { + int offset2 = offset + offsets[i]; + for (int f = 0; f < nOut; f++) + output2[f] += weights[i] * clut[offset2 + f]; + } + + // output table + float[] output = new float[nOut]; + for (int i = 0; i < nOut; i++) + { + int index = (int) Math.floor(output2[i] * ((double) nOutTableEntries + - 1.0)); + + // clip values. + if (index >= nOutTableEntries - 1) + output[i] = outTable[i][nOutTableEntries - 1]; + else if (index < 0) + output[i] = outTable[i][0]; + else + { + // linear interpolation + double a = output2[i] * ((double) nOutTableEntries - 1.0) + - (double) index; + output[i] = (float) ((double) ((int) outTable[i][index] & (0xFFFF)) * (1 + - a) + + (double) ((int) outTable[i][index + 1] & (0xFFFF)) * a) / 65536f; + } + } + + if (outputLab) + return LabtoXYZ(output); + return output; + } + + /** + * Converts CIE Lab coordinates to (D50) XYZ ones. + */ + private float[] LabtoXYZ(float[] in) + { + // Convert from byte-packed format to a + // more convenient one (actual Lab values) + // (See ICC spec for details) + // factor is 100 * 65536 / 65280 + in[0] = (float) (100.392156862745 * in[0]); + in[1] = (in[1] * 256.0f) - 128.0f; + in[2] = (in[2] * 256.0f) - 128.0f; + + float[] out = new float[3]; + + out[1] = (in[0] + 16.0f) / 116.0f; + out[0] = in[1] / 500.0f + out[1]; + out[2] = out[1] - in[2] / 200.0f; + + for (int i = 0; i < 3; i++) + { + double exp = out[i] * out[i] * out[i]; + if (exp <= 0.008856) + out[i] = (out[i] - 16.0f / 116.0f) / 7.787f; + else + out[i] = (float) exp; + out[i] = D50[i] * out[i]; + } + return out; + } + + /** + * Converts CIE XYZ coordinates to Lab ones. + */ + private float[] XYZtoLab(float[] in) + { + float[] temp = new float[3]; + + for (int i = 0; i < 3; i++) + { + temp[i] = in[i] / D50[i]; + + if (temp[i] <= 0.008856f) + temp[i] = (7.7870689f * temp[i]) + (16f / 116.0f); + else + temp[i] = (float) Math.exp((1.0 / 3.0) * Math.log(temp[i])); + } + + float[] out = new float[3]; + out[0] = (116.0f * temp[1]) - 16f; + out[1] = 500.0f * (temp[0] - temp[1]); + out[2] = 200.0f * (temp[1] - temp[2]); + + // Normalize to packed format + out[0] = (float) (out[0] / 100.392156862745); + out[1] = (out[1] + 128f) / 256f; + out[2] = (out[2] + 128f) / 256f; + for (int i = 0; i < 3; i++) + { + if (out[i] < 0f) + out[i] = 0f; + if (out[i] > 1f) + out[i] = 1f; + } + return out; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java b/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java new file mode 100644 index 0000000..63ba08a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java @@ -0,0 +1,69 @@ +/* ColorSpaceConverter.java -- an interface for colorspace conversion + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * ColorSpaceConverter - used by java.awt.color.ICC_ColorSpace + * + * Color space conversion can occur in several ways: + * + * -Directly (for the built in spaces sRGB, linear RGB, gray, CIE XYZ and PYCC + * -ICC_ProfileRGB works through TRC curves and a matrix + * -ICC_ProfileGray works through a single TRC + * -Everything else is done through Color lookup tables. + * + * The different conversion methods are implemented through + * an interface. The built-in colorspaces are implemented directly + * with the relevant conversion equations. + * + * In this way, we hopefully will always use the fastest and most + * accurate method available. + * + * @author Sven de Marothy + */ +public interface ColorSpaceConverter +{ + float[] toCIEXYZ(float[] in); + + float[] fromCIEXYZ(float[] in); + + float[] toRGB(float[] in); + + float[] fromRGB(float[] in); +} diff --git a/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java b/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java new file mode 100644 index 0000000..3c72513 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java @@ -0,0 +1,137 @@ +/* GrayProfileConverter.java -- Gray profile conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + +import java.awt.color.ICC_Profile; +import java.awt.color.ICC_ProfileGray; +import java.awt.color.ProfileDataException; + +/** + * GrayProfileConverter - converts Grayscale profiles (ICC_ProfileGray) + * + * This type of profile contains a single tone reproduction curve (TRC). + * Conversion consists of simple TRC lookup. + * + * This implementation is very lazy and does everything applying the TRC and + * utilizing the built-in linear grayscale color space. + * + * @author Sven de Marothy + */ +public class GrayProfileConverter implements ColorSpaceConverter +{ + private GrayScaleConverter gc; + private ToneReproductionCurve trc; + private ColorLookUpTable toPCS; + private ColorLookUpTable fromPCS; + + /** + * Constructs the converter described by an ICC_ProfileGray object + */ + public GrayProfileConverter(ICC_ProfileGray profile) + { + try + { + trc = new ToneReproductionCurve(profile.getGamma()); + } + catch (ProfileDataException e) + { + trc = new ToneReproductionCurve(profile.getTRC()); + } + + // linear grayscale converter + gc = new GrayScaleConverter(); + + // If a CLUT is available, it should be used, and the TRCs ignored. + // Note: A valid profile may only have CLUTs in one direction, and + // TRC:s without useful info, making reverse-transforms impossible. + // In this case the TRC will be used for the reverse-transform with + // unpredictable results. This is in line with the Java specification, + try + { + toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag); + } + catch (Exception e) + { + toPCS = null; + } + + try + { + fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag); + } + catch (Exception e) + { + fromPCS = null; + } + } + + public float[] toCIEXYZ(float[] in) + { + if (toPCS != null) + return toPCS.lookup(in); + float[] gray = new float[1]; + gray[0] = trc.lookup(in[0]); + return gc.toCIEXYZ(gray); + } + + public float[] toRGB(float[] in) + { + float[] gray = new float[1]; + gray[0] = trc.lookup(in[0]); + return gc.toRGB(gray); + } + + public float[] fromRGB(float[] in) + { + // get linear grayscale value + float[] gray = gc.fromRGB(in); + gray[0] = trc.reverseLookup(gray[0]); + return gray; + } + + public float[] fromCIEXYZ(float[] in) + { + if (fromPCS != null) + return fromPCS.lookup(in); + + float[] gray = gc.fromCIEXYZ(in); + gray[0] = trc.reverseLookup(gray[0]); + return gray; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java b/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java new file mode 100644 index 0000000..7a27ddb --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java @@ -0,0 +1,110 @@ +/* GrayScaleConverter.java -- Linear grayscale conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * Linear Grayscale converter + * + * @author Sven de Marothy + */ +public class GrayScaleConverter implements ColorSpaceConverter +{ + // intensity factors (ITU Rec. BT.709) + double[] coeff = { 0.2125f, 0.7154f, 0.0721f }; + + /** + * CIE 1931 D50 white point (in Lab coordinates) + */ + private static float[] D50 = { 0.96422f, 1.00f, 0.82521f }; + + public float[] toCIEXYZ(float[] in) + { + float g = in[0]; + if (g < 0) + g = 1 + g; + float[] out = { g * D50[0], g * D50[1], g * D50[2] }; // White spot + return out; + } + + public float[] toRGB(float[] in) + { + float[] out = new float[3]; + if (in[0] <= 0.00304f) + out[0] = in[0] * 12.92f; + else + out[0] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(in[0]))) + - 0.055f; + out[1] = out[2] = out[0]; + return out; + } + + public float[] fromCIEXYZ(float[] in) + { + float[] temp = new float[3]; + temp[0] = 3.1338f * in[0] - 1.6171f * in[1] - 0.4907f * in[2]; + temp[1] = -0.9785f * in[0] + 1.9160f * in[1] + 0.0334f * in[2]; + temp[2] = 0.0720f * in[0] - 0.2290f * in[1] + 1.4056f * in[2]; + float[] out = new float[1]; + for (int i = 0; i < 3; i++) + out[0] = (float) (temp[i] * coeff[i]); + return out; + } + + public float[] fromRGB(float[] in) + { + float[] out = new float[1]; + + // Convert non-linear RGB coordinates to linear ones, + // numbers from the w3 spec. + out[0] = 0; + for (int i = 0; i < 3; i++) + { + float n = in[i]; + if (n < 0) + n = 0f; + if (n > 1) + n = 1f; + if (n <= 0.03928f) + out[0] += (float) (coeff[i] * n / 12.92); + else + out[0] += (float) (coeff[i] * Math.exp(2.4 * Math.log((n + 0.055) / 1.055))); + } + return out; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java b/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java new file mode 100644 index 0000000..13a4e2c --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java @@ -0,0 +1,152 @@ +/* LinearRGBConverter.java -- conversion to a linear RGB color space + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * LinearRGBConverter - conversion routines for a linear sRGB colorspace + * sRGB is a standard for RGB colorspaces, adopted by the w3c. + * + * The specification is available at: + * http://www.w3.org/Graphics/Color/sRGB.html + * + * @author Sven de Marothy + */ +public class LinearRGBConverter implements ColorSpaceConverter +{ + /** + * linear RGB --> sRGB + * Use the inverse gamma curve + */ + public float[] toRGB(float[] in) + { + float[] out = new float[3]; + for (int i = 0; i < 3; i++) + { + float n = in[i]; + if (n < 0) + n = 0f; + if (n > 1) + n = 1f; + if (n <= 0.00304f) + out[i] = in[0] * 12.92f; + else + out[i] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(n))) + - 0.055f; + } + return out; + } + + /** + * sRGB --> linear RGB + * Use the gamma curve (gamma=2.4 in sRGB) + */ + public float[] fromRGB(float[] in) + { + float[] out = new float[3]; + + // Convert non-linear RGB coordinates to linear ones, + // numbers from the w3 spec. + for (int i = 0; i < 3; i++) + { + float n = in[i]; + if (n < 0) + n = 0f; + if (n > 1) + n = 1f; + if (n <= 0.03928f) + out[i] = (float) (n / 12.92); + else + out[i] = (float) (Math.exp(2.4 * Math.log((n + 0.055) / 1.055))); + } + return out; + } + + /** + * Linear RGB --> CIE XYZ (D50 relative) + * This is a simple matrix transform, the matrix (relative D65) + * is given in the sRGB spec. This has been combined with a + * linear Bradford transform for the D65-->D50 mapping, resulting + * in a single matrix which does the whole thing. + * + */ + public float[] fromCIEXYZ(float[] in) + { + /* + * Note: The numbers which were used to calculate this only had four + * digits of accuracy. So don't be fooled by the number of digits here. + * If someone has more accurate source, feel free to update this. + */ + float[] out = new float[3]; + out[0] = (float) (3.13383065124221 * in[0] - 1.61711949411313 * in[1] + - 0.49071914111101 * in[2]); + out[1] = (float) (-0.97847026691142 * in[0] + 1.91597856031996 * in[1] + + 0.03340430640699 * in[2]); + out[2] = (float) (0.07203679486279 * in[0] - 0.22903073553113 * in[1] + + 1.40557835776234 * in[2]); + if (out[0] < 0) + out[0] = 0f; + if (out[1] < 0) + out[1] = 0f; + if (out[2] < 0) + out[2] = 0f; + if (out[0] > 1.0f) + out[0] = 1.0f; + if (out[1] > 1.0f) + out[1] = 1.0f; + if (out[2] > 1.0f) + out[2] = 1.0f; + return out; + } + + /** + * Linear RGB --> CIE XYZ (D50 relative) + * Uses the inverse of the above matrix. + */ + public float[] toCIEXYZ(float[] in) + { + float[] out = new float[3]; + out[0] = (float) (0.43606375022190 * in[0] + 0.38514960146481 * in[1] + + 0.14308641888799 * in[2]); + out[1] = (float) (0.22245089403542 * in[0] + 0.71692584775182 * in[1] + + 0.06062451125578 * in[2]); + out[2] = (float) (0.01389851860679 * in[0] + 0.09707969011198 * in[1] + + 0.71399604572506 * in[2]); + return out; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/ProfileHeader.java b/libjava/classpath/gnu/java/awt/color/ProfileHeader.java new file mode 100644 index 0000000..4fdef56 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/ProfileHeader.java @@ -0,0 +1,398 @@ +/* ProfileHeader.java -- Encapsules ICC Profile header data + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.nio.ByteBuffer; + + +/** + * Header, abstracts and validates the header data. + * + * @author Sven de Marothy + */ +public class ProfileHeader +{ + /** + * Magic identifier (ASCII 'acsp') + */ + private static final int icMagicNumber = 0x61637370; + + /** + * Mapping from ICC Profile signatures to ColorSpace types + */ + private static final int[] csTypeMap = + { + ICC_Profile.icSigXYZData, + ColorSpace.TYPE_XYZ, + ICC_Profile.icSigLabData, + ColorSpace.TYPE_Lab, + ICC_Profile.icSigLuvData, + ColorSpace.TYPE_Luv, + ICC_Profile.icSigYCbCrData, + ColorSpace.TYPE_YCbCr, + ICC_Profile.icSigYxyData, + ColorSpace.TYPE_Yxy, + ICC_Profile.icSigRgbData, + ColorSpace.TYPE_RGB, + ICC_Profile.icSigGrayData, + ColorSpace.TYPE_GRAY, + ICC_Profile.icSigHsvData, + ColorSpace.TYPE_HSV, + ICC_Profile.icSigHlsData, + ColorSpace.TYPE_HLS, + ICC_Profile.icSigCmykData, + ColorSpace.TYPE_CMYK, + ICC_Profile.icSigCmyData, + ColorSpace.TYPE_CMY, + ICC_Profile.icSigSpace2CLR, + ColorSpace.TYPE_2CLR, + ICC_Profile.icSigSpace3CLR, + ColorSpace.TYPE_3CLR, + ICC_Profile.icSigSpace4CLR, + ColorSpace.TYPE_4CLR, + ICC_Profile.icSigSpace5CLR, + ColorSpace.TYPE_5CLR, + ICC_Profile.icSigSpace6CLR, + ColorSpace.TYPE_6CLR, + ICC_Profile.icSigSpace7CLR, + ColorSpace.TYPE_7CLR, + ICC_Profile.icSigSpace8CLR, + ColorSpace.TYPE_8CLR, + ICC_Profile.icSigSpace9CLR, + ColorSpace.TYPE_9CLR, + ICC_Profile.icSigSpaceACLR, + ColorSpace.TYPE_ACLR, + ICC_Profile.icSigSpaceBCLR, + ColorSpace.TYPE_BCLR, + ICC_Profile.icSigSpaceCCLR, + ColorSpace.TYPE_CCLR, + ICC_Profile.icSigSpaceDCLR, + ColorSpace.TYPE_DCLR, + ICC_Profile.icSigSpaceECLR, + ColorSpace.TYPE_ECLR, + ICC_Profile.icSigSpaceFCLR, + ColorSpace.TYPE_FCLR + }; + + /** + * Size of an ICC header (128 bytes) + */ + public static final int HEADERSIZE = 128; + + /** + * Mapping of ICC class signatures to profile class constants + */ + private static final int[] classMap = + { + ICC_Profile.icSigInputClass, + ICC_Profile.CLASS_INPUT, + ICC_Profile.icSigDisplayClass, + ICC_Profile.CLASS_DISPLAY, + ICC_Profile.icSigOutputClass, + ICC_Profile.CLASS_OUTPUT, + ICC_Profile.icSigLinkClass, + ICC_Profile.CLASS_DEVICELINK, + ICC_Profile.icSigColorSpaceClass, + ICC_Profile.CLASS_COLORSPACECONVERSION, + ICC_Profile.icSigAbstractClass, + ICC_Profile.CLASS_ABSTRACT, + ICC_Profile.icSigNamedColorClass, + ICC_Profile.CLASS_NAMEDCOLOR + }; + private int size; + private int cmmId; + + // Major/Minor version, The ICC-1998 spec is major v2 + private int majorVersion; + + // Major/Minor version, The ICC-1998 spec is major v2 + private int minorVersion; + private int profileClass; // profile device class + private int colorSpace; // data color space type + private int profileColorSpace; // profile connection space (PCS) type + private byte[] timestamp; // original creation timestamp + private int platform; // platform signature + private int flags; // flags + private int magic; // magic number. + private int manufacturerSig; // manufacturer sig + private int modelSig; // model sig + private byte[] attributes; // Attributes + private int intent; // rendering intent + private byte[] illuminant; // illuminant info (Coordinates of D50 in the PCS) + private int creatorSig; // Creator sig (same type as manufacturer) + + /** + * Creates a 'default' header for use with our predefined profiles. + * Note the device and profile color spaces are not set. + */ + public ProfileHeader() + { + creatorSig = 0; + intent = 0; + modelSig = manufacturerSig = (int) 0x6E6f6E65; // 'none' + magic = icMagicNumber; + cmmId = 0; + platform = 0; // no preferred platform + timestamp = new byte[8]; + majorVersion = 2; + minorVersion = 0x10; + flags = 0; + + // D50 in XYZ format (encoded) + illuminant = new byte[] + { + (byte) 0x00, (byte) 0x00, (byte) 0xf6, (byte) 0xd6, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xd3, (byte) 0x2d + }; + attributes = new byte[8]; + profileClass = ICC_Profile.CLASS_DISPLAY; + } + + /** + * Creates a header from profile data. Only the header portion (128 bytes) + * is read, so the array passed need not be the full profile. + */ + public ProfileHeader(byte[] data) + { + ByteBuffer buf = ByteBuffer.wrap(data); + + // Get size (the sign bit shouldn't matter. + // A valid profile can never be +2Gb) + size = buf.getInt(ICC_Profile.icHdrSize); + + // CMM ID + cmmId = buf.getInt(ICC_Profile.icHdrCmmId); + + // Version number + majorVersion = (int) (data[ICC_Profile.icHdrVersion]); + minorVersion = (int) (data[ICC_Profile.icHdrVersion + 1]); + + // Profile/Device class + int classSig = buf.getInt(ICC_Profile.icHdrDeviceClass); + profileClass = -1; + for (int i = 0; i < classMap.length; i += 2) + if (classMap[i] == classSig) + { + profileClass = classMap[i + 1]; + break; + } + + // get the data color space + int csSig = buf.getInt(ICC_Profile.icHdrColorSpace); + colorSpace = -1; + for (int i = 0; i < csTypeMap.length; i += 2) + if (csTypeMap[i] == csSig) + { + colorSpace = csTypeMap[i + 1]; + break; + } + + // get the profile color space (PCS), must be xyz or lab except + // for device-link-class profiles + int pcsSig = buf.getInt(ICC_Profile.icHdrPcs); + profileColorSpace = -1; + if (profileClass != ICC_Profile.CLASS_DEVICELINK) + { + if (pcsSig == ICC_Profile.icSigXYZData) + profileColorSpace = ColorSpace.TYPE_XYZ; + if (pcsSig == ICC_Profile.icSigLabData) + profileColorSpace = ColorSpace.TYPE_Lab; + } + else + { + for (int i = 0; i < csTypeMap.length; i += 2) + if (csTypeMap[i] == pcsSig) + { + profileColorSpace = csTypeMap[i + 1]; + break; + } + } + + // creation timestamp + timestamp = new byte[8]; + System.arraycopy(data, ICC_Profile.icHdrDate, timestamp, 0, 8); + + // magic number + magic = buf.getInt(ICC_Profile.icHdrMagic); + + // platform info + platform = buf.getInt(ICC_Profile.icHdrPlatform); + // get flags + flags = buf.getInt(ICC_Profile.icHdrFlags); + // get manufacturer sign + manufacturerSig = buf.getInt(ICC_Profile.icHdrManufacturer); + // get header model + modelSig = buf.getInt(ICC_Profile.icHdrModel); + // attributes + attributes = new byte[8]; + System.arraycopy(data, ICC_Profile.icHdrAttributes, attributes, 0, 8); + // rendering intent + intent = buf.getInt(ICC_Profile.icHdrRenderingIntent); + // illuminant info + illuminant = new byte[12]; + System.arraycopy(data, ICC_Profile.icHdrIlluminant, illuminant, 0, 12); + // Creator signature + creatorSig = buf.getInt(ICC_Profile.icHdrCreator); + // The rest of the header (Total size: 128 bytes) is unused.. + } + + /** + * Verify that the header is valid + * @param size equals the file size if it is to be verified, -1 otherwise + * @throws IllegalArgumentException if the header is found to be invalid. + */ + public void verifyHeader(int size) throws IllegalArgumentException + { + // verify size + if (size != -1 && this.size != size) + throw new IllegalArgumentException("Invalid profile length:" + size); + + // Check version number + if (majorVersion != 2) + throw new IllegalArgumentException("Wrong major version number:" + + majorVersion); + + // Profile/Device class + if (profileClass == -1) + throw new IllegalArgumentException("Invalid profile/device class"); + + // get the data color space + if (colorSpace == -1) + throw new IllegalArgumentException("Invalid colorspace"); + + // profile color space + if (profileColorSpace == -1) + throw new IllegalArgumentException("Invalid PCS."); + + // check magic number + if (magic != icMagicNumber) + throw new IllegalArgumentException("Invalid magic number!"); + } + + /** + * Creates a header, setting the header file size at the same time. + * @param size the profile file size. + */ + public byte[] getData(int size) + { + byte[] data = new byte[HEADERSIZE]; + ByteBuffer buf = ByteBuffer.wrap(data); + buf.putInt(ICC_Profile.icHdrSize, size); + buf.putInt(ICC_Profile.icHdrCmmId, cmmId); + buf.putShort(ICC_Profile.icHdrVersion, + (short) (majorVersion << 8 | minorVersion)); + for (int i = 1; i < classMap.length; i += 2) + if (profileClass == classMap[i]) + buf.putInt(ICC_Profile.icHdrDeviceClass, classMap[i - 1]); + for (int i = 1; i < csTypeMap.length; i += 2) + if (csTypeMap[i] == colorSpace) + buf.putInt(ICC_Profile.icHdrColorSpace, csTypeMap[i - 1]); + for (int i = 1; i < csTypeMap.length; i += 2) + if (csTypeMap[i] == profileColorSpace) + buf.putInt(ICC_Profile.icHdrPcs, csTypeMap[i - 1]); + + System.arraycopy(timestamp, 0, data, ICC_Profile.icHdrDate, + timestamp.length); + buf.putInt(ICC_Profile.icHdrMagic, icMagicNumber); + buf.putInt(ICC_Profile.icHdrPlatform, platform); + buf.putInt(ICC_Profile.icHdrFlags, flags); + buf.putInt(ICC_Profile.icHdrManufacturer, manufacturerSig); + buf.putInt(ICC_Profile.icHdrModel, modelSig); + System.arraycopy(attributes, 0, data, ICC_Profile.icHdrAttributes, + attributes.length); + buf.putInt(ICC_Profile.icHdrRenderingIntent, intent); + System.arraycopy(illuminant, 0, data, ICC_Profile.icHdrIlluminant, + illuminant.length); + buf.putInt(ICC_Profile.icHdrCreator, creatorSig); + return buf.array(); + } + + public int getSize() + { + return size; + } + + public void setSize(int s) + { + size = s; + } + + public int getMajorVersion() + { + return majorVersion; + } + + public int getMinorVersion() + { + return minorVersion; + } + + public int getProfileClass() + { + return profileClass; + } + + public void setProfileClass(int pc) + { + profileClass = pc; + } + + public int getColorSpace() + { + return colorSpace; + } + + public int getProfileColorSpace() + { + return profileColorSpace; + } + + public void setColorSpace(int cs) + { + colorSpace = cs; + } + + public void setProfileColorSpace(int pcs) + { + profileColorSpace = pcs; + } + +} diff --git a/libjava/classpath/gnu/java/awt/color/PyccConverter.java b/libjava/classpath/gnu/java/awt/color/PyccConverter.java new file mode 100644 index 0000000..cd50d87 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/PyccConverter.java @@ -0,0 +1,72 @@ +/* PyccConverter.java -- PhotoYCC conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * PyccConverter - conversion routines for the PhotoYCC colorspace + * + * Also known as PhotoCD YCC, it is an expansion of the conventional + * YCC color space to also include colors with over 100% white. + * + * XXX FIXME: Not yet implemented, implementation pending. + * + * @author Sven de Marothy + */ +public class PyccConverter implements ColorSpaceConverter +{ + public float[] toRGB(float[] in) + { + return null; + } + + public float[] fromRGB(float[] in) + { + return null; + } + + public float[] toCIEXYZ(float[] in) + { + return null; + } + + public float[] fromCIEXYZ(float[] in) + { + return null; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java b/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java new file mode 100644 index 0000000..0cbd28f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java @@ -0,0 +1,244 @@ +/* RgbProfileConverter.java -- RGB Profile conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + +import java.awt.color.ICC_Profile; +import java.awt.color.ICC_ProfileRGB; +import java.awt.color.ProfileDataException; + +/** + * RgbProfileConverter - converts RGB profiles (ICC_ProfileRGB) + * + * This type of profile contains a matrix and three + * tone reproduction curves (TRCs). + * + * Device RGB --> CIE XYZ is done through first multiplying with + * a matrix, then each component is looked-up against it's TRC. + * + * The opposite transform is done using the inverse of the matrix, + * and TRC:s. + * + * @author Sven de Marothy + */ +public class RgbProfileConverter implements ColorSpaceConverter +{ + private float[][] matrix; + private float[][] inv_matrix; + private ToneReproductionCurve rTRC; + private ToneReproductionCurve gTRC; + private ToneReproductionCurve bTRC; + private ColorLookUpTable toPCS; + private ColorLookUpTable fromPCS; + + /** + * CIE 1931 D50 white point (in Lab coordinates) + */ + private static float[] D50 = { 0.96422f, 1.00f, 0.82521f }; + + /** + * Constructs an RgbProfileConverter from a given ICC_ProfileRGB + */ + public RgbProfileConverter(ICC_ProfileRGB profile) + { + toPCS = fromPCS = null; + matrix = profile.getMatrix(); + + // get TRCs + try + { + rTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.REDCOMPONENT)); + } + catch (ProfileDataException e) + { + rTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.REDCOMPONENT)); + } + try + { + gTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.GREENCOMPONENT)); + } + catch (ProfileDataException e) + { + gTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.GREENCOMPONENT)); + } + try + { + bTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.BLUECOMPONENT)); + } + catch (ProfileDataException e) + { + bTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.BLUECOMPONENT)); + } + + // If a CLUT is available, it should be used, and the TRCs ignored. + // Note: A valid profile may only have CLUTs in one direction, and + // TRC:s without useful info, making reverse-transforms impossible. + // In this case the TRC will be used for the reverse-transform with + // unpredictable results. This is in line with the Java specification, + try + { + toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag); + } + catch (Exception e) + { + toPCS = null; + } + + try + { + fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag); + } + catch (Exception e) + { + fromPCS = null; + } + + // Calculate the inverse matrix if no reverse CLUT is available + if(fromPCS == null) + inv_matrix = invertMatrix(matrix); + else + { + // otherwise just set it to an identity matrix + inv_matrix = new float[3][3]; + inv_matrix[0][0] = inv_matrix[1][1] = inv_matrix[2][2] = 1.0f; + } + } + + public float[] toCIEXYZ(float[] in) + { + // CLUT takes precedence + if (toPCS != null) + return toPCS.lookup(in); + + float[] temp = new float[3]; + float[] out = new float[3]; + + // device space --> linear gamma + temp[0] = rTRC.lookup(in[0]); + temp[1] = gTRC.lookup(in[1]); + temp[2] = bTRC.lookup(in[2]); + + // matrix multiplication + out[0] = matrix[0][0] * temp[0] + matrix[0][1] * temp[1] + + matrix[0][2] * temp[2]; + out[1] = matrix[1][0] * temp[0] + matrix[1][1] * temp[1] + + matrix[1][2] * temp[2]; + out[2] = matrix[2][0] * temp[0] + matrix[2][1] * temp[1] + + matrix[2][2] * temp[2]; + + return out; + } + + public float[] toRGB(float[] in) + { + return SrgbConverter.XYZtoRGB(toCIEXYZ(in)); + } + + public float[] fromCIEXYZ(float[] in) + { + if (fromPCS != null) + return fromPCS.lookup(in); + + float[] temp = new float[3]; + float[] out = new float[3]; + + // matrix multiplication + temp[0] = inv_matrix[0][0] * in[0] + inv_matrix[0][1] * in[1] + + inv_matrix[0][2] * in[2]; + temp[1] = inv_matrix[1][0] * in[0] + inv_matrix[1][1] * in[1] + + inv_matrix[1][2] * in[2]; + temp[2] = inv_matrix[2][0] * in[0] + inv_matrix[2][1] * in[1] + + inv_matrix[2][2] * in[2]; + + // device space --> linear gamma + out[0] = rTRC.reverseLookup(temp[0]); + out[1] = gTRC.reverseLookup(temp[1]); + out[2] = bTRC.reverseLookup(temp[2]); + + // FIXME: Sun appears to clip the return values to [0,1] + // I don't believe that is a Good Thing, + // (some colorspaces may allow values outside that range.) + // So we return the actual values here. + return out; + } + + public float[] fromRGB(float[] in) + { + return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in)); + } + + /** + * Inverts a 3x3 matrix, returns the inverse, + * throws an IllegalArgumentException if the matrix is not + * invertible (this shouldn't happen for a valid profile) + */ + private float[][] invertMatrix(float[][] matrix) + { + float[][] out = new float[3][3]; + double determinant = matrix[0][0] * (matrix[1][1] * matrix[2][2] + - matrix[2][1] * matrix[1][2]) + - matrix[0][1] * (matrix[1][0] * matrix[2][2] + - matrix[2][0] * matrix[1][2]) + + matrix[0][2] * (matrix[1][0] * matrix[2][1] + - matrix[2][0] * matrix[1][1]); + + if (determinant == 0.0) + throw new IllegalArgumentException("Can't invert conversion matrix."); + float invdet = (float) (1.0 / determinant); + + out[0][0] = invdet * (matrix[1][1] * matrix[2][2] + - matrix[1][2] * matrix[2][1]); + out[0][1] = invdet * (matrix[0][2] * matrix[2][1] + - matrix[0][1] * matrix[2][2]); + out[0][2] = invdet * (matrix[0][1] * matrix[1][2] + - matrix[0][2] * matrix[1][1]); + out[1][0] = invdet * (matrix[1][2] * matrix[2][0] + - matrix[1][0] * matrix[2][2]); + out[1][1] = invdet * (matrix[0][0] * matrix[2][2] + - matrix[0][2] * matrix[2][0]); + out[1][2] = invdet * (matrix[0][2] * matrix[1][0] + - matrix[0][0] * matrix[1][2]); + out[2][0] = invdet * (matrix[1][0] * matrix[2][1] + - matrix[1][1] * matrix[2][0]); + out[2][1] = invdet * (matrix[0][1] * matrix[2][0] + - matrix[0][0] * matrix[2][1]); + out[2][2] = invdet * (matrix[0][0] * matrix[1][1] + - matrix[0][1] * matrix[1][0]); + return out; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/SrgbConverter.java b/libjava/classpath/gnu/java/awt/color/SrgbConverter.java new file mode 100644 index 0000000..a30a0db --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/SrgbConverter.java @@ -0,0 +1,152 @@ +/* SrgbConverter.java -- sRGB conversion class + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * SrgbConverter - conversion routines for the sRGB colorspace + * sRGB is a standard for RGB colorspaces, adopted by the w3c. + * + * The specification is available at: + * http://www.w3.org/Graphics/Color/sRGB.html + * + * @author Sven de Marothy + */ +/** + * + * Note the matrix numbers used here are NOT identical to those in the + * w3 spec, as those numbers are CIE XYZ relative a D65 white point. + * The CIE XYZ we use is relative a D50 white point, so therefore a + * linear Bradford transform matrix for D65->D50 mapping has been applied. + * (The ICC documents describe this transform) + * + * Linearized Bradford transform: + * 0.8951 0.2664 -0.1614 + * -0.7502 1.7135 0.0367 + * 0.0389 -0.0685 1.0296 + * + * Inverse: + * 0.9870 -0.1471 0.1600 + * 0.4323 0.5184 0.0493 + * -0.00853 0.0400 0.9685 + */ +public class SrgbConverter implements ColorSpaceConverter +{ + public float[] fromCIEXYZ(float[] in) + { + return XYZtoRGB(in); + } + + public float[] toCIEXYZ(float[] in) + { + return RGBtoXYZ(in); + } + + public float[] toRGB(float[] in) + { + float[] out = new float[3]; + System.arraycopy(in, 0, out, 0, 3); + return out; + } + + public float[] fromRGB(float[] in) + { + float[] out = new float[3]; + System.arraycopy(in, 0, out, 0, 3); + return out; + } + + /** + * CIE XYZ (D50 relative) --> sRGB + * + * Static as it's used by other ColorSpaceConverters to + * convert to sRGB if the color space is defined in XYZ. + */ + public static float[] XYZtoRGB(float[] in) + { + float[] temp = new float[3]; + temp[0] = 3.1338f * in[0] - 1.6171f * in[1] - 0.4907f * in[2]; + temp[1] = -0.9785f * in[0] + 1.9160f * in[1] + 0.0334f * in[2]; + temp[2] = 0.0720f * in[0] - 0.2290f * in[1] + 1.4056f * in[2]; + + float[] out = new float[3]; + for (int i = 0; i < 3; i++) + { + if (temp[i] < 0) + temp[i] = 0.0f; + if (temp[i] > 1) + temp[i] = 1.0f; + if (temp[i] <= 0.00304f) + out[i] = temp[i] * 12.92f; + else + out[i] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(temp[i]))) + - 0.055f; + } + return out; + } + + /** + * sRGB --> CIE XYZ (D50 relative) + * + * Static as it's used by other ColorSpaceConverters to + * convert to XYZ if the color space is defined in RGB. + */ + public static float[] RGBtoXYZ(float[] in) + { + float[] temp = new float[3]; + float[] out = new float[3]; + for (int i = 0; i < 3; i++) + if (in[i] <= 0.03928f) + temp[i] = in[i] / 12.92f; + else + temp[i] = (float) Math.exp(2.4 * Math.log((in[i] + 0.055) / 1.055)); + + /* + * Note: The numbers which were used to calculate this only had four + * digits of accuracy. So don't be fooled by the number of digits here. + * If someone has more accurate source, feel free to update this. + */ + out[0] = (float) (0.436063750222 * temp[0] + 0.385149601465 * temp[1] + + 0.143086418888 * temp[2]); + out[1] = (float) (0.222450894035 * temp[0] + 0.71692584775 * temp[1] + + 0.060624511256 * temp[2]); + out[2] = (float) (0.0138985186 * temp[0] + 0.097079690112 * temp[1] + + 0.713996045725 * temp[2]); + return out; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/TagEntry.java b/libjava/classpath/gnu/java/awt/color/TagEntry.java new file mode 100644 index 0000000..a978646 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/TagEntry.java @@ -0,0 +1,121 @@ +/* TagEntry.java -- A utility class used for storing the tags in ICC_Profile + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * TagEntry - stores a profile tag. + * These are conveniently stored in a hashtable with the tag signature + * as a key. A legal profile can only have one tag with a given sig, + * so we can conveniently ignore collisions. + * + * @author Sven de Marothy + */ +public class TagEntry +{ + // tag table entry size + public static final int entrySize = 12; + private int signature; + private int size; + private int offset; + private byte[] data; + + public TagEntry(int sig, int offset, int size, byte[] data) + { + this.signature = sig; + this.offset = offset; + this.size = size; + this.data = new byte[size]; + System.arraycopy(data, offset, this.data, 0, size); + } + + public TagEntry(int sig, byte[] data) + { + this.signature = sig; + this.size = data.length; + this.data = new byte[size]; + System.arraycopy(data, offset, this.data, 0, size); + } + + public byte[] getData() + { + byte[] d = new byte[size]; + System.arraycopy(this.data, 0, d, 0, size); + return d; + } + + public String hashKey() + { + return tagHashKey(signature); + } + + public String toString() + { + String s = ""; + s = s + (char) ((byte) ((signature >> 24) & 0xFF)); + s = s + (char) ((byte) ((signature >> 16) & 0xFF)); + s = s + (char) ((byte) ((signature >> 8) & 0xFF)); + s = s + (char) ((byte) (signature & 0xFF)); + return s; + } + + public int getSignature() + { + return signature; + } + + public int getSize() + { + return size; + } + + public int getOffset() + { + return offset; + } + + public void setOffset(int offset) + { + this.offset = offset; + } + + public static String tagHashKey(int sig) + { + return "" + sig; + } +} diff --git a/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java b/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java new file mode 100644 index 0000000..a1bccbd --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java @@ -0,0 +1,177 @@ +/* ToneReproductionCurve.java -- Representation of an ICC 'curv' type TRC + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.color; + + +/** + * ToneReproductionCurve - TRCs are used to describe RGB + * and Grayscale profiles. The TRC is essentially the gamma + * function of the color space. + * + * For example, Apple RGB has a gamma of 1.8, most monitors are ~2.2, + * sRGB is 2.4 with a small linear part near 0. + * Linear spaces are of course 1.0. + * (The exact function is implemented in SrgbConverter) + * + * The ICC specification allows the TRC to be described as a single + * Gamma value, where the function is thus out = in**gamma. + * Alternatively, the gamma function may be represented by a lookup table + * of values, in which case linear interpolation is used. + * + * @author Sven de Marothy + */ +public class ToneReproductionCurve +{ + private float[] trc; + private float gamma; + private float[] reverseTrc; + + /** + * Constructs a TRC from a gamma values + */ + public ToneReproductionCurve(float gamma) + { + trc = null; + reverseTrc = null; + this.gamma = gamma; + } + + /** + * Constructs a TRC from a set of float values + */ + public ToneReproductionCurve(float[] trcValues) + { + trc = new float[trcValues.length]; + System.arraycopy(trcValues, 0, trc, 0, trcValues.length); + setupReverseTrc(); + } + + /** + * Constructs a TRC from a set of short values normalized to + * the 0-65535 range (as in the ICC profile file). + * (Note the values are treated as unsigned) + */ + public ToneReproductionCurve(short[] trcValues) + { + trc = new float[trcValues.length]; + for (int i = 0; i < trcValues.length; i++) + trc[i] = (float) ((int) trcValues[i] & (0xFFFF)) / 65535.0f; + setupReverseTrc(); + } + + /** + * Performs a TRC lookup + */ + public float lookup(float in) + { + float out; + + if (trc == null) + { + if (in == 0f) + return 0.0f; + return (float) Math.exp(gamma * Math.log(in)); + } + else + { + double alpha = in * (trc.length - 1); + int index = (int) Math.floor(alpha); + alpha = alpha - (double) index; + if (index >= trc.length - 1) + return trc[trc.length - 1]; + if (index <= 0) + return trc[0]; + out = (float) (trc[index] * (1.0 - alpha) + trc[index + 1] * alpha); + } + return out; + } + + /** + * Performs an reverse lookup + */ + public float reverseLookup(float in) + { + float out; + + if (trc == null) + { + if (in == 0f) + return 0.0f; + return (float) Math.exp((1.0 / gamma) * Math.log(in)); + } + else + { + double alpha = in * (reverseTrc.length - 1); + int index = (int) Math.floor(alpha); + alpha = alpha - (double) index; + if (index >= reverseTrc.length - 1) + return reverseTrc[reverseTrc.length - 1]; + if (index <= 0) + return reverseTrc[0]; + out = (float) (reverseTrc[index] * (1.0 - alpha) + + reverseTrc[index + 1] * alpha); + } + return out; + } + + /** + * Calculates a reverse-lookup table. + * We use a whopping 10,000 entries.. This is should be more than any + * real-life TRC table (typically around 256-1024) so we won't be losing + * any precision. + * + * This will of course generate completely invalid results if the curve + * is not monotonic and invertable. But what's the alternative? + */ + public void setupReverseTrc() + { + reverseTrc = new float[10000]; + int j = 0; + for (int i = 0; i < 10000; i++) + { + float n = ((float) i) / 10000f; + while (trc[j + 1] < n && j < trc.length - 2) + j++; + + if (j == trc.length - 2) + reverseTrc[i] = trc[trc.length - 1]; + else + reverseTrc[i] = (j + (n - trc[j]) / (trc[j + 1] - trc[j])) / ((float) trc.length); + } + } +} diff --git a/libjava/classpath/gnu/java/awt/color/package.html b/libjava/classpath/gnu/java/awt/color/package.html new file mode 100644 index 0000000..c4705cc --- /dev/null +++ b/libjava/classpath/gnu/java/awt/color/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.awt.color package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.awt.color</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png b/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png Binary files differnew file mode 100644 index 0000000..588c910 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png diff --git a/libjava/classpath/gnu/java/awt/image/ImageDecoder.java b/libjava/classpath/gnu/java/awt/image/ImageDecoder.java new file mode 100644 index 0000000..141c854 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/image/ImageDecoder.java @@ -0,0 +1,156 @@ +/* ImageDecoder.java -- + Copyright (C) 1999, 2000, 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.java.awt.image; + +import java.awt.image.ImageConsumer; +import java.awt.image.ImageProducer; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Vector; + +public abstract class ImageDecoder implements ImageProducer +{ + Vector consumers = new Vector (); + String filename; + URL url; + byte[] data; + int offset; + int length; + InputStream input; + + static + { + // FIXME: there was some broken code here that looked like + // it wanted to rely on this property. I don't have any idea + // what it was intended to do. + // String endian = System.getProperties ().getProperty ("gnu.cpu.endian"); + } + + public ImageDecoder (String filename) + { + this.filename = filename; + } + + public ImageDecoder (URL url) + { + this.url = url; + } + + public ImageDecoder (InputStream is) + { + this.input = is; + } + + public ImageDecoder (byte[] imagedata, int imageoffset, int imagelength) + { + data = imagedata; + offset = imageoffset; + length = imagelength; + } + + public void addConsumer (ImageConsumer ic) + { + consumers.addElement (ic); + } + + public boolean isConsumer (ImageConsumer ic) + { + return consumers.contains (ic); + } + + public void removeConsumer (ImageConsumer ic) + { + consumers.removeElement (ic); + } + + public void startProduction (ImageConsumer ic) + { + if (!isConsumer(ic)) + addConsumer(ic); + + Vector list = (Vector) consumers.clone (); + try + { + // Create the input stream here rather than in the + // ImageDecoder constructors so that exceptions cause + // imageComplete to be called with an appropriate error + // status. + if (input == null) + { + try + { + if (url != null) + input = url.openStream(); + else + { + if (filename != null) + input = new FileInputStream (filename); + else + input = new ByteArrayInputStream (data, offset, length); + } + produce (list, input); + } + finally + { + input = null; + } + } + else + { + produce (list, input); + } + } + catch (Exception e) + { + for (int i = 0; i < list.size (); i++) + { + ImageConsumer ic2 = (ImageConsumer) list.elementAt (i); + ic2.imageComplete (ImageConsumer.IMAGEERROR); + } + } + } + + public void requestTopDownLeftRightResend (ImageConsumer ic) + { + } + + public abstract void produce (Vector v, InputStream is) throws IOException; +} diff --git a/libjava/classpath/gnu/java/awt/image/XBMDecoder.java b/libjava/classpath/gnu/java/awt/image/XBMDecoder.java new file mode 100644 index 0000000..0793d8e --- /dev/null +++ b/libjava/classpath/gnu/java/awt/image/XBMDecoder.java @@ -0,0 +1,155 @@ +/* XBMDecoder.java -- Decodes X-bitmaps + Copyright (C) 1999, 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.java.awt.image; + +import java.awt.image.ColorModel; +import java.awt.image.ImageConsumer; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.StringTokenizer; +import java.util.Vector; + +public class XBMDecoder extends ImageDecoder +{ + BufferedReader reader; + static final ColorModel cm = ColorModel.getRGBdefault (); + static final int black = 0xff000000; + static final int transparent = 0x00000000; + static final int masktable[] = { 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 }; + + public XBMDecoder (String filename) + { + super (filename); + } + + public XBMDecoder (URL url) + { + super (url); + } + + public void produce (Vector v, InputStream is) throws IOException + { + reader = new BufferedReader (new InputStreamReader (is)); + int width = -1, height = -1; + + for (int i = 0; i < 2; i++) + { + String line = reader.readLine (); + StringTokenizer st = new StringTokenizer (line); + + st.nextToken (); // #define + st.nextToken (); // name_[width|height] + if (i == 0) + width = Integer.parseInt (st.nextToken (), 10); + else + height = Integer.parseInt (st.nextToken (), 10); + } + + for (int i = 0; i < v.size (); i++) + { + ImageConsumer ic = (ImageConsumer) v.elementAt (i); + + ic.setDimensions (width, height); + ic.setColorModel (cm); + ic.setHints (ImageConsumer.COMPLETESCANLINES + | ImageConsumer.SINGLEFRAME + | ImageConsumer.SINGLEPASS + | ImageConsumer.TOPDOWNLEFTRIGHT); + } + + /* skip to the byte array */ + while (reader.read () != '{') { } + + /* loop through each scanline */ + for (int line = 0; line < height; line++) + { + int scanline[] = getScanline (reader, width); + + for (int i = 0; i < v.size (); i++) + { + ImageConsumer ic = (ImageConsumer) v.elementAt (i); + ic.setPixels (0, 0 + line, width, 1, cm, scanline, 0, width); + } + } + + /* tell each ImageConsumer that we're finished */ + for (int i = 0; i < v.size (); i++) + { + ImageConsumer ic = (ImageConsumer) v.elementAt (i); + ic.imageComplete (ImageConsumer.STATICIMAGEDONE); + } + } + + public static int[] getScanline (Reader in, int len) throws IOException + { + char byteStr[] = new char[2]; + int scanline[] = new int[len]; + int x = 0; + + while (x < len) + { + int ch = in.read (); + if (ch == '0') + { + in.read (); // 'x' + + byteStr[0] = (char) in.read (); + byteStr[1] = (char) in.read (); + + int byteVal = Integer.parseInt (new String (byteStr), 16); + + for (int i = 0; i < 8; i++, x++) + { + if (x == len) // condition occurs if bitmap is padded + return scanline; + + scanline[x] = ((byteVal & masktable[i]) != 0) ? + black : transparent; + } + } + } + + return scanline; + } +} diff --git a/libjava/classpath/gnu/java/awt/image/package.html b/libjava/classpath/gnu/java/awt/image/package.html new file mode 100644 index 0000000..8823367 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/image/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.awt.image package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.awt.image</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/awt/package.html b/libjava/classpath/gnu/java/awt/package.html new file mode 100644 index 0000000..1661685 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.awt package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.awt</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java new file mode 100644 index 0000000..78ab3a9 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java @@ -0,0 +1,846 @@ +/* ClasspathFontPeer.java -- Font peer used by GNU Classpath. + Copyright (C) 2003, 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.java.awt.peer; + +import gnu.java.awt.ClasspathToolkit; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.font.TextAttribute; +import java.awt.font.TransformAttribute; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.peer.FontPeer; +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * A peer for fonts that are used inside Classpath. The purpose of + * this interface is to abstract from platform-specific font handling + * in the Classpath implementation of java.awt.Font and related + * classes. + * + * <p><b>State kept by the peer:</b> a peer is generated for each Font + * object in the default implementation. If you wish to share peers between + * fonts, you will need to subclass both ClasspathFontPeer and + * {@link ClasspathToolKit}.</p> + * + * <p><b>Thread Safety:</b> Methods of this interface may be called + * from arbitrary threads at any time. Implementations of the + * <code>ClasspathFontPeer</code> interface are required to perform + * the necessary synchronization.</p> + * + * @see java.awt.Font#getPeer + * @see java.awt.Toolkit#getFontPeer + * + * @author Sascha Brawer (brawer@dandelis.ch) + * @author Graydon Hoare (graydon@redhat.com) + */ +public abstract class ClasspathFontPeer + implements FontPeer +{ + + /*************************************************************************/ + + /* + * Instance Variables + */ + + /** + * The 3 names of this font. all fonts have 3 names, some of which + * may be equal: + * + * logical -- name the font was constructed from + * family -- a designer or brand name (Helvetica) + * face -- specific instance of a design (Helvetica Regular) + * + * @see isLogicalFontName + */ + + protected String logicalName; + protected String familyName; + protected String faceName; + + /** + * The font style, which is a combination (by OR-ing) of the font style + * constants PLAIN, BOLD and ITALIC, in this class. + */ + protected int style; + + /** + * The font point size. A point is 1/72 of an inch. + */ + protected float size; + + /** + * The affine transformation the font is currently subject to. + */ + protected AffineTransform transform; + + protected static ClasspathToolkit tk() + { + return (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); + } + + /* + * Confusingly, a Logical Font is a concept unrelated to + * a Font's Logical Name. + * + * A Logical Font is one of 6 built-in, abstract font types + * which must be supported by any java environment: SansSerif, + * Serif, Monospaced, Dialog, and DialogInput. + * + * A Font's Logical Name is the name the font was constructed + * from. This might be the name of a Logical Font, or it might + * be the name of a Font Face. + */ + + protected static boolean isLogicalFontName(String name) + { + String uname = name.toUpperCase (); + return (uname.equals ("SANSSERIF") || + uname.equals ("SERIF") || + uname.equals ("MONOSPACED") || + uname.equals ("DIALOG") || + uname.equals ("DIALOGINPUT")); + } + + protected static String logicalFontNameToFaceName (String name) + { + String uname = name.toUpperCase (); + if (uname.equals("SANSSERIF")) + return "Helvetica"; + else if (uname.equals ("SERIF")) + return "Times"; + else if (uname.equals ("MONOSPACED")) + return "Courier"; + else if (uname.equals ("DIALOG")) + return "Helvetica"; + else if (uname.equals ("DIALOGINPUT")) + return "Helvetica"; + else + return "Helvetica"; + } + + protected static String faceNameToFamilyName (String name) + { + return name; + } + + public static void copyStyleToAttrs (int style, Map attrs) + { + if ((style & Font.BOLD) == Font.BOLD) + attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); + else + attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR); + + if ((style & Font.ITALIC) == Font.ITALIC) + attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); + else + attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR); + } + + protected static void copyFamilyToAttrs (String fam, Map attrs) + { + if (fam != null) + attrs.put (TextAttribute.FAMILY, fam); + } + + public static void copySizeToAttrs (float size, Map attrs) + { + attrs.put (TextAttribute.SIZE, new Float (size)); + } + + protected static void copyTransformToAttrs (AffineTransform trans, Map attrs) + { + if (trans != null) + attrs.put(TextAttribute.TRANSFORM, new TransformAttribute (trans)); + } + + + protected void setStandardAttributes (String name, String family, int style, + float size, AffineTransform trans) + { + this.logicalName = name; + + if (isLogicalFontName (name)) + this.faceName = logicalFontNameToFaceName (name); + else + this.faceName = name; + + if (family != null) + this.familyName = family; + else + this.familyName = faceNameToFamilyName (faceName); + + this.style = style; + this.size = size; + this.transform = trans; + } + + + protected void setStandardAttributes (String name, Map attribs) + { + String family = this.familyName; + AffineTransform trans = this.transform; + float size = this.size; + int style = this.style; + + if (attribs.containsKey (TextAttribute.FAMILY)) + family = (String) attribs.get (TextAttribute.FAMILY); + + if (name == null) + name = "SansSerif"; + + if (attribs.containsKey (TextAttribute.WEIGHT)) + { + Float weight = (Float) attribs.get (TextAttribute.WEIGHT); + if (weight.floatValue () >= TextAttribute.WEIGHT_BOLD.floatValue ()) + style += Font.BOLD; + } + + if (attribs.containsKey (TextAttribute.POSTURE)) + { + Float posture = (Float) attribs.get (TextAttribute.POSTURE); + if (posture.floatValue () >= TextAttribute.POSTURE_OBLIQUE.floatValue ()) + style += Font.ITALIC; + } + + if (attribs.containsKey (TextAttribute.SIZE)) + { + Float sz = (Float) attribs.get (TextAttribute.SIZE); + size = sz.floatValue (); + + // Pango doesn't accept 0 as a font size. + if (size < 1) + size = 1; + } + else + size = 12; + + if (attribs.containsKey (TextAttribute.TRANSFORM)) + { + TransformAttribute ta = (TransformAttribute) + attribs.get(TextAttribute.TRANSFORM); + trans = ta.getTransform (); + } + + setStandardAttributes (name, family, style, size, trans); + } + + protected void getStandardAttributes (Map attrs) + { + copyFamilyToAttrs (this.familyName, attrs); + copySizeToAttrs (this.size, attrs); + copyStyleToAttrs (this.style, attrs); + copyTransformToAttrs (this.transform, attrs); + } + + + /* Begin public API */ + + public ClasspathFontPeer (String name, Map attrs) + { + setStandardAttributes (name, attrs); + } + + public ClasspathFontPeer (String name, int style, int size) + { + setStandardAttributes (name, (String)null, style, + (float)size, (AffineTransform)null); + } + + /** + * Implementation of {@link Font#getName} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public String getName (Font font) + { + return logicalName; + } + + /** + * Implementation of {@link Font#getFamily()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public String getFamily (Font font) + { + return familyName; + } + + /** + * Implementation of {@link Font#getFamily(Locale)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public String getFamily (Font font, Locale lc) + { + return familyName; + } + + /** + * Implementation of {@link Font#getFontName()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public String getFontName (Font font) + { + return faceName; + } + + /** + * Implementation of {@link Font#getFontName(Locale)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public String getFontName (Font font, Locale lc) + { + return faceName; + } + + /** + * Implementation of {@link Font#getSize} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public float getSize (Font font) + { + return size; + } + + /** + * Implementation of {@link Font#isPlain} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public boolean isPlain (Font font) + { + return style == Font.PLAIN; + } + + /** + * Implementation of {@link Font#isBold} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public boolean isBold (Font font) + { + return ((style & Font.BOLD) == Font.BOLD); + } + + /** + * Implementation of {@link Font#isItalic} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public boolean isItalic (Font font) + { + return ((style & Font.ITALIC) == Font.ITALIC); + } + + /** + * Implementation of {@link Font#deriveFont(int, float)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, int style, float size) + { + Map attrs = new HashMap (); + getStandardAttributes (attrs); + copyStyleToAttrs (style, attrs); + copySizeToAttrs (size, attrs); + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#deriveFont(float)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, float size) + { + Map attrs = new HashMap (); + getStandardAttributes (attrs); + copySizeToAttrs (size, attrs); + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#deriveFont(int)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, int style) + { + Map attrs = new HashMap (); + getStandardAttributes (attrs); + copyStyleToAttrs (style, attrs); + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#deriveFont(int, AffineTransform)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, int style, AffineTransform t) + { + Map attrs = new HashMap (); + getStandardAttributes (attrs); + copyStyleToAttrs (style, attrs); + copyTransformToAttrs (t, attrs); + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#deriveFont(AffineTransform)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, AffineTransform t) + { + Map attrs = new HashMap (); + getStandardAttributes (attrs); + copyTransformToAttrs (t, attrs); + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#deriveFont(Map)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Font deriveFont (Font font, Map attrs) + { + return tk().getFont (logicalName, attrs); + } + + /** + * Implementation of {@link Font#getAttributes()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public Map getAttributes (Font font) + { + HashMap h = new HashMap (); + getStandardAttributes (h); + return h; + } + + /** + * Implementation of {@link Font#getAvailableAttributes()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public AttributedCharacterIterator.Attribute[] getAvailableAttributes(Font font) + { + AttributedCharacterIterator.Attribute a[] = + new AttributedCharacterIterator.Attribute[5]; + a[0] = TextAttribute.FAMILY; + a[1] = TextAttribute.SIZE; + a[2] = TextAttribute.POSTURE; + a[3] = TextAttribute.WEIGHT; + a[4] = TextAttribute.TRANSFORM; + return a; + } + + /** + * Implementation of {@link Font#getTransform()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public AffineTransform getTransform (Font font) + { + if (transform == null) + transform = new AffineTransform (); + return transform; + } + + /** + * Implementation of {@link Font#isTransformed()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public boolean isTransformed (Font font) + { + return ! transform.isIdentity (); + } + + /** + * Implementation of {@link Font#getItalicAngle()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public float getItalicAngle (Font font) + { + if ((style & Font.ITALIC) == Font.ITALIC) + return TextAttribute.POSTURE_OBLIQUE.floatValue (); + else + return TextAttribute.POSTURE_REGULAR.floatValue (); + } + + + /** + * Implementation of {@link Font#getStyle()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public int getStyle (Font font) + { + return style; + } + + + + + /* Remaining methods are abstract */ + + /** + * Implementation of {@link Font#canDisplay(char)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract boolean canDisplay (Font font, char c); + + /** + * Implementation of {@link Font#canDisplay(String)}, + * {@link Font#canDisplay(char [], int, int)}, and + * {@link Font#canDisplay(CharacterIterator, int, int)}. + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit); + + + /** + * Returns the name of this font face inside the family, for example + * <i>“Light”</i>. + * + * <p>This method is currently not used by {@link Font}. However, + * this name would be needed by any serious desktop publishing + * application. + * + * @param font the font whose sub-family name is requested. + * + * @param locale the locale for which to localize the name. If + * <code>locale</code> is <code>null</code>, the returned name is + * localized to the user’s default locale. + * + * @return the name of the face inside its family, or + * <code>null</code> if the font does not provide a sub-family name. + */ + + public abstract String getSubFamilyName (Font font, Locale locale); + + + /** + * Implementation of {@link Font#getPSName()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract String getPostScriptName (Font font); + + + /** + * Implementation of {@link Font#getNumGlyphs()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract int getNumGlyphs (Font font); + + + /** + * Implementation of {@link Font#getMissingGlyphCode()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract int getMissingGlyphCode (Font font); + + + /** + * Implementation of {@link Font#getBaselineFor(char)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract byte getBaselineFor (Font font, char c); + + + /** + * Returns a name for the specified glyph. This is useful for + * generating PostScript or PDF files that embed some glyphs of a + * font. If the implementation follows glyph naming conventions + * specified by Adobe, search engines can extract the original text + * from the generated PostScript and PDF files. + * + * <p>This method is currently not used by GNU Classpath. However, + * it would be very useful for someone wishing to write a good + * PostScript or PDF stream provider for the + * <code>javax.print</code> package. + * + * <p><b>Names are not unique:</b> Under some rare circumstances, + * the same name can be returned for different glyphs. It is + * therefore recommended that printer drivers check whether the same + * name has already been returned for antoher glyph, and make the + * name unique by adding the string ".alt" followed by the glyph + * index.</p> + * + * <p>This situation would occur for an OpenType or TrueType font + * that has a <code>post</code> table of format 3 and provides a + * mapping from glyph IDs to Unicode sequences through a + * <code>Zapf</code> table. If the same sequence of Unicode + * codepoints leads to different glyphs (depending on contextual + * position, for example, or on typographic sophistication level), + * the same name would get synthesized for those glyphs. To avoid + * this, the font peer would have to go through the names of all + * glyphs, which would make this operation very inefficient with + * large fonts. + * + * @param font the font containing the glyph whose name is + * requested. + * + * @param glyphIndex the glyph whose name the caller wants to + * retrieve. + * + * @return the glyph name, or <code>null</code> if a font does not + * provide glyph names. + */ + + public abstract String getGlyphName (Font font, int glyphIndex); + + + /** + * Implementation of {@link + * Font#createGlyphVector(FontRenderContext, String)}, {@link + * Font#createGlyphVector(FontRenderContext, char[])}, and {@link + * Font#createGlyphVector(FontRenderContext, CharacterIterator)}. + * + * @param font the font object that the created GlyphVector will return + * when it gets asked for its font. This argument is needed because the + * public API of {@link GlyphVector} works with {@link java.awt.Font}, + * not with font peers. + */ + + public abstract GlyphVector createGlyphVector (Font font, + FontRenderContext frc, + CharacterIterator ci); + + + /** + * Implementation of {@link Font#createGlyphVector(FontRenderContext, + * int[])}. + * + * @param font the font object that the created GlyphVector will return + * when it gets asked for its font. This argument is needed because the + * public API of {@link GlyphVector} works with {@link java.awt.Font}, + * not with font peers. + */ + + public abstract GlyphVector createGlyphVector (Font font, + FontRenderContext ctx, + int[] glyphCodes); + + + /** + * Implementation of {@link Font#layoutGlyphVector(FontRenderContext, + * char[], int, int, int)}. + * + * @param font the font object that the created GlyphVector will return + * when it gets asked for its font. This argument is needed because the + * public API of {@link GlyphVector} works with {@link java.awt.Font}, + * not with font peers. + */ + + public abstract GlyphVector layoutGlyphVector (Font font, + FontRenderContext frc, + char[] chars, int start, + int limit, int flags); + + + /** + * Implementation of {@link Font#getFontMetrics()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract FontMetrics getFontMetrics (Font font); + + + /** + * Implementation of {@link Font#hasUniformLineMetrics()} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract boolean hasUniformLineMetrics (Font font); + + + /** + * Implementation of {@link Font#getLineMetrics(CharacterIterator, int, + * int, FontRenderContext)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract LineMetrics getLineMetrics (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext rc); + + /** + * Implementation of {@link Font#getMaxCharBounds(FontRenderContext)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract Rectangle2D getMaxCharBounds (Font font, + FontRenderContext rc); + + /** + * Implementation of {@link Font#getStringBounds(CharacterIterator, int, + * int, FontRenderContext)} + * + * @param font the font this peer is being called from. This may be + * useful if you are sharing peers between Font objects. Otherwise it may + * be ignored. + */ + + public abstract Rectangle2D getStringBounds (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext frc); + +} diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java new file mode 100644 index 0000000..70df2ef --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java @@ -0,0 +1,104 @@ +/* ClasspathTextLayoutPeer.java + Copyright (C) 2003 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.java.awt.peer; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.font.TextHitInfo; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +/** + * @author Graydon Hoare + */ + +public interface ClasspathTextLayoutPeer +{ + TextHitInfo getStrongCaret (TextHitInfo hit1, + TextHitInfo hit2); + + void draw (Graphics2D g2, float x, float y); + + byte getBaseline (); + + boolean isLeftToRight (); + boolean isVertical (); + + float getAdvance (); + float getAscent (); + float getDescent (); + float getLeading (); + + int getCharacterCount (); + byte getCharacterLevel (int index); + + float[] getBaselineOffsets (); + Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint); + Rectangle2D getBounds (); + + float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds); + Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds); + Shape[] getCaretShapes (int offset, Rectangle2D bounds, + TextLayout.CaretPolicy policy); + + Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, + Rectangle2D bounds); + int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint); + + TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy); + TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy); + TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds); + TextHitInfo getVisualOtherHit (TextHitInfo hit); + + float getVisibleAdvance (); + Shape getOutline (AffineTransform tx); + Shape getVisualHighlightShape (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint, + Rectangle2D bounds); + + TextLayout getJustifiedLayout (float justificationWidth); + void handleJustify (float justificationWidth); + + Object clone (); + int hashCode (); + boolean equals (ClasspathTextLayoutPeer tl); + String toString (); +} diff --git a/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java new file mode 100644 index 0000000..4c64a1d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java @@ -0,0 +1,47 @@ +/* EmbeddedWindowPeer.java -- Interface for window peers that may be + embedded into other applications + Copyright (C) 2003 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.java.awt.peer; + +import java.awt.peer.FramePeer; + +public interface EmbeddedWindowPeer extends FramePeer +{ + void embed (long handle); +} diff --git a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java new file mode 100644 index 0000000..3bcaebc --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java @@ -0,0 +1,298 @@ +/* GLightweightPeer.java -- + Copyright (C) 2003, 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.java.awt.peer; + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.PaintEvent; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.VolatileImage; +import java.awt.peer.ContainerPeer; +import java.awt.peer.LightweightPeer; + +/* + * Another possible implementation strategy for lightweight peers is + * to make GLightweightPeer a placeholder class that implements + * LightweightPeer. Then the Component and Container classes could + * identify a peer as lightweight and handle it specially. The + * current approach is probably more clear but less efficient. + */ + +/** + * A stub class that implements the ComponentPeer and ContainerPeer + * interfaces using callbacks into the Component and Container + * classes. GLightweightPeer allows the Component and Container + * classes to treat lightweight and heavyweight peers in the same way. + * + * Lightweight components are painted directly onto their parent + * containers through an Image object provided by the toolkit. + */ +public class GLightweightPeer + implements LightweightPeer, ContainerPeer +{ + private Component comp; + + private Insets containerInsets; + + public GLightweightPeer(Component comp) + { + this.comp = comp; + } + + // -------- java.awt.peer.ContainerPeer implementation: + + public Insets insets() + { + return getInsets (); + } + + public Insets getInsets() + { + if (containerInsets == null) + containerInsets = new Insets (0,0,0,0); + return containerInsets; + } + + public void beginValidate() + { + } + + public void endValidate() + { + } + + public void beginLayout() + { + } + + public void endLayout() + { + } + + public boolean isPaintPending() + { + return false; + } + + // -------- java.awt.peer.ComponentPeer implementation: + + public int checkImage(Image img, int width, int height, ImageObserver o) + { + return comp.getToolkit().checkImage(img, width, height, o); + } + + public Image createImage(ImageProducer prod) + { + return comp.getToolkit().createImage(prod); + } + + /* This method is not called. */ + public Image createImage(int width, int height) + { + return null; + } + + public void disable() {} + + public void dispose() {} + + public void enable() {} + + public GraphicsConfiguration getGraphicsConfiguration() + { + return null; + } + + public FontMetrics getFontMetrics(Font f) + { + return comp.getToolkit().getFontMetrics(f); + } + + /* Returning null here tells the Component object that called us to + * use its parent's Graphics. */ + public Graphics getGraphics() + { + return null; + } + + public Point getLocationOnScreen() + { + Point parentLocation = comp.getParent().getLocationOnScreen(); + return new Point (parentLocation.x + comp.getX(), + parentLocation.y + comp.getY()); + } + + public Dimension getMinimumSize() + { + return new Dimension(comp.getWidth(), comp.getHeight()); + } + + /* A lightweight component's preferred size is equivalent to its + * Component width and height values. */ + public Dimension getPreferredSize() + { + return new Dimension(comp.getWidth(), comp.getHeight()); + } + + /* Returning null here tells the Component object that called us to + * use its parent's Toolkit. */ + public Toolkit getToolkit() + { + return null; + } + + public void handleEvent(AWTEvent e) {} + + public void hide() {} + + public boolean isFocusable() + { + return false; + } + + public boolean isFocusTraversable() + { + return false; + } + + public Dimension minimumSize() + { + return getMinimumSize(); + } + + public Dimension preferredSize() + { + return getPreferredSize(); + } + + public void paint(Graphics graphics) {} + + public boolean prepareImage(Image img, int width, int height, + ImageObserver o) + { + return comp.getToolkit().prepareImage(img, width, height, o); + } + + public void print(Graphics graphics) {} + + public void repaint(long tm, int x, int y, int width, int height) {} + + public void requestFocus() {} + + public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x) + { + return false; + } + + public void reshape(int x, int y, int width, int height) {} + + public void setBackground(Color color) {} + + public void setBounds(int x, int y, int width, int height) {} + + public void setCursor(Cursor cursor) {} + + public void setEnabled(boolean enabled) {} + + public void setEventMask(long eventMask) {} + + public void setFont(Font font) {} + + public void setForeground(Color color) {} + + public void setVisible(boolean visible) {} + + public void show() {} + + public ColorModel getColorModel () + { + return comp.getColorModel (); + } + + public boolean isObscured() + { + return false; + } + + public boolean canDetermineObscurity() + { + return false; + } + + public void coalescePaintEvent(PaintEvent e) { } + + public void updateCursorImmediately() { } + + public VolatileImage createVolatileImage(int width, int height) + { + return null; + } + + public boolean handlesWheelScrolling() + { + return false; + } + + public void createBuffers(int x, BufferCapabilities capabilities) + throws AWTException { } + + public Image getBackBuffer() + { + return null; + } + + public void flip(BufferCapabilities.FlipContents contents) { } + + public void destroyBuffers() { } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java new file mode 100644 index 0000000..e73df9e --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java @@ -0,0 +1,109 @@ +/* GThreadMutex.java -- Implements a mutex object for glib's gthread + abstraction, for use with GNU Classpath's --portable-native-sync option. + This is used in gthread-jni.c + + Copyright (C) 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.java.awt.peer.gtk; + +/** Implements a mutex object for glib's gthread + abstraction, for use with GNU Classpath's --portable-native-sync option. + This is used in gthread-jni.c. + + We use this object to implement the POSIX semantics for Mutexes. They are + needed are needed for the function vector that is passed to glib's + g_thread subpackage's initialization function. + + The GThreadMutex object itself serves as the Real Lock; if code has + entered the monitor for this GThreadMutex object (in Java language, if + it's synchronized on this object) then it holds the lock that this object + represents. + + @author Steven Augart + May, 2004 + + +*/ + +class GThreadMutex +{ + /** Might "lock" be locked? Is anyone waiting + to get that lock? How long is the queue? + + If zero, nobody holds a lock on this GThreadMutex object, and nobody is + trying to get one. Before someone attempts to acquire a lock on this + object, they must increment potentialLockers. After they release their + lock on this object, they must decrement potentialLockers. + + Access to this field is guarded by synchronizing on the object + <code>lockForPotentialLockers</code>. + + After construction, we only access this field via JNI. + */ + volatile int potentialLockers; + + /** An object to synchronize to if you want to examine or modify the + <code>potentialLockers</code> field. Only hold this lock for brief + moments, just long enough to check or set the value of + <code>lockForPotentialLockers</code>. + + We use this representation so that g_thread_mutex_trylock() will work + with the POSIX semantics. This is the only case in which you ever hold a + lock on <code>lockForPotentialLockers</code> while trying to get another + lock -- if you are the mutex_trylock() implementation, and you have just + checked that <code>potentialLockers</code> has the value zero. In that + case, mutex_trylock() holds the lock on lockForPotentialLockers so that + another thread calling mutex_trylock() or mutex_lock() won't increment + potentialLockers after we've checked it and before we've gained the lock + on the POSIX mutex. Of course, in that case the operation of gaining + the POSIX lock itself will succeed immediately, and once it has + succeeded, trylock releases lockForPotentialLockers right away, + incremented to 1 (one). + + After construction, we only access this field via JNI. + */ + Object lockForPotentialLockers; + + GThreadMutex() + { + potentialLockers = 0; + lockForPotentialLockers = new Object(); + } +} +// Local Variables: +// c-file-style: "gnu" +// End: diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java new file mode 100644 index 0000000..9a1b8e3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java @@ -0,0 +1,303 @@ +/* GThreadNativeMethodRunner.java -- Implements pthread_create(), under + glib's gthread abstraction, for use with GNU Classpath's + --portable-native-sync option. + This is used by gthread-jni.c + + Copyright (C) 2004, 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.java.awt.peer.gtk; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** Implements pthread_create(), under glib's gthread abstraction, for use + with GNU Classpath's --portable-native-sync option. This is used in + gthread-jni.c + + Also implements a registry for threads, mapping Thread objects to small + integers. The registry uses weak references for threads that aren't + joinable, so that they will be garbage collected. + + There are a number of possible alternative implementations. + + + The rest of this comment consists of an answer to a question that was + raised on the commit-classpath mailing list: + + Mark Wielaard wrote: + + > Can't we assume that jobject and gpointer are both (void *) so we don't + > need the int <-> Thread (global jobject ref) mapping? + > Maybe there are platforms where jobject and gpointer aren't the same, + > but I guess that is pretty unlikely. + + + I agree with you on the pointer size issues. A gpointer is a void *, so + it's certainly guaranteed to be at least as large as any other + pointer. And a jobject is implicitly an opaque pointer (in Jikes RVM, we + use small integers, but we coerce them into the representation of a + pointer). + + The int <==> Thread mapping addresses a different issue. I realize that I + did not document this properly (two and a half lines in thread_create), + and the point is subtle (at least to me; took me a while to figure out). + + The int => Thread mapping always returns jobjects that are local + references, not global ones. This is because Thread objects need to be + able to go away and be garbage collected after the thread they refer to + has died. + + If we keep a global object reference to a thread, then when do we delete + that global object reference? We have an answer in the case of GThread + objects that were explicitly created with the joinable attribute. It is + safe for us to maintain a global reference to any joinable thread, since + the joinable thread must linger (even if only in a zombie state) + until it's explicitly joined via a g_thread_join() call. The global ref + could be cleaned up at that point too. + + However, in the case of GThreads that were created non-joinable by + g_thread_create(), and in the case of Java threads that were created + within pure Java code (not via g_thread_create()), we don't want them to + linger forever, and there is no way to tell when the last reference + to such threads needs to expire. In the case of this application -- AWT + with GTK peers -- it would probably be safe anyway, since there are not + very many threads we create, but I was going for correctness even in the + case of long-running programs that might set up and tear down AWT + interfaces many times. + + So, I duplicated the POSIX thread-ID semantics. The thread ID of a + non-joinable thread remains valid as long as that thread is still alive. + Once that thread dies, the old thread ID may be reused at any moment. And + that's why the array indexed by thread ID numbers is an array of weak + references. + + That's also why the int => Thread jobject mapping function always returns + local references, since global references would lock the Thread in memory + forever. + + I would dearly love there to be a cleaner solution. I dislike the + repeated dips from C code into Java that are necessary to look up thread + ID numbers. If anyone can think of one, I'm all ears. +*/ + +class GThreadNativeMethodRunner + extends Thread +{ + /** The C function pointer that was passed to g_thread_create(). + Specifically, this the numeric address of an object of + C type "void *(*funcPtr)(void *funcArg)". + */ + private final long funcPtr; + + /** The argument for the function "funcPtr(funcArg)". */ + private final long funcArg; + + GThreadNativeMethodRunner(long funcPtr, long funcArg, boolean joinable) + { + this.funcPtr = funcPtr; + this.funcArg = funcArg; + + if (joinable) + registerSelfJoinable(); + } + + public void run() + { + nativeRun(funcPtr, funcArg); + } + + private native void nativeRun(long funcPtr, long funcArg); + + /** THREADS is an array of threads, indexed by thread ID codes. Not sure + whether this is the "best" approach but it does make it O(1) to look up a + thread by its ID. + + Zero is a valid thread ID code. Any negative number is invalid. + + Possible future fixes (TODO?) + + - The THREADS array will only grow. probably not a problem. + But we could keep count when nulling entries and shrink when we have + lots of nulls at the end. Probably not worth it. --mjw + + - Could make this a set of Object; see the comment on "joinable" below. + + The initial size of 17 is just a starting point. Any number will do, + including zero. + */ + private static WeakReference[] threads = new WeakReference[17]; + + /** Used by threadToThreadID, below. Returns the registration number of + the newly-registered thread. + */ + private static synchronized int registerThread(Thread t) + { + int i; + + for (i = 0; i < threads.length; ++i) + { + WeakReference ref = threads[i]; + if (ref == null) + break; // found an empty spot. + } + + if (i == threads.length) + { + /* expand the array */ + WeakReference[] bigger = new WeakReference[threads.length * 2]; + System.arraycopy(threads, 0, bigger, 0, threads.length); + threads = bigger; + } + + threads[i] = new WeakReference(t); + + return i; + } + + /** Look up the Thread ID # for a Thread. Assign a Thread ID # if none + exists. This is a general routine for handling all threads, including + the VM's main thread, if appropriate. + + + Runs in O(n/2) time. + + We can't just issue a threadID upon thread creation. If we were to do + that, not all threads would have a threadID, because not all threads + are launched by GThreadNativeMethodRunner. + */ + static synchronized int threadToThreadID(Thread t) + { + for (int i = 0; i < threads.length; ++i ) + { + if (threads[i] == null) + continue; + Thread referent = (Thread) threads[i].get(); + if (referent == null) + { + threads[i] = null; // Purge the dead WeakReference. + continue; + } + if (referent.equals(t)) + return i; + } // for() + + /* No match found. */ + return registerThread(t); + } + + /** @param threadID Must be a non-negative integer. + + Used to return null if the thread number was out of range or if + the thread was unregistered. Now we throw an exception. + + Possible Alternative Interface: We could go back to returning null in + some sort of check-free mode, so code that calls this function must + be prepared to get null. + */ + static Thread threadIDToThread(int threadID) + throws IllegalArgumentException + { + if (threadID < 0) + throw new IllegalArgumentException("Received a negative threadID, " + + threadID); + if (threadID >= threads.length) + throw new IllegalArgumentException("Received a threadID (" + threadID + + ") higher than was" + + " ever issued"); + + /* Note: if the user is using a stale reference, things will just + break. We might end up getting a different thread than the one + expected. + + TODO: Add an error-checking mode where the user's problems with threads + are announced. For instance, if the user asks for the thread + associated with a threadID that was never issued, we could print a + warning or even abort. + + TODO: Consider optionally disabling all of the error-checking we + already have; it probably slows down the implementation. We could + just return NULL. This is just the reverse of the above TODO item. + */ + + WeakReference threadRef = threads[threadID]; + + if (threadRef == null) + throw new IllegalArgumentException("Asked to look up a stale or unissued" + + "threadID (" + threadID + ")" ); + + + Thread referent = (Thread) threadRef.get(); + if (referent == null) + throw new IllegalArgumentException ("Asked to look up a stale threadID (" + + threadID + ")"); + return referent; + } + + /** Joinable threads need a hard reference, so that they won't go away when + they die. That is because their thread IDs need to stay valid until the + thread is joined via thread_join(threadID). Joinable threads have to be + explicitly joined before they are allowed to go away completely. + + Possible Alternative Implementation: Eliminate the Joinable set. When + calling getThreadIDFromThread() you know whether or not the thread + is joinable. So just store the Thread itself in the threads array? + Make that array an Object array and check with instanceof. This + looks cleaner and more robust to me and it saves a native -> Java + call. But instanceof might be expensive. --mjw + */ + private static final Set joinable = + Collections.synchronizedSet(new HashSet()); + + /** Only called from the constructor. */ + private void registerSelfJoinable() + { + joinable.add(this); + } + + /** This method is only called from JNI, and only after we have succeeded in + a thread_join() operation. */ + static void deRegisterJoinable(Thread thread) + { + joinable.remove(thread); + } +} + +// Local Variables: +// c-file-style: "gnu" +// End: diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java new file mode 100644 index 0000000..7a439e8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java @@ -0,0 +1,134 @@ +/* GdkFontMetrics.java + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import gnu.java.awt.ClasspathToolkit; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Toolkit; + +public class GdkFontMetrics extends FontMetrics +{ + + private int[] font_metrics; + GdkFontPeer peer; + + static final int FONT_METRICS_ASCENT = 0; + static final int FONT_METRICS_MAX_ASCENT = 1; + static final int FONT_METRICS_DESCENT = 2; + static final int FONT_METRICS_MAX_DESCENT = 3; + static final int FONT_METRICS_MAX_ADVANCE = 4; + + static final int TEXT_METRICS_X_BEARING = 0; + static final int TEXT_METRICS_Y_BEARING = 1; + static final int TEXT_METRICS_WIDTH = 2; + static final int TEXT_METRICS_HEIGHT = 3; + static final int TEXT_METRICS_X_ADVANCE = 4; + static final int TEXT_METRICS_Y_ADVANCE = 5; + + + public GdkFontMetrics (Font font) + { + super (font.getPeer() instanceof GdkFontPeer + ? font + : ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) + .getFont (font.getName(), font.getAttributes ())); + + peer = (GdkFontPeer) this.font.getPeer(); + + font_metrics = new int[5]; + double [] hires = new double[5]; + peer.getFontMetrics (hires); + for (int i = 0; i < 5; ++i) + font_metrics[i] = (int) hires[i]; + } + + public int stringWidth (String str) + { + double [] hires = new double[6]; + peer.getTextMetrics(str, hires); + return (int) hires [TEXT_METRICS_WIDTH]; + } + + public int charWidth (char ch) + { + return stringWidth (new String (new char[] { ch })); + } + + public int charsWidth (char data[], int off, int len) + { + return stringWidth (new String (data, off, len)); + } + + /* + Sun's Motif implementation always returns 0 or 1 here (???), but + going by the X11 man pages, it seems as though we should return + font.ascent + font.descent. + */ + public int getLeading () + { + return 1; + } + + public int getAscent () + { + return font_metrics[FONT_METRICS_ASCENT]; + } + + public int getMaxAscent () + { + return font_metrics[FONT_METRICS_MAX_ASCENT]; + } + + public int getDescent () + { + return font_metrics[FONT_METRICS_DESCENT]; + } + + public int getMaxDescent () + { + return font_metrics[FONT_METRICS_MAX_DESCENT]; + } + + public int getMaxAdvance () + { + return font_metrics[FONT_METRICS_MAX_ADVANCE]; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java new file mode 100644 index 0000000..c6d42b3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -0,0 +1,307 @@ +/* GdkFontPeer.java -- Implements FontPeer with GTK+ + Copyright (C) 1999, 2004, 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.java.awt.peer.gtk; + +import gnu.classpath.Configuration; +import gnu.java.awt.peer.ClasspathFontPeer; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; + +public class GdkFontPeer extends ClasspathFontPeer +{ + static native void initStaticState(); + private final int native_state = GtkGenericPeer.getUniqueInteger (); + private static ResourceBundle bundle; + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("gtkpeer"); + } + + initStaticState (); + + try + { + bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font"); + } + catch (Throwable ignored) + { + bundle = null; + } + } + + private native void initState (); + private native void dispose (); + private native void setFont (String family, int style, int size, boolean useGraphics2D); + + native void getFontMetrics(double [] metrics); + native void getTextMetrics(String str, double [] metrics); + + protected void finalize () + { + if (GtkToolkit.useGraphics2D ()) + GdkGraphics2D.releasePeerGraphicsResource(this); + dispose (); + } + + /* + * Helpers for the 3-way overloading that this class seems to suffer + * from. Remove them if you feel like they're a performance bottleneck, + * for the time being I prefer my code not be written and debugged in + * triplicate. + */ + + private String buildString(CharacterIterator iter) + { + StringBuffer sb = new StringBuffer(); + for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) + sb.append(c); + return sb.toString(); + } + + private String buildString(CharacterIterator iter, int begin, int limit) + { + StringBuffer sb = new StringBuffer(); + int i = 0; + for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next(), i++) + { + if (begin <= i) + sb.append(c); + if (limit <= i) + break; + } + return sb.toString(); + } + + private String buildString(char[] chars, int begin, int limit) + { + return new String(chars, begin, limit - begin); + } + + /* Public API */ + + public GdkFontPeer (String name, int style) + { + // All fonts get a default size of 12 if size is not specified. + this(name, style, 12); + } + + public GdkFontPeer (String name, int style, int size) + { + super(name, style, size); + initState (); + setFont (this.familyName, this.style, (int)this.size, + GtkToolkit.useGraphics2D()); + } + + public GdkFontPeer (String name, Map attributes) + { + super(name, attributes); + initState (); + setFont (this.familyName, this.style, (int)this.size, + GtkToolkit.useGraphics2D()); + } + + public String getSubFamilyName(Font font, Locale locale) + { + return null; + } + + public String getPostScriptName(Font font) + { + return null; + } + + public boolean canDisplay (Font font, char c) + { + // FIXME: inquire with pango + return true; + } + + public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) + { + // FIXME: inquire with pango + return -1; + } + + private native GdkGlyphVector getGlyphVector(String txt, + Font f, + FontRenderContext ctx); + + public GlyphVector createGlyphVector (Font font, + FontRenderContext ctx, + CharacterIterator i) + { + return getGlyphVector(buildString (i), font, ctx); + } + + public GlyphVector createGlyphVector (Font font, + FontRenderContext ctx, + int[] glyphCodes) + { + return null; + // return new GdkGlyphVector (font, this, ctx, glyphCodes); + } + + public byte getBaselineFor (Font font, char c) + { + throw new UnsupportedOperationException (); + } + + protected class GdkFontLineMetrics extends LineMetrics + { + FontMetrics fm; + int nchars; + + public GdkFontLineMetrics (FontMetrics m, int n) + { + fm = m; + nchars = n; + } + + public float getAscent() + { + return (float) fm.getAscent (); + } + + public int getBaselineIndex() + { + return Font.ROMAN_BASELINE; + } + + public float[] getBaselineOffsets() + { + return new float[3]; + } + + public float getDescent() + { + return (float) fm.getDescent (); + } + + public float getHeight() + { + return (float) fm.getHeight (); + } + + public float getLeading() { return 0.f; } + public int getNumChars() { return nchars; } + public float getStrikethroughOffset() { return 0.f; } + public float getStrikethroughThickness() { return 0.f; } + public float getUnderlineOffset() { return 0.f; } + public float getUnderlineThickness() { return 0.f; } + + } + + public LineMetrics getLineMetrics (Font font, CharacterIterator ci, + int begin, int limit, FontRenderContext rc) + { + return new GdkFontLineMetrics (getFontMetrics (font), limit - begin); + } + + public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc) + { + throw new UnsupportedOperationException (); + } + + public int getMissingGlyphCode (Font font) + { + throw new UnsupportedOperationException (); + } + + public String getGlyphName (Font font, int glyphIndex) + { + throw new UnsupportedOperationException (); + } + + public int getNumGlyphs (Font font) + { + throw new UnsupportedOperationException (); + } + + public Rectangle2D getStringBounds (Font font, CharacterIterator ci, + int begin, int limit, FontRenderContext frc) + { + GdkGlyphVector gv = getGlyphVector(buildString (ci, begin, limit), font, frc); + return gv.getVisualBounds(); + } + + public boolean hasUniformLineMetrics (Font font) + { + return true; + } + + public GlyphVector layoutGlyphVector (Font font, FontRenderContext frc, + char[] chars, int start, int limit, + int flags) + { + int nchars = (limit - start) + 1; + char[] nc = new char[nchars]; + + for (int i = 0; i < nchars; ++i) + nc[i] = chars[start + i]; + + return createGlyphVector (font, frc, + new StringCharacterIterator (new String (nc))); + } + + public LineMetrics getLineMetrics (Font font, String str, + FontRenderContext frc) + { + return new GdkFontLineMetrics (getFontMetrics (font), str.length ()); + } + + public FontMetrics getFontMetrics (Font font) + { + return new GdkFontMetrics (font); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java new file mode 100644 index 0000000..f0ddea4 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java @@ -0,0 +1,359 @@ +/* GdkGlyphVector.java -- Glyph vector object + Copyright (C) 2003, 2004, 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.java.awt.peer.gtk; + +import java.awt.Font; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphJustificationInfo; +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +public class GdkGlyphVector extends GlyphVector +{ + + /* We use a simple representation for glyph vectors here. Glyph i + * consumes 8 doubles: + * + * logical x: extents[ 10*i ] + * logical y: extents[ 10*i + 1 ] + * logical width: extents[ 10*i + 2 ] + * logical height: extents[ 10*i + 3 ] + * + * visual x: extents[ 10*i + 4 ] + * visual y: extents[ 10*i + 5 ] + * visual width: extents[ 10*i + 6 ] + * visual height: extents[ 10*i + 7 ] + * + * origin pos x: extents[ 10*i + 8 ] + * origin pos y: extents[ 10*i + 9 ] + * + * as well as one int, code[i], representing the glyph code in the font. + */ + + double [] extents; + int [] codes; + + Font font; + FontRenderContext fontRenderContext; + + Rectangle2D allLogical; + Rectangle2D allVisual; + + public GdkGlyphVector(double[] extents, int[] codes, Font font, FontRenderContext frc) + { + this.extents = extents; + this.codes = codes; + this.font = font; + this.fontRenderContext = frc; + + allLogical = new Rectangle2D.Double(); + allVisual = new Rectangle2D.Double(); + + for (int i = 0; i < codes.length; ++i) + { + allLogical.add (new Rectangle2D.Double(extents[10*i ] + extents[10*i + 8], + extents[10*i + 1] + extents[10*i + 9], + extents[10*i + 2], + extents[10*i + 3])); + + allVisual.add (new Rectangle2D.Double(extents[10*i + 4] + extents[10*i + 8], + extents[10*i + 5] + extents[10*i + 9], + extents[10*i + 6], + extents[10*i + 7])); + } + } + + /* + geometric notes: + + the FRC contains a mapping from points -> pixels. + + typographics points are typically 1/72 of an inch. + + pixel displays are often around 72 dpi. + + so the FRC can get away with using an identity transform on a screen, + often. behavior is documented by sun to fall back to an identity + transform if the internal transformation is null. + + coordinates coming up from pango are expressed as floats -- in device + space, so basically pixels-with-fractional-bits -- derived from their + storage format in pango (1024ths of pixels). + + it is not clear from the javadocs whether the results of methods like + getGlyphPositions ought to return coordinates in device space, or + "point" space, or what. for now I'm returning them in device space. + + */ + + public double[] getExtents() + { + return extents; + } + + public int[] getCodes() + { + return codes; + } + + public Font getFont () + { + return font; + } + + public FontRenderContext getFontRenderContext () + { + return fontRenderContext; + } + + public int getGlyphCharIndex (int glyphIndex) + { + // FIXME: currently pango does not provide glyph-by-glyph + // reverse mapping information, so we assume a broken 1:1 + // glyph model here. This is plainly wrong. + return glyphIndex; + } + + public int[] getGlyphCharIndices (int beginGlyphIndex, + int numEntries, + int[] codeReturn) + { + int ix[] = codeReturn; + if (ix == null) + ix = new int[numEntries]; + + for (int i = 0; i < numEntries; i++) + ix[i] = getGlyphCharIndex (beginGlyphIndex + i); + return ix; + } + + public int getGlyphCode (int glyphIndex) + { + return codes[glyphIndex]; + } + + public int[] getGlyphCodes (int beginGlyphIndex, int numEntries, + int[] codeReturn) + { + if (codeReturn == null) + codeReturn = new int[numEntries]; + + System.arraycopy(codes, beginGlyphIndex, codeReturn, 0, numEntries); + return codeReturn; + } + + public Shape getGlyphLogicalBounds (int i) + { + return new Rectangle2D.Double (extents[8*i], extents[8*i + 1], + extents[8*i + 2], extents[8*i + 3]); + } + + public GlyphMetrics getGlyphMetrics (int i) + { + // FIXME: pango does not yield vertical layout information at the + // moment. + + boolean is_horizontal = true; + double advanceX = extents[8*i + 2]; // "logical width" == advanceX + double advanceY = 0; + + return new GlyphMetrics (is_horizontal, + (float) advanceX, (float) advanceY, + (Rectangle2D) getGlyphVisualBounds(i), + GlyphMetrics.STANDARD); + } + + public Shape getGlyphOutline (int glyphIndex) + { + throw new UnsupportedOperationException (); + } + + public Shape getGlyphOutline (int glyphIndex, float x, float y) + { + throw new UnsupportedOperationException (); + } + + public Rectangle getGlyphPixelBounds (int i, + FontRenderContext renderFRC, + float x, float y) + { + return new Rectangle((int) x, (int) y, + (int) extents[8*i + 6], (int) extents[8*i + 7]); + } + + public Point2D getGlyphPosition (int i) + { + return new Point2D.Double (extents[10*i + 8], + extents[10*i + 9]); + } + + public float[] getGlyphPositions (int beginGlyphIndex, + int numEntries, + float[] positionReturn) + { + float fx[] = positionReturn; + if (fx == null) + fx = new float[numEntries * 2]; + + for (int i = 0; i < numEntries; ++i) + { + fx[2*i ] = (float) extents[10*i + 8]; + fx[2*i + 1] = (float) extents[10*i + 9]; + } + return fx; + } + + public AffineTransform getGlyphTransform (int glyphIndex) + { + // Glyphs don't have independent transforms in these simple glyph + // vectors; docs specify null is an ok return here. + return null; + } + + public Shape getGlyphVisualBounds (int i) + { + return new Rectangle2D.Double(extents[8*i + 4], extents[8*i + 5], + extents[8*i + 6], extents[8*i + 7]); + } + + public int getLayoutFlags () + { + return 0; + } + + public Rectangle2D getLogicalBounds () + { + return allLogical; + } + + public int getNumGlyphs () + { + return codes.length; + } + + public Shape getOutline () + { + throw new UnsupportedOperationException (); + } + + public Rectangle getPixelBounds (FontRenderContext renderFRC, + float x, float y) + { + return new Rectangle((int)x, + (int)y, + (int) allVisual.getWidth(), + (int) allVisual.getHeight()); + } + + public Rectangle2D getVisualBounds () + { + return allVisual; + } + + public void performDefaultLayout () + { + } + + public void setGlyphPosition (int i, Point2D newPos) + { + extents[8*i ] = newPos.getX(); + extents[8*i + 1] = newPos.getY(); + + extents[8*i + 4] = newPos.getX(); + extents[8*i + 5] = newPos.getY(); + } + + public void setGlyphTransform (int glyphIndex, + AffineTransform newTX) + { + // not yet.. maybe not ever? + throw new UnsupportedOperationException (); + } + + public boolean equals(GlyphVector gv) + { + if (gv == null) + return false; + + if (! (gv instanceof GdkGlyphVector)) + return false; + + GdkGlyphVector ggv = (GdkGlyphVector) gv; + + if ((ggv.codes.length != this.codes.length) + || (ggv.extents.length != this.extents.length)) + return false; + + if ((ggv.font == null && this.font != null) + || (ggv.font != null && this.font == null) + || (!ggv.font.equals(this.font))) + return false; + + if ((ggv.fontRenderContext == null && this.fontRenderContext != null) + || (ggv.fontRenderContext != null && this.fontRenderContext == null) + || (!ggv.fontRenderContext.equals(this.fontRenderContext))) + return false; + + for (int i = 0; i < ggv.codes.length; ++i) + if (ggv.codes[i] != this.codes[i]) + return false; + + for (int i = 0; i < ggv.extents.length; ++i) + if (ggv.extents[i] != this.extents[i]) + return false; + + return true; + } + + public GlyphJustificationInfo getGlyphJustificationInfo(int idx) + { + throw new UnsupportedOperationException (); + } + + public Shape getOutline(float x, float y) + { + throw new UnsupportedOperationException (); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java new file mode 100644 index 0000000..a125be7 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -0,0 +1,388 @@ +/* GdkGraphics.java + Copyright (C) 1998, 1999, 2002, 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.java.awt.peer.gtk; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.SystemColor; +import java.awt.image.ImageObserver; +import java.text.AttributedCharacterIterator; + +public class GdkGraphics extends Graphics +{ + private final int native_state = GtkGenericPeer.getUniqueInteger(); + + Color color, xorColor; + GtkComponentPeer component; + Font font; + Rectangle clip; + GtkImage image; + + int xOffset = 0; + int yOffset = 0; + + static final int GDK_COPY = 0, GDK_XOR = 2; + + native void initState (GtkComponentPeer component); + native void initState (int width, int height); + native void initFromImage (GtkImage image); + native void copyState (GdkGraphics g); + + GdkGraphics (GdkGraphics g) + { + color = g.color; + xorColor = g.xorColor; + font = g.font; + clip = new Rectangle (g.clip); + component = g.component; + + copyState (g); + } + + GdkGraphics (int width, int height) + { + initState (width, height); + color = Color.black; + clip = new Rectangle (0, 0, width, height); + font = new Font ("Dialog", Font.PLAIN, 12); + } + + GdkGraphics (GtkImage image) + { + this.image = image; + initFromImage (image); + color = Color.black; + clip = new Rectangle (0, 0, + image.getWidth(null), image.getHeight(null)); + font = new Font ("Dialog", Font.PLAIN, 12); + } + + GdkGraphics (GtkComponentPeer component) + { + this.component = component; + font = component.awtComponent.getFont (); + color = Color.black; + + if (component.isRealized ()) + initComponentGraphics (); + else + connectSignals (component); + } + + void initComponentGraphics () + { + initState (component); + color = component.awtComponent.getForeground (); + Dimension d = component.awtComponent.getSize (); + clip = new Rectangle (0, 0, d.width, d.height); + } + + native void connectSignals (GtkComponentPeer component); + + public native void clearRect(int x, int y, int width, int height); + + public void clipRect (int x, int y, int width, int height) + { + if (component != null && ! component.isRealized ()) + return; + + clip = clip.intersection (new Rectangle (x, y, width, height)); + setClipRectangle (clip.x, clip.y, clip.width, clip.height); + } + + public native void copyArea(int x, int y, int width, int height, + int dx, int dy); + + public Graphics create () + { + return new GdkGraphics (this); + } + + public native void dispose(); + + public boolean drawImage (Image img, int x, int y, + Color bgcolor, ImageObserver observer) + { + return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), + bgcolor, observer); + } + + public boolean drawImage (Image img, int x, int y, ImageObserver observer) + { + return drawImage (img, x, y, null, observer); + } + + public boolean drawImage (Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + if (img instanceof GtkImage) + return ((GtkImage)img).drawImage (this, x, y, width, height, + bgcolor, observer); + else + return (new GtkImage(img.getSource())).drawImage (this, x, y, + width, height, + bgcolor, observer); + } + + public boolean drawImage (Image img, int x, int y, int width, int height, + ImageObserver observer) + { + return drawImage (img, x, y, width, height, null, observer); + } + + public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (img instanceof GtkImage) + return ((GtkImage)img).drawImage(this, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, bgcolor, observer); + else + return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, + dx2, dy2, + sx1, sy1, sx2, sy2, + bgcolor, observer); + } + + public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) + { + return drawImage (img, dx1, dy1, dx2, dy2, + sx1, sy1, sx2, sy2, + null, observer); + } + + public native void drawLine(int x1, int y1, int x2, int y2); + + public native void drawArc(int x, int y, int width, int height, + int startAngle, int arcAngle); + public native void fillArc(int x, int y, int width, int height, + int startAngle, int arcAngle); + public native void drawOval(int x, int y, int width, int height); + public native void fillOval(int x, int y, int width, int height); + + public native void drawPolygon(int[] xPoints, int[] yPoints, int nPoints); + public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints); + + public native void drawPolyline(int[] xPoints, int[] yPoints, int nPoints); + + public native void drawRect(int x, int y, int width, int height); + public native void fillRect(int x, int y, int width, int height); + + GdkFontPeer getFontPeer() + { + return (GdkFontPeer) getFont().getPeer(); + } + + native void drawString (GdkFontPeer f, String str, int x, int y); + public void drawString (String str, int x, int y) + { + drawString(getFontPeer(), str, x, y); + } + + + public void drawString (AttributedCharacterIterator ci, int x, int y) + { + throw new Error ("not implemented"); + } + + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) + { + if (arcWidth > width) + arcWidth = width; + if (arcHeight > height) + arcHeight = height; + + int xx = x + width - arcWidth; + int yy = y + height - arcHeight; + + drawArc (x, y, arcWidth, arcHeight, 90, 90); + drawArc (xx, y, arcWidth, arcHeight, 0, 90); + drawArc (xx, yy, arcWidth, arcHeight, 270, 90); + drawArc (x, yy, arcWidth, arcHeight, 180, 90); + + int y1 = y + arcHeight / 2; + int y2 = y + height - arcHeight / 2; + drawLine (x, y1, x, y2); + drawLine (x + width, y1, x + width, y2); + + int x1 = x + arcWidth / 2; + int x2 = x + width - arcWidth / 2; + drawLine (x1, y, x2, y); + drawLine (x1, y + height, x2, y + height); + } + + public void fillRoundRect (int x, int y, int width, int height, + int arcWidth, int arcHeight) + { + if (arcWidth > width) + arcWidth = width; + if (arcHeight > height) + arcHeight = height; + + int xx = x + width - arcWidth; + int yy = y + height - arcHeight; + + fillArc (x, y, arcWidth, arcHeight, 90, 90); + fillArc (xx, y, arcWidth, arcHeight, 0, 90); + fillArc (xx, yy, arcWidth, arcHeight, 270, 90); + fillArc (x, yy, arcWidth, arcHeight, 180, 90); + + fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1); + fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height); + } + + public Shape getClip () + { + return getClipBounds (); + } + + public Rectangle getClipBounds () + { + if (clip == null) + return null; + else + return clip.getBounds(); + } + + public Color getColor () + { + return color; + } + + public Font getFont () + { + return font; + } + + public FontMetrics getFontMetrics (Font font) + { + return new GdkFontMetrics (font); + } + + native void setClipRectangle (int x, int y, int width, int height); + + public void setClip (int x, int y, int width, int height) + { + if ((component != null && ! component.isRealized ()) + || clip == null) + return; + + clip.x = x; + clip.y = y; + clip.width = width; + clip.height = height; + + setClipRectangle (x, y, width, height); + } + + public void setClip (Rectangle clip) + { + setClip (clip.x, clip.y, clip.width, clip.height); + } + + public void setClip (Shape clip) + { + if (clip != null) + setClip(clip.getBounds()); + } + + private native void setFGColor(int red, int green, int blue); + + public void setColor (Color c) + { + if (c == null) + color = Color.BLACK; + else + color = c; + + if (xorColor == null) /* paint mode */ + setFGColor (color.getRed (), color.getGreen (), color.getBlue ()); + else /* xor mode */ + setFGColor (color.getRed () ^ xorColor.getRed (), + color.getGreen () ^ xorColor.getGreen (), + color.getBlue () ^ xorColor.getBlue ()); + } + + public void setFont (Font font) + { + this.font = font; + } + + native void setFunction (int gdk_func); + + public void setPaintMode () + { + xorColor = null; + + setFunction (GDK_COPY); + setFGColor (color.getRed (), color.getGreen (), color.getBlue ()); + } + + public void setXORMode (Color c) + { + xorColor = c; + + setFunction (GDK_XOR); + setFGColor (color.getRed () ^ xorColor.getRed (), + color.getGreen () ^ xorColor.getGreen (), + color.getBlue () ^ xorColor.getBlue ()); + } + + public native void translateNative(int x, int y); + + public void translate (int x, int y) + { + if (component != null && ! component.isRealized ()) + return; + + clip.x -= x; + clip.y -= y; + + translateNative (x, y); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java new file mode 100644 index 0000000..b820317 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -0,0 +1,1453 @@ +/* GdkGraphics2D.java -- + Copyright (C) 2003, 2004, 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.java.awt.peer.gtk; + +import gnu.classpath.Configuration; +import gnu.java.awt.ClasspathToolkit; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.TexturePaint; +import java.awt.Toolkit; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ColorModel; +import java.awt.image.CropImageFilter; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageObserver; +import java.awt.image.ImagingOpException; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; +import java.awt.image.WritableRaster; +import java.awt.image.renderable.RenderContext; +import java.awt.image.renderable.RenderableImage; +import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +public class GdkGraphics2D extends Graphics2D +{ + ////////////////////////////////////// + ////// State Management Methods ////// + ////////////////////////////////////// + + static + { + if (! Configuration.GTK_CAIRO_ENABLED) + throw new Error("Grahics2D not implemented. " + + "Cairo was not found or disabled at configure time"); + + if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary("gtkpeer"); + + if (GtkToolkit.useGraphics2D()) + initStaticState(); + } + + static native void initStaticState(); + + private final int native_state = GtkGenericPeer.getUniqueInteger(); + + // These are package-private to avoid accessor methods. + Paint paint; + Stroke stroke; + Color fg; + Color bg; + Shape clip; + AffineTransform transform; + private GtkComponentPeer component; + // This is package-private to avoid an accessor method. + Font font; + private RenderingHints hints; + private BufferedImage bimage; + private boolean pixelConversionRequired; + private int[] pixelBuffer; + // This is package-private to avoid an accessor method. + Composite comp; + private Stack stateStack; + + private native void initState(GtkComponentPeer component); + private native void initState(int width, int height); + private native void initState(int[] pixes, int width, int height); + private native void copyState(GdkGraphics2D g); + public native void dispose(); + private native void cairoSurfaceSetFilter(int filter); + native void connectSignals(GtkComponentPeer component); + + public void finalize() + { + dispose(); + } + + public Graphics create() + { + return new GdkGraphics2D(this); + } + + public Graphics create(int x, int y, int width, int height) + { + return new GdkGraphics2D(width, height); + } + + GdkGraphics2D(GdkGraphics2D g) + { + paint = g.paint; + stroke = g.stroke; + setRenderingHints(g.hints); + + if (g.fg.getAlpha() != -1) + fg = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(), + g.fg.getAlpha()); + else + fg = new Color(g.fg.getRGB()); + + if (g.bg.getAlpha() != -1) + bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(), + g.bg.getAlpha()); + else + bg = new Color(g.bg.getRGB()); + + if (g.clip == null) + clip = null; + else + clip = new Rectangle(g.getClipBounds()); + + if (g.transform == null) + transform = new AffineTransform(); + else + transform = new AffineTransform(g.transform); + + font = g.font; + component = g.component; + copyState(g); + + setColor(fg); + setBackground(bg); + setPaint(paint); + setStroke(stroke); + setTransform(transform); + setClip(clip); + stateStack = new Stack(); + } + + GdkGraphics2D(int width, int height) + { + initState(width, height); + + setColor(Color.black); + setBackground(new Color(0, 0, 0, 0)); + setPaint(getColor()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); + + stateStack = new Stack(); + } + + GdkGraphics2D(GtkComponentPeer component) + { + this.component = component; + + if (component.isRealized()) + initComponentGraphics2D(); + else + connectSignals(component); + } + + void initComponentGraphics2D() + { + initState(component); + + setColor(component.awtComponent.getForeground()); + setBackground(component.awtComponent.getBackground()); + setPaint(getColor()); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); + + stateStack = new Stack(); + } + + GdkGraphics2D(BufferedImage bimage) + { + this.bimage = bimage; + this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(), + bimage.getRaster()); + if (this.pixelBuffer == null) + { + this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster() + .getHeight()]; + this.pixelConversionRequired = true; + } + else + { + this.pixelConversionRequired = false; + } + + initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight()); + + setColor(Color.black); + setBackground(new Color(0, 0, 0, 0)); + setPaint(getColor()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); + + stateStack = new Stack(); + + // draw current buffered image to the pixmap associated + // with it, if the image is not equal to our paint buffer. + if (pixelConversionRequired) + drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null); + } + + //////////////////////////////////// + ////// Native Drawing Methods ////// + //////////////////////////////////// + + // GDK drawing methods + private native void gdkDrawDrawable(GdkGraphics2D other, int x, int y); + + // drawing utility methods + private native void drawPixels(int[] pixels, int w, int h, int stride, + double[] i2u); + private native void setTexturePixels(int[] pixels, int w, int h, int stride); + private native void setGradient(double x1, double y1, double x2, double y2, + int r1, int g1, int b1, int a1, int r2, + int g2, int b2, int a2, boolean cyclic); + + // simple passthroughs to cairo + private native void cairoSave(); + private native void cairoRestore(); + private native void cairoSetMatrix(double[] m); + private native void cairoSetOperator(int cairoOperator); + private native void cairoSetRGBAColor(double red, double green, + double blue, double alpha); + private native void cairoSetFillRule(int cairoFillRule); + private native void cairoSetLineWidth(double width); + private native void cairoSetLineCap(int cairoLineCap); + private native void cairoSetLineJoin(int cairoLineJoin); + private native void cairoSetDash(double[] dashes, int ndash, double offset); + + private native void cairoSetMiterLimit(double limit); + private native void cairoNewPath(); + private native void cairoMoveTo(double x, double y); + private native void cairoLineTo(double x, double y); + private native void cairoCurveTo(double x1, double y1, double x2, double y2, + double x3, double y3); + private native void cairoRelMoveTo(double dx, double dy); + private native void cairoRelLineTo(double dx, double dy); + private native void cairoRelCurveTo(double dx1, double dy1, double dx2, + double dy2, double dx3, double dy3); + private native void cairoRectangle(double x, double y, double width, + double height); + private native void cairoClosePath(); + private native void cairoStroke(); + private native void cairoFill(); + private native void cairoClip(); + + ///////////////////////////////////////////// + ////// General Drawing Support Methods ////// + ///////////////////////////////////////////// + + private class DrawState + { + private Paint paint; + private Stroke stroke; + private Color fg; + private Color bg; + private Shape clip; + private AffineTransform transform; + private Font font; + private Composite comp; + + DrawState(GdkGraphics2D g) + { + this.paint = g.paint; + this.stroke = g.stroke; + this.fg = g.fg; + this.bg = g.bg; + this.clip = g.clip; + if (g.transform != null) + this.transform = (AffineTransform) g.transform.clone(); + this.font = g.font; + this.comp = g.comp; + } + + public void restore(GdkGraphics2D g) + { + g.paint = this.paint; + g.stroke = this.stroke; + g.fg = this.fg; + g.bg = this.bg; + g.clip = this.clip; + g.transform = this.transform; + g.font = this.font; + g.comp = this.comp; + } + } + + private void stateSave() + { + stateStack.push(new DrawState(this)); + cairoSave(); + } + + private void stateRestore() + { + ((DrawState) (stateStack.pop())).restore(this); + cairoRestore(); + } + + // Some operations (drawing rather than filling) require that their + // coords be shifted to land on 0.5-pixel boundaries, in order to land on + // "middle of pixel" coordinates and light up complete pixels. + private boolean shiftDrawCalls = false; + + private double shifted(double coord, boolean doShift) + { + if (doShift) + return Math.floor(coord) + 0.5; + else + return coord; + } + + private void walkPath(PathIterator p, boolean doShift) + { + double x = 0; + double y = 0; + double[] coords = new double[6]; + + cairoSetFillRule(p.getWindingRule()); + for (; ! p.isDone(); p.next()) + { + int seg = p.currentSegment(coords); + switch (seg) + { + case PathIterator.SEG_MOVETO: + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoMoveTo(x, y); + break; + case PathIterator.SEG_LINETO: + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoLineTo(x, y); + break; + case PathIterator.SEG_QUADTO: + // splitting a quadratic bezier into a cubic: + // see: http://pfaedit.sourceforge.net/bezier.html + double x1 = x + (2.0 / 3.0) * (shifted(coords[0], doShift) - x); + double y1 = y + (2.0 / 3.0) * (shifted(coords[1], doShift) - y); + + double x2 = x1 + (1.0 / 3.0) * (shifted(coords[2], doShift) - x); + double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y); + + x = shifted(coords[2], doShift); + y = shifted(coords[3], doShift); + cairoCurveTo(x1, y1, x2, y2, x, y); + break; + case PathIterator.SEG_CUBICTO: + x = shifted(coords[4], doShift); + y = shifted(coords[5], doShift); + cairoCurveTo(shifted(coords[0], doShift), + shifted(coords[1], doShift), + shifted(coords[2], doShift), + shifted(coords[3], doShift), x, y); + break; + case PathIterator.SEG_CLOSE: + cairoClosePath(); + break; + } + } + } + + private Map getDefaultHints() + { + HashMap defaultHints = new HashMap(); + + defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); + + defaultHints.put(RenderingHints.KEY_STROKE_CONTROL, + RenderingHints.VALUE_STROKE_DEFAULT); + + defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_OFF); + + defaultHints.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + + defaultHints.put(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_DEFAULT); + + return defaultHints; + } + + public static int[] findSimpleIntegerArray (ColorModel cm, Raster raster) + { + if (cm == null || raster == null) + return null; + + if (! cm.getColorSpace().isCS_sRGB()) + return null; + + if (! (cm instanceof DirectColorModel)) + return null; + + DirectColorModel dcm = (DirectColorModel) cm; + + if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00 + || dcm.getBlueMask() != 0x000000FF) + return null; + + if (! (raster instanceof WritableRaster)) + return null; + + if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT) + return null; + + if (! (raster.getDataBuffer() instanceof DataBufferInt)) + return null; + + DataBufferInt db = (DataBufferInt) raster.getDataBuffer(); + + if (db.getNumBanks() != 1) + return null; + + // Finally, we have determined that this is a single bank, [A]RGB-int + // buffer in sRGB space. It's worth checking all this, because it means + // that cairo can paint directly into the data buffer, which is very + // fast compared to all the normal copying and converting. + + return db.getData(); + } + + private void updateBufferedImage() + { + if (bimage != null && pixelConversionRequired) + { + int height = bimage.getHeight(); + int width = bimage.getWidth(); + int index = 0; + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + bimage.setRGB(x, y, pixelBuffer[index++]); + } + } + + private boolean drawImage(Image img, AffineTransform xform, + Color bgcolor, ImageObserver obs) + { + if (img == null) + return false; + + // FIXME: I'll fix this, /Sven +// if (img instanceof GtkOffScreenImage +// && img.getGraphics() instanceof GdkGraphics2D +// && (xform == null || xform.getType() == AffineTransform.TYPE_IDENTITY +// || xform.getType() == AffineTransform.TYPE_TRANSLATION)) +// { +// // we are being asked to flush a double buffer from Gdk +// GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics(); +// gdkDrawDrawable(g2, (int) xform.getTranslateX(), +// (int) xform.getTranslateY()); + +// updateBufferedImage(); + +// return true; +// } +// else + { + // In this case, xform is an AffineTransform that transforms bounding + // box of the specified image from image space to user space. However + // when we pass this transform to cairo, cairo will use this transform + // to map "user coordinates" to "pixel" coordinates, which is the + // other way around. Therefore to get the "user -> pixel" transform + // that cairo wants from "image -> user" transform that we currently + // have, we will need to invert the transformation matrix. + AffineTransform invertedXform = new AffineTransform(); + + try + { + invertedXform = xform.createInverse(); + if (img instanceof BufferedImage) + { + // draw an image which has actually been loaded + // into memory fully + BufferedImage b = (BufferedImage) img; + return drawRaster(b.getColorModel(), b.getTile(0, 0), + invertedXform, bgcolor); + } + else + return this.drawImage(GdkPixbufDecoder.createBufferedImage(img + .getSource()), + xform, bgcolor, obs); + } + catch (NoninvertibleTransformException e) + { + throw new ImagingOpException("Unable to invert transform " + + xform.toString()); + } + } + } + + ////////////////////////////////////////////////// + ////// Implementation of Graphics2D Methods ////// + ////////////////////////////////////////////////// + + public void draw(Shape s) + { + if (stroke != null && ! (stroke instanceof BasicStroke)) + { + fill(stroke.createStrokedShape(s)); + return; + } + + cairoNewPath(); + + if (s instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(shifted(r.getX(), shiftDrawCalls), + shifted(r.getY(), shiftDrawCalls), r.getWidth(), + r.getHeight()); + } + else + walkPath(s.getPathIterator(null), shiftDrawCalls); + cairoStroke(); + + updateBufferedImage(); + } + + public void fill(Shape s) + { + cairoNewPath(); + if (s instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + else + walkPath(s.getPathIterator(null), false); + + cairoFill(); + + updateBufferedImage(); + } + + public void clip(Shape s) + { + // update it + if (clip == null || s == null) + clip = s; + else if (s instanceof Rectangle2D && clip instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) s; + Rectangle2D curr = (Rectangle2D) clip; + clip = curr.createIntersection(r); + } + else + throw new UnsupportedOperationException(); + + // draw it + if (clip != null) + { + cairoNewPath(); + if (clip instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) clip; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + else + walkPath(clip.getPathIterator(null), false); + + // cairoClosePath (); + cairoClip(); + } + } + + public Paint getPaint() + { + return paint; + } + + public AffineTransform getTransform() + { + return (AffineTransform) transform.clone(); + } + + public void setPaint(Paint p) + { + if (paint == null) + return; + + paint = p; + if (paint instanceof Color) + { + setColor((Color) paint); + } + else if (paint instanceof TexturePaint) + { + TexturePaint tp = (TexturePaint) paint; + BufferedImage img = tp.getImage(); + + // map the image to the anchor rectangle + int width = (int) tp.getAnchorRect().getWidth(); + int height = (int) tp.getAnchorRect().getHeight(); + + double scaleX = width / (double) img.getWidth(); + double scaleY = width / (double) img.getHeight(); + + AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0); + AffineTransformOp op = new AffineTransformOp(at, getRenderingHints()); + BufferedImage texture = op.filter(img, null); + int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width); + setTexturePixels(pixels, width, height, width); + } + else if (paint instanceof GradientPaint) + { + GradientPaint gp = (GradientPaint) paint; + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + Color c1 = gp.getColor1(); + Color c2 = gp.getColor2(); + setGradient(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(), + c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(), + c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic()); + } + else + throw new java.lang.UnsupportedOperationException(); + } + + public void setTransform(AffineTransform tx) + { + transform = tx; + if (transform != null) + { + double[] m = new double[6]; + transform.getMatrix(m); + cairoSetMatrix(m); + } + } + + public void transform(AffineTransform tx) + { + if (transform == null) + transform = new AffineTransform(tx); + else + transform.concatenate(tx); + setTransform(transform); + if (clip != null) + { + // FIXME: this should actuall try to transform the shape + // rather than degrade to bounds. + Rectangle2D r = clip.getBounds2D(); + double[] coords = new double[] + { + r.getX(), r.getY(), r.getX() + r.getWidth(), + r.getY() + r.getHeight() + }; + try + { + tx.createInverse().transform(coords, 0, coords, 0, 2); + r.setRect(coords[0], coords[1], coords[2] - coords[0], + coords[3] - coords[1]); + clip = r; + } + catch (java.awt.geom.NoninvertibleTransformException e) + { + } + } + } + + public void rotate(double theta) + { + transform(AffineTransform.getRotateInstance(theta)); + } + + public void rotate(double theta, double x, double y) + { + transform(AffineTransform.getRotateInstance(theta, x, y)); + } + + public void scale(double sx, double sy) + { + transform(AffineTransform.getScaleInstance(sx, sy)); + } + + public void translate(double tx, double ty) + { + transform(AffineTransform.getTranslateInstance(tx, ty)); + } + + public void translate(int x, int y) + { + translate((double) x, (double) y); + } + + public void shear(double shearX, double shearY) + { + transform(AffineTransform.getShearInstance(shearX, shearY)); + } + + public Stroke getStroke() + { + return stroke; + } + + public void setStroke(Stroke st) + { + stroke = st; + if (stroke instanceof BasicStroke) + { + BasicStroke bs = (BasicStroke) stroke; + cairoSetLineCap(bs.getEndCap()); + cairoSetLineWidth(bs.getLineWidth()); + cairoSetLineJoin(bs.getLineJoin()); + cairoSetMiterLimit(bs.getMiterLimit()); + float[] dashes = bs.getDashArray(); + if (dashes != null) + { + double[] double_dashes = new double[dashes.length]; + for (int i = 0; i < dashes.length; i++) + double_dashes[i] = dashes[i]; + cairoSetDash(double_dashes, double_dashes.length, + (double) bs.getDashPhase()); + } + } + } + + //////////////////////////////////////////////// + ////// Implementation of Graphics Methods ////// + //////////////////////////////////////////////// + + public void setPaintMode() + { + setComposite(java.awt.AlphaComposite.SrcOver); + } + + public void setXORMode(Color c) + { + setComposite(new gnu.java.awt.BitwiseXORComposite(c)); + } + + public void setColor(Color c) + { + if (c == null) + c = Color.BLACK; + + fg = c; + paint = c; + cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0, + fg.getBlue() / 255.0, fg.getAlpha() / 255.0); + } + + public Color getColor() + { + return fg; + } + + public void clipRect(int x, int y, int width, int height) + { + clip(new Rectangle(x, y, width, height)); + } + + public Shape getClip() + { + return clip.getBounds2D(); //getClipInDevSpace(); + } + + public Rectangle getClipBounds() + { + if (clip == null) + return null; + else + return clip.getBounds(); + } + + protected Rectangle2D getClipInDevSpace() + { + Rectangle2D uclip = clip.getBounds2D(); + if (transform == null) + return uclip; + else + { + Point2D pos = transform.transform(new Point2D.Double(uclip.getX(), + uclip.getY()), + (Point2D) null); + Point2D extent = transform.deltaTransform(new Point2D.Double(uclip + .getWidth(), + uclip + .getHeight()), + (Point2D) null); + return new Rectangle2D.Double(pos.getX(), pos.getY(), extent.getX(), + extent.getY()); + } + } + + public void setClip(int x, int y, int width, int height) + { + setClip(new Rectangle2D.Double((double) x, (double) y, (double) width, + (double) height)); + } + + public void setClip(Shape s) + { + clip = s; + if (s != null) + { + cairoNewPath(); + if (s instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + else + walkPath(s.getPathIterator(null), false); + + // cairoClosePath (); + cairoClip(); + } + } + + private static BasicStroke draw3DRectStroke = new BasicStroke(); + + public void draw3DRect(int x, int y, int width, int height, boolean raised) + { + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.draw3DRect(x, y, width, height, raised); + setStroke(tmp); + updateBufferedImage(); + } + + public void fill3DRect(int x, int y, int width, int height, boolean raised) + { + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.fill3DRect(x, y, width, height, raised); + setStroke(tmp); + updateBufferedImage(); + } + + public void drawRect(int x, int y, int width, int height) + { + draw(new Rectangle(x, y, width, height)); + } + + public void fillRect(int x, int y, int width, int height) + { + cairoNewPath(); + cairoRectangle(x, y, width, height); + cairoFill(); + } + + public void clearRect(int x, int y, int width, int height) + { + cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0, + bg.getBlue() / 255.0, 1.0); + cairoNewPath(); + cairoRectangle(x, y, width, height); + cairoFill(); + setColor(fg); + + updateBufferedImage(); + } + + public void setBackground(Color c) + { + bg = c; + } + + public Color getBackground() + { + return bg; + } + + private void doPolygon(int[] xPoints, int[] yPoints, int nPoints, + boolean close, boolean fill) + { + if (nPoints < 1) + return; + GeneralPath gp = new GeneralPath(PathIterator.WIND_EVEN_ODD); + gp.moveTo((float) xPoints[0], (float) yPoints[0]); + for (int i = 1; i < nPoints; i++) + gp.lineTo((float) xPoints[i], (float) yPoints[i]); + + if (close) + gp.closePath(); + + Shape sh = gp; + if (fill == false && stroke != null && ! (stroke instanceof BasicStroke)) + { + sh = stroke.createStrokedShape(gp); + fill = true; + } + + if (fill) + fill(sh); + else + draw(sh); + } + + public void drawLine(int x1, int y1, int x2, int y2) + { + int[] xp = new int[2]; + int[] yp = new int[2]; + + xp[0] = x1; + xp[1] = x2; + yp[0] = y1; + yp[1] = y2; + + doPolygon(xp, yp, 2, false, false); + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) + { + doPolygon(xPoints, yPoints, nPoints, true, true); + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) + { + doPolygon(xPoints, yPoints, nPoints, true, false); + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) + { + doPolygon(xPoints, yPoints, nPoints, false, false); + } + + private boolean drawRaster(ColorModel cm, Raster r, + AffineTransform imageToUser, Color bgcolor) + { + if (r == null) + return false; + + SampleModel sm = r.getSampleModel(); + DataBuffer db = r.getDataBuffer(); + + if (db == null || sm == null) + return false; + + if (cm == null) + cm = ColorModel.getRGBdefault(); + + double[] i2u = new double[6]; + if (imageToUser != null) + imageToUser.getMatrix(i2u); + else + { + i2u[0] = 1; + i2u[1] = 0; + i2u[2] = 0; + i2u[3] = 1; + i2u[4] = 0; + i2u[5] = 0; + } + + int[] pixels = findSimpleIntegerArray(cm, r); + + if (pixels == null) + { + // FIXME: I don't think this code will work correctly with a non-RGB + // MultiPixelPackedSampleModel. Although this entire method should + // probably be rewritten to better utilize Cairo's different supported + // data formats. + if (sm instanceof MultiPixelPackedSampleModel) + { + pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels); + for (int i = 0; i < pixels.length; i++) + pixels[i] = cm.getRGB(pixels[i]); + } + else + { + pixels = new int[r.getWidth() * r.getHeight()]; + for (int i = 0; i < pixels.length; i++) + pixels[i] = cm.getRGB(db.getElem(i)); + } + } + + // Change all transparent pixels in the image to the specified bgcolor, + // or (if there's no alpha) fill in an alpha channel so that it paints + // correctly. + if (cm.hasAlpha()) + { + if (bgcolor != null && cm.hasAlpha()) + for (int i = 0; i < pixels.length; i++) + { + if (cm.getAlpha(pixels[i]) == 0) + pixels[i] = bgcolor.getRGB(); + } + } + else + for (int i = 0; i < pixels.length; i++) + pixels[i] |= 0xFF000000; + + drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u); + + updateBufferedImage(); + + return true; + } + + public void drawRenderedImage(RenderedImage image, AffineTransform xform) + { + drawRaster(image.getColorModel(), image.getData(), xform, bg); + } + + public void drawRenderableImage(RenderableImage image, AffineTransform xform) + { + drawRenderedImage(image.createRendering(new RenderContext(xform)), xform); + } + + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) + { + return drawImage(img, xform, bg, obs); + } + + public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y) + { + Image filtered = op.filter(image, null); + drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, null); + } + + public boolean drawImage(Image img, int x, int y, ImageObserver observer) + { + return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, + observer); + } + + /////////////////////////////////////////////// + ////// Unimplemented Stubs and Overloads ////// + /////////////////////////////////////////////// + + public boolean hit(Rectangle rect, Shape text, boolean onStroke) + { + throw new java.lang.UnsupportedOperationException(); + } + + public GraphicsConfiguration getDeviceConfiguration() + { + throw new java.lang.UnsupportedOperationException(); + } + + public void setComposite(Composite comp) + { + this.comp = comp; + + if (comp instanceof AlphaComposite) + { + AlphaComposite a = (AlphaComposite) comp; + cairoSetOperator(a.getRule()); + Color c = getColor(); + setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), + (int) (a.getAlpha() * ((float) c.getAlpha())))); + } + else + throw new java.lang.UnsupportedOperationException(); + } + + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) + { + hints.put(hintKey, hintValue); + + if (hintKey.equals(RenderingHints.KEY_INTERPOLATION) + || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION)) + { + if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilter(0); + + else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilter(1); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilter(2); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilter(3); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilter(4); + } + + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); + } + + public Object getRenderingHint(RenderingHints.Key hintKey) + { + return hints.get(hintKey); + } + + public void setRenderingHints(Map hints) + { + this.hints = new RenderingHints(getDefaultHints()); + this.hints.add(new RenderingHints(hints)); + + if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilter(0); + + else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilter(1); + } + + if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilter(2); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilter(3); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilter(4); + } + + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); + } + + public void addRenderingHints(Map hints) + { + this.hints.add(new RenderingHints(hints)); + } + + public RenderingHints getRenderingHints() + { + return hints; + } + + public Composite getComposite() + { + if (comp == null) + return AlphaComposite.SrcOver; + else + return comp; + } + + public FontRenderContext getFontRenderContext() + { + return new FontRenderContext(transform, true, true); + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) + { + throw new java.lang.UnsupportedOperationException(); + } + + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) + { + draw(new Arc2D.Double((double) x, (double) y, (double) width, + (double) height, (double) startAngle, + (double) arcAngle, Arc2D.OPEN)); + } + + public boolean drawImage(Image img, int x, int y, Color bgcolor, + ImageObserver observer) + { + return drawImage(img, x, y, img.getWidth(observer), + img.getHeight(observer), bgcolor, observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + double scaleX = width / (double) img.getWidth(observer); + double scaleY = height / (double) img.getHeight(observer); + + return drawImage(img, new AffineTransform(scaleX, 0f, 0f, scaleY, x, y), + bgcolor, observer); + } + + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) + { + return drawImage(img, x, y, width, height, bg, observer); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) + { + if (img == null) + return false; + + Image subImage; + + int sourceWidth = sx2 - sx1; + int sourceHeight = sy2 - sy1; + + int destWidth = dx2 - dx1; + int destHeight = dy2 - dy1; + + double scaleX = destWidth / (double) sourceWidth; + double scaleY = destHeight / (double) sourceHeight; + + // Get the subimage of the source enclosed in the + // rectangle specified by sx1, sy1, sx2, sy2 + + if (img instanceof BufferedImage) + { + BufferedImage b = (BufferedImage) img; + subImage = b.getSubimage(sx1, sy1, sx2, sy2); + } + else + { + // FIXME: This code currently doesn't work. Null Pointer + // exception is thrown in this case. This happens + // because img.getSource() always returns null, since source gets + // never initialized when it is created with the help of + // createImage(int width, int height). + CropImageFilter filter = new CropImageFilter(sx1, sx2, sx2, sy2); + FilteredImageSource src = new FilteredImageSource(img.getSource(), + filter); + + subImage = Toolkit.getDefaultToolkit().createImage(src); + } + + return drawImage(subImage, + new AffineTransform(scaleX, 0, 0, scaleY, dx1, dy1), + bgcolor, observer); + } + + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) + { + return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bg, observer); + } + + public void drawOval(int x, int y, int width, int height) + { + drawArc(x, y, width, height, 0, 360); + } + + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) + { + if (arcWidth > width) + arcWidth = width; + if (arcHeight > height) + arcHeight = height; + + int xx = x + width - arcWidth; + int yy = y + height - arcHeight; + + drawArc(x, y, arcWidth, arcHeight, 90, 90); + drawArc(xx, y, arcWidth, arcHeight, 0, 90); + drawArc(xx, yy, arcWidth, arcHeight, 270, 90); + drawArc(x, yy, arcWidth, arcHeight, 180, 90); + + int y1 = y + arcHeight / 2; + int y2 = y + height - arcHeight / 2; + drawLine(x, y1, x, y2); + drawLine(x + width, y1, x + width, y2); + + int x1 = x + arcWidth / 2; + int x2 = x + width - arcWidth / 2; + drawLine(x1, y, x2, y); + drawLine(x1, y + height, x2, y + height); + } + + // these are the most accelerated painting paths + native void cairoDrawGlyphVector(GdkFontPeer font, + float x, float y, int n, + int[] codes, float[] positions); + + native void cairoDrawGdkTextLayout(GdkTextLayout gl, + float x, float y); + + GdkFontPeer getFontPeer() + { + return (GdkFontPeer) getFont().getPeer(); + } + + public void drawGdkTextLayout(GdkTextLayout gl, float x, float y) + { + cairoDrawGdkTextLayout (gl, x, y); + updateBufferedImage (); + } + + public void drawString(String str, float x, float y) + { + drawGlyphVector(getFont().createGlyphVector(null, str), x, y); + updateBufferedImage (); + } + + public void drawString(String str, int x, int y) + { + drawString (str, (float) x, (float) y); + } + + public void drawString(AttributedCharacterIterator ci, int x, int y) + { + drawString (ci, (float) x, (float) y); + } + + public void drawGlyphVector(GlyphVector gv, float x, float y) + { + int n = gv.getNumGlyphs (); + int[] codes = gv.getGlyphCodes (0, n, null); + float[] positions = gv.getGlyphPositions (0, n, null); + + setFont (gv.getFont ()); + cairoDrawGlyphVector (getFontPeer(), x, y, n, codes, positions); + updateBufferedImage (); + } + + public void drawString(AttributedCharacterIterator ci, float x, float y) + { + GlyphVector gv = getFont().createGlyphVector(getFontRenderContext(), ci); + drawGlyphVector(gv, x, y); + } + + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) + { + fill(new Arc2D.Double((double) x, (double) y, (double) width, + (double) height, (double) startAngle, + (double) arcAngle, Arc2D.OPEN)); + } + + public void fillOval(int x, int y, int width, int height) + { + fillArc(x, y, width, height, 0, 360); + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) + { + if (arcWidth > width) + arcWidth = width; + if (arcHeight > height) + arcHeight = height; + + int xx = x + width - arcWidth; + int yy = y + height - arcHeight; + + fillArc(x, y, arcWidth, arcHeight, 90, 90); + fillArc(xx, y, arcWidth, arcHeight, 0, 90); + fillArc(xx, yy, arcWidth, arcHeight, 270, 90); + fillArc(x, yy, arcWidth, arcHeight, 180, 90); + + fillRect(x, y + arcHeight / 2, width, height - arcHeight + 1); + fillRect(x + arcWidth / 2, y, width - arcWidth + 1, height); + } + + public Font getFont() + { + if (font == null) + return new Font("SansSerif", Font.PLAIN, 12); + return font; + } + + // Until such time as pango is happy to talk directly to cairo, we + // actually need to redirect some calls from the GtkFontPeer and + // GtkFontMetrics into the drawing kit and ask cairo ourselves. + + static native void releasePeerGraphicsResource(GdkFontPeer f); + + public FontMetrics getFontMetrics() + { + return getFontMetrics(getFont()); + } + + public FontMetrics getFontMetrics(Font f) + { + // the reason we go via the toolkit here is to try to get + // a cached object. the toolkit keeps such a cache. + return Toolkit.getDefaultToolkit().getFontMetrics(f); + } + + public void setFont(Font f) + { + if (f.getPeer() instanceof GdkFontPeer) + font = f; + else + font = + ((ClasspathToolkit)(Toolkit.getDefaultToolkit())) + .getFont(f.getName(), f.getAttributes()); + } + + public String toString() + { + return (getClass().getName() + + "[font=" + getFont().toString() + + ",color=" + fg.toString() + + "]"); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java new file mode 100644 index 0000000..bfad87a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java @@ -0,0 +1,138 @@ +/* GdkGraphicsConfiguration.java -- describes characteristics of graphics + Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.peer.gtk; + +import java.awt.BufferCapabilities; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.ImageCapabilities; +import java.awt.Rectangle; + +import java.awt.geom.AffineTransform; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; + +public class GdkGraphicsConfiguration + extends GraphicsConfiguration +{ + GdkScreenGraphicsDevice gdkScreenGraphicsDevice; + ColorModel cm; + Rectangle bounds; + + public GtkToolkit getToolkit() + { + return gdkScreenGraphicsDevice.getToolkit(); + } + + public GdkGraphicsConfiguration(GdkScreenGraphicsDevice dev) + { + this.gdkScreenGraphicsDevice = dev; + cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel(); + bounds = getToolkit().getBounds(); + } + + public GraphicsDevice getDevice() + { + return gdkScreenGraphicsDevice; + } + + public BufferedImage createCompatibleImage(int w, int h) + { + return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + } + + public BufferedImage createCompatibleImage(int w, int h, + int transparency) + { + return createCompatibleImage(w, h); + } + + public VolatileImage createCompatibleVolatileImage(int w, int h) + { + return new GtkVolatileImage(w, h); + } + + public VolatileImage createCompatibleVolatileImage(int w, int h, + ImageCapabilities caps) + throws java.awt.AWTException + { + return new GtkVolatileImage(w, h, caps); + } + + public ColorModel getColorModel() + { + return cm; + } + + public ColorModel getColorModel(int transparency) + { + return getColorModel(); + } + + public AffineTransform getDefaultTransform() + { + // FIXME: extract the GDK DPI information here. + return new AffineTransform(); + } + + public AffineTransform getNormalizingTransform() + { + // FIXME: extract the GDK DPI information here. + return new AffineTransform(); + } + + public Rectangle getBounds() + { + return bounds; + } + + public BufferCapabilities getBufferCapabilities() + { + return new BufferCapabilities(getImageCapabilities(), + getImageCapabilities(), + BufferCapabilities.FlipContents.UNDEFINED); + } + + public ImageCapabilities getImageCapabilities() + { + return new ImageCapabilities(false); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java new file mode 100644 index 0000000..4f9d1c2 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -0,0 +1,107 @@ +/* GdkGraphicsEnvironment.java -- information about the graphics environment + Copyright (C) 2004, 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.java.awt.peer.gtk; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; +import java.awt.image.BufferedImage; +import java.util.Locale; + +public class GdkGraphicsEnvironment extends GraphicsEnvironment +{ + GtkToolkit gtkToolkit; + + public GtkToolkit getToolkit() + { + return gtkToolkit; + } + + public GdkGraphicsEnvironment (GtkToolkit tk) + { + super(); + gtkToolkit = tk; + } + + public GraphicsDevice[] getScreenDevices () + { + // FIXME: Support multiple screens, since GDK can. + return new GraphicsDevice[] { new GdkScreenGraphicsDevice (this) }; + } + + public GraphicsDevice getDefaultScreenDevice () + { + if (GraphicsEnvironment.isHeadless ()) + throw new HeadlessException (); + + return new GdkScreenGraphicsDevice (this); + } + + public Graphics2D createGraphics (BufferedImage image) + { + return new GdkGraphics2D (image); + } + + private native int nativeGetNumFontFamilies(); + private native void nativeGetFontFamilies(String[] family_names); + + public Font[] getAllFonts () + { + throw new java.lang.UnsupportedOperationException (); + } + + public String[] getAvailableFontFamilyNames () + { + String[] family_names; + int array_size; + + array_size = nativeGetNumFontFamilies(); + family_names = new String[array_size]; + + nativeGetFontFamilies(family_names); + return family_names; + } + + public String[] getAvailableFontFamilyNames (Locale l) + { + throw new java.lang.UnsupportedOperationException (); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java new file mode 100644 index 0000000..57d5a36 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -0,0 +1,681 @@ +/* GdkPixbufDecoder.java -- Image data decoding object + Copyright (C) 2003, 2004, 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.java.awt.peer.gtk; + +import gnu.classpath.Configuration; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageProducer; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Locale; +import java.util.Vector; + +import javax.imageio.IIOImage; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.spi.IIORegistry; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; + +public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder +{ + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("gtkpeer"); + } + initStaticState (); + } + + static native void initStaticState(); + private final int native_state = GtkGenericPeer.getUniqueInteger (); + + // initState() has been called, but pumpDone() has not yet been called. + private boolean needsClose = false; + + // the current set of ImageConsumers for this decoder + Vector curr; + + // interface to GdkPixbuf + native void initState (); + native void pumpBytes (byte[] bytes, int len) throws IOException; + native void pumpDone () throws IOException; + native void finish (boolean needsClose); + static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink); + + // gdk-pixbuf provids data in RGBA format + static final ColorModel cm = new DirectColorModel (32, 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); + public GdkPixbufDecoder (InputStream in) + { + super (in); + } + + public GdkPixbufDecoder (String filename) + { + super (filename); + } + + public GdkPixbufDecoder (URL url) + { + super (url); + } + + public GdkPixbufDecoder (byte[] imagedata, int imageoffset, int imagelength) + { + super (imagedata, imageoffset, imagelength); + } + + // called back by native side + void areaPrepared (int width, int height) + { + + if (curr == null) + return; + + for (int i = 0; i < curr.size (); i++) + { + ImageConsumer ic = (ImageConsumer) curr.elementAt (i); + ic.setDimensions (width, height); + ic.setColorModel (cm); + ic.setHints (ImageConsumer.RANDOMPIXELORDER); + } + } + + // called back by native side + void areaUpdated (int x, int y, int width, int height, + int pixels[], int scansize) + { + if (curr == null) + return; + + for (int i = 0; i < curr.size (); i++) + { + ImageConsumer ic = (ImageConsumer) curr.elementAt (i); + ic.setPixels (x, y, width, height, cm, pixels, 0, scansize); + } + } + + // called from an async image loader of one sort or another, this method + // repeatedly reads bytes from the input stream and passes them through a + // GdkPixbufLoader using the native method pumpBytes. pumpBytes in turn + // decodes the image data and calls back areaPrepared and areaUpdated on + // this object, feeding back decoded pixel blocks, which we pass to each + // of the ImageConsumers in the provided Vector. + + public void produce (Vector v, InputStream is) throws IOException + { + curr = v; + + byte bytes[] = new byte[4096]; + int len = 0; + initState(); + needsClose = true; + while ((len = is.read (bytes)) != -1) + pumpBytes (bytes, len); + pumpDone(); + needsClose = false; + + for (int i = 0; i < curr.size (); i++) + { + ImageConsumer ic = (ImageConsumer) curr.elementAt (i); + ic.imageComplete (ImageConsumer.STATICIMAGEDONE); + } + + curr = null; + } + + public void finalize() + { + finish(needsClose); + } + + + public static class ImageFormatSpec + { + public String name; + public boolean writable = false; + public ArrayList mimeTypes = new ArrayList(); + public ArrayList extensions = new ArrayList(); + + public ImageFormatSpec(String name, boolean writable) + { + this.name = name; + this.writable = writable; + } + + public synchronized void addMimeType(String m) + { + mimeTypes.add(m); + } + + public synchronized void addExtension(String e) + { + extensions.add(e); + } + } + + static ArrayList imageFormatSpecs; + + public static ImageFormatSpec registerFormat(String name, boolean writable) + { + ImageFormatSpec ifs = new ImageFormatSpec(name, writable); + synchronized(GdkPixbufDecoder.class) + { + if (imageFormatSpecs == null) + imageFormatSpecs = new ArrayList(); + imageFormatSpecs.add(ifs); + } + return ifs; + } + + static String[] getFormatNames(boolean writable) + { + ArrayList names = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + names.add(ifs.name); + + /* + * In order to make the filtering code work, we need to register + * this type under every "format name" likely to be used as a synonym. + * This generally means "all the extensions people might use". + */ + + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + names.add((String) j.next()); + } + } + Object[] objs = names.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + static String[] getFormatExtensions(boolean writable) + { + ArrayList extensions = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + extensions.add((String) j.next()); + } + } + Object[] objs = extensions.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + static String[] getFormatMimeTypes(boolean writable) + { + ArrayList mimeTypes = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + Iterator j = ifs.mimeTypes.iterator(); + while (j.hasNext()) + mimeTypes.add((String) j.next()); + } + } + Object[] objs = mimeTypes.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + + static String findFormatName(Object ext, boolean needWritable) + { + if (ext == null) + throw new IllegalArgumentException("extension is null"); + + if (!(ext instanceof String)) + throw new IllegalArgumentException("extension is not a string"); + + String str = (String) ext; + + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + + if (needWritable && !ifs.writable) + continue; + + if (ifs.name.equals(str)) + return str; + + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + { + String extension = (String)j.next(); + if (extension.equals(str)) + return ifs.name; + } + + j = ifs.mimeTypes.iterator(); + while (j.hasNext()) + { + String mimeType = (String)j.next(); + if (mimeType.equals(str)) + return ifs.name; + } + } + throw new IllegalArgumentException("unknown extension '" + str + "'"); + } + + private static GdkPixbufReaderSpi readerSpi; + private static GdkPixbufWriterSpi writerSpi; + + public static synchronized GdkPixbufReaderSpi getReaderSpi() + { + if (readerSpi == null) + readerSpi = new GdkPixbufReaderSpi(); + return readerSpi; + } + + public static synchronized GdkPixbufWriterSpi getWriterSpi() + { + if (writerSpi == null) + writerSpi = new GdkPixbufWriterSpi(); + return writerSpi; + } + + public static void registerSpis(IIORegistry reg) + { + reg.registerServiceProvider(getReaderSpi(), ImageReaderSpi.class); + reg.registerServiceProvider(getWriterSpi(), ImageWriterSpi.class); + } + + public static class GdkPixbufWriterSpi extends ImageWriterSpi + { + public GdkPixbufWriterSpi() + { + super("GdkPixbuf", "2.x", + GdkPixbufDecoder.getFormatNames(true), + GdkPixbufDecoder.getFormatExtensions(true), + GdkPixbufDecoder.getFormatMimeTypes(true), + "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriter", + new Class[] { ImageOutputStream.class }, + new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReaderSpi" }, + false, null, null, null, null, + false, null, null, null, null); + } + + public boolean canEncodeImage(ImageTypeSpecifier ts) + { + return true; + } + + public ImageWriter createWriterInstance(Object ext) + { + return new GdkPixbufWriter(this, ext); + } + + public String getDescription(java.util.Locale loc) + { + return "GdkPixbuf Writer SPI"; + } + + } + + public static class GdkPixbufReaderSpi extends ImageReaderSpi + { + public GdkPixbufReaderSpi() + { + super("GdkPixbuf", "2.x", + GdkPixbufDecoder.getFormatNames(false), + GdkPixbufDecoder.getFormatExtensions(false), + GdkPixbufDecoder.getFormatMimeTypes(false), + "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReader", + new Class[] { ImageInputStream.class }, + new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriterSpi" }, + false, null, null, null, null, + false, null, null, null, null); + } + + public boolean canDecodeInput(Object obj) + { + return true; + } + + public ImageReader createReaderInstance(Object ext) + { + return new GdkPixbufReader(this, ext); + } + + public String getDescription(Locale loc) + { + return "GdkPixbuf Reader SPI"; + } + } + + private static class GdkPixbufWriter + extends ImageWriter + { + String ext; + public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext) + { + super(ownerSpi); + this.ext = findFormatName(ext, true); + } + + public IIOMetadata convertImageMetadata (IIOMetadata inData, + ImageTypeSpecifier imageType, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata convertStreamMetadata (IIOMetadata inData, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata getDefaultStreamMetadata (ImageWriteParam param) + { + return null; + } + + public void write (IIOMetadata streamMetadata, IIOImage i, ImageWriteParam param) + throws IOException + { + RenderedImage image = i.getRenderedImage(); + Raster ras = image.getData(); + int width = ras.getWidth(); + int height = ras.getHeight(); + ColorModel model = image.getColorModel(); + int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras); + + if (pixels == null) + { + BufferedImage img = new BufferedImage(width, height, + (model != null && model.hasAlpha() ? + BufferedImage.TYPE_INT_ARGB + : BufferedImage.TYPE_INT_RGB)); + int[] pix = new int[4]; + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix))); + pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(), + img.getRaster()); + model = img.getColorModel(); + } + + processImageStarted(1); + streamImage(pixels, this.ext, width, height, model.hasAlpha(), + (DataOutput) this.getOutput()); + processImageComplete(); + } + } + + private static class GdkPixbufReader + extends ImageReader + implements ImageConsumer + { + // ImageConsumer parts + GdkPixbufDecoder dec; + BufferedImage bufferedImage; + ColorModel defaultModel; + int width; + int height; + String ext; + + public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext) + { + super(ownerSpi); + this.ext = findFormatName(ext, false); + } + + public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext, GdkPixbufDecoder d) + { + this(ownerSpi, ext); + dec = d; + } + + public void setDimensions(int w, int h) + { + processImageStarted(1); + width = w; + height = h; + } + + public void setProperties(Hashtable props) {} + + public void setColorModel(ColorModel model) + { + defaultModel = model; + } + + public void setHints(int flags) {} + + public void setPixels(int x, int y, int w, int h, + ColorModel model, byte[] pixels, + int offset, int scansize) + { + } + + public void setPixels(int x, int y, int w, int h, + ColorModel model, int[] pixels, + int offset, int scansize) + { + if (model == null) + model = defaultModel; + + if (bufferedImage == null) + { + bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ? + BufferedImage.TYPE_INT_ARGB + : BufferedImage.TYPE_INT_RGB)); + } + + int pixels2[]; + if (model != null) + { + pixels2 = new int[pixels.length]; + for (int yy = 0; yy < h; yy++) + for (int xx = 0; xx < w; xx++) + { + int i = yy * scansize + xx; + pixels2[i] = model.getRGB (pixels[i]); + } + } + else + pixels2 = pixels; + + bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize); + processImageProgress(y / (height == 0 ? 1 : height)); + } + + public void imageComplete(int status) + { + processImageComplete(); + } + + public BufferedImage getBufferedImage() + { + if (bufferedImage == null && dec != null) + dec.startProduction (this); + return bufferedImage; + } + + // ImageReader parts + + public int getNumImages(boolean allowSearch) + throws IOException + { + return 1; + } + + public IIOMetadata getImageMetadata(int i) + { + return null; + } + + public IIOMetadata getStreamMetadata() + throws IOException + { + return null; + } + + public Iterator getImageTypes(int imageIndex) + throws IOException + { + BufferedImage img = getBufferedImage(); + Vector vec = new Vector(); + vec.add(new ImageTypeSpecifier(img)); + return vec.iterator(); + } + + public int getHeight(int imageIndex) + throws IOException + { + return getBufferedImage().getHeight(); + } + + public int getWidth(int imageIndex) + throws IOException + { + return getBufferedImage().getWidth(); + } + + public void setInput(Object input, + boolean seekForwardOnly, + boolean ignoreMetadata) + { + super.setInput(input, seekForwardOnly, ignoreMetadata); + dec = new GdkPixbufDecoder((InputStream) getInput()); + } + + public BufferedImage read(int imageIndex, ImageReadParam param) + throws IOException + { + return getBufferedImage (); + } + } + + // remaining helper class and static method is a convenience for the Gtk + // peers, for loading a BufferedImage in off a disk file without going + // through the whole imageio system. + + public static BufferedImage createBufferedImage (String filename) + { + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (filename)); + return r.getBufferedImage (); + } + + public static BufferedImage createBufferedImage (URL u) + { + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (u)); + return r.getBufferedImage (); + } + + public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset, + int imagelength) + { + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (imagedata, + imageoffset, + imagelength)); + return r.getBufferedImage (); + } + + public static BufferedImage createBufferedImage (ImageProducer producer) + { + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null); + producer.startProduction(r); + return r.getBufferedImage (); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java new file mode 100644 index 0000000..6d0218d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java @@ -0,0 +1,94 @@ +/* GdkRobot.java -- an XTest implementation of RobotPeer + Copyright (C) 2004, 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.java.awt.peer.gtk; + +import java.awt.AWTException; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.peer.RobotPeer; + +/** + * Implements the RobotPeer interface using the XTest extension. + * + * @author Thomas Fitzsimmons + */ +public class GdkRobotPeer implements RobotPeer +{ + // gdk-pixbuf provides data in RGBA format + static final ColorModel cm = new DirectColorModel (32, 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); + + public GdkRobotPeer (GraphicsDevice screen) throws AWTException + { + // FIXME: make use of screen parameter when GraphicsDevice is + // implemented. + if (!initXTest ()) + throw new AWTException ("XTest extension not supported"); + } + + native boolean initXTest (); + + // RobotPeer methods + public native void mouseMove (int x, int y); + public native void mousePress (int buttons); + public native void mouseRelease (int buttons); + public native void mouseWheel (int wheelAmt); + public native void keyPress (int keycode); + public native void keyRelease (int keycode); + native int[] nativeGetRGBPixels (int x, int y, int width, int height); + + public int getRGBPixel (int x, int y) + { + return cm.getRGB (nativeGetRGBPixels (x, y, 1, 1)[0]); + } + + public int[] getRGBPixels (Rectangle r) + { + int[] gdk_pixels = nativeGetRGBPixels (r.x, r.y, r.width, r.height); + int[] pixels = new int[r.width * r.height]; + + for (int i = 0; i < r.width * r.height; i++) + pixels[i] = cm.getRGB (gdk_pixels[i]); + + return pixels; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java new file mode 100644 index 0000000..2bf9d23 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java @@ -0,0 +1,115 @@ +/* GdkScreenGraphicsDevice.java -- information about a screen device + Copyright (C) 2004, 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.java.awt.peer.gtk; + +import java.awt.Dimension; +import java.awt.DisplayMode; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; + +public class GdkScreenGraphicsDevice extends GraphicsDevice +{ + GdkGraphicsEnvironment env; + + public GtkToolkit getToolkit() + { + return env.getToolkit(); + } + + public GdkScreenGraphicsDevice (GdkGraphicsEnvironment e) + { + super (); + env = e; + } + + public int getType () + { + return GraphicsDevice.TYPE_RASTER_SCREEN; + } + + public String getIDstring () + { + // FIXME: query X for this string + return "default GDK device ID string"; + } + + public GraphicsConfiguration[] getConfigurations () + { + // FIXME: query X for the list of possible configurations + return new GraphicsConfiguration [] { new GdkGraphicsConfiguration(this) }; + } + + public GraphicsConfiguration getDefaultConfiguration () + { + + // FIXME: query X for default configuration + return new GdkGraphicsConfiguration(this); + } + + + /** + * Returns the current display mode of this device, or null if unknown. + * + * @return the current display mode + * @see #setDisplayMode(DisplayMode) + * @see #getDisplayModes() + * @since 1.4 + */ + public DisplayMode getDisplayMode() + { + // determine display mode + Dimension dim = getToolkit().getScreenSize(); + DisplayMode mode = new DisplayMode(dim.width, dim.height, 0, + DisplayMode.REFRESH_RATE_UNKNOWN); + return mode; + } + + /** + * This device does not yet support fullscreen exclusive mode, so this + * returns <code>false</code>. + * + * @return <code>false</code> + * @since 1.4 + */ + public boolean isFullScreenSupported() + { + return false; + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java new file mode 100644 index 0000000..ff51745 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java @@ -0,0 +1,434 @@ +/* GdkTextLayout.java + Copyright (C) 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.peer.gtk; + +import gnu.classpath.Configuration; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.font.TextAttribute; +import java.awt.font.TextHitInfo; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Rectangle2D; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.text.CharacterIterator; + +/** + * This is an implementation of the text layout peer interface which + * delegates all the hard work to pango. + * + * @author Graydon Hoare + */ + +public class GdkTextLayout + implements ClasspathTextLayoutPeer +{ + // native side, plumbing, etc. + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("gtkpeer"); + } + initStaticState (); + } + private native void setText(String str); + private native void getExtents(double[] inkExtents, + double[] logExtents); + private native void indexToPos(int idx, double[] pos); + private native void initState (); + private native void dispose (); + static native void initStaticState(); + private final int native_state = GtkGenericPeer.getUniqueInteger (); + protected void finalize () + { + dispose (); + } + + // we hold on to these to make sure we can render when presented + // with non-GdkGraphics2D paint targets + private AttributedString attributedString; + private FontRenderContext fontRenderContext; + + public GdkTextLayout(AttributedString str, FontRenderContext frc) + { + initState(); + attributedString = str; + fontRenderContext = frc; + } + + protected class CharacterIteratorProxy + implements CharacterIterator + { + public CharacterIterator target; + public int begin; + public int limit; + public int index; + + public CharacterIteratorProxy (CharacterIterator ci) + { + target = ci; + } + + public int getBeginIndex () + { + return begin; + } + + public int getEndIndex () + { + return limit; + } + + public int getIndex () + { + return index; + } + + public char setIndex (int idx) + throws IllegalArgumentException + { + if (idx < begin || idx >= limit) + throw new IllegalArgumentException (); + char ch = target.setIndex (idx); + index = idx; + return ch; + } + + public char first () + { + int save = target.getIndex (); + char ch = target.setIndex (begin); + target.setIndex (save); + return ch; + } + + public char last () + { + if (begin == limit) + return this.first (); + + int save = target.getIndex (); + char ch = target.setIndex (limit - 1); + target.setIndex (save); + return ch; + } + + public char current () + { + return target.current(); + } + + public char next () + { + if (index >= limit - 1) + return CharacterIterator.DONE; + else + { + index++; + return target.next(); + } + } + + public char previous () + { + if (index <= begin) + return CharacterIterator.DONE; + else + { + index--; + return target.previous (); + } + } + + public Object clone () + { + CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target); + cip.begin = this.begin; + cip.limit = this.limit; + cip.index = this.index; + return cip; + } + + } + + + // public side + + public void draw (Graphics2D g2, float x, float y) + { + if (g2 instanceof GdkGraphics2D) + { + // we share pango structures directly with GdkGraphics2D + // when legal + GdkGraphics2D gg2 = (GdkGraphics2D) g2; + gg2.drawGdkTextLayout(this, x, y); + } + else + { + // falling back to a rather tedious layout algorithm when + // not legal + AttributedCharacterIterator ci = attributedString.getIterator (); + CharacterIteratorProxy proxy = new CharacterIteratorProxy (ci); + Font defFont = g2.getFont (); + + /* Note: this implementation currently only interprets FONT text + * attributes. There is a reasonable argument to be made for some + * attributes being interpreted out here, where we have control of the + * Graphics2D and can construct or derive new fonts, and some + * attributes being interpreted by the GlyphVector itself. So far, for + * all attributes except FONT we do neither. + */ + + for (char c = ci.first (); + c != CharacterIterator.DONE; + c = ci.next ()) + { + proxy.begin = ci.getIndex (); + proxy.limit = ci.getRunLimit(TextAttribute.FONT); + if (proxy.limit <= proxy.begin) + continue; + + proxy.index = proxy.begin; + + Object fnt = ci.getAttribute(TextAttribute.FONT); + GlyphVector gv; + if (fnt instanceof Font) + gv = ((Font)fnt).createGlyphVector (fontRenderContext, proxy); + else + gv = defFont.createGlyphVector (fontRenderContext, proxy); + + g2.drawGlyphVector (gv, x, y); + + int n = gv.getNumGlyphs (); + for (int i = 0; i < n; ++i) + { + GlyphMetrics gm = gv.getGlyphMetrics (i); + if (gm.getAdvanceX() == gm.getAdvance ()) + x += gm.getAdvanceX (); + else + y += gm.getAdvanceY (); + } + } + } + } + + public TextHitInfo getStrongCaret (TextHitInfo hit1, + TextHitInfo hit2) + { + throw new Error("not implemented"); + } + + public byte getBaseline () + { + throw new Error("not implemented"); + } + + public boolean isLeftToRight () + { + throw new Error("not implemented"); + } + + public boolean isVertical () + { + throw new Error("not implemented"); + } + + public float getAdvance () + { + throw new Error("not implemented"); + } + + public float getAscent () + { + throw new Error("not implemented"); + } + + public float getDescent () + { + throw new Error("not implemented"); + } + + public float getLeading () + { + throw new Error("not implemented"); + } + + public int getCharacterCount () + { + throw new Error("not implemented"); + } + + public byte getCharacterLevel (int index) + { + throw new Error("not implemented"); + } + + public float[] getBaselineOffsets () + { + throw new Error("not implemented"); + } + + public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint) + { + throw new Error("not implemented"); + } + + public Rectangle2D getBounds () + { + double[] inkExtents = new double[4]; + double[] logExtents = new double[4]; + getExtents(inkExtents, logExtents); + return new Rectangle2D.Double(logExtents[0], logExtents[1], + logExtents[2], logExtents[3]); + } + + public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + public Shape[] getCaretShapes (int offset, Rectangle2D bounds, + TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + + public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, + Rectangle2D bounds) + { + AffineTransform at = new AffineTransform(); + GeneralPath gp = new GeneralPath(); + double [] rect = new double[4]; + Rectangle2D tmp = new Rectangle2D.Double(); + for (int i = firstEndpoint; i <= secondEndpoint; ++i) + { + indexToPos(i, rect); + tmp.setRect(rect[0], rect[1], rect[2], rect[3]); + Rectangle2D.intersect(tmp, bounds, tmp); + gp.append(tmp.getPathIterator(at), false); + } + return gp; + } + + public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint) + { + throw new Error("not implemented"); + } + + public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy) + { + throw new Error("not implemented"); + } + public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds) + { + throw new Error("not implemented"); + } + public TextHitInfo getVisualOtherHit (TextHitInfo hit) + { + throw new Error("not implemented"); + } + + public float getVisibleAdvance () + { + throw new Error("not implemented"); + } + + public Shape getOutline (AffineTransform tx) + { + throw new Error("not implemented"); + } + + public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, + TextHitInfo secondEndpoint, + Rectangle2D bounds) + { + throw new Error("not implemented"); + } + + + public TextLayout getJustifiedLayout (float justificationWidth) + { + throw new Error("not implemented"); + } + + public void handleJustify (float justificationWidth) + { + throw new Error("not implemented"); + } + + public Object clone () + { + throw new Error("not implemented"); + } + + public int hashCode () + { + throw new Error("not implemented"); + } + + public boolean equals (ClasspathTextLayoutPeer tl) + { + throw new Error("not implemented"); + } + + public String toString () + { + throw new Error("not implemented"); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java new file mode 100644 index 0000000..ab5df9f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java @@ -0,0 +1,107 @@ +/* GtkButtonPeer.java -- Implements ButtonPeer with GTK + Copyright (C) 1998, 1999, 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Component; +import java.awt.Point; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.peer.ButtonPeer; + +public class GtkButtonPeer extends GtkComponentPeer + implements ButtonPeer +{ + native void create (String label); + + public native void connectSignals (); + + native void gtkWidgetModifyFont (String name, int style, int size); + native void gtkSetLabel (String label); + native void gtkWidgetSetForeground (int red, int green, int blue); + native void gtkWidgetSetBackground (int red, int green, int blue); + native void gtkActivate (); + native void gtkWidgetRequestFocus (); + native void setNativeBounds (int x, int y, int width, int height); + + public GtkButtonPeer (Button b) + { + super (b); + } + + void create () + { + create (((Button) awtComponent).getLabel ()); + } + + public void setLabel (String label) + { + gtkSetLabel(label); + } + + public void handleEvent (AWTEvent e) + { + if (e.getID () == MouseEvent.MOUSE_RELEASED && isEnabled ()) + { + MouseEvent me = (MouseEvent) e; + Point p = me.getPoint(); + p.translate(((Component) me.getSource()).getX(), + ((Component) me.getSource()).getY()); + if (!me.isConsumed () + && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0 + && awtComponent.getBounds().contains(p)) + postActionEvent (((Button) awtComponent).getActionCommand (), + me.getModifiersEx ()); + } + + if (e.getID () == KeyEvent.KEY_PRESSED) + { + KeyEvent ke = (KeyEvent) e; + if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_SPACE) + { + postActionEvent (((Button) awtComponent).getActionCommand (), + ke.getModifiersEx ()); + gtkActivate (); + } + } + + super.handleEvent (e); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java new file mode 100644 index 0000000..dc21761 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java @@ -0,0 +1,100 @@ +/* GtkCanvasPeer.java + Copyright (C) 1998, 1999 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.PaintEvent; +import java.awt.peer.CanvasPeer; + +public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer +{ + native void create (); + + public GtkCanvasPeer (Canvas c) + { + super (c); + } + + public Graphics getGraphics () + { + if (GtkToolkit.useGraphics2D ()) + return new GdkGraphics2D (this); + else + return new GdkGraphics (this); + } + + public void handleEvent (AWTEvent event) + { + int id = event.getID(); + + switch (id) + { + case PaintEvent.PAINT: + case PaintEvent.UPDATE: + { + try + { + Graphics g = getGraphics (); + g.setClip (((PaintEvent)event).getUpdateRect()); + + if (id == PaintEvent.PAINT) + awtComponent.paint (g); + else + awtComponent.update (g); + + g.dispose (); + } + catch (InternalError e) + { + System.err.println (e); + } + } + break; + } + } + + /* Preferred size for a drawing widget is always what the user requested */ + public Dimension getPreferredSize () + { + return awtComponent.getSize (); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java new file mode 100644 index 0000000..46b0733 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java @@ -0,0 +1,86 @@ +/* GtkCheckboxGroupPeer.java - Wrap a CheckboxGroup + Copyright (C) 2002 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.java.awt.peer.gtk; + +import java.awt.CheckboxGroup; +import java.util.WeakHashMap; + +// Note that there is no peer interface for a CheckboxGroup. We +// introduce our own in order to make it easier to keep a piece of +// native state for each one. +public class GtkCheckboxGroupPeer extends GtkGenericPeer +{ + // This maps from a CheckboxGroup to the native peer. + private static WeakHashMap map = new WeakHashMap (); + + // Find the native peer corresponding to a CheckboxGroup. + public static synchronized GtkCheckboxGroupPeer + getCheckboxGroupPeer (CheckboxGroup group) + { + if (group == null) + return null; + GtkCheckboxGroupPeer nat = (GtkCheckboxGroupPeer) map.get (group); + if (nat == null) + { + nat = new GtkCheckboxGroupPeer (); + map.put (group, nat); + } + return nat; + } + + private GtkCheckboxGroupPeer () + { + // We don't need any special state here. Note that we can't store + // a reference to the java-side CheckboxGroup. That would mean + // they could never be collected. + super (null); + } + + // Dispose of our native resources. + public native void dispose (); + + // Remove a given checkbox from this group. + public native void remove (GtkCheckboxPeer box); + + // When collected, clean up the native state. + protected void finalize () + { + dispose (); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java new file mode 100644 index 0000000..01a6e31 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java @@ -0,0 +1,69 @@ +/* GtkCheckboxMenuItemPeer.java -- Implements CheckboxMenuItemPeer with GTK+ + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.CheckboxMenuItem; +import java.awt.ItemSelectable; +import java.awt.event.ItemEvent; +import java.awt.peer.CheckboxMenuItemPeer; + +public class GtkCheckboxMenuItemPeer extends GtkMenuItemPeer + implements CheckboxMenuItemPeer +{ + native void create (String label); + + public GtkCheckboxMenuItemPeer (CheckboxMenuItem menu) + { + super (menu); + setState (menu.getState ()); + } + + public native void setState(boolean t); + + protected void postMenuActionEvent () + { + CheckboxMenuItem item = (CheckboxMenuItem)awtWidget; + q().postEvent (new ItemEvent ((ItemSelectable)awtWidget, + ItemEvent.ITEM_STATE_CHANGED, + item.getActionCommand(), + item.getState() ? ItemEvent.DESELECTED : ItemEvent.SELECTED)); + + super.postMenuActionEvent(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java new file mode 100644 index 0000000..8517572 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java @@ -0,0 +1,128 @@ +/* GtkCheckboxPeer.java -- Implements CheckboxPeer with GTK + Copyright (C) 1998, 1999, 2002, 2003 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.java.awt.peer.gtk; + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.peer.CheckboxPeer; + +public class GtkCheckboxPeer extends GtkComponentPeer + implements CheckboxPeer +{ + // Group from last time it was set. + public GtkCheckboxGroupPeer old_group; + // The current state of the GTK checkbox. + private boolean currentState; + + public native void create (GtkCheckboxGroupPeer group); + public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group); + public native void connectSignals (); + native void gtkWidgetModifyFont (String name, int style, int size); + native void gtkButtonSetLabel (String label); + native void gtkToggleButtonSetActive (boolean is_active); + + public GtkCheckboxPeer (Checkbox c) + { + super (c); + } + + // FIXME: we must be able to switch between a checkbutton and a + // radiobutton dynamically. + public void create () + { + Checkbox checkbox = (Checkbox) awtComponent; + CheckboxGroup g = checkbox.getCheckboxGroup (); + old_group = GtkCheckboxGroupPeer.getCheckboxGroupPeer (g); + create (old_group); + gtkToggleButtonSetActive (checkbox.getState ()); + gtkButtonSetLabel (checkbox.getLabel ()); + } + + public void setState (boolean state) + { + if (currentState != state) + gtkToggleButtonSetActive (state); + } + + public void setLabel (String label) + { + gtkButtonSetLabel (label); + } + + public void setCheckboxGroup (CheckboxGroup group) + { + GtkCheckboxGroupPeer gp + = GtkCheckboxGroupPeer.getCheckboxGroupPeer (group); + if (gp != old_group) + { + if (old_group != null) + old_group.remove (this); + nativeSetCheckboxGroup (gp); + old_group = gp; + } + } + + // Override the superclass postItemEvent so that the peer doesn't + // need information that we have. + public void postItemEvent (Object item, int stateChange) + { + Checkbox currentCheckBox = ((Checkbox)awtComponent); + // A firing of the event is only desired if the state has changed due to a + // button press. The currentCheckBox's state must be different from the + // one that the stateChange is changing to. + // stateChange = 1 if it goes from false -> true + // stateChange = 2 if it goes from true -> false + if (( !currentCheckBox.getState() && stateChange == 1) + || (currentCheckBox.getState() && stateChange == 2)) + { + super.postItemEvent (awtComponent, stateChange); + currentState = !currentCheckBox.getState(); + currentCheckBox.setState(currentState); + } + } + + public void dispose () + { + // Notify the group so that the native state can be cleaned up + // appropriately. + if (old_group != null) + old_group.remove (this); + super.dispose (); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java new file mode 100644 index 0000000..5028ea7 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -0,0 +1,130 @@ +/* GtkChoicePeer.java -- Implements ChoicePeer with GTK + Copyright (C) 1998, 1999, 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.java.awt.peer.gtk; + +import java.awt.Choice; +import java.awt.event.ItemEvent; +import java.awt.peer.ChoicePeer; + +public class GtkChoicePeer extends GtkComponentPeer + implements ChoicePeer +{ + public GtkChoicePeer (Choice c) + { + super (c); + + int count = c.getItemCount (); + if (count > 0) + { + String items[] = new String[count]; + for (int i = 0; i < count; i++) + items[i] = c.getItem (i); + + append (items); + } + + int selected = c.getSelectedIndex(); + if (selected >= 0) + select(selected); + } + + native void create (); + + native void append (String items[]); + native int nativeGetSelected (); + native void nativeAdd (String item, int index); + native void nativeRemove (int index); + native void nativeRemoveAll (); + + native void connectSignals (); + + public native void select (int position); + + public void add (String item, int index) + { + int before = nativeGetSelected(); + + nativeAdd (item, index); + + /* Generate an ItemEvent if we added the first one or + if we inserted at or before the currently selected item. */ + if ((before < 0) || (before >= index)) + { + // Must set our state before notifying listeners + ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0)); + postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED); + } + } + + public void remove (int index) + { + int before = nativeGetSelected(); + int after; + + nativeRemove (index); + after = nativeGetSelected(); + + /* Generate an ItemEvent if we are removing the currently selected item + and there are at least one item left. */ + if ((before == index) && (after >= 0)) + { + // Must set our state before notifying listeners + ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0)); + postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED); + } + } + + public void removeAll () + { + nativeRemoveAll(); + } + + public void addItem (String item, int position) + { + add (item, position); + } + + protected void postChoiceItemEvent (String label, int stateChange) + { + // Must set our state before notifying listeners + if (stateChange == ItemEvent.SELECTED) + ((Choice) awtComponent).select (label); + postItemEvent (label, stateChange); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java new file mode 100644 index 0000000..c719cdd --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java @@ -0,0 +1,170 @@ +/* GtkClipboard.java + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class GtkClipboard extends Clipboard +{ + /* the number of milliseconds that we'll wait around for the + owner of the GDK_SELECTION_PRIMARY selection to convert + the requested data */ + static final int SELECTION_RECEIVED_TIMEOUT = 5000; + + /* We currently only support transferring of text between applications */ + static String selection; + static Object selectionLock = new Object (); + + static boolean hasSelection = false; + + protected GtkClipboard() + { + super("System Clipboard"); + initNativeState(); + } + + public Transferable getContents(Object requestor) + { + synchronized (this) + { + if (hasSelection) + return contents; + } + + /* Java doesn't own the selection, so we need to ask X11 */ + // XXX: Does this hold with Swing too ? + synchronized (selectionLock) + { + requestStringConversion(); + + try + { + selectionLock.wait(SELECTION_RECEIVED_TIMEOUT); + } + catch (InterruptedException e) + { + return null; + } + + return selection == null ? null : new StringSelection(selection); + } + } + + void stringSelectionReceived(String newSelection) + { + synchronized (selectionLock) + { + selection = newSelection; + selectionLock.notify(); + } + } + + /* convert Java clipboard data into a String suitable for sending + to another application */ + synchronized String stringSelectionHandler() throws IOException + { + String selection = null; + + try + { + if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) + selection = (String)contents.getTransferData(DataFlavor.stringFlavor); + else if (contents.isDataFlavorSupported(DataFlavor.plainTextFlavor)) + { + StringBuffer sbuf = new StringBuffer(); + InputStreamReader reader; + char readBuf[] = new char[512]; + int numChars; + + reader = new InputStreamReader + ((InputStream) + contents.getTransferData(DataFlavor.plainTextFlavor), "UNICODE"); + + while (true) + { + numChars = reader.read(readBuf); + if (numChars == -1) + break; + sbuf.append(readBuf, 0, numChars); + } + + selection = new String(sbuf); + } + } + catch (Exception e) + { + } + + return selection; + } + + public synchronized void setContents(Transferable contents, + ClipboardOwner owner) + { + selectionGet(); + + this.contents = contents; + this.owner = owner; + + hasSelection = true; + } + + synchronized void selectionClear() + { + hasSelection = false; + + if (owner != null) + { + owner.lostOwnership(this, contents); + owner = null; + contents = null; + } + } + + native void initNativeState(); + static native void requestStringConversion(); + static native void selectionGet(); +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java new file mode 100644 index 0000000..1578a9c --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -0,0 +1,651 @@ +/* GtkComponentPeer.java -- Implements ComponentPeer with GTK + Copyright (C) 1998, 1999, 2002, 2004, 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Insets; +import java.awt.ItemSelectable; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.FocusEvent; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.PaintEvent; +import java.awt.event.TextEvent; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.VolatileImage; +import java.awt.peer.ComponentPeer; + +public class GtkComponentPeer extends GtkGenericPeer + implements ComponentPeer +{ + VolatileImage backBuffer; + BufferCapabilities caps; + + Component awtComponent; + + Insets insets; + + boolean isInRepaint; + + /* this isEnabled differs from Component.isEnabled, in that it + knows if a parent is disabled. In that case Component.isEnabled + may return true, but our isEnabled will always return false */ + native boolean isEnabled (); + static native boolean modalHasGrab(); + + native int[] gtkWidgetGetForeground (); + native int[] gtkWidgetGetBackground (); + native void gtkWidgetGetDimensions (int[] dim); + native void gtkWidgetGetPreferredDimensions (int[] dim); + native void gtkWidgetGetLocationOnScreen (int[] point); + native void gtkWidgetSetCursor (int type); + native void gtkWidgetSetBackground (int red, int green, int blue); + native void gtkWidgetSetForeground (int red, int green, int blue); + native void gtkWidgetSetSensitive (boolean sensitive); + native void gtkWidgetSetParent (ComponentPeer parent); + native void gtkWidgetRequestFocus (); + native void gtkWidgetDispatchKeyEvent (int id, long when, int mods, + int keyCode, int keyLocation); + + native boolean isRealized (); + + void realize () + { + // Default implementation does nothing + } + + native void setNativeEventMask (); + + void create () + { + throw new RuntimeException (); + } + + native void connectSignals (); + + protected GtkComponentPeer (Component awtComponent) + { + super (awtComponent); + this.awtComponent = awtComponent; + insets = new Insets (0, 0, 0, 0); + + create (); + + connectSignals (); + + if (awtComponent.getForeground () != null) + setForeground (awtComponent.getForeground ()); + if (awtComponent.getBackground () != null) + setBackground (awtComponent.getBackground ()); + if (awtComponent.getFont() != null) + setFont(awtComponent.getFont()); + + Component parent = awtComponent.getParent (); + + // Only set our parent on the GTK side if our parent on the AWT + // side is not showing. Otherwise the gtk peer will be shown + // before we've had a chance to position and size it properly. + if (awtComponent instanceof Window + || (parent != null && ! parent.isShowing ())) + setParentAndBounds (); + + setNativeEventMask (); + + realize (); + } + + void setParentAndBounds () + { + setParent (); + + setComponentBounds (); + + setVisibleAndEnabled (); + } + + void setParent () + { + ComponentPeer p; + Component component = awtComponent; + do + { + component = component.getParent (); + p = component.getPeer (); + } + while (p instanceof java.awt.peer.LightweightPeer); + + if (p != null) + gtkWidgetSetParent (p); + } + + void beginNativeRepaint () + { + isInRepaint = true; + } + + void endNativeRepaint () + { + isInRepaint = false; + } + + /* + * Set the bounds of this peer's AWT Component based on dimensions + * returned by the native windowing system. Most Components impose + * their dimensions on the peers which is what the default + * implementation does. However some peers, like GtkFileDialogPeer, + * need to pass their size back to the AWT Component. + */ + void setComponentBounds () + { + Rectangle bounds = awtComponent.getBounds (); + + if (bounds.x == 0 && bounds.y == 0 + && bounds.width == 0 && bounds.height == 0) + return; + + setBounds (bounds.x, bounds.y, bounds.width, bounds.height); + } + + void setVisibleAndEnabled () + { + setVisible (awtComponent.isVisible ()); + setEnabled (awtComponent.isEnabled ()); + } + + public int checkImage (Image image, int width, int height, + ImageObserver observer) + { + return getToolkit().checkImage(image, width, height, observer); + } + + public Image createImage (ImageProducer producer) + { + return new GtkImage (producer); + } + + public Image createImage (int width, int height) + { + Image image; + if (GtkToolkit.useGraphics2D ()) + image = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB); + else + image = new GtkImage (width, height); + + Graphics g = image.getGraphics(); + g.setColor(getBackground()); + g.fillRect(0, 0, width, height); + return image; + } + + public void disable () + { + setEnabled (false); + } + + public void enable () + { + setEnabled (true); + } + + public ColorModel getColorModel () + { + return ColorModel.getRGBdefault (); + } + + public FontMetrics getFontMetrics (Font font) + { + return getToolkit().getFontMetrics(font); + } + + public Graphics getGraphics () + { + if (GtkToolkit.useGraphics2D ()) + return new GdkGraphics2D (this); + else + return new GdkGraphics (this); + } + + public Point getLocationOnScreen () + { + int point[] = new int[2]; + gtkWidgetGetLocationOnScreen (point); + return new Point (point[0], point[1]); + } + + public Dimension getMinimumSize () + { + return minimumSize (); + } + + public Dimension getPreferredSize () + { + return preferredSize (); + } + + public Toolkit getToolkit () + { + return Toolkit.getDefaultToolkit(); + } + + public void handleEvent (AWTEvent event) + { + int id = event.getID(); + KeyEvent ke = null; + + switch (id) + { + case PaintEvent.PAINT: + case PaintEvent.UPDATE: + { + try + { + Graphics g = getGraphics (); + + // Some peers like GtkFileDialogPeer are repainted by Gtk itself + if (g == null) + break; + + g.setClip (((PaintEvent) event).getUpdateRect()); + + if (id == PaintEvent.PAINT) + awtComponent.paint (g); + else + awtComponent.update (g); + + g.dispose (); + } + catch (InternalError e) + { + System.err.println (e); + } + } + break; + case KeyEvent.KEY_PRESSED: + ke = (KeyEvent) event; + gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (), + ke.getKeyCode (), ke.getKeyLocation ()); + break; + case KeyEvent.KEY_RELEASED: + ke = (KeyEvent) event; + gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (), + ke.getKeyCode (), ke.getKeyLocation ()); + break; + } + } + + public boolean isFocusTraversable () + { + return true; + } + + public Dimension minimumSize () + { + int dim[] = new int[2]; + + gtkWidgetGetPreferredDimensions (dim); + + return new Dimension (dim[0], dim[1]); + } + + public void paint (Graphics g) + { + } + + public Dimension preferredSize () + { + int dim[] = new int[2]; + + gtkWidgetGetPreferredDimensions (dim); + + return new Dimension (dim[0], dim[1]); + } + + public boolean prepareImage (Image image, int width, int height, + ImageObserver observer) + { + return getToolkit().prepareImage(image, width, height, observer); + } + + public void print (Graphics g) + { + throw new RuntimeException (); + } + + public void repaint (long tm, int x, int y, int width, int height) + { + if (x == 0 && y == 0 && width == 0 && height == 0) + return; + + q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, + new Rectangle (x, y, width, height))); + } + + public void requestFocus () + { + gtkWidgetRequestFocus(); + postFocusEvent(FocusEvent.FOCUS_GAINED, false); + } + + public void reshape (int x, int y, int width, int height) + { + setBounds (x, y, width, height); + } + + public void setBackground (Color c) + { + gtkWidgetSetBackground (c.getRed(), c.getGreen(), c.getBlue()); + } + + native void setNativeBounds (int x, int y, int width, int height); + + public void setBounds (int x, int y, int width, int height) + { + Component parent = awtComponent.getParent (); + + // Heavyweight components that are children of one or more + // lightweight containers have to be handled specially. Because + // calls to GLightweightPeer.setBounds do nothing, GTK has no + // knowledge of the lightweight containers' positions. So we have + // to add the offsets manually when placing a heavyweight + // component within a lightweight container. The lightweight + // container may itself be in a lightweight container and so on, + // so we need to continue adding offsets until we reach a + // container whose position GTK knows -- that is, the first + // non-lightweight. + boolean lightweightChild = false; + Insets i; + while (parent.isLightweight ()) + { + lightweightChild = true; + + i = ((Container) parent).getInsets (); + + x += parent.getX () + i.left; + y += parent.getY () + i.top; + + parent = parent.getParent (); + } + + // We only need to convert from Java to GTK coordinates if we're + // placing a heavyweight component in a Window. + if (parent instanceof Window && !lightweightChild) + { + Insets insets = ((Window) parent).getInsets (); + GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer (); + int menuBarHeight = 0; + if (peer instanceof GtkFramePeer) + menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight (); + + // Convert from Java coordinates to GTK coordinates. + setNativeBounds (x - insets.left, y - insets.top + menuBarHeight, + width, height); + } + else + setNativeBounds (x, y, width, height); + } + + void setCursor () + { + setCursor (awtComponent.getCursor ()); + } + + public void setCursor (Cursor cursor) + { + gtkWidgetSetCursor (cursor.getType ()); + } + + public void setEnabled (boolean b) + { + gtkWidgetSetSensitive (b); + } + + public void setFont (Font f) + { + // FIXME: This should really affect the widget tree below me. + // Currently this is only handled if the call is made directly on + // a text widget, which implements setFont() itself. + gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize()); + } + + public void setForeground (Color c) + { + gtkWidgetSetForeground (c.getRed(), c.getGreen(), c.getBlue()); + } + + public Color getForeground () + { + int rgb[] = gtkWidgetGetForeground (); + return new Color (rgb[0], rgb[1], rgb[2]); + } + + public Color getBackground () + { + int rgb[] = gtkWidgetGetBackground (); + return new Color (rgb[0], rgb[1], rgb[2]); + } + + public void setVisible (boolean b) + { + if (b) + show (); + else + hide (); + } + + public native void hide (); + public native void show (); + + protected void postMouseEvent(int id, long when, int mods, int x, int y, + int clickCount, boolean popupTrigger) + { + q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, + clickCount, popupTrigger)); + } + + protected void postExposeEvent (int x, int y, int width, int height) + { + if (!isInRepaint) + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + new Rectangle (x, y, width, height))); + } + + protected void postKeyEvent (int id, long when, int mods, + int keyCode, char keyChar, int keyLocation) + { + KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods, + keyCode, keyChar, keyLocation); + + // Also post a KEY_TYPED event if keyEvent is a key press that + // doesn't represent an action or modifier key. + if (keyEvent.getID () == KeyEvent.KEY_PRESSED + && (!keyEvent.isActionKey () + && keyCode != KeyEvent.VK_SHIFT + && keyCode != KeyEvent.VK_CONTROL + && keyCode != KeyEvent.VK_ALT)) + { + synchronized (q) + { + q().postEvent (keyEvent); + q().postEvent (new KeyEvent (awtComponent, KeyEvent.KEY_TYPED, when, mods, + KeyEvent.VK_UNDEFINED, keyChar, keyLocation)); + } + } + else + q().postEvent (keyEvent); + } + + protected void postFocusEvent (int id, boolean temporary) + { + q().postEvent (new FocusEvent (awtComponent, id, temporary)); + } + + protected void postItemEvent (Object item, int stateChange) + { + q().postEvent (new ItemEvent ((ItemSelectable)awtComponent, + ItemEvent.ITEM_STATE_CHANGED, + item, stateChange)); + } + + protected void postTextEvent () + { + q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED)); + } + + public GraphicsConfiguration getGraphicsConfiguration () + { + // FIXME: just a stub for now. + return null; + } + + public void setEventMask (long mask) + { + // FIXME: just a stub for now. + } + + public boolean isFocusable () + { + return false; + } + + public boolean requestFocus (Component source, boolean b1, + boolean b2, long x) + { + return false; + } + + public boolean isObscured () + { + return false; + } + + public boolean canDetermineObscurity () + { + return false; + } + + public void coalescePaintEvent (PaintEvent e) + { + + } + + public void updateCursorImmediately () + { + + } + + public boolean handlesWheelScrolling () + { + return false; + } + + // Convenience method to create a new volatile image on the screen + // on which this component is displayed. + public VolatileImage createVolatileImage (int width, int height) + { + return new GtkVolatileImage (width, height); + } + + // Creates buffers used in a buffering strategy. + public void createBuffers (int numBuffers, BufferCapabilities caps) + throws AWTException + { + // numBuffers == 2 implies double-buffering, meaning one back + // buffer and one front buffer. + if (numBuffers == 2) + backBuffer = new GtkVolatileImage(awtComponent.getWidth(), + awtComponent.getHeight(), + caps.getBackBufferCapabilities()); + else + throw new AWTException("GtkComponentPeer.createBuffers:" + + " multi-buffering not supported"); + this.caps = caps; + } + + // Return the back buffer. + public Image getBackBuffer () + { + return backBuffer; + } + + // FIXME: flip should be implemented as a fast native operation + public void flip (BufferCapabilities.FlipContents contents) + { + getGraphics().drawImage(backBuffer, + awtComponent.getWidth(), + awtComponent.getHeight(), + null); + + // create new back buffer and clear it to the background color. + if (contents == BufferCapabilities.FlipContents.BACKGROUND) + { + backBuffer = createVolatileImage(awtComponent.getWidth(), + awtComponent.getHeight()); + backBuffer.getGraphics().clearRect(0, 0, + awtComponent.getWidth(), + awtComponent.getHeight()); + } + // FIXME: support BufferCapabilities.FlipContents.PRIOR + } + + // Release the resources allocated to back buffers. + public void destroyBuffers () + { + backBuffer.flush(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java new file mode 100644 index 0000000..c2865f7 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -0,0 +1,156 @@ +/* GtkContainerPeer.java -- Implements ContainerPeer with GTK + Copyright (C) 1998, 1999 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.java.awt.peer.gtk; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Window; +import java.awt.peer.ComponentPeer; +import java.awt.peer.ContainerPeer; + +public class GtkContainerPeer extends GtkComponentPeer + implements ContainerPeer +{ + Container c; + boolean isValidating; + + public GtkContainerPeer(Container c) + { + super (c); + this.c = c; + } + + public void beginValidate () + { + isValidating = true; + } + + public void endValidate () + { + Component parent = awtComponent.getParent (); + + // Only set our parent on the GTK side if our parent on the AWT + // side is not showing. Otherwise the gtk peer will be shown + // before we've had a chance to position and size it properly. + if (parent != null && parent.isShowing ()) + { + Component[] components = ((Container) awtComponent).getComponents (); + int ncomponents = components.length; + + for (int i = 0; i < ncomponents; i++) + { + ComponentPeer peer = components[i].getPeer (); + + // Skip lightweight peers. + if (peer instanceof GtkComponentPeer) + ((GtkComponentPeer) peer).setParentAndBounds (); + } + + // GTK windows don't have parents. + if (!(awtComponent instanceof Window)) + setParentAndBounds (); + } + + isValidating = false; + } + + public Insets getInsets() + { + return insets; + } + + public Insets insets() + { + return getInsets (); + } + + public void setBounds (int x, int y, int width, int height) + { + super.setBounds (x, y, width, height); + } + + public void setFont(Font f) + { + super.setFont(f); + Component[] components = ((Container) awtComponent).getComponents(); + for (int i = 0; i < components.length; i++) + { + if (components[i].isLightweight ()) + components[i].setFont (f); + else + { + GtkComponentPeer peer = (GtkComponentPeer) components[i].getPeer(); + if (peer != null && ! peer.awtComponent.isFontSet()) + peer.setFont(f); + } + } + } + + public Graphics getGraphics () + { + return super.getGraphics(); + } + + public void beginLayout () { } + public void endLayout () { } + public boolean isPaintPending () { return false; } + + public void setBackground (Color c) + { + super.setBackground(c); + + Object components[] = ((Container) awtComponent).getComponents(); + for (int i = 0; i < components.length; i++) + { + Component comp = (Component) components[i]; + + // If the child's background has not been explicitly set yet, + // it should inherit this container's background. This makes the + // child component appear as if it has a transparent background. + // Note that we do not alter the background property of the child, + // but only repaint the child with the parent's background color. + if (!comp.isBackgroundSet() && comp.getPeer() != null) + comp.getPeer().setBackground(c); + } + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java new file mode 100644 index 0000000..c2cbc37 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -0,0 +1,94 @@ +/* GtkDialogPeer.java -- Implements DialogPeer with GTK + Copyright (C) 1998, 1999, 2002 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.java.awt.peer.gtk; + +import java.awt.Dialog; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.PaintEvent; +import java.awt.peer.DialogPeer; + +public class GtkDialogPeer extends GtkWindowPeer + implements DialogPeer +{ + public GtkDialogPeer (Dialog dialog) + { + super (dialog); + } + + public Graphics getGraphics () + { + Graphics g; + if (GtkToolkit.useGraphics2D ()) + g = new GdkGraphics2D (this); + else + g = new GdkGraphics (this); + g.translate (-insets.left, -insets.top); + return g; + } + + protected void postMouseEvent(int id, long when, int mods, int x, int y, + int clickCount, boolean popupTrigger) + { + super.postMouseEvent (id, when, mods, + x + insets.left, y + insets.top, + clickCount, popupTrigger); + } + + protected void postExposeEvent (int x, int y, int width, int height) + { + if (!isInRepaint) + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + new Rectangle (x + insets.left, + y + insets.top, + width, height))); + } + + void create () + { + // Create a decorated dialog window. + create (GDK_WINDOW_TYPE_HINT_DIALOG, true); + + Dialog dialog = (Dialog) awtComponent; + + gtkWindowSetModal (dialog.isModal ()); + setTitle (dialog.getTitle ()); + setResizable (dialog.isResizable ()); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java new file mode 100644 index 0000000..0533d27 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java @@ -0,0 +1,73 @@ +/* GtkEmbeddedWindowPeer.java -- Implements EmbeddedWindowPeer using a + GtkPlug + Copyright (C) 2003 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.java.awt.peer.gtk; + +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.EmbeddedWindowPeer; + +public class GtkEmbeddedWindowPeer extends GtkFramePeer + implements EmbeddedWindowPeer +{ + native void create (long socket_id); + + void create () + { + create (((EmbeddedWindow) awtComponent).getHandle ()); + } + + native void construct (long socket_id); + + // FIXME: embed doesn't work right now, though I believe it should. + // This means that you can't call setVisible (true) on an + // EmbeddedWindow before calling setHandle with a valid handle. The + // problem is that somewhere after the call to + // GtkEmbeddedWindow.create and before the call to + // GtkEmbeddedWindow.construct, the GtkPlug peer is being realized. + // GtkSocket silently fails to embed an already-realized GtkPlug. + public void embed (long handle) + { + construct (handle); + } + + public GtkEmbeddedWindowPeer (EmbeddedWindow w) + { + super (w); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java new file mode 100644 index 0000000..bd1f077 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java @@ -0,0 +1,219 @@ +/* GtkFileDialogPeer.java -- Implements FileDialogPeer with GTK + Copyright (C) 1998, 1999, 2002, 2004, 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.java.awt.peer.gtk; + +import java.awt.Dialog; +import java.awt.FileDialog; +import java.awt.Graphics; +import java.awt.Window; +import java.awt.peer.FileDialogPeer; +import java.io.File; +import java.io.FilenameFilter; + +public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer +{ + static final String FS = System.getProperty("file.separator"); + + private String currentFile = null; + private String currentDirectory = null; + private FilenameFilter filter; + + native void create (GtkContainerPeer parent); + native void connectSignals (); + native void nativeSetFile (String file); + public native String nativeGetDirectory(); + public native void nativeSetDirectory(String directory); + native void nativeSetFilenameFilter (FilenameFilter filter); + + public void create() + { + create((GtkContainerPeer) awtComponent.getParent().getPeer()); + + FileDialog fd = (FileDialog) awtComponent; + + setDirectory(fd.getDirectory()); + setFile(fd.getFile()); + + FilenameFilter filter = fd.getFilenameFilter(); + if (filter != null) + setFilenameFilter(filter); + } + + public GtkFileDialogPeer (FileDialog fd) + { + super (fd); + } + + void setComponentBounds () + { + if (awtComponent.getHeight () == 0 + && awtComponent.getWidth () == 0) + { + int[] dims = new int[2]; + gtkWidgetGetPreferredDimensions (dims); + ((GtkFileDialogPeer) this).setBoundsCallback ((Window) awtComponent, + awtComponent.getX (), + awtComponent.getY (), + dims[0], dims[1]); + } + super.setComponentBounds (); + } + + public void setFile (String fileName) + { + /* If nothing changed do nothing. This usually happens because + the only way we have to set the file name in FileDialog is by + calling its SetFile which will call us back. */ + if ((fileName == null && currentFile == null) + || (fileName != null && fileName.equals (currentFile))) + return; + + if (fileName == null || fileName.equals ("")) + { + currentFile = ""; + nativeSetFile (""); + return; + } + + // GtkFileChooser requires absolute filenames. If the given filename + // is not absolute, let's construct it based on current directory. + currentFile = fileName; + if (fileName.indexOf(FS) == 0) + { + nativeSetFile (fileName); + } + else + { + nativeSetFile (nativeGetDirectory() + FS + fileName); + } + } + + public void setDirectory (String directory) + { + /* If nothing changed so nothing. This usually happens because + the only way we have to set the directory in FileDialog is by + calling its setDirectory which will call us back. */ + if ((directory == null && currentDirectory == null) + || (directory != null && directory.equals (currentDirectory))) + return; + + if (directory == null || directory.equals ("")) + { + currentDirectory = FS; + nativeSetFile (FS); + return; + } + + currentDirectory = directory; + nativeSetDirectory (directory); + } + + public void setFilenameFilter (FilenameFilter filter) + { + this.filter = filter; + nativeSetFilenameFilter(filter); + } + + /* This method interacts with the native callback function of the + same name. The native function will extract the filename from the + GtkFileFilterInfo object and send it to this method, which will + in turn call the filter's accept() method and give back the return + value. */ + boolean filenameFilterCallback (String fullname) { + String filename = fullname.substring(fullname.lastIndexOf(FS) + 1); + String dirname = fullname.substring(0, fullname.lastIndexOf(FS)); + File dir = new File(dirname); + return filter.accept(dir, filename); + } + + public Graphics getGraphics () + { + // GtkFileDialog will repaint by itself + return null; + } + + void gtkHideFileDialog () + { + ((Dialog) awtComponent).hide(); + } + + void gtkDisposeFileDialog () + { + ((Dialog) awtComponent).dispose(); + } + + /* Callback to set the file and directory values when the user is finished + * with the dialog. + */ + void gtkSetFilename (String fileName) + { + FileDialog fd = (FileDialog) awtWidget; + if (fileName == null) + { + currentFile = null; + fd.setFile(null); + return; + } + + int sepIndex = fileName.lastIndexOf (FS); + if (sepIndex < 0) + { + /* This should never happen on Unix (all paths start with '/') */ + currentFile = fileName; + } + else + { + if (fileName.length() > (sepIndex + 1)) + { + String fn = fileName.substring (sepIndex + 1); + currentFile = fn; + } + else + { + currentFile = null; + } + + String dn = fileName.substring (0, sepIndex + 1); + currentDirectory = dn; + fd.setDirectory(dn); + } + + fd.setFile (currentFile); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java new file mode 100644 index 0000000..80ad158 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java @@ -0,0 +1,225 @@ +/* GtkFontPeer.java -- Implements FontPeer with GTK+ + Copyright (C) 1999, 2004, 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.java.awt.peer.gtk; + +import gnu.java.awt.peer.ClasspathFontPeer; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class GtkFontPeer extends ClasspathFontPeer +{ + private static ResourceBundle bundle; + + static + { + try + { + bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font"); + } + catch (Throwable ignored) + { + bundle = null; + } + } + + private final String Xname; + + public GtkFontPeer (String name, int style) + { + // All fonts get a default size of 12 if size is not specified. + this(name, style, 12); + } + + public GtkFontPeer (String name, int style, int size) + { + super(name, style, size); + + String Xname = null; + if (bundle != null) + { + try + { + Xname = bundle.getString (name.toLowerCase () + "." + style); + } + catch (MissingResourceException mre) + { + // ignored + } + } + + if (Xname == null) + { + String weight; + String slant; + String spacing; + + if (style == Font.ITALIC || (style == (Font.BOLD+Font.ITALIC))) + slant = "i"; + else + slant = "r"; + if (style == Font.BOLD || (style == (Font.BOLD+Font.ITALIC))) + weight = "bold"; + else + weight = "medium"; + if (name.equals("Serif") || name.equals("SansSerif") + || name.equals("Helvetica") || name.equals("Times")) + spacing = "p"; + else + spacing = "c"; + + Xname = "-*-*-" + weight + "-" + slant + "-normal-*-*-" + size + "-*-*-" + spacing + "-*-*-*"; + } + + this.Xname = Xname; + } + + public String getXLFD () + { + return Xname; + } + + + /* remaining methods are for static compatibility with the newer + ClasspathFontPeer superclass; none of these methods ever existed or + worked on the older FontPeer interface, but we need to pretend to + support them anyways. */ + + public boolean canDisplay (Font font, char c) + { + throw new UnsupportedOperationException(); + } + + public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) + { + throw new UnsupportedOperationException(); + } + + public String getSubFamilyName (Font font, Locale locale) + { + throw new UnsupportedOperationException(); + } + + public String getPostScriptName (Font font) + { + throw new UnsupportedOperationException(); + } + + public int getNumGlyphs (Font font) + { + throw new UnsupportedOperationException(); + } + + public int getMissingGlyphCode (Font font) + { + throw new UnsupportedOperationException(); + } + + public byte getBaselineFor (Font font, char c) + { + throw new UnsupportedOperationException(); + } + + public String getGlyphName (Font font, int glyphIndex) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector createGlyphVector (Font font, + FontRenderContext frc, + CharacterIterator ci) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector createGlyphVector (Font font, + FontRenderContext ctx, + int[] glyphCodes) + { + throw new UnsupportedOperationException(); + } + + public GlyphVector layoutGlyphVector (Font font, + FontRenderContext frc, + char[] chars, int start, + int limit, int flags) + { + throw new UnsupportedOperationException(); + } + + public FontMetrics getFontMetrics (Font font) + { + throw new UnsupportedOperationException(); + } + + public boolean hasUniformLineMetrics (Font font) + { + throw new UnsupportedOperationException(); + } + + public LineMetrics getLineMetrics (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext rc) + { + throw new UnsupportedOperationException(); + } + + public Rectangle2D getMaxCharBounds (Font font, + FontRenderContext rc) + { + throw new UnsupportedOperationException(); + } + + public Rectangle2D getStringBounds (Font font, + CharacterIterator ci, + int begin, int limit, + FontRenderContext frc) + { + throw new UnsupportedOperationException(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java new file mode 100644 index 0000000..b242d66 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -0,0 +1,256 @@ +/* GtkFramePeer.java -- Implements FramePeer with GTK + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MenuBar; +import java.awt.Rectangle; +import java.awt.Window; +import java.awt.event.PaintEvent; +import java.awt.image.ColorModel; +import java.awt.peer.FramePeer; +import java.awt.peer.MenuBarPeer; + +public class GtkFramePeer extends GtkWindowPeer + implements FramePeer +{ + private int menuBarHeight; + private MenuBarPeer menuBar; + native int getMenuBarHeight (MenuBarPeer bar); + native void setMenuBarWidth (MenuBarPeer bar, int width); + native void setMenuBarPeer (MenuBarPeer bar); + native void removeMenuBarPeer (); + native void gtkFixedSetVisible (boolean visible); + + int getMenuBarHeight () + { + return menuBar == null ? 0 : getMenuBarHeight (menuBar); + } + + public void setMenuBar (MenuBar bar) + { + if (bar == null && menuBar != null) + { + // We're removing the menubar. + gtkFixedSetVisible (false); + menuBar = null; + removeMenuBarPeer (); + insets.top -= menuBarHeight; + menuBarHeight = 0; + awtComponent.validate (); + gtkFixedSetVisible (true); + } + else if (bar != null && menuBar == null) + { + // We're adding a menubar where there was no menubar before. + gtkFixedSetVisible (false); + menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer(); + setMenuBarPeer (menuBar); + int menuBarWidth = + awtComponent.getWidth () - insets.left - insets.right; + if (menuBarWidth > 0) + setMenuBarWidth (menuBar, menuBarWidth); + menuBarHeight = getMenuBarHeight (); + insets.top += menuBarHeight; + awtComponent.validate (); + gtkFixedSetVisible (true); + } + else if (bar != null && menuBar != null) + { + // We're swapping the menubar. + gtkFixedSetVisible (false); + removeMenuBarPeer(); + int oldHeight = menuBarHeight; + int menuBarWidth = + awtComponent.getWidth () - insets.left - insets.right; + menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer (); + setMenuBarPeer (menuBar); + if (menuBarWidth > 0) + setMenuBarWidth (menuBar, menuBarWidth); + menuBarHeight = getMenuBarHeight (); + if (oldHeight != menuBarHeight) + { + insets.top += (menuBarHeight - oldHeight); + awtComponent.validate (); + } + gtkFixedSetVisible (true); + } + } + + public void setBounds (int x, int y, int width, int height) + { + int menuBarWidth = width - insets.left - insets.right; + if (menuBar != null && menuBarWidth > 0) + setMenuBarWidth (menuBar, menuBarWidth); + + nativeSetBounds (x, y, + width - insets.left - insets.right, + height - insets.top - insets.bottom + + menuBarHeight); + } + + public void setResizable (boolean resizable) + { + // Call setSize; otherwise when resizable is changed from true to + // false the frame will shrink to the dimensions it had before it + // was resizable. + setSize (awtComponent.getWidth() - insets.left - insets.right, + awtComponent.getHeight() - insets.top - insets.bottom + + menuBarHeight); + gtkWindowSetResizable (resizable); + } + + protected void postInsetsChangedEvent (int top, int left, + int bottom, int right) + { + insets.top = top + menuBarHeight; + insets.left = left; + insets.bottom = bottom; + insets.right = right; + } + + public GtkFramePeer (Frame frame) + { + super (frame); + } + + void create () + { + // Create a normal decorated window. + create (GDK_WINDOW_TYPE_HINT_NORMAL, true); + + Frame frame = (Frame) awtComponent; + + setMenuBar (frame.getMenuBar ()); + + setTitle (frame.getTitle ()); + gtkWindowSetResizable (frame.isResizable ()); + setIconImage(frame.getIconImage()); + } + + native void nativeSetIconImage (GtkImage image); + + public void setIconImage (Image image) + { + if (image != null) + { + if (image instanceof GtkImage) + nativeSetIconImage((GtkImage) image); + else + nativeSetIconImage(new GtkImage(image.getSource())); + } + } + + public Graphics getGraphics () + { + Graphics g; + if (GtkToolkit.useGraphics2D ()) + g = new GdkGraphics2D (this); + else + g = new GdkGraphics (this); + g.translate (-insets.left, -insets.top); + return g; + } + + protected void postConfigureEvent (int x, int y, int width, int height) + { + int frame_x = x - insets.left; + // Since insets.top includes the MenuBar height, we need to add back + // the MenuBar height to the frame's y position. + // If no MenuBar exists in this frame, the MenuBar height will be 0. + int frame_y = y - insets.top + menuBarHeight; + int frame_width = width + insets.left + insets.right; + // Ditto as above. Since insets.top already includes the MenuBar's height, + // we need to subtract the MenuBar's height from the top inset. + int frame_height = height + insets.top + insets.bottom - menuBarHeight; + if (frame_x != awtComponent.getX() + || frame_y != awtComponent.getY() + || frame_width != awtComponent.getWidth() + || frame_height != awtComponent.getHeight()) + { + if (frame_width != awtComponent.getWidth() && menuBar != null + && width > 0) + setMenuBarWidth (menuBar, width); + + setBoundsCallback ((Window) awtComponent, + frame_x, + frame_y, + frame_width, + frame_height); + + awtComponent.validate(); + } + } + + protected void postMouseEvent(int id, long when, int mods, int x, int y, + int clickCount, boolean popupTrigger) + { + super.postMouseEvent (id, when, mods, + x + insets.left, y + insets.top, + clickCount, popupTrigger); + } + + protected void postExposeEvent (int x, int y, int width, int height) + { + if (!isInRepaint) + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + new Rectangle (x + insets.left, + y + insets.top, + width, height))); + } + + public int getState () + { + return 0; + } + + public void setState (int state) + { + + } + + public void setMaximizedBounds (Rectangle r) + { + + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java new file mode 100644 index 0000000..705eed2 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java @@ -0,0 +1,98 @@ +/* GtkGenericPeer.java - Has a hashcode. Yuck. + Copyright (C) 1998, 1999, 2002 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.java.awt.peer.gtk; + +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; + +public class GtkGenericPeer +{ + final int native_state = getUniqueInteger (); + + // Next native state value we will assign. + private static int next_native_state = 0; + + // The widget or other java-side object we wrap. + protected Object awtWidget; + + // Global event queue. + protected static EventQueue q = null; + + // Dispose of our native state. + public native void dispose (); + + static EventQueue q () + { + return Toolkit.getDefaultToolkit ().getSystemEventQueue (); + } + + protected GtkGenericPeer (Object awtWidget) + { + this.awtWidget = awtWidget; + } + + public static void enableQueue (EventQueue sq) + { + if (q == null) + q = sq; + } + + protected void postActionEvent (String command, int mods) + { + q().postEvent (new ActionEvent (awtWidget, ActionEvent.ACTION_PERFORMED, + command, mods)); + } + + // Return a unique integer for use in the native state mapping + // code. We can't use a hash code since that is not guaranteed to + // be unique. + static synchronized int getUniqueInteger () + { + // Let's assume this will never wrap. + return next_native_state++; + } + + native void gtkWidgetModifyFont (String name, int style, int size); + + static void printCurrentThread () + { + System.out.println ("gtkgenericpeer, thread: " + Thread.currentThread ()); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java new file mode 100644 index 0000000..abb4137 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java @@ -0,0 +1,494 @@ +/* GtkImage.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.java.awt.peer.gtk; + +import java.awt.Graphics; +import java.awt.Color; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.io.File; +import java.io.IOException; +import java.util.Hashtable; +import java.util.Vector; +import gnu.classpath.RawData; + +/** + * GtkImage - wraps a GdkPixbuf or GdkPixmap. + * + * The constructor GtkImage(int, int) creates an 'off-screen' GdkPixmap, + * this can be drawn to (it's a GdkDrawable), and correspondingly, you can + * create a GdkGraphics object for it. + * + * This corresponds to the Image implementation returned by + * Component.createImage(int, int). + * + * A GdkPixbuf is 'on-screen' and the gdk cannot draw to it, + * this is used for the other constructors (and other createImage methods), and + * corresponds to the Image implementations returned by the Toolkit.createImage + * methods, and is basically immutable. + * + * @author Sven de Marothy + */ +public class GtkImage extends Image +{ + int width = -1, height = -1; + + /** + * Properties. + */ + Hashtable props; + + /** + * Loaded or not flag, for asynchronous compatibility. + */ + boolean isLoaded; + + /** + * Pointer to the GdkPixbuf + */ + RawData pixmap; + + /** + * Observer queue. + */ + Vector observers; + + /** + * If offScreen is set, a GdkBitmap is wrapped and not a Pixbuf. + */ + boolean offScreen; + + /** + * Error flag for loading. + */ + boolean errorLoading; + + /** + * Original source, if created from an ImageProducer. + */ + ImageProducer source; + + /* + * The 32-bit AABBGGRR format the GDK uses. + */ + static ColorModel nativeModel = new DirectColorModel(32, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); + + /** + * Returns a copy of the pixel data as a java array. + */ + private native int[] getPixels(); + + /** + * Sets the pixel data from a java array. + */ + private native void setPixels(int[] pixels); + + /** + * Loads an image using gdk-pixbuf. + */ + private native boolean loadPixbuf(String name); + + /** + * Allocates a Gtk Pixbuf or pixmap + */ + private native void createPixmap(); + + /** + * Frees the above. + */ + private native void freePixmap(); + + /** + * Sets the pixmap to scaled copy of src image. hints are rendering hints. + */ + private native void createScaledPixmap(GtkImage src, int hints); + + /** + * Draws the image, optionally scaled and composited. + */ + private native void drawPixelsScaled (GdkGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, int width, int height, + boolean composite); + + /** + * Draws the image, optionally scaled flipped and composited. + */ + private native void drawPixelsScaledFlipped (GdkGraphics gc, + int bg_red, int bg_green, + int bg_blue, + boolean flipX, boolean flipY, + int srcX, int srcY, + int srcWidth, int srcHeight, + int dstX, int dstY, + int dstWidth, int dstHeight, + boolean composite); + + /** + * Constructs a GtkImage from an ImageProducer. Asynchronity is handled in + * the following manner: + * A GtkImageConsumer gets the image data, and calls setImage() when + * completely finished. The GtkImage is not considered loaded until the + * GtkImageConsumer is completely finished. We go for all "all or nothing". + */ + public GtkImage (ImageProducer producer) + { + isLoaded = false; + observers = new Vector(); + source = producer; + errorLoading = false; + source.startProduction(new GtkImageConsumer(this, source)); + offScreen = false; + } + + /** + * Constructs a GtkImage by loading a given file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public GtkImage (String filename) + { + File f = new File(filename); + try + { + if (loadPixbuf(f.getCanonicalPath()) != true) + throw new IllegalArgumentException("Couldn't load image: "+filename); + } + catch(IOException e) + { + throw new IllegalArgumentException("Couldn't load image: "+filename); + } + + isLoaded = true; + observers = null; + offScreen = false; + props = new Hashtable(); + } + + /** + * Constructs an empty GtkImage. + */ + public GtkImage (int width, int height) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + observers = null; + offScreen = true; + createPixmap(); + } + + /** + * Constructs a scaled version of the src bitmap, using the GDK. + */ + private GtkImage (GtkImage src, int width, int height, int hints) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + observers = null; + offScreen = false; + + // Use the GDK scaling method. + createScaledPixmap(src, hints); + } + + /** + * Callback from the image consumer. + */ + public void setImage(int width, int height, + int[] pixels, Hashtable properties) + { + this.width = width; + this.height = height; + props = (properties != null) ? properties : new Hashtable(); + + if (width <= 0 || height <= 0 || pixels == null) + { + errorLoading = true; + return; + } + + isLoaded = true; + deliver(); + createPixmap(); + setPixels(pixels); + } + + // java.awt.Image methods //////////////////////////////////////////////// + + public synchronized int getWidth (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return width; + } + + public synchronized int getHeight (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return height; + } + + public synchronized Object getProperty (String name, ImageObserver observer) + { + if (addObserver(observer)) + return UndefinedProperty; + + Object value = props.get (name); + return (value == null) ? UndefinedProperty : value; + } + + /** + * Returns the source of this image. + */ + public ImageProducer getSource () + { + if (!isLoaded) + return null; + return new MemoryImageSource(width, height, nativeModel, getPixels(), + 0, width); + } + + /** + * Creates a GdkGraphics context for this pixmap. + */ + public Graphics getGraphics () + { + if (!isLoaded) + return null; + if (offScreen) + return new GdkGraphics(this); + else + throw new IllegalAccessError("This method only works for off-screen" + +" Images."); + } + + /** + * Returns a scaled instance of this pixmap. + */ + public Image getScaledInstance(int width, + int height, + int hints) + { + if (width <= 0 || height <= 0) + throw new IllegalArgumentException("Width and height of scaled bitmap"+ + "must be >= 0"); + + return new GtkImage(this, width, height, hints); + } + + /** + * If the image is loaded and comes from an ImageProducer, + * regenerate the image from there. + * + * I have no idea if this is ever actually used. Since GtkImage can't be + * instantiated directly, how is the user to know if it was created from + * an ImageProducer or not? + */ + public synchronized void flush () + { + if (isLoaded && source != null) + { + observers = new Vector(); + isLoaded = false; + freePixmap(); + source.startProduction(new GtkImageConsumer(this, source)); + } + } + + public void finalize() + { + if (isLoaded) + freePixmap(); + } + + /** + * Returns the image status, used by GtkToolkit + */ + public int checkImage (ImageObserver observer) + { + if (addObserver(observer)) + { + if (errorLoading == true) + return ImageObserver.ERROR; + else + return 0; + } + + return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT; + } + + // Drawing methods //////////////////////////////////////////////// + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (GdkGraphics g, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + boolean flipX = (dx1 > dx2)^(sx1 > sx2); + boolean flipY = (dy1 > dy2)^(sy1 > sy2); + int dstWidth = Math.abs (dx2 - dx1); + int dstHeight = Math.abs (dy2 - dy1); + int srcWidth = Math.abs (sx2 - sx1); + int srcHeight = Math.abs (sy2 - sy1); + int srcX = (sx1 < sx2) ? sx1 : sx2; + int srcY = (sy1 < sy2) ? sy1 : sy2; + int dstX = (dx1 < dx2) ? dx1 : dx2; + int dstY = (dy1 < dy2) ? dy1 : dy2; + + // Clipping. This requires the dst to be scaled as well, + if (srcWidth > width) + { + dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth)); + srcWidth = width - srcX; + } + + if (srcHeight > height) + { + dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight)); + srcHeight = height - srcY; + } + + if (srcWidth + srcX > width) + { + dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth); + srcWidth = width - srcX; + } + + if (srcHeight + srcY > height) + { + dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight); + srcHeight = height - srcY; + } + + if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0) + return true; + + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + return true; + } + + /** + * Draws an image to the GdkGraphics context, at (x,y) scaled to + * width and height, with optional compositing with a background color. + */ + public boolean drawImage (GdkGraphics g, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + + return true; + } + + // Private methods //////////////////////////////////////////////// + + /** + * Delivers notifications to all queued observers. + */ + private void deliver() + { + int flags = ImageObserver.HEIGHT | + ImageObserver.WIDTH | + ImageObserver.PROPERTIES | + ImageObserver.ALLBITS; + + if (observers != null) + for(int i=0; i < observers.size(); i++) + ((ImageObserver)observers.elementAt(i)). + imageUpdate(this, flags, 0, 0, width, height); + + observers = null; + } + + /** + * Adds an observer, if we need to. + * @return true if an observer was added. + */ + private boolean addObserver(ImageObserver observer) + { + if (!isLoaded) + { + if(observer != null) + if (!observers.contains (observer)) + observers.addElement (observer); + return true; + } + return false; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java new file mode 100644 index 0000000..564cc8d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java @@ -0,0 +1,155 @@ +/* GtkImageConsumer.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.awt.peer.gtk; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Helper class to GtkImage. Sits and gathers pixels for a GtkImage and then + * calls GtkImage.setImage(). + * + * @author Sven de Marothy + */ +public class GtkImageConsumer implements ImageConsumer +{ + private GtkImage target; + private int width, height; + private Hashtable properties; + private int[] pixelCache = null; + private ImageProducer source; + + public GtkImageConsumer(GtkImage target, ImageProducer source) + { + this.target = target; + this.source = source; + } + + public synchronized void imageComplete (int status) + { + source.removeConsumer(this); + target.setImage(width, height, pixelCache, properties); + } + + public synchronized void setColorModel (ColorModel model) + { + // This method is to inform on what the most used color model + // in the image is, for optimization reasons. We ignore this + // information. + } + + public synchronized void setDimensions (int width, int height) + { + pixelCache = new int[width*height]; + + this.width = width; + this.height = height; + } + + public synchronized void setHints (int flags) + { + // This method informs us in which order the pixels are + // delivered, for progressive-loading support, etc. + // Since we wait until it's all loaded, we can ignore the hints. + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, byte[] pixels, + int offset, int scansize) + { + setPixels (x, y, width, height, cm, convertPixels (pixels), offset, + scansize); + } + + public synchronized void setPixels (int x, int y, int width, int height, + ColorModel cm, int[] pixels, + int offset, int scansize) + { + if (pixelCache == null) + return; // Not sure this should ever happen. + + if (cm.equals(GtkImage.nativeModel)) + for (int i = 0; i < height; i++) + System.arraycopy (pixels, offset + (i * scansize), + pixelCache, (y + i) * this.width + x, + width); + else + { + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + { + // get in AARRGGBB and convert to AABBGGRR + int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]); + byte b = (byte)(pix & 0xFF); + byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF); + pix &= 0xFF00FF00; + pix |= ((b & 0xFF) << 16); + pix |= (r & 0xFF); + pixelCache[(y + i) * this.width + x + j] = pix; + } + } + } + + /** + * This is an old method, no idea if it's correct. + */ + private int[] convertPixels (byte[] pixels) + { + int ret[] = new int[pixels.length]; + + for (int i = 0; i < pixels.length; i++) + ret[i] = pixels[i] & 0xFF; + + return ret; + } + + public synchronized void setProperties (Hashtable props) + { + this.properties = props; + } +} + + diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java new file mode 100644 index 0000000..fdd5fd1 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java @@ -0,0 +1,84 @@ +/* GtkLabelPeer.java -- Implements LabelPeer with GTK + Copyright (C) 1998, 1999, 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.java.awt.peer.gtk; + +import java.awt.Label; +import java.awt.peer.LabelPeer; + +public class GtkLabelPeer extends GtkComponentPeer + implements LabelPeer +{ + native void create (String text, float alignment); + native void gtkWidgetModifyFont (String name, int style, int size); + native void nativeSetAlignment (float alignment); + + public native void setText(String text); + native void setNativeBounds (int x, int y, int width, int height); + + void create () + { + Label label = (Label) awtComponent; + create (label.getText (), getGtkAlignment (label.getAlignment ())); + } + + public GtkLabelPeer (Label l) + { + super (l); + } + + public void setAlignment (int alignment) + { + nativeSetAlignment (getGtkAlignment (alignment)); + } + + float getGtkAlignment (int alignment) + { + switch (alignment) + { + case Label.LEFT: + return 0.0f; + case Label.CENTER: + return 0.5f; + case Label.RIGHT: + return 1.0f; + } + + return 0.0f; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java new file mode 100644 index 0000000..ff12fe3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java @@ -0,0 +1,180 @@ +/* GtkListPeer.java -- Implements ListPeer with GTK + Copyright (C) 1998, 1999 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.Dimension; +import java.awt.List; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.peer.ListPeer; + +public class GtkListPeer extends GtkComponentPeer + implements ListPeer +{ + void create () + { + List list = (List) awtComponent; + + create (list.getRows ()); + + setMultipleMode (list.isMultipleMode ()); + } + + native void create (int rows); + native void connectSignals (); + native void gtkWidgetModifyFont (String name, int style, int size); + native void gtkWidgetRequestFocus (); + + native void getSize (int rows, int visibleRows, int dims[]); + + public GtkListPeer (List list) + { + super (list); + + setMultipleMode (list.isMultipleMode ()); + + if (list.getItemCount () > 0) + append (list.getItems ()); + } + + native void append (String items[]); + + public native void add (String item, int index); + + public void addItem (String item, int index) + { + add (item, index); + } + + public void clear () + { + removeAll (); + } + + public native void delItems (int start, int end); + public native void deselect (int index); + + public Dimension getMinimumSize (int rows) + { + return minimumSize (rows); + } + + public Dimension getPreferredSize (int rows) + { + return preferredSize (rows); + } + + public native int[] getSelectedIndexes (); + public native void makeVisible (int index); + + public Dimension minimumSize (int rows) + { + int dims[] = new int[2]; + + int visibleRows = ((List) awtComponent).getRows(); + getSize (rows, visibleRows, dims); + return new Dimension (dims[0], dims[1]); + } + + public Dimension preferredSize (int rows) + { + int dims[] = new int[2]; + + int visibleRows = ((List) awtComponent).getRows(); + getSize (rows, visibleRows, dims); + return new Dimension (dims[0], dims[1]); + } + + public void removeAll () + { + delItems (0, -1); + } + + public native void select (int index); + public native void setMultipleMode (boolean b); + + public void setMultipleSelections (boolean b) + { + setMultipleMode (b); + } + + public void handleEvent (AWTEvent e) + { + if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ()) + { + // Only generate the ActionEvent on the second click of a + // multiple click. + MouseEvent me = (MouseEvent) e; + if (!me.isConsumed () + && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0 + && me.getClickCount() == 2) + { + String selectedItem = ((List) awtComponent).getSelectedItem (); + + // Double-click only generates an Action event if + // something is selected. + if (selectedItem != null) + postActionEvent (((List) awtComponent).getSelectedItem (), + me.getModifiersEx ()); + } + } + + if (e.getID () == KeyEvent.KEY_PRESSED) + { + KeyEvent ke = (KeyEvent) e; + if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_ENTER) + { + String selectedItem = ((List) awtComponent).getSelectedItem (); + + // Enter only generates an Action event if something is + // selected. + if (selectedItem != null) + postActionEvent (selectedItem, ke.getModifiersEx ()); + } + } + + super.handleEvent (e); + } + + protected void postItemEvent (int item, int stateChange) + { + postItemEvent (new Integer (item), stateChange); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java new file mode 100644 index 0000000..79eeaf9 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java @@ -0,0 +1,80 @@ +/* GtkMenuBarPeer.java -- Implements MenuBarPeer with GTK+ + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuComponent; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.MenuPeer; + +public class GtkMenuBarPeer extends GtkMenuComponentPeer + implements MenuBarPeer +{ + + native void create (); + native void addMenu (MenuPeer menu); + + public GtkMenuBarPeer (MenuBar target) + { + super (target); + } + + void setFont () + { + MenuComponent mc = (MenuComponent) awtWidget; + Font f = mc.getFont (); + + if (f == null) + mc.setFont (new Font ("Dialog", Font.PLAIN, 12)); + } + + // FIXME: remove this method or replace it with one that does + // something useful. + /* In Gnome, help menus are no longer right flushed. */ + native void nativeSetHelpMenu(MenuPeer menuPeer); + + public void addHelpMenu (Menu menu) + { + // nativeSetHelpMenu((MenuPeer) menu.getPeer()); + } + + public native void delMenu(int index); +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java new file mode 100644 index 0000000..8d9d1ca --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java @@ -0,0 +1,63 @@ +/* GtkMenuComponentPeer.java -- Implements MenuComponentPeer with GTK+ + Copyright (C) 1999 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.java.awt.peer.gtk; + +import java.awt.peer.MenuComponentPeer; + +public class GtkMenuComponentPeer extends GtkGenericPeer + implements MenuComponentPeer +{ + void create () + { + throw new RuntimeException (); + } + + void setFont () + { + } + + public GtkMenuComponentPeer (Object awtWidget) + { + super (awtWidget); + create (); + setFont (); + } + + public native void dispose(); +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java new file mode 100644 index 0000000..5728f26 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java @@ -0,0 +1,120 @@ +/* GtkMenuItemPeer.java -- Implements MenuItemPeer with GTK+ + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuComponent; +import java.awt.MenuItem; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.MenuPeer; + +public class GtkMenuItemPeer extends GtkMenuComponentPeer + implements MenuItemPeer +{ + native void create (String label); + native void connectSignals (); + native void gtkWidgetModifyFont (String name, int style, int size); + + void create () + { + create (((MenuItem) awtWidget).getLabel()); + } + + public GtkMenuItemPeer (MenuItem item) + { + super (item); + setEnabled (item.isEnabled ()); + setParent (item); + + if (item.getParent() instanceof Menu && ! (item instanceof Menu)) + connectSignals(); + } + + void setFont () + { + MenuComponent mc = ((MenuComponent) awtWidget); + Font f = mc.getFont (); + + if (f == null) + { + MenuComponent parent = (MenuComponent) mc.getParent (); + Font pf = parent.getFont (); + gtkWidgetModifyFont (pf.getName (), pf.getStyle (), pf.getSize ()); + } + else + gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize()); + } + + void setParent (MenuItem item) + { + // add ourself differently, based on what type of parent we have + // yes, the typecasting here is nasty. + Object parent = item.getParent (); + if (parent instanceof MenuBar) + { + ((GtkMenuBarPeer)((MenuBar)parent).getPeer ()).addMenu ((MenuPeer) this); + } + else // parent instanceof Menu + { + ((GtkMenuPeer)((Menu)parent).getPeer ()).addItem (this, + item.getShortcut ()); + } + } + + public void disable () + { + setEnabled (false); + } + + public void enable () + { + setEnabled (true); + } + + public native void setEnabled(boolean b); + + public native void setLabel(String label); + + protected void postMenuActionEvent () + { + postActionEvent (((MenuItem)awtWidget).getActionCommand (), 0); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java new file mode 100644 index 0000000..80332dd --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java @@ -0,0 +1,103 @@ +/* GtkMenuPeer.java -- Implements MenuPeer with GTK+ + Copyright (C) 1999, 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.java.awt.peer.gtk; + +import java.awt.Component; +import java.awt.Menu; +import java.awt.MenuContainer; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.MenuPeer; + +public class GtkMenuPeer extends GtkMenuItemPeer + implements MenuPeer +{ + native void create (String label); + native void addItem (MenuItemPeer item, int key, boolean shiftModifier); + native void setupAccelGroup (GtkGenericPeer container); + native void addTearOff (); + + public GtkMenuPeer (Menu menu) + { + super (menu); + + if (menu.isTearOff()) + addTearOff(); + + MenuContainer parent = menu.getParent (); + if (parent instanceof Menu) + setupAccelGroup ((GtkGenericPeer)((Menu)parent).getPeer ()); + else if (parent instanceof Component) + setupAccelGroup ((GtkGenericPeer)((Component)parent).getPeer ()); + else + setupAccelGroup (null); + } + + public void addItem (MenuItem item) + { + int key = 0; + boolean shiftModifier = false; + + MenuShortcut ms = item.getShortcut (); + if (ms != null) + { + key = ms.getKey (); + shiftModifier = ms.usesShiftModifier (); + } + + addItem ((MenuItemPeer) item.getPeer (), key, shiftModifier); + } + + public void addItem (MenuItemPeer item, MenuShortcut ms) + { + int key = 0; + boolean shiftModifier = false; + + if (ms != null) + { + key = ms.getKey (); + shiftModifier = ms.usesShiftModifier (); + } + + addItem (item, key, shiftModifier); + } + + public native void delItem(int index); +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java new file mode 100644 index 0000000..fb5adde --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java @@ -0,0 +1,70 @@ +/* GtkPanelPeer.java -- Implements PanelPeer with GTK + Copyright (C) 1998, 1999 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.Panel; +import java.awt.event.MouseEvent; +import java.awt.peer.PanelPeer; + +public class GtkPanelPeer extends GtkContainerPeer + implements PanelPeer +{ + native void create (); + + public GtkPanelPeer (Panel p) + { + super (p); + } + + public void handleEvent (AWTEvent event) + { + int id = event.getID(); + + switch (id) + { + case MouseEvent.MOUSE_PRESSED: + awtComponent.requestFocusInWindow (); + break; + } + super.handleEvent (event); + } + + native void connectSignals (); +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java new file mode 100644 index 0000000..d14c16d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java @@ -0,0 +1,74 @@ +/* GtkPopupMenuPeer.java -- Implements PopupMenuPeer with GTK+ + Copyright (C) 1999 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.java.awt.peer.gtk; + +import java.awt.Component; +import java.awt.Event; +import java.awt.MenuItem; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.peer.PopupMenuPeer; + +public class GtkPopupMenuPeer extends GtkMenuPeer + implements PopupMenuPeer +{ + public GtkPopupMenuPeer (PopupMenu menu) + { + super (menu); + } + + native void setupAccelGroup (GtkGenericPeer container); + + void setParent (MenuItem item) + { + // we don't need to "add" ourselves to our parent + } + + native void show (int x, int y, long time); + public void show (Component origin, int x, int y) + { + Point abs = origin.getLocationOnScreen (); + show (abs.x + x, abs.y + y, 0); + } + + public void show (Event e) + { + + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java new file mode 100644 index 0000000..69f8b49 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java @@ -0,0 +1,113 @@ +/* GtkScrollPanePeer.java -- Implements ScrollPanePeer with GTK + Copyright (C) 1998, 1999, 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.java.awt.peer.gtk; + +import java.awt.Adjustable; +import java.awt.Dimension; +import java.awt.ScrollPane; +import java.awt.peer.ScrollPanePeer; + +public class GtkScrollPanePeer extends GtkContainerPeer + implements ScrollPanePeer +{ + native void create (int width, int height); + + void create () + { + create (awtComponent.getWidth (), awtComponent.getHeight ()); + } + + // native void gtkScrolledWindowSetScrollPosition(int x, int y); + native void gtkScrolledWindowSetHScrollIncrement (int u); + native void gtkScrolledWindowSetVScrollIncrement (int u); + + public GtkScrollPanePeer (ScrollPane sp) + { + super (sp); + + setPolicy (sp.getScrollbarDisplayPolicy ()); + } + + native void setPolicy (int policy); + public void childResized (int width, int height) + { + int dim[] = new int[2]; + + gtkWidgetGetDimensions (dim); + + // If the child is in this range, GTK adds both scrollbars, but + // the AWT doesn't. So set the peer's scroll policy to + // GTK_POLICY_NEVER. + if ((width > dim[0] - getVScrollbarWidth () + && width <= dim[0]) + && (height > dim[1] - getHScrollbarHeight () + && height <= dim[1])) + setPolicy (ScrollPane.SCROLLBARS_NEVER); + else + setPolicy (((ScrollPane) awtComponent).getScrollbarDisplayPolicy ()); + } + + public native int getHScrollbarHeight(); + public native int getVScrollbarWidth(); + public native void setScrollPosition(int x, int y); + + public Dimension getPreferredSize () + { + return awtComponent.getSize(); + } + + public void setUnitIncrement (Adjustable adj, int u) + { + if (adj.getOrientation()==Adjustable.HORIZONTAL) + gtkScrolledWindowSetHScrollIncrement (u); + else + gtkScrolledWindowSetVScrollIncrement (u); + } + + public void setValue (Adjustable adj, int v) + { +// System.out.println("SPP: setVal: "+adj+":"+v); +// Point p=myScrollPane.getScrollPosition (); +// if (adj.getOrientation()==Adjustable.HORIZONTAL) +// gtkScrolledWindowSetScrollPosition (v,p.y); +// else +// gtkScrolledWindowSetScrollPosition (p.x,v); +// adj.setValue(v); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java new file mode 100644 index 0000000..aa3a26e --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java @@ -0,0 +1,80 @@ +/* GtkScrollbarPeer.java -- Implements ScrollbarPeer with GTK+ + Copyright (C) 1998, 1999, 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.java.awt.peer.gtk; + +import java.awt.Adjustable; +import java.awt.Scrollbar; +import java.awt.event.AdjustmentEvent; +import java.awt.peer.ScrollbarPeer; + +public class GtkScrollbarPeer extends GtkComponentPeer + implements ScrollbarPeer +{ + void create () + { + Scrollbar sb = (Scrollbar) awtComponent; + + create (sb.getOrientation (), sb.getValue (), + sb.getMinimum (), sb.getMaximum (), + sb.getUnitIncrement (), sb.getBlockIncrement (), + sb.getVisibleAmount ()); + } + + native void create (int orientation, int value, + int min, int max, int stepIncr, int pageIncr, + int visibleAmount); + + native void connectSignals (); + + public GtkScrollbarPeer (Scrollbar s) + { + super (s); + } + + public native void setLineIncrement(int amount); + public native void setPageIncrement(int amount); + public native void setValues(int value, int visible, int min, int max); + + protected void postAdjustmentEvent (int type, int value) + { + q().postEvent (new AdjustmentEvent ((Adjustable)awtComponent, + AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, + type, value)); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java new file mode 100644 index 0000000..a842b83 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java @@ -0,0 +1,212 @@ +/* GtkTextAreaPeer.java -- Implements TextAreaPeer with GTK + Copyright (C) 1998, 1999, 2002 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.java.awt.peer.gtk; + +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Rectangle; +import java.awt.TextArea; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.TextComponentPeer; + +public class GtkTextAreaPeer extends GtkComponentPeer + implements TextComponentPeer, TextAreaPeer +{ + private static transient int DEFAULT_ROWS = 10; + private static transient int DEFAULT_COLS = 80; + + native void create (int width, int height, int scrollbarVisibility); + + native void gtkWidgetModifyFont (String name, int style, int size); + native void gtkWidgetRequestFocus (); + + public native void connectSignals (); + + public native int getCaretPosition (); + public native void setCaretPosition (int pos); + public native int getSelectionStart (); + public native int getSelectionEnd (); + public native String getText (); + public native void select (int start, int end); + public native void setEditable (boolean state); + public native void setText (String text); + + public int getIndexAtPoint(int x, int y) + { + // FIXME + return 0; + } + + public Rectangle getCharacterBounds (int pos) + { + // FIXME + return null; + } + + public long filterEvents (long filter) + { + // FIXME + return filter; + } + + void create () + { + Font f = awtComponent.getFont (); + + // By default, Sun sets a TextArea's font when its peer is + // created. If f != null then the peer's font is set by + // GtkComponent.create. + if (f == null) + { + f = new Font ("Dialog", Font.PLAIN, 12); + awtComponent.setFont (f); + } + + FontMetrics fm = getFontMetrics (f); + + TextArea ta = ((TextArea) awtComponent); + int sizeRows = ta.getRows (); + int sizeCols = ta.getColumns (); + + sizeRows = sizeRows == 0 ? DEFAULT_ROWS : sizeRows; + sizeCols = sizeCols == 0 ? DEFAULT_COLS : sizeCols; + + int width = sizeCols * fm.getMaxAdvance (); + int height = sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ()); + + create (width, height, ta.getScrollbarVisibility ()); + setEditable (ta.isEditable ()); + } + + public GtkTextAreaPeer (TextArea ta) + { + super (ta); + + setText (ta.getText ()); + setCaretPosition (0); + } + + public native void insert (String str, int pos); + public native void replaceRange (String str, int start, int end); + + public Dimension getMinimumSize (int rows, int cols) + { + return minimumSize (rows == 0 ? DEFAULT_ROWS : rows, + cols == 0 ? DEFAULT_COLS : cols); + } + + public Dimension getPreferredSize (int rows, int cols) + { + return preferredSize (rows == 0 ? DEFAULT_ROWS : rows, + cols == 0 ? DEFAULT_COLS : cols); + } + + native int getHScrollbarHeight (); + native int getVScrollbarWidth (); + + // Deprecated + public Dimension minimumSize (int rows, int cols) + { + TextArea ta = ((TextArea) awtComponent); + int height = 0; + int width = 0; + + if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH + || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY) + height = getHScrollbarHeight (); + + if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH + || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY) + width = getVScrollbarWidth (); + + Font f = awtComponent.getFont (); + if (f == null) + return new Dimension (width, height); + + FontMetrics fm = getFontMetrics (f); + + int sizeRows = rows == 0 ? DEFAULT_ROWS : rows; + int sizeCols = cols == 0 ? DEFAULT_COLS : cols; + + width += sizeCols * fm.getMaxAdvance (); + height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ()); + + return new Dimension (width, height); + } + + public Dimension preferredSize (int rows, int cols) + { + TextArea ta = ((TextArea) awtComponent); + int height = 0; + int width = 0; + + if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH + || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY) + height = getHScrollbarHeight (); + + if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH + || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY) + width = getVScrollbarWidth (); + + Font f = awtComponent.getFont (); + if (f == null) + return new Dimension (width, height); + + FontMetrics fm = getFontMetrics (f); + + int sizeRows = rows == 0 ? DEFAULT_ROWS : rows; + int sizeCols = cols == 0 ? DEFAULT_COLS : cols; + + width += sizeCols * fm.getMaxAdvance (); + height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ()); + + return new Dimension (width, height); + } + + public void replaceText (String str, int start, int end) + { + replaceRange (str, start, end); + } + + public void insertText (String str, int pos) + { + insert (str, pos); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java new file mode 100644 index 0000000..73a976b --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java @@ -0,0 +1,196 @@ +/* GtkTextFieldPeer.java -- Implements TextFieldPeer with GTK + Copyright (C) 1998, 1999, 2002 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.java.awt.peer.gtk; + +import java.awt.AWTEvent; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Rectangle; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.TextComponentPeer; + +public class GtkTextFieldPeer extends GtkComponentPeer + implements TextComponentPeer, TextFieldPeer +{ + native void create (int width); + native void gtkWidgetSetBackground (int red, int green, int blue); + native void gtkWidgetSetForeground (int red, int green, int blue); + + public native void connectSignals (); + + public native int getCaretPosition (); + public native void setCaretPosition (int pos); + public native int getSelectionStart (); + public native int getSelectionEnd (); + public native String getText (); + public native void select (int start, int end); + public native void setEditable (boolean state); + public native void setText (String text); + + public int getIndexAtPoint(int x, int y) + { + // FIXME + return 0; + } + + public Rectangle getCharacterBounds (int pos) + { + // FIXME + return null; + } + + public long filterEvents (long filter) + { + // FIXME + return filter; + } + + void create () + { + Font f = awtComponent.getFont (); + + // By default, Sun sets a TextField's font when its peer is + // created. If f != null then the peer's font is set by + // GtkComponent.create. + if (f == null) + { + f = new Font ("Dialog", Font.PLAIN, 12); + awtComponent.setFont (f); + } + + FontMetrics fm = getFontMetrics (f); + + TextField tf = ((TextField) awtComponent); + int cols = tf.getColumns (); + + int text_width = cols * fm.getMaxAdvance (); + + create (text_width); + + setEditable (tf.isEditable ()); + } + + native int gtkEntryGetBorderWidth (); + + native void gtkWidgetModifyFont (String name, int style, int size); + + public GtkTextFieldPeer (TextField tf) + { + super (tf); + + setText (tf.getText ()); + setCaretPosition (0); + + if (tf.echoCharIsSet ()) + setEchoChar (tf.getEchoChar ()); + } + + public Dimension getMinimumSize (int cols) + { + return minimumSize (cols); + } + + public Dimension getPreferredSize (int cols) + { + return preferredSize (cols); + } + + public native void setEchoChar (char c); + + // Deprecated + public Dimension minimumSize (int cols) + { + int dim[] = new int[2]; + + gtkWidgetGetPreferredDimensions (dim); + + Font f = awtComponent.getFont (); + if (f == null) + return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]); + + FontMetrics fm = getFontMetrics (f); + + int text_width = cols * fm.getMaxAdvance (); + + int width = text_width + 2 * gtkEntryGetBorderWidth (); + + return new Dimension (width, dim[1]); + } + + public Dimension preferredSize (int cols) + { + int dim[] = new int[2]; + + gtkWidgetGetPreferredDimensions (dim); + + Font f = awtComponent.getFont (); + if (f == null) + return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]); + + FontMetrics fm = getFontMetrics (f); + + int text_width = cols * fm.getMaxAdvance (); + + int width = text_width + 2 * gtkEntryGetBorderWidth (); + + return new Dimension (width, dim[1]); + } + + public void setEchoCharacter (char c) + { + setEchoChar (c); + } + + public void handleEvent (AWTEvent e) + { + if (e.getID () == KeyEvent.KEY_PRESSED) + { + KeyEvent ke = (KeyEvent) e; + + if (!ke.isConsumed () + && ke.getKeyCode () == KeyEvent.VK_ENTER) + postActionEvent (getText (), ke.getModifiersEx ()); + } + + super.handleEvent (e); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java new file mode 100644 index 0000000..6990110 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -0,0 +1,653 @@ +/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers + Copyright (C) 1998, 1999, 2002, 2003, 2004, 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.java.awt.peer.gtk; + +import gnu.classpath.Configuration; +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; +import gnu.java.awt.peer.EmbeddedWindowPeer; + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.font.FontRenderContext; +import java.awt.im.InputMethodHighlight; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.peer.*; +import java.io.InputStream; +import java.net.URL; +import java.text.AttributedString; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +import javax.imageio.spi.IIORegistry; + +/* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer(). + This merits comment. We are basically calling Sun's bluff on this one. + We think Sun has deprecated it simply to discourage its use as it is + bad programming style. However, we need to get at a component's peer in + this class. If getPeer() ever goes away, we can implement a hash table + that will keep up with every window's peer, but for now this is faster. */ + +/** + * This class accesses a system property called + * <tt>gnu.java.awt.peer.gtk.Graphics</tt>. If the property is defined and + * equal to "Graphics2D", the cairo-based GdkGraphics2D will be used in + * drawing contexts. Any other value will cause the older GdkGraphics + * object to be used. + */ +public class GtkToolkit extends gnu.java.awt.ClasspathToolkit +{ + Hashtable containers = new Hashtable(); + static EventQueue q; + static Clipboard systemClipboard; + static boolean useGraphics2dSet; + static boolean useGraphics2d; + + public static boolean useGraphics2D() + { + if (useGraphics2dSet) + return useGraphics2d; + useGraphics2d = System.getProperty("gnu.java.awt.peer.gtk.Graphics", + "Graphics").equals("Graphics2D"); + useGraphics2dSet = true; + return useGraphics2d; + } + + static native void gtkInit(int portableNativeSync); + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary("gtkpeer"); + + int portableNativeSync; + String portNatSyncProp = + System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); + + if (portNatSyncProp == null) + portableNativeSync = -1; // unset + else if (Boolean.valueOf(portNatSyncProp).booleanValue()) + portableNativeSync = 1; // true + else + portableNativeSync = 0; // false + + gtkInit(portableNativeSync); + } + + public GtkToolkit () + { + systemClipboard = new GtkClipboard (); + } + + public native void beep(); + private native void getScreenSizeDimensions(int[] xy); + + public int checkImage (Image image, int width, int height, + ImageObserver observer) + { + int status = ImageObserver.ALLBITS + | ImageObserver.WIDTH + | ImageObserver.HEIGHT; + + if (image instanceof GtkImage) + return ((GtkImage) image).checkImage (observer); + + if (observer != null) + observer.imageUpdate (image, status, + -1, -1, + image.getWidth (observer), + image.getHeight (observer)); + + return status; + } + + /** + * A helper class to return to clients in cases where a BufferedImage is + * desired but its construction fails. + */ + private class GtkErrorImage extends Image + { + public GtkErrorImage() + { + } + + public int getWidth(ImageObserver observer) + { + return -1; + } + + public int getHeight(ImageObserver observer) + { + return -1; + } + + public ImageProducer getSource() + { + + return new ImageProducer() + { + HashSet consumers = new HashSet(); + public void addConsumer(ImageConsumer ic) + { + consumers.add(ic); + } + + public boolean isConsumer(ImageConsumer ic) + { + return consumers.contains(ic); + } + + public void removeConsumer(ImageConsumer ic) + { + consumers.remove(ic); + } + + public void startProduction(ImageConsumer ic) + { + consumers.add(ic); + Iterator i = consumers.iterator(); + while(i.hasNext()) + { + ImageConsumer c = (ImageConsumer) i.next(); + c.imageComplete(ImageConsumer.IMAGEERROR); + } + } + public void requestTopDownLeftRightResend(ImageConsumer ic) + { + startProduction(ic); + } + }; + } + + public Graphics getGraphics() + { + return null; + } + + public Object getProperty(String name, ImageObserver observer) + { + return null; + } + public Image getScaledInstance(int width, int height, int flags) + { + return new GtkErrorImage(); + } + + public void flush() + { + } + } + + + /** + * Helper to return either a BufferedImage -- the argument -- or a + * GtkErrorImage if the argument is null. + */ + + private Image bufferedImageOrError(BufferedImage b) + { + if (b == null) + return new GtkErrorImage(); + else + return b; + } + + + public Image createImage (String filename) + { + if (useGraphics2D()) + return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (filename)); + else + return new GtkImage (filename); + } + + public Image createImage (URL url) + { + if (useGraphics2D()) + return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (url)); + else + { + GdkPixbufDecoder d = new GdkPixbufDecoder (url); + GtkImage image = new GtkImage (d); + return image; + } + } + + public Image createImage (ImageProducer producer) + { + if (useGraphics2D()) + return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (producer)); + else + return new GtkImage (producer); + } + + public Image createImage (byte[] imagedata, int imageoffset, + int imagelength) + { + if (useGraphics2D()) + return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (imagedata, + imageoffset, + imagelength)); + else + { + GdkPixbufDecoder d = new GdkPixbufDecoder (imagedata, + imageoffset, + imagelength); + GtkImage image = new GtkImage (d); + return image; + } + } + + /** + * Creates an ImageProducer from the specified URL. The image is assumed + * to be in a recognised format. + * + * @param url URL to read image data from. + */ + public ImageProducer createImageProducer(URL url) + { + return new GdkPixbufDecoder(url); + } + + /** + * Returns the native color model (which isn't the same as the default + * ARGB color model, but doesn't have to be). + */ + public ColorModel getColorModel () + { + /* Return the GDK-native ABGR format */ + return new DirectColorModel(32, + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); + } + + public String[] getFontList () + { + return (new String[] { "Dialog", + "DialogInput", + "Monospaced", + "Serif", + "SansSerif" }); + } + + private class LRUCache extends LinkedHashMap + { + int max_entries; + public LRUCache(int max) + { + super(max, 0.75f, true); + max_entries = max; + } + protected boolean removeEldestEntry(Map.Entry eldest) + { + return size() > max_entries; + } + } + + private LRUCache fontCache = new LRUCache(50); + private LRUCache metricsCache = new LRUCache(50); + private LRUCache imageCache = new LRUCache(50); + + public FontMetrics getFontMetrics (Font font) + { + synchronized (metricsCache) + { + if (metricsCache.containsKey(font)) + return (FontMetrics) metricsCache.get(font); + } + + FontMetrics m = new GdkFontMetrics (font); + synchronized (metricsCache) + { + metricsCache.put(font, m); + } + return m; + } + + public Image getImage (String filename) + { + if (imageCache.containsKey(filename)) + return (Image) imageCache.get(filename); + else + { + Image im = createImage(filename); + imageCache.put(filename, im); + return im; + } + } + + public Image getImage (URL url) + { + if (imageCache.containsKey(url)) + return (Image) imageCache.get(url); + else + { + Image im = createImage(url); + imageCache.put(url, im); + return im; + } + } + + public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) + { + return null; + } + + public native int getScreenResolution(); + + public Dimension getScreenSize () + { + int dim[] = new int[2]; + getScreenSizeDimensions(dim); + return new Dimension(dim[0], dim[1]); + } + + public Clipboard getSystemClipboard() + { + return systemClipboard; + } + + /** + * Prepares a GtkImage. For every other kind of Image it just + * assumes the image is already prepared for rendering. + */ + public boolean prepareImage (Image image, int width, int height, + ImageObserver observer) + { + /* GtkImages are always prepared, as long as they're loaded. */ + if (image instanceof GtkImage) + return ((((GtkImage)image).checkImage (observer) & + ImageObserver.ALLBITS) != 0); + + /* Assume anything else is too */ + return true; + } + + public native void sync(); + + protected void setComponentState (Component c, GtkComponentPeer cp) + { + /* Make the Component reflect Peer defaults */ + if (c.getForeground () == null) + c.setForeground (cp.getForeground ()); + if (c.getBackground () == null) + c.setBackground (cp.getBackground ()); + // if (c.getFont () == null) + // c.setFont (cp.getFont ()); + + /* Make the Peer reflect the state of the Component */ + if (! (c instanceof Window)) + { + cp.setCursor (c.getCursor ()); + + Rectangle bounds = c.getBounds (); + cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height); + cp.setVisible (c.isVisible ()); + } + } + + protected ButtonPeer createButton (Button b) + { + return new GtkButtonPeer (b); + } + + protected CanvasPeer createCanvas (Canvas c) + { + return new GtkCanvasPeer (c); + } + + protected CheckboxPeer createCheckbox (Checkbox cb) + { + return new GtkCheckboxPeer (cb); + } + + protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi) + { + return new GtkCheckboxMenuItemPeer (cmi); + } + + protected ChoicePeer createChoice (Choice c) + { + return new GtkChoicePeer (c); + } + + protected DialogPeer createDialog (Dialog d) + { + return new GtkDialogPeer (d); + } + + protected FileDialogPeer createFileDialog (FileDialog fd) + { + return new GtkFileDialogPeer (fd); + } + + protected FramePeer createFrame (Frame f) + { + return new GtkFramePeer (f); + } + + protected LabelPeer createLabel (Label label) + { + return new GtkLabelPeer (label); + } + + protected ListPeer createList (List list) + { + return new GtkListPeer (list); + } + + protected MenuPeer createMenu (Menu m) + { + return new GtkMenuPeer (m); + } + + protected MenuBarPeer createMenuBar (MenuBar mb) + { + return new GtkMenuBarPeer (mb); + } + + protected MenuItemPeer createMenuItem (MenuItem mi) + { + return new GtkMenuItemPeer (mi); + } + + protected PanelPeer createPanel (Panel p) + { + return new GtkPanelPeer (p); + } + + protected PopupMenuPeer createPopupMenu (PopupMenu target) + { + return new GtkPopupMenuPeer (target); + } + + protected ScrollPanePeer createScrollPane (ScrollPane sp) + { + return new GtkScrollPanePeer (sp); + } + + protected ScrollbarPeer createScrollbar (Scrollbar sb) + { + return new GtkScrollbarPeer (sb); + } + + protected TextAreaPeer createTextArea (TextArea ta) + { + return new GtkTextAreaPeer (ta); + } + + protected TextFieldPeer createTextField (TextField tf) + { + return new GtkTextFieldPeer (tf); + } + + protected WindowPeer createWindow (Window w) + { + return new GtkWindowPeer (w); + } + + public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w) + { + return new GtkEmbeddedWindowPeer (w); + } + + /** + * @deprecated part of the older "logical font" system in earlier AWT + * implementations. Our newer Font class uses getClasspathFontPeer. + */ + protected FontPeer getFontPeer (String name, int style) { + // All fonts get a default size of 12 if size is not specified. + return getFontPeer(name, style, 12); + } + + /** + * Private method that allows size to be set at initialization time. + */ + private FontPeer getFontPeer (String name, int style, int size) + { + Map attrs = new HashMap (); + ClasspathFontPeer.copyStyleToAttrs (style, attrs); + ClasspathFontPeer.copySizeToAttrs (size, attrs); + return getClasspathFontPeer (name, attrs); + } + + /** + * Newer method to produce a peer for a Font object, even though Sun's + * design claims Font should now be peerless, we do not agree with this + * model, hence "ClasspathFontPeer". + */ + + public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs) + { + Map keyMap = new HashMap (attrs); + // We don't know what kind of "name" the user requested (logical, face, + // family), and we don't actually *need* to know here. The worst case + // involves failure to consolidate fonts with the same backend in our + // cache. This is harmless. + keyMap.put ("GtkToolkit.RequestedFontName", name); + if (fontCache.containsKey (keyMap)) + return (ClasspathFontPeer) fontCache.get (keyMap); + else + { + ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs); + fontCache.put (keyMap, newPeer); + return newPeer; + } + } + + public ClasspathTextLayoutPeer getClasspathTextLayoutPeer (AttributedString str, + FontRenderContext frc) + { + return new GdkTextLayout(str, frc); + } + + protected EventQueue getSystemEventQueueImpl() + { + synchronized (GtkToolkit.class) + { + if (q == null) + { + q = new EventQueue(); + GtkGenericPeer.enableQueue (q); + } + } + return q; + } + + protected native void loadSystemColors (int[] systemColors); + + public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e) + { + throw new Error("not implemented"); + } + + public Map mapInputMethodHighlight(InputMethodHighlight highlight) + { + throw new Error("not implemented"); + } + + public Rectangle getBounds() + { + int[] dims = new int[2]; + getScreenSizeDimensions(dims); + return new Rectangle(0, 0, dims[0], dims[1]); + } + + // ClasspathToolkit methods + + public GraphicsEnvironment getLocalGraphicsEnvironment() + { + return new GdkGraphicsEnvironment(this); + } + + public Font createFont(int format, InputStream stream) + { + throw new UnsupportedOperationException(); + } + + public RobotPeer createRobot (GraphicsDevice screen) throws AWTException + { + return new GdkRobotPeer (screen); + } + + public void registerImageIOSpis(IIORegistry reg) + { + GdkPixbufDecoder.registerSpis(reg); + } + + public native boolean nativeQueueEmpty(); + public native void wakeNativeQueue(); + public native void iterateNativeQueue(EventQueue locked, boolean block); + +} // class GtkToolkit diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java new file mode 100644 index 0000000..496090a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java @@ -0,0 +1,118 @@ +/* GtkVolatileImage.java -- a hardware-accelerated image buffer + 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.java.awt.peer.gtk; + +import java.awt.ImageCapabilities; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.awt.image.VolatileImage; + +public class GtkVolatileImage extends VolatileImage +{ + private int width; + private int height; + private ImageCapabilities caps; + + public GtkVolatileImage(int width, int height) + { + this(width, height, null); + } + + public GtkVolatileImage(int width, int height, ImageCapabilities caps) + { + this.width = width; + this.height = height; + this.caps = caps; + } + + // FIXME: should return a buffered image snapshot of the accelerated + // visual + public BufferedImage getSnapshot() + { + return null; + } + + public int getWidth() + { + return width; + } + + public int getHeight() + { + return height; + } + + // FIXME: should return a graphics wrapper around this image's + // visual + public Graphics2D createGraphics() + { + return null; + } + + public int validate(GraphicsConfiguration gc) + { + return VolatileImage.IMAGE_OK; + } + + public boolean contentsLost() + { + return false; + } + + public ImageCapabilities getCapabilities() + { + return caps; + } + + public synchronized Object getProperty (String name, ImageObserver observer) + { + return null; + } + + public synchronized int getWidth (ImageObserver observer) + { + return width; + } + + public synchronized int getHeight (ImageObserver observer) + { + return height; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java new file mode 100644 index 0000000..71e05a8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -0,0 +1,212 @@ +/* GtkWindowPeer.java -- Implements WindowPeer with GTK + Copyright (C) 1998, 1999, 2002, 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.java.awt.peer.gtk; + +import java.awt.Component; +import java.awt.Frame; +import java.awt.Window; +import java.awt.event.WindowEvent; +import java.awt.peer.WindowPeer; + +public class GtkWindowPeer extends GtkContainerPeer + implements WindowPeer +{ + protected static final int GDK_WINDOW_TYPE_HINT_NORMAL = 0; + protected static final int GDK_WINDOW_TYPE_HINT_DIALOG = 1; + protected static final int GDK_WINDOW_TYPE_HINT_MENU = 2; + protected static final int GDK_WINDOW_TYPE_HINT_TOOLBAR = 3; + protected static final int GDK_WINDOW_TYPE_HINT_SPLASHSCREEN = 4; + protected static final int GDK_WINDOW_TYPE_HINT_UTILITY = 5; + protected static final int GDK_WINDOW_TYPE_HINT_DOCK = 6; + protected static final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7; + + private boolean hasBeenShown = false; + private int oldState = Frame.NORMAL; + + native void gtkWindowSetTitle (String title); + native void gtkWindowSetResizable (boolean resizable); + native void gtkWindowSetModal (boolean modal); + + native void realize (); + + int getWidth () + { + return awtComponent.getWidth(); + } + + int getHeight () + { + return awtComponent.getHeight(); + } + + native void create (int type, boolean decorated, GtkWindowPeer parent); + + void create (int type, boolean decorated) + { + GtkWindowPeer parent_peer = null; + Component parent = awtComponent.getParent(); + + if (parent != null) + parent_peer = (GtkWindowPeer) awtComponent.getParent().getPeer(); + + create (type, decorated, parent_peer); + } + + void create () + { + // Create a normal undecorated window. + create (GDK_WINDOW_TYPE_HINT_NORMAL, false); + } + + void setParent () + { + setVisible (awtComponent.isVisible ()); + setEnabled (awtComponent.isEnabled ()); + } + + void setVisibleAndEnabled () + { + } + + native void connectSignals (); + + public GtkWindowPeer (Window window) + { + super (window); + } + + public native void toBack(); + public native void toFront(); + + native void nativeSetBounds (int x, int y, int width, int height); + + public void setBounds (int x, int y, int width, int height) + { + nativeSetBounds (x, y, + width - insets.left - insets.right, + height - insets.top - insets.bottom); + } + + public void setTitle (String title) + { + gtkWindowSetTitle (title); + } + + native void setSize (int width, int height); + + public void setResizable (boolean resizable) + { + // Call setSize; otherwise when resizable is changed from true to + // false the window will shrink to the dimensions it had before it + // was resizable. + setSize (awtComponent.getWidth() - insets.left - insets.right, + awtComponent.getHeight() - insets.top - insets.bottom); + gtkWindowSetResizable (resizable); + } + + native void setBoundsCallback (Window window, + int x, int y, + int width, int height); + + protected void postInsetsChangedEvent (int top, int left, + int bottom, int right) + { + insets.top = top; + insets.left = left; + insets.bottom = bottom; + insets.right = right; + } + + protected void postConfigureEvent (int x, int y, int width, int height) + { + int frame_x = x - insets.left; + int frame_y = y - insets.top; + int frame_width = width + insets.left + insets.right; + int frame_height = height + insets.top + insets.bottom; + + if (frame_x != awtComponent.getX() + || frame_y != awtComponent.getY() + || frame_width != awtComponent.getWidth() + || frame_height != awtComponent.getHeight()) + { + setBoundsCallback ((Window) awtComponent, + frame_x, frame_y, frame_width, frame_height); + + awtComponent.validate(); + } + } + + native void nativeSetVisible (boolean b); + public void setVisible (boolean b) + { + // Prevent the window manager from automatically placing this + // window when it is shown. + if (b) + setBounds (awtComponent.getX(), + awtComponent.getY(), + awtComponent.getWidth(), + awtComponent.getHeight()); + nativeSetVisible (b); + } + + void postWindowEvent (int id, Window opposite, int newState) + { + if (id == WindowEvent.WINDOW_OPENED) + { + // Post a WINDOW_OPENED event the first time this window is shown. + if (!hasBeenShown) + { + q().postEvent (new WindowEvent ((Window) awtComponent, id, + opposite)); + hasBeenShown = true; + } + } + else if (id == WindowEvent.WINDOW_STATE_CHANGED) + { + if (oldState != newState) + { + q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite, + oldState, newState)); + oldState = newState; + } + } + else + q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/package.html b/libjava/classpath/gnu/java/awt/peer/gtk/package.html new file mode 100644 index 0000000..8dd4dd8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.awt.peer.gtk package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.awt.peer.gtk</title></head> + +<body> +<p>This package implements the GTK peer for java.awt.</p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/awt/peer/package.html b/libjava/classpath/gnu/java/awt/peer/package.html new file mode 100644 index 0000000..846759a --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.awt.peer package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.awt.peer</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java b/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java new file mode 100644 index 0000000..0cf73e5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/BeanInfoEmbryo.java @@ -0,0 +1,171 @@ +/* gnu.java.beans.BeanInfoEmbryo + Copyright (C) 1998, 2002 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.java.beans; + +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Vector; + +/** + ** A BeanInfoEmbryo accumulates information about a Bean + ** while it is in the process of being created, and then + ** when you are done accumulating the information, the + ** getBeanInfo() method may be called to create a BeanInfo + ** object based on the information.<P> + ** + ** This class is not well-synchronized. (It can be, it + ** just isn't yet.) + ** + ** @author John Keiser + ** @version 1.1.0, 30 Jul 1998 + ** @see java.beans.BeanInfo + **/ + +public class BeanInfoEmbryo { + + // by using a TreeMap the properties will be sorted alphabetically by name + // which matches the (undocumented) behavior of jdk + TreeMap properties = new TreeMap(); + Hashtable events = new Hashtable(); + Vector methods = new Vector(); + + BeanDescriptor beanDescriptor; + BeanInfo[] additionalBeanInfo; + java.awt.Image[] im; + String defaultPropertyName; + String defaultEventName; + + public BeanInfoEmbryo() { + } + + public BeanInfo getBeanInfo() { + int defaultProperty = -1; + int defaultEvent = -1; + + PropertyDescriptor[] Aproperties = new PropertyDescriptor[properties.size()]; + int i = 0; + Iterator it = properties.entrySet().iterator(); + while (it.hasNext()) { + Aproperties[i] = (PropertyDescriptor) (((Map.Entry)it.next()).getValue()); + if(defaultPropertyName != null && Aproperties[i].getName().equals(defaultPropertyName)) { + defaultProperty = i; + } + i++; + } + + EventSetDescriptor[] Aevents = new EventSetDescriptor[events.size()]; + i = 0; + Enumeration e = events.elements(); + while (e.hasMoreElements()) { + Aevents[i] = (EventSetDescriptor) e.nextElement(); + if(defaultEventName != null && Aevents[i].getName().equals(defaultEventName)) { + defaultEvent = i; + } + i++; + } + + MethodDescriptor[] Amethods = new MethodDescriptor[methods.size()]; + methods.copyInto(Amethods); + + return new ExplicitBeanInfo(beanDescriptor,additionalBeanInfo,Aproperties,defaultProperty,Aevents,defaultEvent,Amethods,im); + } + + public void setBeanDescriptor(BeanDescriptor b) { + beanDescriptor = b; + } + + public void setAdditionalBeanInfo(BeanInfo[] b) { + additionalBeanInfo = b; + } + + public boolean hasProperty(PropertyDescriptor p) { + return properties.get(p.getName()) != null; + } + public void addProperty(PropertyDescriptor p) { + properties.put(p.getName(),p); + } + public void addIndexedProperty(IndexedPropertyDescriptor p) { + properties.put(p.getName(),p); + } + + public boolean hasEvent(EventSetDescriptor e) { + return events.get(e.getName()) != null; + } + public void addEvent(EventSetDescriptor e) { + events.put(e.getName(),e); + } + + public boolean hasMethod(MethodDescriptor m) { + for(int i=0;i<methods.size();i++) { + Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod(); + if(m.getMethod().getName().equals(thisMethod.getName()) + && Arrays.equals(m.getMethod().getParameterTypes(), + thisMethod.getParameterTypes())) { + return true; + } + } + return false; + } + public void addMethod(MethodDescriptor m) { + methods.addElement(m); + } + + public void setDefaultPropertyName(String defaultPropertyName) { + this.defaultPropertyName = defaultPropertyName; + } + + public void setDefaultEventName(String defaultEventName) { + this.defaultEventName = defaultEventName; + } + + public void setIcons(java.awt.Image[] im) { + this.im = im; + } +} diff --git a/libjava/classpath/gnu/java/beans/DummyAppletContext.java b/libjava/classpath/gnu/java/beans/DummyAppletContext.java new file mode 100644 index 0000000..4facb47 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/DummyAppletContext.java @@ -0,0 +1,200 @@ +/* gnu.java.beans.DummyAppletContext + Copyright (C) 2004, 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.java.beans; + +import java.applet.Applet; +import java.applet.AppletContext; +import java.applet.AudioClip; +import java.awt.Image; +import java.awt.Toolkit; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; + +/** A placeholder <code>AppletContext</code> implementation that does nothing. + * + * <p>This is the default implementation for GNU Classpath and is used for <code>Applet</code> + * beans being created with {@link java.beans.Beans.instantiate}.</p> + * + * <p>It has no functionality in order to allow it to be used without any dependencies + * (e.g. sound, network access, ...).</p> + * + * @author Robert Schuster + */ +class DummyAppletContext implements AppletContext +{ + private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_SET); + private static final AudioClip DUMMY_CLIP = new DummyAudioClip(); + + DummyAppletContext() + { + } + + /** Implementation is VM neutral and returns a dummy {@link AudioClip} instance + * for every URL that returns a non-<code>null</code> object on + * <code>URL.openConnection()</code>. + * + * @see java.applet.AppletContext#getAudioClip(java.net.URL) + * + * FIXME: When Java Sound API (javax.sound) is included in Classpath or URL is able to handle + * sampled sound this should be adjusted. + */ + public AudioClip getAudioClip(URL url) + { + try + { + return (url.openConnection() != null ? DUMMY_CLIP : null); + } + catch (IOException ioe) + { + return null; + } + } + + /** Loads the <code>Image</code> instance by delegating to + * {@link java.awt.Toolkit.createImage(URL) }. + * + * @see java.applet.AppletContext#getImage(java.net.URL) + * @see java.awt.Toolkit#createImage(java.net.URL) + */ + public Image getImage(URL url) + { + return Toolkit.getDefaultToolkit().createImage(url); + } + + /** Returns <code>null</code> for every argument. + * + * @see java.applet.AppletContext#getApplet(java.lang.String) + */ + public Applet getApplet(String name) + { + return null; + } + + /** Returns always an empty <code>Enumeration</code>. + * + * @see java.applet.AppletContext#getApplets() + */ + public Enumeration getApplets() + { + return EMPTY_ENUMERATION; + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showDocument(java.net.URL) + */ + public void showDocument(URL url) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showDocument(java.net.URL, java.lang.String) + */ + public void showDocument(URL url, String target) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#showStatus(java.lang.String) + */ + public void showStatus(String message) + { + } + + /** Does nothing. + * + * @see java.applet.AppletContext#setStream(java.lang.String, java.io.InputStream) + */ + public void setStream(String key, InputStream stream) + throws IOException + { + throw new IOException("Dummy implementation imposes zero InputStream associations."); + } + + /** Returns <code>null</code> for every argument. + * + * @see java.applet.AppletContext#getStream(java.lang.String) + */ + public InputStream getStream(String key) + { + return null; + } + + /** Returns always an empty iterator. + * + * @see java.applet.AppletContext#getStreamKeys() + */ + public Iterator getStreamKeys() + { + return Collections.EMPTY_SET.iterator(); + } + + /** Dummy <code>AudioClip</code> implementation that does nothing but + * preventing <code>NullPointerException</code>S being thrown in programs + * that expect a valid <code>AudioClip</code> instance to be returned by + * their Applet. + * + * @author Robert Schuster + */ + static class DummyAudioClip implements AudioClip + { + public void play() + { + } + + public void stop() + { + } + + public void loop() + { + } + + public String toString() + { + return "DummyAudioClip never plays anything - implement javax.sound and make us happy :)"; + } + } +} diff --git a/libjava/classpath/gnu/java/beans/DummyAppletStub.java b/libjava/classpath/gnu/java/beans/DummyAppletStub.java new file mode 100644 index 0000000..3bcb435 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/DummyAppletStub.java @@ -0,0 +1,115 @@ +/* gnu.java.beans.DummyAppletStub + Copyright (C) 2004, 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.java.beans; + +import java.applet.AppletContext; +import java.applet.AppletStub; +import java.net.URL; + +/** Placeholder implementation of <code>AppletStub</code> providing no functionality. + * <p>This class is used for <code>Applet</code> being created with + * {@link java.beans.Bean.instantiate}.</p> + * + * @author Robert Schuster + */ +public class DummyAppletStub implements AppletStub +{ + private URL documentBase; + private URL codeBase; + private DummyAppletContext context; + + public DummyAppletStub(URL newCodeBase, URL newDocumentBase) + { + codeBase = newCodeBase; + documentBase = newDocumentBase; + + context = new DummyAppletContext(); + } + + /** Returns always <code>true</code>. + * + * @see java.applet.AppletStub#isActive() + */ + public boolean isActive() + { + return true; + } + + /** + * @see java.applet.AppletStub#getDocumentBase() + */ + public URL getDocumentBase() + { + return documentBase; + } + + /** + * @see java.applet.AppletStub#getCodeBase() + */ + public URL getCodeBase() + { + return codeBase; + } + + /** Implementation returns <code>null</code> for every parameter name. + * + * @see java.applet.AppletStub#getParameter(java.lang.String) + */ + public String getParameter(String name) + { + return null; + } + + /** Returns a non-functional context instance. + * + * @see java.applet.AppletStub#getAppletContext() + */ + public AppletContext getAppletContext() + { + return context; + } + + /** Does nothing. + * + * @see java.applet.AppletStub#appletResize(int, int) + */ + public void appletResize(int width, int height) + { + } +} diff --git a/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java b/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java new file mode 100644 index 0000000..6da5e86 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/ExplicitBeanInfo.java @@ -0,0 +1,149 @@ +/* ExplicitBeanInfo.java -- + Copyright (C) 1998, 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.java.beans; + +import java.awt.Image; +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; + +/** + ** ExplicitBeanInfo lets you specify in the constructor + ** all the various parts of the BeanInfo. + ** + ** @author John Keiser + ** @version 1.1.0, 30 Jul 1998 + ** @see java.beans.BeanInfo + **/ + +public class ExplicitBeanInfo implements BeanInfo { + /** The BeanDescriptor returned by getBeanDescriptor. **/ + protected BeanDescriptor beanDescriptor; + + /** The EventSetDescriptor array returned by + ** getEventSetDescriptors(). + **/ + protected EventSetDescriptor[] eventSetDescriptors = new EventSetDescriptor[0]; + + /** The PropertyDescriptor array returned by + ** getPropertyDescriptors(). + **/ + protected PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0]; + + /** The MethodDescriptor array returned by + ** getMethodDescriptors(). + **/ + protected MethodDescriptor[] methodDescriptors; + + /** The default property index. **/ + protected int defaultPropertyIndex; + + /** The default event index. **/ + protected int defaultEventIndex; + + /** The BeanInfo array returned by + ** getAdditionalBeanInfo(). + **/ + protected BeanInfo[] additionalBeanInfo; + + /** The set of icons. **/ + protected Image[] icons; + + public ExplicitBeanInfo(BeanDescriptor beanDescriptor, + BeanInfo[] additionalBeanInfo, + PropertyDescriptor[] propertyDescriptors, + int defaultPropertyIndex, + EventSetDescriptor[] eventSetDescriptors, + int defaultEventIndex, + MethodDescriptor[] methodDescriptors, + Image[] icons) { + this.beanDescriptor = beanDescriptor; + this.additionalBeanInfo = additionalBeanInfo; + this.propertyDescriptors = propertyDescriptors; + this.defaultPropertyIndex = defaultPropertyIndex; + this.eventSetDescriptors = eventSetDescriptors; + this.defaultEventIndex = defaultEventIndex; + this.methodDescriptors = methodDescriptors; + this.icons = icons; + } + + /** Get Bean descriptor. **/ + public BeanDescriptor getBeanDescriptor() { + return beanDescriptor; + } + + /** Get Bean events. **/ + public EventSetDescriptor[] getEventSetDescriptors() { + return eventSetDescriptors; + } + + /** Get default event set. **/ + public int getDefaultEventIndex() { + return defaultEventIndex; + } + + /** Get Bean properties. **/ + public PropertyDescriptor[] getPropertyDescriptors() { + return propertyDescriptors; + } + + /** Get "default" property. **/ + public int getDefaultPropertyIndex() { + return defaultPropertyIndex; + } + + /** Get Bean methods. **/ + public MethodDescriptor[] getMethodDescriptors() { + return methodDescriptors; + } + + /** Get additional Bean info. **/ + public BeanInfo[] getAdditionalBeanInfo() { + return additionalBeanInfo; + } + + /** Get Bean icons. + ** @param iconType the type of icon + **/ + public Image getIcon(int iconType) { + return icons != null ? icons[iconType - 1] : null; + } +} diff --git a/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java new file mode 100644 index 0000000..e0d9480 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/IntrospectionIncubator.java @@ -0,0 +1,441 @@ +/* gnu.java.beans.IntrospectionIncubator + Copyright (C) 1998, 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.java.beans; + +import gnu.java.lang.ArrayHelper; +import gnu.java.lang.ClassHelper; + +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.MethodDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + ** IntrospectionIncubator takes in a bunch of Methods, and + ** Introspects only those Methods you give it.<br/> + ** + ** See {@link addMethod(Method)} for details which rules apply to + ** the methods. + ** + ** @author John Keiser + ** @author Robert Schuster + ** @see gnu.java.beans.ExplicitBeanInfo + ** @see java.beans.BeanInfo + **/ + +public class IntrospectionIncubator { + Hashtable propertyMethods = new Hashtable(); + Hashtable listenerMethods = new Hashtable(); + Vector otherMethods = new Vector(); + + Class propertyStopClass; + Class eventStopClass; + Class methodStopClass; + + public IntrospectionIncubator() { + } + + /** Examines the given method and files it in a suitable collection. + * It files the method as a property method if it finds: + * <ul> + * <li>boolean "is" getter</li> + * <li>"get" style getter</li> + * <li>single argument setter</li> + * <li>indiced setter and getter</li> + * </ul> + * It files the method as a listener method if all of these rules apply: + * <ul> + * <li>the method name starts with "add" or "remove"</li> + * <li>there is only a single argument</li> + * <li>the argument type is a subclass of <code>java.util.EventListener</code></li> + * </ul> + * All public methods are filed as such. + * + * @param method The method instance to examine. + */ + public void addMethod(Method method) { + if(Modifier.isPublic(method.getModifiers())) { + String name = ClassHelper.getTruncatedName(method.getName()); + Class retType = method.getReturnType(); + Class[] params = method.getParameterTypes(); + boolean isVoid = retType.equals(java.lang.Void.TYPE); + Class methodClass = method.getDeclaringClass(); + + /* Accepts the method for examination if no stop class is given or the method is declared in a subclass of the stop class. + * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}. + * This block finds out whether the method is a suitable getter or setter method (or read/write method). + */ + if(isReachable(propertyStopClass, methodClass)) { + /* At this point a method may regarded as a property's read or write method if its name + * starts with "is", "get" or "set". However, if a method is static it cannot be part + * of a property. + */ + if(Modifier.isStatic(method.getModifiers())) { + // files method as other because it is static + otherMethods.addElement(method); + } else if(name.startsWith("is") + && retType.equals(java.lang.Boolean.TYPE) + && params.length == 0) { + // files method as boolean "is" style getter + addToPropertyHash(name,method,IS); + } else if(name.startsWith("get") && !isVoid) { + if(params.length == 0) { + // files as legal non-argument getter + addToPropertyHash(name,method,GET); + } else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) { + // files as legal indiced getter + addToPropertyHash(name,method,GET_I); + } else { + // files as other because the method's signature is not Bean-like + otherMethods.addElement(method); + } + } else if(name.startsWith("set") && isVoid) { + if(params.length == 1) { + // files as legal single-argument setter method + addToPropertyHash(name,method,SET); + } else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) { + // files as legal indiced setter method + addToPropertyHash(name,method,SET_I); + } else { + // files as other because the method's signature is not Bean-like + otherMethods.addElement(method); + } + } + } + + if(isReachable(eventStopClass, methodClass)) { + if(name.startsWith("add") + && isVoid + && params.length == 1 + && java.util.EventListener.class.isAssignableFrom(params[0])) { + addToListenerHash(name,method,ADD); + } else if(name.startsWith("remove") + && isVoid + && params.length == 1 + && java.util.EventListener.class.isAssignableFrom(params[0])) { + addToListenerHash(name,method,REMOVE); + } + } + + if(isReachable(methodStopClass, methodClass)) { + // files as reachable public method + otherMethods.addElement(method); + } + + } + } + + public void addMethods(Method[] m) { + for(int i=0;i<m.length;i++) { + addMethod(m[i]); + } + } + + public void setPropertyStopClass(Class c) { + propertyStopClass = c; + } + + public void setEventStopClass(Class c) { + eventStopClass = c; + } + + public void setMethodStopClass(Class c) { + methodStopClass = c; + } + + + public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException { + BeanInfoEmbryo b = new BeanInfoEmbryo(); + findXXX(b,IS); + findXXXInt(b,GET_I); + findXXXInt(b,SET_I); + findXXX(b,GET); + findXXX(b,SET); + findAddRemovePairs(b); + for(int i=0;i<otherMethods.size();i++) { + MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i)); + if(!b.hasMethod(newMethod)) { + b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i))); + } + } + return b; + } + + public BeanInfo getBeanInfo() throws IntrospectionException { + return getBeanInfoEmbryo().getBeanInfo(); + } + + + void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException { + Enumeration listenerEnum = listenerMethods.keys(); + while(listenerEnum.hasMoreElements()) { + DoubleKey k = (DoubleKey)listenerEnum.nextElement(); + Method[] m = (Method[])listenerMethods.get(k); + if(m[ADD] != null && m[REMOVE] != null) { + EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()), + k.getType(), k.getType().getMethods(), + m[ADD],m[REMOVE]); + e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class)); + if(!b.hasEvent(e)) { + b.addEvent(e); + } + } + } + } + + void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException { + Enumeration keys = propertyMethods.keys(); + while(keys.hasMoreElements()) { + DoubleKey k = (DoubleKey)keys.nextElement(); + Method[] m = (Method[])propertyMethods.get(k); + if(m[funcType] != null) { + PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()), + m[IS] != null ? m[IS] : m[GET], + m[SET]); + if(m[SET] != null) { + p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class)); + } + if(!b.hasProperty(p)) { + b.addProperty(p); + } + } + } + } + + void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException { + Enumeration keys = propertyMethods.keys(); + while(keys.hasMoreElements()) { + DoubleKey k = (DoubleKey)keys.nextElement(); + Method[] m = (Method[])propertyMethods.get(k); + if(m[funcType] != null) { + boolean constrained; + if(m[SET_I] != null) { + constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class); + } else { + constrained = false; + } + + /** Find out if there is an array type get or set **/ + Class arrayType = Array.newInstance(k.getType(),0).getClass(); + DoubleKey findSetArray = new DoubleKey(arrayType,k.getName()); + Method[] m2 = (Method[])propertyMethods.get(findSetArray); + IndexedPropertyDescriptor p; + if(m2 == null) { + p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()), + null,null, + m[GET_I],m[SET_I]); + } else { + if(constrained && m2[SET] != null) { + constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class); + } + p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()), + m2[GET],m2[SET], + m[GET_I],m[SET_I]); + } + p.setConstrained(constrained); + if(!b.hasProperty(p)) { + b.addProperty(p); + } + } + } + } + + static final int IS=0; + static final int GET_I=1; + static final int SET_I=2; + static final int GET=3; + static final int SET=4; + + static final int ADD=0; + static final int REMOVE=1; + + void addToPropertyHash(String name, Method method, int funcType) { + String newName; + Class type; + + switch(funcType) { + case IS: + type = java.lang.Boolean.TYPE; + newName = name.substring(2); + break; + case GET_I: + type = method.getReturnType(); + newName = name.substring(3); + break; + case SET_I: + type = method.getParameterTypes()[1]; + newName = name.substring(3); + break; + case GET: + type = method.getReturnType(); + newName = name.substring(3); + break; + case SET: + type = method.getParameterTypes()[0]; + newName = name.substring(3); + break; + default: + return; + } + newName = capitalize(newName); + if (newName.length() == 0) + return; + + DoubleKey k = new DoubleKey(type,newName); + Method[] methods = (Method[])propertyMethods.get(k); + if(methods == null) { + methods = new Method[5]; + propertyMethods.put(k,methods); + } + methods[funcType] = method; + } + + void addToListenerHash(String name, Method method, int funcType) { + String newName; + Class type; + + switch(funcType) { + case ADD: + type = method.getParameterTypes()[0]; + newName = name.substring(3,name.length()-8); + break; + case REMOVE: + type = method.getParameterTypes()[0]; + newName = name.substring(6,name.length()-8); + break; + default: + return; + } + newName = capitalize(newName); + if (newName.length() == 0) + return; + + DoubleKey k = new DoubleKey(type,newName); + Method[] methods = (Method[])listenerMethods.get(k); + if(methods == null) { + methods = new Method[2]; + listenerMethods.put(k,methods); + } + methods[funcType] = method; + } + + /* Determines whether <code>stopClass</code> is <code>null</code> + * or <code>declaringClass<code> is a true subclass of <code>stopClass</code>. + * This expression is useful to detect whether a method should be introspected or not. + * The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}. + */ + static boolean isReachable(Class stopClass, Class declaringClass) { + return stopClass == null || (stopClass.isAssignableFrom(declaringClass) && !stopClass.equals(declaringClass)); + } + + /** Transforms a property name into a part of a method name. + * E.g. "value" becomes "Value" which can then concatenated with + * "set", "get" or "is" to form a valid method name. + * + * Implementation notes: + * If "" is the argument, it is returned without changes. + * If <code>null</code> is the argument, <code>null</code> is returned. + * + * @param name Name of a property. + * @return Part of a method name of a property. + */ + static String capitalize(String name) { + try { + if(Character.isUpperCase(name.charAt(0))) { + return name; + } else { + char[] c = name.toCharArray(); + c[0] = Character.toLowerCase(c[0]); + return new String(c); + } + } catch(StringIndexOutOfBoundsException E) { + return name; + } catch(NullPointerException E) { + return null; + } + } +} + +/** This class is a hashmap key that consists of a <code>Class</code> and a + * <code>String</code> element. + * + * It is used for XXX: find out what this is used for + * + * @author John Keiser + * @author Robert Schuster + */ +class DoubleKey { + Class type; + String name; + + DoubleKey(Class type, String name) { + this.type = type; + this.name = name; + } + + Class getType() { + return type; + } + + String getName() { + return name; + } + + public boolean equals(Object o) { + if(o instanceof DoubleKey) { + DoubleKey d = (DoubleKey)o; + return d.type.equals(type) && d.name.equals(name); + } else { + return false; + } + } + + public int hashCode() { + return type.hashCode() ^ name.hashCode(); + } +} diff --git a/libjava/classpath/gnu/java/beans/TODO b/libjava/classpath/gnu/java/beans/TODO new file mode 100644 index 0000000..9112806 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/TODO @@ -0,0 +1 @@ +- overhaul efficiency diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java new file mode 100644 index 0000000..0e95d43 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractContext.java @@ -0,0 +1,70 @@ +/* gnu.java.beans.decoder.AbstractContext + Copyright (C) 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.java.beans.decoder; + + +/** AbstractContext implements some basic functionality of the Context + * interface and is therefore the base of all Context implementations. + * + * @author Robert Schuster + */ +abstract class AbstractContext implements Context +{ + private boolean isStatement; + private String id; + + public String getId() + { + return id; + } + + public void setId(String newId) + { + id = newId; + } + + public boolean isStatement() + { + return isStatement; + } + + public void setStatement(boolean b) + { + isStatement = b; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java new file mode 100644 index 0000000..47f04fa --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractCreatableObjectContext.java @@ -0,0 +1,113 @@ +/* gnu.java.beans.decoder.AbstractCreatableContext + Copyright (C) 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.java.beans.decoder; + + +/** AbstractCreatableObjectContext is the base class for all Context implementations + * which create a result object in their lifetime. It provides means for preventing + * to create the object twice. + * + * @author Robert Schuster + * + */ +abstract class AbstractCreatableObjectContext extends AbstractObjectContext +{ + AbstractCreatableObjectContext() + { + } + + /** Adds a parameter object to this Context if the result object has not been + * created yet. Otherwise an AssemblyException is thrown that indicates a wrong + * behavior of the decoder. + */ + public final void addParameterObject(Object o) throws AssemblyException + { + if (object == null) + addParameterObjectImpl(o); + else + throw new AssemblyException(new IllegalStateException("No more parameter objects are allowed when the object as already been created.")); + } + + /** Adds a parameter object to this Context. Implement this without caring + * for illegal states because this has been done already. + * + * @param obj The parameter object to be added. + */ + protected abstract void addParameterObjectImpl(Object obj); + + /** Creates the result object if it does not exist already. + */ + public final void notifyStatement(Context outerContext) + throws AssemblyException + { + if (object != null) + return; + + object = createObject(outerContext); + } + + /** Creates the result object. This method is called only once. Implement this + * without checking for double invocations as this is already being prevented. + * + * @param outerContext The Context that exists around this one. + * @return The result object. + * @throws AssemblerException if the object creation fails somehow. + */ + protected abstract Object createObject(Context outerContext) + throws AssemblyException; + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public final Object endContext(Context outerContext) + throws AssemblyException + { + notifyStatement(outerContext); + return object; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + /* Returns true when the AbstractCreatableObjectContext has not created the result object yet + * (A failed subcontext automatically lets this context fail too.) + */ + return object == null; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java b/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java new file mode 100644 index 0000000..e5578a9 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractElementHandler.java @@ -0,0 +1,316 @@ +/* gnu.java.beans.decoder.AbstractElementHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** ElementHandler manages a Context instance and interacts with + * its parent and child handlers. + * + * @author Robert Schuster + */ +abstract class AbstractElementHandler implements ElementHandler +{ + /** The Context instance of this handler. The instance is available after the startElement() + * method was called. Otherwise the handler is marked as failed. + */ + private Context context; + + /** The parent handler. */ + private ElementHandler parent; + + /** Stores whether this handler is marked as failed. */ + private boolean hasFailed; + + /** Stores the character data which is contained in the body of the XML tag. */ + private StringBuffer buffer = new StringBuffer(); + + /** Stores whether this ElementHandler can have subelements. The information for this is taken from + * javabeans.dtd which can be found here: + * <a href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">Java Persistence Article</a> + */ + private boolean allowsSubelements; + + /** Creates a new ElementHandler with the given ElementHandler instance + * as parent. + * + * @param parentHandler The parent handler. + */ + protected AbstractElementHandler(ElementHandler parentHandler, + boolean allowsSubs) + { + parent = parentHandler; + allowsSubelements = allowsSubs; + } + + /** Evaluates the attributes and creates a Context instance. + * If the creation of the Context instance fails the ElementHandler + * is marked as failed which may affect the parent handler other. + * + * @param attributes Attributes of the XML tag. + */ + public final void start(Attributes attributes, + ExceptionListener exceptionListener) + { + try + { + // lets the subclass create the appropriate Context instance + context = startElement(attributes, exceptionListener); + } + catch (AssemblyException pe) + { + Throwable t = pe.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw new InternalError("Unexpected Throwable type in AssemblerException. Please file a bug report."); + + notifyContextFailed(); + + return; + } + } + + /** Analyses the content of the Attributes instance and creates a Context + * object accordingly. + * An AssemblerException is thrown when the Context instance could not + * be created. + * + * @param attributes Attributes of the XML tag. + * @return A Context instance. + * @throws AssemblerException when Context instance could not be created. + */ + protected abstract Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException; + + /** Post-processes the Context. + */ + public final void end(ExceptionListener exceptionListener) + { + // skips processing if the handler is marked as failed (because the Context + // is then invalid or may not exist at all) + if (!hasFailed) + { + try + { + // note: the order of operations is very important here + // sends the stored character data to the Context + endElement(buffer.toString()); + + // reports to the parent handler if this handler's Context is a + // statement (returning no value BACK to the parent's Context) + if (context.isStatement()) + { + // This may create a valid result in the parent's Context + // or let it fail + parent.notifyStatement(exceptionListener); + + // skips any further processing if the parent handler is now marked + // as failed + if (parent.hasFailed()) + return; + } + + // processes the Context and stores the result + putObject(context.getId(), context.endContext(parent.getContext())); + + // transfers the Context's results to the parent's Context + // if it is an expression (rather than a statement) + if (! context.isStatement()) + parent.getContext().addParameterObject(context.getResult()); + } + catch (AssemblyException pe) + { + // notifies that an exception was thrown in this handler's Context + Throwable t = pe.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw (InternalError) new InternalError("Severe problem while decoding XML data.") + .initCause(t); + + // marks the handler as failed + notifyContextFailed(); + } + } + } + + /** Notifies the handler's Context that its child Context will not return + * a value back. Some Context variants need this information to know when + * a method or a constructor call can be made. + * + * This method is called by a child handler. + */ + public void notifyStatement(ExceptionListener exceptionListener) + { + try + { + + // propagates to parent handler first to generate objects + // needed by this Context instance + if(context.isStatement()) + { + parent.notifyStatement(exceptionListener); + } + + // Some Context instances do stuff which can fail now. If that + // happens this handler is marked as failed. + context.notifyStatement(parent.getContext()); + } + catch (AssemblyException ae) + { + // notifies that an exception was thrown in this handler's Context + Throwable t = ae.getCause(); + + if (t instanceof Exception) + exceptionListener.exceptionThrown((Exception) t); + else + throw (InternalError) new InternalError("Severe problem while decoding XML data.") + .initCause(t); + + // marks the handler as failed + notifyContextFailed(); + } + } + + /** Marks this and any depending parent handlers as failed. Which means that on their end + * no result is calculated. + * + * When a handler has failed no more handlers are accepted within it. + */ + public final void notifyContextFailed() + { + hasFailed = true; + + // marks the parent handler as failed if its Context + // is affected by the failure of this handler's Context + if (parent.getContext().subContextFailed()) + parent.notifyContextFailed(); + } + + /** Returns whether this handler has failed. + * + * This is used to skip child elements. + * + * @return Whether this handler has failed. + */ + public final boolean hasFailed() + { + return hasFailed; + } + + /** Processes the character data when the element ends. + * + * The default implementation does nothing for convenience. + * + * @param characters + * @throws AssemblerException + */ + protected void endElement(String characters) throws AssemblyException + { + // XXX: throw an exception when unexpected character data is available? + } + + /** Adds characters from the body of the XML tag to the buffer. + * + * @param ch + * @param start + * @param length + * @throws SAXException + */ + public final void characters(char[] ch, int start, int length) + { + // simply appends character data + buffer.append(ch, start, length); + } + + /** Stores an object globally under a unique id. If the id is + * null the object is not stored. + * + * @param objectId + * @param o + */ + public void putObject(String objectId, Object o) + { + if (objectId != null) + parent.putObject(objectId, o); + } + + /** Returns a previously stored object. If the id is null the + * result is null, too. + * + * @param objectId + * @return Returns a previously stored object or null. + */ + public Object getObject(String objectId) throws AssemblyException + { + return objectId == null ? null : parent.getObject(objectId); + } + + /** Returns the Class instance as if called Class.forName() but + * uses a ClassLoader given by the user. + * + * @param className + * @return + * @throws ClassNotFoundException + */ + public Class instantiateClass(String className) + throws ClassNotFoundException + { + return parent.instantiateClass(className); + } + + public final boolean isSubelementAllowed(String subElementName) + { + return allowsSubelements && ! subElementName.equals("java"); + } + + public final Context getContext() + { + return context; + } + + public final ElementHandler getParent() + { + return parent; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java new file mode 100644 index 0000000..202c33b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AbstractObjectContext.java @@ -0,0 +1,127 @@ +/* gnu.java.beans.decoder.AbstractObjectContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** AbstractObjectContext is the base for all Context implementations which + * create or provide a result object during their lifetime. + * + * <p>This class provides the implementation for an indexed get and set method. + * But this does not mean that the result object supports these operation.</p> + * + * @author Robert Schuster + * + */ +abstract class AbstractObjectContext extends AbstractContext +{ + protected Object object; + + AbstractObjectContext() + {} + + /** Sets the result object of the Context. + * + * @param obj The result object to be set. + */ + protected final void setObject(Object obj) + { + object = obj; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public final void set(int index, Object o) throws AssemblyException + { + try + { + Method method = + object.getClass().getMethod( + "set", + new Class[] { Integer.TYPE, Object.class }); + + method.invoke(object, new Object[] { new Integer(index), o }); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public final Object get(int index) throws AssemblyException + { + try + { + Method method = + object.getClass().getMethod( + "get", + new Class[] { Integer.TYPE }); + + return method.invoke(object, new Object[] { new Integer(index)}); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + public final Object getResult() + { + return object; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java b/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java new file mode 100644 index 0000000..cf4267f --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ArrayContext.java @@ -0,0 +1,122 @@ +/* gnu.java.beans.decoder.ArrayContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.Array; + +/** A Context implementation for a fixed size array. The array + * elements have to be set using IndexContext instances. + * + * @author Robert Schuster + */ +class ArrayContext extends AbstractContext +{ + private Object array; + + ArrayContext(String id, Class klass, int length) + { + setId(id); + array = Array.newInstance(klass, length); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Adding objects without an index to a fixed array is not possible.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) + { + // method call intentionally ignored because there is not any useful effect + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + return array; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns false to indicate that assembling the array does not fail only because + // a subelement failed. + return false; + } + + public void set(int index, Object o) throws AssemblyException + { + try + { + Array.set(array, index, o); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + throw new AssemblyException(aioobe); + } + } + + public Object get(int index) throws AssemblyException + { + try + { + return Array.get(array, index); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + throw new AssemblyException(aioobe); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + return array; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java b/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java new file mode 100644 index 0000000..23f0285 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ArrayHandler.java @@ -0,0 +1,118 @@ +/* gnu.java.beans.decoder.ArrayHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.util.HashMap; + +import org.xml.sax.Attributes; + +/** ArrayHandler processes the <array> tag. Depending on the existance of the 'length' attribute a Context for + * a fixed-size or growable array is created. + * + * @author Robert Schuster + */ +class ArrayHandler extends AbstractElementHandler +{ + /** Contains a mapping between a textual description of a primitive type (like "byte") and + * its corresponding wrapper class. This allows it to easily construct Array objects for + * primitive data types. + */ + private static HashMap typeMap = new HashMap(); + + static + { + typeMap.put("byte", Byte.TYPE); + typeMap.put("short", Short.TYPE); + typeMap.put("int", Integer.TYPE); + typeMap.put("long", Long.TYPE); + + typeMap.put("float", Float.TYPE); + typeMap.put("double", Double.TYPE); + + typeMap.put("boolean", Boolean.TYPE); + + typeMap.put("char", Character.TYPE); + } + + /** + * @param PersistenceParser + */ + ArrayHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException, AssemblyException + { + String id = attributes.getValue("id"); + String className = attributes.getValue("class"); + + if (className != null) + { + try + { + Class klass; + + if (typeMap.containsKey(className)) + klass = (Class) typeMap.get(className); + else + klass = instantiateClass(className); + + String length = attributes.getValue("length"); + if (length != null) + // creates Array with predefined length + return new ArrayContext(id, klass, Integer.parseInt(length)); + else + // creates Array without length restriction + return new GrowableArrayContext(id, klass); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + throw new AssemblyException(new IllegalArgumentException("Missing 'class' attribute in <array> tag.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java b/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java new file mode 100644 index 0000000..29dfa65 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/AssemblyException.java @@ -0,0 +1,57 @@ +/* gnu.java.beans.decoder.AssemblyException + Copyright (C) 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.java.beans.decoder; + + +/** The AssemblyException is used to wrap the cause of problems when assembling objects. + * In all cases only the wrapped exception is given to the PersistenceParser's + * ExceptionListener instance (never the AssemblyException itself). + * + * <p>Note: Often multiple steps are needed to construct a fully usuable object instance. + * Such a construction can be called assembly and thats why this exception was + * named AssemblyException.</p> + * + * @author Robert Schuster + */ +class AssemblyException extends Exception +{ + AssemblyException(Throwable cause) + { + super(cause); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java new file mode 100644 index 0000000..a34fe34 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java @@ -0,0 +1,67 @@ +/* gnu.java.beans.decoder.BooleanHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Boolean instance from the character data in a <boolean> tag. + * + * @author Robert Schuster + */ +class BooleanHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + BooleanHandler(ElementHandler parent) + { + super(parent); + + // TODO Auto-generated constructor stub + } + + protected Object parse(String number) throws AssemblyException + { + if (number.equals("true")) + return new Boolean(true); + + if (number.equals("false")) + return new Boolean(false); + + throw new AssemblyException(new IllegalArgumentException("Element contained no valid boolean value.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java b/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java new file mode 100644 index 0000000..d6c33d1 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ByteHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.ByteHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Byte instance from the character data in a <byte> tag. + * + * @author Robert Schuster + */ +class ByteHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ByteHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Byte.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/CharHandler.java b/libjava/classpath/gnu/java/beans/decoder/CharHandler.java new file mode 100644 index 0000000..1b31e5b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/CharHandler.java @@ -0,0 +1,62 @@ +/* gnu.java.beans.decoder.CharHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Character instance from the character data in a <char> tag. + * + * @author Robert Schuster + */ +class CharHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + CharHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws AssemblyException + { + if (number.length() > 1) + throw new AssemblyException(new IllegalArgumentException("Element contained no valid character.")); + + return new Character(number.charAt(0)); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java b/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java new file mode 100644 index 0000000..1dbdd63 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ClassHandler.java @@ -0,0 +1,66 @@ +/* gnu.java.beans.decoder.ClassHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Class instance from the character data in a <class> tag. + * + * @author Robert Schuster + */ +class ClassHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ClassHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) throws AssemblyException + { + try + { + return instantiateClass(characters); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java b/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java new file mode 100644 index 0000000..7838fb7 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ConstructorContext.java @@ -0,0 +1,102 @@ +/* gnu.java.beans.decoder.ConstructorContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** A ConstructorContext is a {@link Context} implementation which collects the parameters for a constructor + * call and instantiates the result object using that constructor. After that sub-contexts can invoke + * methods on the result object. + * + * <p>The constructor is invoked when a sub-context is a statement or the Context ends.</p> + * + * @author Robert Schuster + */ +class ConstructorContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private Class klass; + + ConstructorContext(String id, Class newClass) + { + setId(id); + // sets superclass field + klass = newClass; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + protected void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object[] args = arguments.toArray(); + + try + { + Constructor constructor = MethodFinder.getConstructor(klass, args); + + // instantiates object (klass field gets re-set by superclass) + return constructor.newInstance(args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + catch (InstantiationException ie) + { + throw new AssemblyException(ie); + } + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/Context.java b/libjava/classpath/gnu/java/beans/decoder/Context.java new file mode 100644 index 0000000..a2db097 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/Context.java @@ -0,0 +1,137 @@ +/* gnu.java.beans.decoder.Context + Copyright (C) 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.java.beans.decoder; + +/** A Context is the environment for an object which is being assembler. If there + * are no errors each handler creates one Context. + * <p>Depending on the result of isStatement() a Context can be statement or an + * expression. An expression returns a value to the Context of its parent handler, + * a statement does not. Whenever a Context is a statement the parent handler's + * Context is informed about that through the {@link notifyStatement}-method.</p> + * + * @author Robert Schuster + */ +interface Context +{ + /** Adds a parameter object to the context. This method is used when + * sub-Contexts return their result. + * + * Some Contexts do not accept more than a certain amount of objects + * and throw an AssemblerException if the amount is exceeded. + * + * @param o The object added to this context. + */ + void addParameterObject(Object o) throws AssemblyException; + + /** Notifies that the next element is a statement. This can mean + * that an argument list is complete to be called. + * + */ + void notifyStatement(Context outerContext) throws AssemblyException; + + /** Notifies that the context ends and the returns the appropriate result + * object. + * + * @param outerContext + * @return + */ + Object endContext(Context outerContext) throws AssemblyException; + + /** Notifies that the assembly of a subcontext failed and returns + * whether this Context is affected in a way that it fails too. + * + * @return Whether the failure of a subcontext lets this context fail, too. + */ + boolean subContextFailed(); + + /** Calls an appropriate indexed set method if it is available or + * throws an AssemblerException if that is not allowed on this Context. + * + * The behaviour of this method is equal to List.set(int, Object). + * + * @param index Index position to be set. + * @param o Object to be set at the given index position. + * @throws AssemblerException Indexed set is not allowed or otherwise failed. + */ + void set(int index, Object o) throws AssemblyException; + + /** Calls an appropriate indexed get method if it is available or + * throws an AssemblerException if that is not allowed on this Context. + * + * The behaviour of this method is equal to List.get(int). + * + * @param index Index position of the object return. + * @throws AssemblerException Indexed get is not allowed or otherwise failed. + */ + Object get(int index) throws AssemblyException; + + /** Returns the result which was calculated by calling endContext() or reportStatement(). + * Its the handler's responsibility to care that any of these two methods was called. + * + * This is used by sub-Contexts to access this Context's result. + * + * @return + */ + Object getResult(); + + /** Gives this Context a unique id. For convenience the id may be null which means + * that no id exists at all. + * + * @param id + */ + void setId(String id); + + /** Returns this Context's unique id or null if does not have such an id. + * + * @return This Context's id or null. + */ + String getId(); + + /** Returns whether this Context is a statement (not returning result back + * to parent handler's Context) or not (= expression). + * + * @return + */ + boolean isStatement(); + + /** Sets whether this Context is a statement or not. + * + * @param b + */ + void setStatement(boolean b); +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java b/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java new file mode 100644 index 0000000..69d84e5 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DecoderContext.java @@ -0,0 +1,124 @@ +/* gnu.java.beans.decoder.DecoderContext + Copyright (C) 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.java.beans.decoder; + +import java.beans.XMLDecoder; +import java.util.ArrayList; +import java.util.Iterator; + +/** DecoderContext is a Context implementation which allows access to + * the XMLDecoder instance itself. This is used for the <java> tag. + * + * @author Robert Schuster + */ +public class DecoderContext extends AbstractContext +{ + private XMLDecoder decoder; + + public DecoderContext(XMLDecoder xmlDecoder) + { + decoder = xmlDecoder; + } + + private ArrayList objects = new ArrayList(); + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + objects.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + return decoder; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Set method is not allowed in decoder context.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Get method is not allowed in decoder context.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + return decoder; + } + + /** Returns an Iterator that retrieves the assembled objects. + * + * @return An Iterator retrieving assembled objects. + */ + public Iterator iterator() + { + return objects.iterator(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DefaultExceptionListener.java b/libjava/classpath/gnu/java/beans/decoder/DefaultExceptionListener.java new file mode 100644 index 0000000..71e7158 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DefaultExceptionListener.java @@ -0,0 +1,57 @@ +/* gnu.java.beans.DefaultExceptionListener + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +/** The DefaultExceptionListener is the default implementation of the ExceptionListener + * interface. An instance of this class is used whenever the user provided no + * ExceptionListener instance on its own. + * + * <p>The implementation just writes the exception's message to <code>System.err</code>.</p> + * + * @author Robert Schuster + */ +public class DefaultExceptionListener implements ExceptionListener +{ + public void exceptionThrown(Exception e) + { + System.err.println("non-critical exception: " + e + " - message: " + + e.getMessage()); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java b/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java new file mode 100644 index 0000000..8f6be7e --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DoubleHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.DoubleHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Double instance from the character data in a <double> tag. + * + * @author Robert Schuster + */ +class DoubleHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + DoubleHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Double.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DummyContext.java b/libjava/classpath/gnu/java/beans/decoder/DummyContext.java new file mode 100644 index 0000000..f3b2454 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DummyContext.java @@ -0,0 +1,116 @@ +/* gnu.java.beans.decoder.DummyContext + Copyright (C) 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.java.beans.decoder; + +/** The DummyContext is used as the Context implementation for the DummyHandler. It + * just prevents having a null-reference. + * + * <p>When the implementation is correct none of this class' methods + * (except <code>notifyStatement()</code>) is called.</p> + * + * @author Robert Schuster + */ +public class DummyContext extends AbstractContext +{ + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + // intentionally ignored + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + fail(); + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#getResult() + */ + public Object getResult() + { + fail(); + return null; + } + + private void fail() + { + throw new InternalError("Invoking the DummyContext is not expected" + + " - Please file a bug report at" + + " http://www/gnu.org/software/classpath/."); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java b/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java new file mode 100644 index 0000000..880d76a --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/DummyHandler.java @@ -0,0 +1,156 @@ +/* gnu.java.beans.decoder.DummyHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** An ElementHandler implementation that is used as an artificial root + * element. This avoids having to check for a null element. + * + * @author Robert Schuster + */ +class DummyHandler implements ElementHandler +{ + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#start(org.xml.sax.Attributes, java.beans.ExceptionListener) + */ + public void start( + Attributes attributes, + ExceptionListener exceptionListener) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#end(java.beans.ExceptionListener) + */ + public void end(ExceptionListener exceptionListener) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#isSubelementAllowed(java.lang.String) + */ + public boolean isSubelementAllowed(String subElementName) + { + return true; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#instantiateClass(java.lang.String) + */ + public Class instantiateClass(String className) + throws ClassNotFoundException + { + fail(); + return null; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#reportStatement(java.beans.ExceptionListener) + */ + public void notifyStatement(ExceptionListener exceptionListener) + { + // ignore + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#hasFailed() + */ + public boolean hasFailed() + { + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#getContext() + */ + public Context getContext() + { + return new DummyContext(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#contextFailed() + */ + public void notifyContextFailed() + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#putObject(java.lang.String, java.lang.Object) + */ + public void putObject(String objectId, Object o) + { + fail(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.ElementHandler#getObject(java.lang.String) + */ + public Object getObject(String objectId) + { + fail(); + return null; + } + + public ElementHandler getParent() + { + fail(); + return null; + } + + private void fail() + { + throw new InternalError("Invoking the DummyHandler is not expected" + + " - Please file a bug report at " + + " http://www.gnu.org/software/classpath/."); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java b/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java new file mode 100644 index 0000000..e6ae60a --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ElementHandler.java @@ -0,0 +1,130 @@ +/* gnu.java.beans.decoder.ElementHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** ElementHandler manages a Context instance and interacts with + * its parent and child handlers. + * + * @author Robert Schuster + */ +interface ElementHandler +{ + /** Evaluates the attributes and creates a Context instance. + * If the creation of the Context instance fails the ElementHandler + * is marked as failed which may affect the parent handler other. + * + * @param attributes Attributes of the XML tag. + */ + void start(Attributes attributes, ExceptionListener exceptionListener); + + /** Post-processes the Context. + */ + void end(ExceptionListener exceptionListener); + + /** Adds characters from the body of the XML tag to the buffer. + * + * @param ch + * @param start + * @param length + * @throws SAXException + */ + void characters(char[] ch, int start, int length); + + /** Returns whether a subelement of the given name is allowed. The rules + * for evaluating this are derived from the javabeans.dtd which can be found + * here: <a href="http://java.sun.com/products/jfc/tsc/articles/persistence3">Java Persistence Article</a>. + * + * @param subElementName + * @return + */ + boolean isSubelementAllowed(String subElementName); + + /** Provides the same functionality as Class.forName() but allows the decoder + * to use a different class loader. + * + * @param className + * @return + * @throws ClassNotFoundException + */ + Class instantiateClass(String className) throws ClassNotFoundException; + + /** Notifies the handler's Context that its child Context will not return + * a value back. Some Context variants need this information to know when + * a method or a constructor call can be made. + * + * This method is called by a child handler. + */ + void notifyStatement(ExceptionListener exceptionListener); + + /** Returns whether this handler has failed. + * + * This is used to skip child elements. + * + * @return Whether this handler has failed. + */ + boolean hasFailed(); + + /** Returns the Context instance this handler is working on. + * + * @return The handler's Context instance. + */ + Context getContext(); + + /** Notifies the handler that its Context failed and starts a recursive + * invocation of the parent handler if it is affected by that failure. + * + * Although the method is a public API member it is only used internally. + */ + void notifyContextFailed(); + + /** Stores the object under the given id. The object is not stored if the + * id is null. + * + * @param objectId + * @param o + */ + void putObject(String objectId, Object o); + + Object getObject(String objectId) throws AssemblyException; + + ElementHandler getParent(); +} diff --git a/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java b/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java new file mode 100644 index 0000000..5f0e15c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/FloatHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.FloatHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Float instance from the character data in a <float> tag. + * + * @author Robert Schuster + */ +class FloatHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + FloatHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Float.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java b/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java new file mode 100644 index 0000000..f24a60b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/GrowableArrayContext.java @@ -0,0 +1,138 @@ +/* gnu.java.beans.decoder.GrowableArrayContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.Array; + +/** A Context implementation for a growable array. The array + * elements have to be set using expressions. + * + * @author Robert Schuster + */ +class GrowableArrayContext extends AbstractContext +{ + private static final int INITIAL_SIZE = 16; + + private Class klass; + private Object array; + private int length; + + GrowableArrayContext(String id, Class newClass) + { + setId(id); + klass = newClass; + array = Array.newInstance(klass, INITIAL_SIZE); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (length == Array.getLength(array)) + { + Object tmp = Array.newInstance(klass, length * 2); + System.arraycopy(array, 0, tmp, 0, length); + array = tmp; + } + + try { + Array.set(array, length++, o); + } catch(IllegalArgumentException iae) { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + throw new AssemblyException( + new IllegalArgumentException("Statements inside a growable array are not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + if (length != Array.getLength(array)) + { + Object tmp = Array.newInstance(klass, length); + System.arraycopy(array, 0, tmp, 0, length); + array = tmp; + } + + return array; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns false to indicate that assembling the array does not fail only because + // a subelement failed + return false; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + try { + Array.set(array, index, o); + } catch(IllegalArgumentException iae) { + throw new AssemblyException(iae); + } + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + return Array.get(array, index); + } + + public Object getResult() + { + return array; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/IndexContext.java b/libjava/classpath/gnu/java/beans/decoder/IndexContext.java new file mode 100644 index 0000000..11f840c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/IndexContext.java @@ -0,0 +1,130 @@ +/* gnu.java.beans.decoder.IndexContext + Copyright (C) 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.java.beans.decoder; + +/** IndexContext is Context implementation that senses whether it is an indexed get or set + * operation and invokes this operation. + * + * <p>An IndexContent is a get operation when no argument is provided and a set operation if one + * argument is provided.</p> + * + * @author Robert Schuster + */ +class IndexContext extends AbstractContext +{ + private Object result; + private Object argument; + private int index; + private boolean isSetter; + + IndexContext(String id, int newIndex) + { + setId(id); + index = newIndex; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (! isSetter) + { + argument = o; + isSetter = true; + } + else + throw new AssemblyException(new IllegalStateException("More than one argument for indiced access is not possible.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Statements inside indiced access are not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + if (isSetter) + { + // setter + outerContext.set(index, argument); + + return null; + } + else + // getter + return result = outerContext.get(index); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // returns true to indicate that indiced access assembly fails when one of its + // argument could not be assembled + return true; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#set(int, java.lang.Object) + */ + public void set(int index, Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("Setter is not allowed inside indiced access.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#get(int) + */ + public Object get(int index) throws AssemblyException + { + throw new AssemblyException(new IllegalStateException("getter is not allowed insided indiced access.")); + } + + public Object getResult() + { + return result; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/IntHandler.java b/libjava/classpath/gnu/java/beans/decoder/IntHandler.java new file mode 100644 index 0000000..a96f4a0 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/IntHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.IntHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Integer instance from the character data in a <int> tag. + * + * @author Robert Schuster + */ +class IntHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + IntHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Integer.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java b/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java new file mode 100644 index 0000000..3bc8c60 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/JavaHandler.java @@ -0,0 +1,93 @@ +/* gnu.java.beans.decoder.JavaHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.util.HashMap; + +import org.xml.sax.Attributes; + +/** Wraps a DecoderContext instance. + * + * @author Robert Schuster + */ +public class JavaHandler extends AbstractElementHandler +{ + private Context context; + private HashMap objectMap = new HashMap(); + private ClassLoader classLoader; + + /** + * @param PersistenceParser + */ + JavaHandler(DummyHandler parent, Context decoderContext, + ClassLoader cl) + { + super(parent, true); + + classLoader = cl; + + context = decoderContext; + + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + // may expect version and class attribute but it not used in JDK + // so we do either + return context; + } + + public Object getObject(String objectId) + { + return objectMap.get(objectId); + } + + public void putObject(String objectId, Object o) + { + if (objectId != null) + objectMap.put(objectId, o); + } + + public Class instantiateClass(String className) + throws ClassNotFoundException + { + return Class.forName(className, false, classLoader); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/LongHandler.java b/libjava/classpath/gnu/java/beans/decoder/LongHandler.java new file mode 100644 index 0000000..d7bfa54 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/LongHandler.java @@ -0,0 +1,59 @@ +/* gnu.java.beans.decoder.LongHandler + Copyright (C) 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.java.beans.decoder; + + +/** Creates a Long instance from the character data in a <long> tag. + * + * @author Robert Schuster + */ +class LongHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + LongHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Long.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/MethodContext.java b/libjava/classpath/gnu/java/beans/decoder/MethodContext.java new file mode 100644 index 0000000..bad0a21 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/MethodContext.java @@ -0,0 +1,107 @@ +/* gnu.java.beans.decoder.MethodContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** MethodContext collects arguments for a method call and creates the result object + * using it. The method is called using the result object of the parent Context. + * + * <p>When the result object is available methods can be called on it using sub-Contexts.</p> + * + * @author Robert Schuster + */ +class MethodContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private String methodName; + + MethodContext(String id, String newMethodName) + { + setId(id); + setStatement(true); + methodName = newMethodName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object outerObject = outerContext.getResult(); + + if (outerObject == null) + throw new AssemblyException( + new NullPointerException( + "No object to invoke method " + methodName)); + + Object[] args = arguments.toArray(); + + try + { + Method method = + MethodFinder.getMethod( + outerObject.getClass(), + methodName, + args); + return method.invoke(outerObject, args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java b/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java new file mode 100644 index 0000000..3968b17 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/MethodFinder.java @@ -0,0 +1,177 @@ +/* gnu.java.beans.decoder.MethodFinder + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.HashMap; + +class MethodFinder +{ + /** Provides a mapping between a wrapper class and its corresponding primitive's type. */ + private static HashMap typeMapping = new HashMap(); + + static { + typeMapping.put(Byte.class, Byte.TYPE); + typeMapping.put(Short.class, Short.TYPE); + typeMapping.put(Integer.class, Integer.TYPE); + typeMapping.put(Long.class, Long.TYPE); + typeMapping.put(Float.class, Float.TYPE); + typeMapping.put(Double.class, Double.TYPE); + + typeMapping.put(Character.class, Character.TYPE); + typeMapping.put(Boolean.class, Boolean.TYPE); + } + + private MethodFinder() + { + } + + /** Searches a Method which can accept the given arguments. + * + * @param klass + * @param name + * @param arguments + * @return + * @throws NoSuchMethodException + */ + static Method getMethod(Class klass, String name, Object[] arguments) + throws NoSuchMethodException + { + // prepares array containing the types of the arguments + Class[] argumentTypes = getArgumentTypes(arguments); + + Method[] methods = klass.getMethods(); + + // iterates over all public methods + for (int i = 0; i < methods.length; i++) + { + if (methods[i].getName().equals(name)) + { + if (matchingArgumentTypes(methods[i].getParameterTypes(), + argumentTypes)) + return methods[i]; + } + } + + throw new NoSuchMethodException( + "Could not find a matching method named " + + name + + "() in class " + + klass); + } + + static Constructor getConstructor(Class klass, Object[] arguments) + throws NoSuchMethodException + { + Class[] argumentTypes = getArgumentTypes(arguments); + Constructor[] constructors = klass.getConstructors(); + + // iterates over all public methods + for (int i = 0; i < constructors.length; i++) + { + if (matchingArgumentTypes(constructors[i].getParameterTypes(), + argumentTypes)) + return constructors[i]; + } + + throw new NoSuchMethodException( + "Could not find a matching constructor in class " + klass); + } + + /** Transforms an array of argument objects into an array of argument types. + * For each argument being null the argument is null, too. An argument type + * being null means: Accepts everything (although this can be ambigous). + * + * @param arguments + * @return + */ + private static Class[] getArgumentTypes(Object[] arguments) + { + if (arguments == null) + return new Class[0]; + + // prepares array containing the types of the arguments + Class[] argumentTypes = new Class[arguments.length]; + for (int i = 0; i < arguments.length; i++) + argumentTypes[i] = + (arguments[i] == null) ? null : arguments[i].getClass(); + return argumentTypes; + } + + /** Tests whether the argument types supplied to the method argument types + * are assignable. In addition to the assignment specifications this method + * handles the primitive's wrapper classes as if they were of their + * primitive type (e.g Boolean.class equals Boolean.TYPE). + * When a supplied argument type is null it is assumed that no argument + * object was supplied for it and the test for this particular parameter will + * pass. + * + * @param methodArgTypes + * @param suppliedArgTypes + * @return + */ + private static boolean matchingArgumentTypes( + Class[] methodArgTypes, + Class[] suppliedArgTypes) + { + if (methodArgTypes.length != suppliedArgTypes.length) + return false; + + for (int i = 0; i < methodArgTypes.length; i++) + { + if (suppliedArgTypes[i] == null) + { + // by definition a non-existant argument type (null) can be converted to everything + continue; + } + else if (typeMapping.containsKey(suppliedArgTypes[i])) + { + Class primitiveType = + (Class) typeMapping.get(suppliedArgTypes[i]); + if (!(methodArgTypes[i].isAssignableFrom(suppliedArgTypes[i]) + || methodArgTypes[i].isAssignableFrom(primitiveType))) + return false; + } + else if (!methodArgTypes[i].isAssignableFrom(suppliedArgTypes[i])) + return false; + } + + return true; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/NullHandler.java b/libjava/classpath/gnu/java/beans/decoder/NullHandler.java new file mode 100644 index 0000000..549617d --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/NullHandler.java @@ -0,0 +1,62 @@ +/* gnu.java.beans.decoder.NullHandler + Copyright (C) 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.java.beans.decoder; + + +/** Just provides the 'null' object. + * + * @author Robert Schuster + */ +class NullHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + NullHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) throws AssemblyException + { + if (! characters.equals("")) + throw new AssemblyException(new IllegalArgumentException("No characters inside <void> tag allowed.")); + + return null; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java b/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java new file mode 100644 index 0000000..cf88a2c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ObjectContext.java @@ -0,0 +1,100 @@ +/* gnu.java.beans.decoder.ObjectHandler + Copyright (C) 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.java.beans.decoder; + +/** ObjectContext is a {@link Context} implementation that wraps a simple Object instance. + * The instance can be provided when the Context is created (due to an 'idref' + * attribute) or later (eg. <int> tag) + * + * <p>The ObjectContext does not accept any parameter object and ignores notifications + * about sub-contexts being statements.</p> + * + * @author Robert Schuster + */ +final class ObjectContext extends AbstractObjectContext +{ + ObjectContext(Object newObject) + { + setObject(newObject); + } + + ObjectContext(String id, Object newObject) + { + setId(id); + setObject(newObject); + } + + ObjectContext() + { + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + throw new AssemblyException(new IllegalArgumentException("Adding objects to an ObjectContext is not allowed.")); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#reportStatement() + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + // can ignore that + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public Object endContext(Context outerContext) throws AssemblyException + { + // just returns the object which is encapsuled (may be null) + return getResult(); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#subContextFailed() + */ + public boolean subContextFailed() + { + // this context will not fail when a subcontext fails because the result is + // already available when the context is created. + return false; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java b/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java new file mode 100644 index 0000000..dc5b329 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ObjectHandler.java @@ -0,0 +1,169 @@ +/* gnu.java.beans.decoder.ObjectHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** An ObjectHandler parses the <object> tag and thereby creates various + * Context implementations. + * + * @author Robert Schuster + * + */ +public class ObjectHandler extends AbstractElementHandler +{ + /** + * XXX: Can all results be stored with an object id? + * + * + * @param PersistenceParser + */ + ObjectHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + String className = attributes.getValue("class"); + String methodName = attributes.getValue("method"); + String fieldName = attributes.getValue("field"); + String index = attributes.getValue("index"); + String propertyName = attributes.getValue("property"); + String id = attributes.getValue("id"); + String idRef = attributes.getValue("idref"); + + /* first check if we just want to access an existing object (idref present) + * + * note: <object idref="foo" method="bar"/> is not valid to call method "bar" + * on the object with id "foo". Instead this should return the object "foo" + * itself. The right way to this is: + * <object idref="foo"> + * <object method="bar"/> + * </object> + * + * This means that if idref is present class, method, field, index and + * property are obsolete. + */ + if (idRef != null) + // reactivates an existing object and giving it another name if id exists + return new ObjectContext(id, getObject(idRef)); + + // decides whether we are in a static (className present) or dynamic context + if (className != null) + { + try + { + Class klass = instantiateClass(className); + + // class name exists which means that we are in a static context. + // so we may want to ... + // access a static field if the fieldName exists + if (fieldName != null) + { + try + { + return new ObjectContext(id, + klass.getField(fieldName).get(null)); + } + catch (NoSuchFieldException nsfe) + { + throw new AssemblyException(nsfe); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + // (falling through is important!) + // run a constructor if methodName is "new" or null + if (methodName == null || methodName.equals("new")) + return new ConstructorContext(id, klass); + + // (falling through is important!) + // run a static method on the given class (if methodName exists, which is implied already) + return new StaticMethodContext(id, klass, methodName); + // XXX: should fail if unexpected attributes are present? + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } + else + { + // className does not exist which means we are in the context of + // some object and want to ... + // access the get(int index) method if index != null + if (index != null) + { + try + { + // Note: http://java.sun.com/products/jfc/tsc/articles/persistence3/ says + // that <void index="4"/> will make up a get()-call. But this is wrong because + // <void/> tags never return values (to the surrounding context) + return new IndexContext(id, Integer.parseInt(index)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + // access a method if methodName exists + if (methodName != null) + return new MethodContext(id, methodName); + + // (falling through is important!) + // access a property if a propertyName exists + if (propertyName != null && propertyName.length() > 0) + // this is reported as an ordinary method access where the propertyName is + // converted into a 'getter'-method name: convert first character of property name + // to upper case and prepend 'get' + // Note: This will be a getter-method because the <object> tag implies that a return + // value is expected. + return new PropertyContext(id, propertyName); + } + + throw new AssemblyException(new IllegalArgumentException("Wrong or missing attributes for <object> tag.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java b/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java new file mode 100644 index 0000000..4eb37ab --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/PersistenceParser.java @@ -0,0 +1,485 @@ +/* gnu.java.beans.PersistenceParser + Copyright (C) 2004, 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.java.beans.decoder; + +import java.beans.ExceptionListener; +import java.beans.XMLDecoder; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** The PersistenceParser parses an XML data stream and delegates actions to ElementHandler + * instances. The parser catches and recovers from all exception which reside from wrong usage + * of attributes and tags. + * + * @author Robert Schuster + */ +public class PersistenceParser extends DefaultHandler implements Context +{ + /** The ExceptionListener instance which is informed of non-critical parsing exceptions. + */ + private ExceptionListener exceptionListener; + + /** When an element was not usable all elements inside it should be skipped. + * This is done by skipping startElement() and endElement() invocations whenever + * this value is above 0. + */ + private int skipElement; + + /** Stores the Creator instances which can instantiate the appropriate handler implementation + * for a given element. + */ + private HashMap handlerCreators = new HashMap(); + + /** Denotes the current ElementHandler. To avoid checking for null-values it is pre-assigned + * with a DummyHandler instance which must not be used but acts as a root element. + */ + private ElementHandler currentHandler; + + /** The real root element that stores all objects created during parsing. + * Package-private to avoid an accessor method. + */ + JavaHandler javaHandler; + + /** Stores the decoded objects. */ + private List objects = new LinkedList(); + + /** The XMLDecoder instance that started this PersistenceParser */ + private XMLDecoder decoder; + + /** Creates a PersistenceParser which reads XML data from the given InputStream, reports + * exceptions to ExceptionListener instance, stores resulting object in the DecoderContext + * and uses the given ClassLoader to resolve classes. + * + * @param inputStream + * @param exceptionListener + * @param decoderContext + * @param cl + */ + public PersistenceParser( + InputStream inputStream, + ExceptionListener exceptionListener, + ClassLoader cl, + XMLDecoder decoder) + { + + this.exceptionListener = exceptionListener; + this.decoder = decoder; + + DummyHandler dummyHandler = new DummyHandler(); + currentHandler = dummyHandler; + javaHandler = new JavaHandler(dummyHandler, this, cl); + + SAXParserFactory factory = SAXParserFactory.newInstance(); + + SAXParser parser; + try + { + parser = factory.newSAXParser(); + } + catch (ParserConfigurationException pce) + { + // should not happen when a parser is available because we did + // not request any requirements on the XML parser + throw (InternalError) new InternalError( + "No SAX Parser available.").initCause( + pce); + } + catch (SAXException saxe) + { + // should not happen when a parser is available because we did + // not request any requirements on the XML parser + throw (InternalError) new InternalError( + "No SAX Parser available.").initCause( + saxe); + } + + // prepares a map of Creator instances which can instantiate a handler which is + // appropriate for the tag that is used as a key for the Creator + handlerCreators.put("java", new JavaHandlerCreator()); + + // calls methods (properties), constructors, access fields + handlerCreators.put("object", new ObjectHandlerCreator()); + handlerCreators.put("void", new VoidHandlerCreator()); + + handlerCreators.put("array", new ArrayHandlerCreator()); + + // these handler directly create an Object (or null) + handlerCreators.put("class", new ClassHandlerCreator()); + handlerCreators.put("null", new NullHandlerCreator()); + + handlerCreators.put("char", new CharHandlerCreator()); + handlerCreators.put("string", new StringHandlerCreator()); + handlerCreators.put("boolean", new BooleanHandlerCreator()); + handlerCreators.put("byte", new ByteHandlerCreator()); + handlerCreators.put("short", new ShortHandlerCreator()); + handlerCreators.put("int", new IntHandlerCreator()); + handlerCreators.put("long", new LongHandlerCreator()); + handlerCreators.put("float", new FloatHandlerCreator()); + handlerCreators.put("double", new DoubleHandlerCreator()); + + // parses the data and sends all exceptions to the ExceptionListener + try + { + parser.parse(inputStream, this); + } + catch (SAXException saxe) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException("XML data not well-formed.")); + } + catch (IOException ioe) + { + exceptionListener.exceptionThrown(ioe); + } + } + + public void startElement( + String uri, + String localName, + String qName, + Attributes attributes) + throws SAXException + { + /* The element is skipped if + * a) the current handler has already failed or a previous error occured + * which makes all children obsolete + */ + if (currentHandler.hasFailed() || skipElement > 0) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element unusable due to previous error: " + qName)); + + skipElement++; + + return; + } + + /* b) Subelements are not allowed within the current ElementHandler. + */ + if (!currentHandler.isSubelementAllowed(qName)) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element is not allowed here: " + qName)); + + skipElement++; + + return; + } + + /* c) The tag name is not a key in the map of Creator instances. This means that + * either the XML data is of a newer version or simply contains a miss-spelled element. + */ + if (!handlerCreators.containsKey(qName)) + { + exceptionListener.exceptionThrown( + new IllegalArgumentException( + "Element unusable because tag is unknown: " + qName)); + + skipElement++; + + return; + } + + // creates a new handler for the new element + AbstractElementHandler handler = + ((Creator) handlerCreators.get(qName)).createHandler( + currentHandler); + + // makes it the current handler to receive character data + currentHandler = handler; + + // starts the handler + currentHandler.start(attributes, exceptionListener); + } + + public void endElement(String uri, String localName, String qName) + throws SAXException + { + // skips processing the current handler if we are parsing an element + // which was marked invalid (in startElement() ) + if (skipElement > 0) + { + skipElement--; + return; + } + + // invokes the handler's finishing method + currentHandler.end(exceptionListener); + + // removes the current handler and reactivates its parent + currentHandler = currentHandler.getParent(); + } + + /** Transfers character data to the current handler + */ + public void characters(char[] ch, int start, int length) + throws SAXException + { + // prevents sending character data of invalid elements + if (skipElement > 0) + return; + + currentHandler.characters(ch, start, length); + } + + /** Creator interface provided a mechanism to instantiate ElementHandler instances + * for the appropriate tag. + * + * @author Robert Schuster + */ + interface Creator + { + /** Creates an ElementHandler instance using the given ElementHandler as its parent. + * + * @param parent The parent ElementHandler of the result. + * @return A new ElementHandler instance. + */ + AbstractElementHandler createHandler(ElementHandler parent); + } + + class BooleanHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new BooleanHandler(parent); + } + } + + class ByteHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ByteHandler(parent); + } + } + + class ShortHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ShortHandler(parent); + } + } + + class IntHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new IntHandler(parent); + } + } + + class LongHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new LongHandler(parent); + } + } + + class FloatHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new FloatHandler(parent); + } + } + + class DoubleHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new DoubleHandler(parent); + } + } + + class CharHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new CharHandler(parent); + } + } + + class StringHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new StringHandler(parent); + } + } + + class JavaHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return javaHandler; + } + } + + class ObjectHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ObjectHandler(parent); + } + } + + class VoidHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new VoidHandler(parent); + } + } + + class ClassHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ClassHandler(parent); + } + } + + class NullHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new NullHandler(parent); + } + } + + class ArrayHandlerCreator implements Creator + { + public AbstractElementHandler createHandler(ElementHandler parent) + { + return new ArrayHandler(parent); + } + } + + /** Adds a decoded object to the Context. */ + public void addParameterObject(Object o) throws AssemblyException + { + objects.add(o); + } + + public void notifyStatement(Context outerContext) throws AssemblyException + { + // can be ignored because theis Context does not react to statement and expressions + // differently + } + + public Object endContext(Context outerContext) throws AssemblyException + { + return null; + } + + public boolean subContextFailed() + { + // failing of subcontexts is no problem for the mother of all contexts + return false; + } + + public void set(int index, Object o) throws AssemblyException + { + // not supported + throw new AssemblyException( + new IllegalArgumentException("Set method is not allowed in decoder context.")); + } + + public Object get(int index) throws AssemblyException + { + // not supported + throw new AssemblyException( + new IllegalArgumentException("Get method is not allowed in decoder context.")); + } + + public Object getResult() + { + // returns the XMLDecoder instance which is requested by child contexts this way. + // That is needed to invoke methods on the decoder. + return decoder; + } + + public void setId(String id) + { + exceptionListener.exceptionThrown(new IllegalArgumentException("id attribute is not allowed for <java> tag.")); + } + + public String getId() + { + // appears to have no id + return null; + } + + public boolean isStatement() + { + // this context is a statement by definition because it never returns anything to a parent because + // there is no such parent (DummyContext does not count!) + return true; + } + + public void setStatement(boolean b) + { + // ignores that because this Context is always a statement + } + + /** Returns an Iterator instance which returns the decoded objects. + * + * This method is used by the XMLDecoder directly. + */ + public Iterator iterator() + { + return objects.iterator(); + } + +} diff --git a/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java b/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java new file mode 100644 index 0000000..838ef81 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/PropertyContext.java @@ -0,0 +1,137 @@ +/* gnu.java.beans.decoder.PropertyContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** PropertyContext is a Context implementation that is very similar to MethodContext + * and IndexContext. The sole purpose of PropertyContext to find out whether it should + * 'set' or 'get' a certain property. This decision is made using the number of + * arguments. + * <p>When the method call has to be made and there is no argument we 'get' the property. + * With one argument it is 'set'.</p> + * + * @author Robert Schuster + */ +class PropertyContext extends AbstractObjectContext +{ + private Object argument; + private String propertyName; + private String prefix = "get"; + private boolean methodCalled; + + PropertyContext(String id, String newPropertyName) + { + setId(id); + propertyName = newPropertyName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObject(Object o) throws AssemblyException + { + if (methodCalled) + throw new AssemblyException(new IllegalArgumentException("Cannot add parameter object when method was already called.")); + + if (argument != null) + throw new AssemblyException(new IllegalArgumentException("Property attribut allows zero or one argument only.")); + + argument = o; + setStatement(true); + prefix = "set"; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + public void notifyStatement(Context outerContext) throws AssemblyException + { + if (methodCalled) + return; + methodCalled = true; + + Object outerObject = outerContext.getResult(); + + if (outerObject == null) + throw new AssemblyException(new NullPointerException("No object to access property " + + propertyName)); + + + // converts property name into a method name + String methodName = prefix + propertyName.substring(0, 1).toUpperCase() + + propertyName.substring(1); + + // prepares the argument + Object[] args = (argument != null) ? new Object[] { argument } : null; + + try + { + Method method = MethodFinder.getMethod(outerObject.getClass(), + methodName, args); + + // stores the result whether it is available or not + setObject(method.invoke(outerObject, args)); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } + + public Object endContext(Context outerContext) throws AssemblyException + { + notifyStatement(outerContext); + + return getResult(); + } + + public boolean subContextFailed() + { + return ! methodCalled; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java b/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java new file mode 100644 index 0000000..ab6ddbe --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/ShortHandler.java @@ -0,0 +1,58 @@ +/* gnu.java.beans.decoder.ShortHandler + Copyright (C) 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.java.beans.decoder; + +/** Creates a Short instance from the character data in a <short> tag. + * + * @author Robert Schuster + */ +class ShortHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + ShortHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String number) throws NumberFormatException + { + return Short.valueOf(number); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java b/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java new file mode 100644 index 0000000..bc187e8 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/SimpleHandler.java @@ -0,0 +1,111 @@ +/* gnu.java.beans.decoder.SimpleHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +/** XML element handler that is specialized on tags that contains a simple string in their + * body which has to be parsed in a specific way. + * <p>All of these tags have in common that they do not accept attributes. A warning is + * send to the parser's ExceptionListener when one or more attributes exist.</p> + * + * @author Robert Schuster + */ +abstract class SimpleHandler extends AbstractElementHandler +{ + private ObjectContext context; + + /** + * @param PersistenceParser + */ + SimpleHandler(ElementHandler parent) + { + super(parent, false); + + // SimpleHandler do not accept any subelements + } + + protected final Context startElement(Attributes attributes, ExceptionListener exceptionListener) + throws AssemblyException + { + + // note: simple elements should not have any attributes. We inform + // the user of this syntactical but uncritical problem by sending + // an IllegalArgumentException for each unneccessary attribute + int size = attributes.getLength(); + for (int i = 0; i < size; i++) { + String attributeName = attributes.getQName(i); + Exception e = + new IllegalArgumentException( + "Unneccessary attribute '" + + attributeName + + "' discarded."); + exceptionListener.exceptionThrown(e); + } + + return context = new ObjectContext(); + } + + public void endElement(String characters) + throws AssemblyException, AssemblyException + { + // reports the number when the character data can be parsed + try + { + context.setObject(parse(characters)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + /** Returns an object that is created from the given characters. If the string is + * converted into a number a NumberFormatException is cathed and reported + * appropriately. + * + * @param characters A string of characters that has to be processed in some way. + * @return An Object instance generated from the given data. + * @throws AssemblerException When the string was invalid. + * @throws NumberFormatException When the string could not be parsed into a number. + */ + protected abstract Object parse(String characters) + throws AssemblyException, NumberFormatException; +} diff --git a/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java b/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java new file mode 100644 index 0000000..959c949 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/StaticMethodContext.java @@ -0,0 +1,95 @@ +/* gnu.java.beans.decoder.StaticMethodContext + Copyright (C) 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.java.beans.decoder; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; + +/** + * @author Robert Schuster + */ +class StaticMethodContext extends AbstractCreatableObjectContext +{ + private ArrayList arguments = new ArrayList(); + private Class klass; + private String methodName; + + StaticMethodContext(String id, Class newClass, String newMethodName) + { + setId(id); + klass = newClass; + methodName = newMethodName; + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#addObject(java.lang.Object) + */ + public void addParameterObjectImpl(Object o) + { + arguments.add(o); + } + + /* (non-Javadoc) + * @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context) + */ + protected Object createObject(Context outerContext) + throws AssemblyException + { + Object[] args = arguments.toArray(); + + try + { + Method method = MethodFinder.getMethod(klass, methodName, args); + return method.invoke(null, args); + } + catch (NoSuchMethodException nsme) + { + throw new AssemblyException(nsme); + } + catch (InvocationTargetException ite) + { + // rethrows the reason for the InvocationTargetsException (ie. the exception in the called code) + throw new AssemblyException(ite.getCause()); + } + catch (IllegalAccessException iae) + { + throw new AssemblyException(iae); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/StringHandler.java b/libjava/classpath/gnu/java/beans/decoder/StringHandler.java new file mode 100644 index 0000000..6f2311a --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/StringHandler.java @@ -0,0 +1,54 @@ +/* gnu.java.beans.decoder.StringHandler + Copyright (C) 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.java.beans.decoder; + +class StringHandler extends SimpleHandler +{ + /** + * @param PersistenceParser + */ + StringHandler(ElementHandler parent) + { + super(parent); + } + + protected Object parse(String characters) + { + return characters; + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java b/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java new file mode 100644 index 0000000..ca3664b --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/VoidHandler.java @@ -0,0 +1,140 @@ +/* gnu.java.beans.decoder.VoidHandler + Copyright (C) 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.java.beans.decoder; + +import java.beans.ExceptionListener; + +import org.xml.sax.Attributes; + +public class VoidHandler extends AbstractElementHandler +{ + /** + * @param PersistenceParser + */ + VoidHandler(ElementHandler parent) + { + super(parent, true); + } + + protected Context startElement( + Attributes attributes, + ExceptionListener exceptionListener) + throws AssemblyException + { + Context ctx = startElementImpl(attributes); + ctx.setStatement(true); + + return ctx; + } + + private Context startElementImpl(Attributes attributes) + throws AssemblyException + { + String id = attributes.getValue("id"); + String className = attributes.getValue("class"); + String methodName = attributes.getValue("method"); + String propertyName = attributes.getValue("property"); + String index = attributes.getValue("index"); + + if (className != null) + { + try + { + Class klass = instantiateClass(className); + + // class name exists which means that we are in a static context. + // so we may want to ... + // run a constructor if methodName is "new" or null + if (methodName == null || methodName.equals("new")) + // if the id is null the result cannot be by the decoder accessed but the + // constructor may have side effects (e.g. registering itself in a global registry) + return new ConstructorContext(id, klass); + + // (falling through is important!) + // run a static method on the given class (if methodName exists, which is implied already) + return new StaticMethodContext(id, klass, methodName); + } + catch (ClassNotFoundException cnfe) + { + throw new AssemblyException(cnfe); + } + } + else + { + // className does not exist which means we are in the context of + // some object and want to ... + // access an element by index + if (index != null) + { + // note: whether this resolves into get(i) or set(i, o) depends on the + // number of arguments and is decided by the ObjectAssembler + try + { + return new IndexContext(id, Integer.parseInt(index)); + } + catch (NumberFormatException nfe) + { + throw new AssemblyException(nfe); + } + } + + // access a method if methodName exists + if (methodName != null) + return new MethodContext(id, methodName); + + // (falling through is important!) + // access a property if a propertyName exists + if (propertyName != null && propertyName.length() > 0) + // this is reported as an ordinary method invocation where the propertyName is + // converted into a 'setter'-method name: convert first character of property name + // to upper case and prepend 'set' + // Note: This will be a setter-method because the <void> tag implies that no return + // value is expected (but a side effect) + return new PropertyContext(id, propertyName); + } + + // if code reaches this point the tag has wrong attributes. The following test + // does not make it better but can provide are more specific error message for + // a common mistake: <void> tags are not allowed to have an idref attribute + throw new AssemblyException( + new IllegalArgumentException( + (attributes.getValue("idref") == null) + ? "Missing attributes for <void> tag" + : "<void> does not support 'idref' attribute.")); + } +} diff --git a/libjava/classpath/gnu/java/beans/decoder/package.html b/libjava/classpath/gnu/java/beans/decoder/package.html new file mode 100644 index 0000000..8fe65ee --- /dev/null +++ b/libjava/classpath/gnu/java/beans/decoder/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans.decoder package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans.decoder</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/beans/editors/ColorEditor.java b/libjava/classpath/gnu/java/beans/editors/ColorEditor.java new file mode 100644 index 0000000..b099eb2 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/ColorEditor.java @@ -0,0 +1,100 @@ +/* gnu.java.beans.editors.ColorEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.awt.Color; +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class ColorEditor extends PropertyEditorSupport { + Color[] stdColors = {Color.black,Color.blue,Color.cyan, + Color.darkGray,Color.gray,Color.green, + Color.lightGray,Color.magenta,Color.orange, + Color.pink,Color.red,Color.white, + Color.yellow}; + String[] stdColorNames = {"black","blue","cyan", + "dark gray","gray","green", + "light gray","magenta","orange", + "pink","red","white", + "yellow"}; + + /** setAsText for Color checks for standard color names + ** and then checks for a #RRGGBB value or just RRGGBB, + ** both in hex. + **/ + public void setAsText(String val) throws IllegalArgumentException { + if(val.length() == 0) { + throw new IllegalArgumentException("Tried to set empty value!"); + } + for(int i=0;i<stdColorNames.length;i++) { + if(stdColorNames[i].equalsIgnoreCase(val)) { + setValue(stdColors[i]); + return; + } + } + if(val.charAt(0) == '#') { + setValue(new Color(Integer.parseInt(val.substring(1),16))); + } else { + setValue(new Color(Integer.parseInt(val,16))); + } + } + + /** getAsText for Color turns the color into either one of the standard + ** colors or into an RGB hex value with # prepended. **/ + public String getAsText() { + for(int i=0;i<stdColors.length;i++) { + if(stdColors[i].equals(getValue())) { + return stdColorNames[i]; + } + } + return "#" + Integer.toHexString(((Color)getValue()).getRGB() & 0x00FFFFFF); + } + + /** getTags for Color returns a list of standard colors. **/ + public String[] getTags() { + return stdColorNames; + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/FontEditor.java b/libjava/classpath/gnu/java/beans/editors/FontEditor.java new file mode 100644 index 0000000..904f7be --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/FontEditor.java @@ -0,0 +1,77 @@ +/* gnu.java.beans.editors.FontEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.awt.Font; +import java.beans.PropertyEditorSupport; + +/** + ** FontEditor is a property editor for java.awt.Font. + ** + ** <STRONG>To Do:</STRONG> Add custom font chooser + ** component. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class FontEditor extends PropertyEditorSupport { + /** setAsText for Font calls Font.decode(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Font.decode(val)); + } + + /** getAsText for Font returns a value in the format + ** expected by Font.decode(). + **/ + public String getAsText() { + Font f = (Font)getValue(); + if(f.isBold()) { + if(f.isItalic()) { + return f.getName()+"-bolditalic-"+f.getSize(); + } else { + return f.getName()+"-bold-"+f.getSize(); + } + } else if(f.isItalic()) { + return f.getName()+"-italic-"+f.getSize(); + } else { + return f.getName()+"-"+f.getSize(); + } + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java new file mode 100644 index 0000000..3620cc1 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeBooleanEditor.java @@ -0,0 +1,76 @@ +/* gnu.java.beans.editors.NativeBooleanEditor + Copyright (C) 1998, 2002 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeBooleanEditor is a property editor for the + ** boolean type.<P> + ** + ** <STRONG>To Do:</STRONG> add support for a checkbox + ** as the custom editor. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeBooleanEditor extends PropertyEditorSupport { + String[] tags = {"true","false"}; + + /** + * setAsText for boolean checks for true or false or t or f. + * "" also means false. + **/ + public void setAsText(String val) throws IllegalArgumentException { + if(val.equalsIgnoreCase("true") || val.equalsIgnoreCase("t")) { + setValue(Boolean.TRUE); + } else if(val.equalsIgnoreCase("false") || val.equalsIgnoreCase("f") || val.equals("")) { + setValue(Boolean.FALSE); + } else { + throw new IllegalArgumentException("Value must be true, false, t, f or empty."); + } + } + + + /** getAsText for boolean calls Boolean.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java new file mode 100644 index 0000000..f3ec5fa --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeByteEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeByteEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeByteEditor extends PropertyEditorSupport { + /** setAsText for byte calls Byte.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Byte.valueOf(val)); + } + + /** getAsText for byte calls Byte.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java new file mode 100644 index 0000000..8d8aae1 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeDoubleEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeDoubleEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeDoubleEditor is a property editor for the + ** double type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeDoubleEditor extends PropertyEditorSupport { + /** setAsText for double calls Double.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Double.valueOf(val)); + } + + /** getAsText for double calls Double.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java new file mode 100644 index 0000000..801377e --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeFloatEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeFloatEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeFloatEditor is a property editor for the + ** float type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeFloatEditor extends PropertyEditorSupport { + /** setAsText for float calls Float.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Float.valueOf(val)); + } + + /** getAsText for float calls Float.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java new file mode 100644 index 0000000..a614884 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeIntEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeIntEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeIntEditor is a property editor for the + ** int type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeIntEditor extends PropertyEditorSupport { + /** setAsText for int calls Integer.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Integer.valueOf(val)); + } + + /** getAsText for int calls Integer.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java new file mode 100644 index 0000000..95e9dc8 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeLongEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeLongEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeLongEditor is a property editor for the + ** long type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeLongEditor extends PropertyEditorSupport { + /** setAsText for long calls Long.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Long.valueOf(val)); + } + + /** getAsText for long calls Long.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java b/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java new file mode 100644 index 0000000..ffaa266 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/NativeShortEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.NativeShortEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeShortEditor is a property editor for the + ** short type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class NativeShortEditor extends PropertyEditorSupport { + /** setAsText for short calls Short.valueOf(). **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(Short.valueOf(val)); + } + + /** getAsText for short calls Short.toString(). **/ + public String getAsText() { + return getValue().toString(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/StringEditor.java b/libjava/classpath/gnu/java/beans/editors/StringEditor.java new file mode 100644 index 0000000..8242d54 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/StringEditor.java @@ -0,0 +1,61 @@ +/* gnu.java.beans.editors.StringEditor + Copyright (C) 1998 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.java.beans.editors; + +import java.beans.PropertyEditorSupport; + +/** + ** NativeByteEditor is a property editor for the + ** byte type. + ** + ** @author John Keiser + ** @version 1.1.0, 29 Jul 1998 + **/ + +public class StringEditor extends PropertyEditorSupport { + /** setAsText just sets the value. **/ + public void setAsText(String val) throws IllegalArgumentException { + setValue(val); + } + + /** getAsText just returns the value. **/ + public String getAsText() { + return (String)getValue(); + } +} diff --git a/libjava/classpath/gnu/java/beans/editors/TODO b/libjava/classpath/gnu/java/beans/editors/TODO new file mode 100644 index 0000000..6877f4c --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/TODO @@ -0,0 +1,4 @@ +- write tests for all editors +- add some sort of ColorChooser as a custom editor for ColorEditor +- add a FileNameEditor +- add a FontChooser as a custom editor for FontEditor diff --git a/libjava/classpath/gnu/java/beans/editors/package.html b/libjava/classpath/gnu/java/beans/editors/package.html new file mode 100644 index 0000000..465f68d --- /dev/null +++ b/libjava/classpath/gnu/java/beans/editors/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans.editors package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans.editors</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/beans/package.html b/libjava/classpath/gnu/java/beans/package.html new file mode 100644 index 0000000..f3b0526 --- /dev/null +++ b/libjava/classpath/gnu/java/beans/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.beans package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.beans</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/io/ASN1ParsingException.java b/libjava/classpath/gnu/java/io/ASN1ParsingException.java new file mode 100644 index 0000000..5d2c64a --- /dev/null +++ b/libjava/classpath/gnu/java/io/ASN1ParsingException.java @@ -0,0 +1,56 @@ +/* ASN1ParsingException.java -- ASN.1 parsing exception. + Copyright (C) 2003 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.java.io; + +/** + * Signals a malformed ASN.1 sequence. + */ +public class ASN1ParsingException extends java.io.IOException +{ + + public ASN1ParsingException() + { + super(); + } + + public ASN1ParsingException(String msg) + { + super(msg); + } +} diff --git a/libjava/classpath/gnu/java/io/Base64InputStream.java b/libjava/classpath/gnu/java/io/Base64InputStream.java new file mode 100644 index 0000000..b0824ab --- /dev/null +++ b/libjava/classpath/gnu/java/io/Base64InputStream.java @@ -0,0 +1,216 @@ +/* Base64InputStream.java -- base-64 input stream. + Copyright (C) 2003, 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.java.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * A filter input stream that decodes data encoded in the Base-64 + * encoding scheme. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class Base64InputStream extends FilterInputStream +{ + + // Constants and fields. + // ------------------------------------------------------------------------ + + /** Base-64 digits. */ + private static final String BASE_64 = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + /** Base-64 padding character. */ + private static final char BASE_64_PAD = '='; + + /** Decoding state. */ + private int state; + + /** Intermediate decoded value. */ + private int temp; + + /** EOF flag. */ + private boolean eof; + + private final byte[] one = new byte[1]; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a new Base-64 input stream. The input bytes must be the + * ASCII characters A-Z, a-z, 0-9, + and /, with optional whitespace, + * and will be decoded into a byte stream. + * + * @param in The source of Base-64 input. + */ + public Base64InputStream(InputStream in) + { + super(in); + state = 0; + temp = 0; + eof = false; + } + + // Class method. + // ------------------------------------------------------------------------ + + /** + * Decode a single Base-64 string to a byte array. + * + * @param base64 The Base-64 encoded data. + * @return The decoded bytes. + * @throws IOException If the given data do not compose a valid Base-64 + * sequence. + */ + public static byte[] decode(String base64) throws IOException + { + Base64InputStream in = + new Base64InputStream(new ByteArrayInputStream(base64.getBytes())); + ByteArrayOutputStream out = + new ByteArrayOutputStream((int) (base64.length() / 0.666)); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) != -1) + out.write(buf, 0, len); + return out.toByteArray(); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public int available() + { + return 0; + } + + public int read() throws IOException + { + if (read(one) == 1) + return one[0]; + return -1; + } + + public int read(byte[] buf, int off, int len) throws IOException + { + if (eof) + return -1; + int count = 0; + while (count < len) + { + int i; + while (Character.isWhitespace((char) (i = in.read()))); + int pos = BASE_64.indexOf((char) i); + if (pos >= 0) + { + switch (state) + { + case 0: + temp = pos << 2; + state = 1; + break; + case 1: + buf[count++] = (byte) (temp | (pos >>> 4)); + temp = (pos & 0x0F) << 4; + state = 2; + break; + case 2: + buf[count++] = (byte) (temp | (pos >>> 2)); + temp = (pos & 0x03) << 6; + state = 3; + break; + case 3: + buf[count++] = (byte) (temp | pos); + state = 0; + break; + } + } + else if (i == BASE_64_PAD) + { + switch (state) + { + case 0: + case 1: + throw new IOException("malformed Base-64 input"); + case 2: + while (Character.isWhitespace((char) (i = in.read()))); + if (i != BASE_64_PAD) + throw new IOException("malformed Base-64 input"); + case 3: + while (Character.isWhitespace((char) (i = in.read()))); + } + eof = true; + break; + } + else // First non-Base-64 character, consider it end-of-stream. + { + if (state != 0) + throw new IOException("malformed Base-64 input"); + eof = true; + break; + } + } + return count; + } + + public boolean markSupported() + { + return false; + } + + public void mark(int markLimit) { } + + public void reset() throws IOException + { + throw new IOException("reset not supported"); + } + + public long skip(long n) throws IOException + { + long skipped; + for (skipped = 0; skipped < n; skipped++) + if (read() == -1) + break; + return skipped; + } +} diff --git a/libjava/classpath/gnu/java/io/ClassLoaderObjectInputStream.java b/libjava/classpath/gnu/java/io/ClassLoaderObjectInputStream.java new file mode 100644 index 0000000..238ab26 --- /dev/null +++ b/libjava/classpath/gnu/java/io/ClassLoaderObjectInputStream.java @@ -0,0 +1,73 @@ +/* gnu.java.io.ClassLoaderObjectInputStream + Copyright (C) 1998 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.java.io; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.StreamCorruptedException; + +/** + * ClassLoaderObjectInputStream is ObjectInputStream, with + * the ability to use a specific ClassLoader. + * + * @author Geoff Berry + * @version 1.1.0, 29 Jul 1998 + */ + +public class ClassLoaderObjectInputStream extends ObjectInputStream { + ClassLoader myClassLoader; + + /** Create the new ClassLoaderObjectInputStream. + * @param in the InputStream to read the Objects from. + * @param myClassLoader the ClassLoader to load classes + * with. + */ + public ClassLoaderObjectInputStream(InputStream in, ClassLoader myClassLoader) throws IOException,StreamCorruptedException { + super(in); + this.myClassLoader = myClassLoader; + } + + /** Overriden method to use the loadClass() method from + * the ClassLoader. + */ + public Class resolveClass(String name) throws IOException, ClassNotFoundException { + return myClassLoader.loadClass(name); + } +} diff --git a/libjava/classpath/gnu/java/io/NullOutputStream.java b/libjava/classpath/gnu/java/io/NullOutputStream.java new file mode 100644 index 0000000..526bd26 --- /dev/null +++ b/libjava/classpath/gnu/java/io/NullOutputStream.java @@ -0,0 +1,56 @@ +/* NullOutputStream.java -- OutputStream that does absolutely nothing + Copyright (C) 1998 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.java.io; + +import java.io.OutputStream; + +/** + This is a placeholder OutputStream that does absolutley nothing + when written to. It is intended to be used in the same manner as + /dev/null. None of this class's methods do anything at all. +*/ +public class NullOutputStream extends OutputStream +{ + public NullOutputStream() {} + public void write( int b ) {} + public void write( byte b[] ) {} + public void write( byte b[], int off, int len ) {} + public void flush() {} + public void close() {} +} diff --git a/libjava/classpath/gnu/java/io/ObjectIdentityWrapper.java b/libjava/classpath/gnu/java/io/ObjectIdentityWrapper.java new file mode 100644 index 0000000..6db2e3a --- /dev/null +++ b/libjava/classpath/gnu/java/io/ObjectIdentityWrapper.java @@ -0,0 +1,100 @@ +/* ObjectIdentityWrapper.java -- Wrapper class used to override equals() + and hashCode() to be as discriminating as possible + Copyright (C) 1998 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.java.io; + +/** + This class is a thin wrapper around <code>Object</code> that makes + the methods <code>hashCode()</code> and <code>equals(Object)</code> + as discriminating as possible. +*/ +public class ObjectIdentityWrapper +{ + + /** + Constructs a <code>ObjectIdentityWrapper</code> that is wrapped + around o. + */ + public ObjectIdentityWrapper( Object o ) + { + object = o; + } + + /** + Uses <code>System.identityHashCode(Object)</code> to compute a + hash code for the object wrapped by this + <code>ObjectIdentityWrapper</code>. + + @see java.lang.System#identityHashCode(java.lang.Object) + @see java.util.Hashtable + @see java.lang.Object#hashCode() + */ + public int hashCode() + { + return System.identityHashCode( object ); + } + + /** + Uses the <code>==</code> operator to test for equality between + the object wrapped by this <code>ObjectIdentityWrapper</code> and + the object wrapped by the <code>ObjectIdentityWrapper</code> o. + Returns false if o is not a <code>ObjectIdentityWrapper</code>. + + @see java.util.Hashtable + @see java.lang.Object#equals() + */ + public boolean equals( Object o ) + { + if( o instanceof ObjectIdentityWrapper ) + return object == ((ObjectIdentityWrapper)o).object; + else + return false; + } + + public String toString() + { + return "ObjectIdentityWrapper< " + object + ", " + hashCode() + " >"; + } + + /** + The <code>Object</code> wrapped by this + <code>ObjectIdentityWrapper</code>. + */ + public Object object; +} diff --git a/libjava/classpath/gnu/java/io/PlatformHelper.java b/libjava/classpath/gnu/java/io/PlatformHelper.java new file mode 100644 index 0000000..d2c6012 --- /dev/null +++ b/libjava/classpath/gnu/java/io/PlatformHelper.java @@ -0,0 +1,228 @@ +/* PlatformHelper.java -- Isolate OS-specific IO helper methods and variables + Copyright (C) 1998, 2002 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.java.io; + +import java.util.StringTokenizer; + +/** + * We had many changes in File.java, URLStreamHandler.java etc. to handle + * path representations on different platforms (Windows/Unix-family). + * Finally we'd like to collect all these ad hoc codes into this utility class. + * --Gansha + */ +public class PlatformHelper +{ + public static final boolean isWindows = System.getProperty("os.name").indexOf("Windows") >= 0; + public static final String separator = System.getProperty("file.separator"); + public static final char separatorChar = separator.charAt(0); + public static final String pathSeparator = System.getProperty("path.separator"); + public static final char pathSeparatorChar = pathSeparator.charAt(0); + + /** + * On most platforms 260 is equal or greater than a max path value, + * so we can set the initial buffer size of StringBuffer to half of this value + * to improve performance. + */ + public static final int INITIAL_MAX_PATH = 260/2; + + /** + * This routine checks the input param "path" whether it begins with root path + * prefix. + * if not, return 0; + * if yes, return the len of root path prefix; + * --for Unix-family platform, root path begins with "/" and len is 1 + * --for Windows platform, root path begins with "drive:\\" and len is 3 + */ + public static final int beginWithRootPathPrefix(String path) + { + if (path.startsWith("/") || path.startsWith("\\")) + return 1; + + if (!isWindows) + return 0; + + if (path.length() > 2 + && Character.isLetter(path.charAt(0)) + && path.charAt(1) == ':' + && (path.charAt(2) == '/' || path.charAt(2) == '\\')) + return 3; + + return 0; + } + + /** + * This routine checks the input param "path" whether it's root directory. + * --for Unix-family platform, root directory is "/" + * --for Windows platform, root directory is "\\" or "drive:\\". + */ + public static final boolean isRootDirectory(String path) + { + int len = path.length(); + return len > 0 && beginWithRootPathPrefix(path) == len; + } + + /** + * This routine canonicalizes input param "path" to formal path representation + * for current platform, including interpreting ".." and "." . + */ + public static final String toCanonicalForm(String path) + { + /*?? + if(path.indexOf('.') < 0 && path.indexOf("..") < 0) + return path; + */ + String tmppath = path.replace('/', separatorChar); + StringBuffer canonpath; + + // We found it'll be more efficient and easy to handle to + // return a lowercased canonical path + if(isWindows) + tmppath = tmppath.toLowerCase(); + + int i; + + if ((i = beginWithRootPathPrefix(tmppath)) == 0 ) + return path; + + /* The original + "canonpath = new StringBuffer(tmppath.substring(0, i))" + isn't very efficient because StringBuffer's + ensureCapacity_unsynchronized will fail definitely each time + and will enlarge buffer and copy contents. . + */ + canonpath = new StringBuffer(INITIAL_MAX_PATH); + canonpath.append(tmppath.substring(0, i)); + tmppath = tmppath.substring(i); + // pathdepth==0 indicates there're only root path in the buffer + int pathdepth = 0; + + StringTokenizer st = new StringTokenizer(tmppath, separator); + + // Traverse each element of the path, handling "." and ".." + // Should handle "~" too? + if (st.hasMoreTokens()) + do + { + String s = st.nextToken(); + + // Handle "." or an empty element. + if (s.equals(".") || s.equals("")) + continue; + + // Handle ".." by deleting the last element from the path + if (s.equals("..")) + { + if (pathdepth == 0) + continue; + + // Strip of trailing separator + canonpath.setLength(canonpath.length() - 1/*separator.length()*/); + String tmpstr = canonpath.toString(); + int idx = tmpstr.lastIndexOf(separator); + + if ((idx == -1) || ((idx + 1/*separator.length()*/) > tmpstr.length())) + //throw new IOException("Can't happen error"); + return path; // Shouldn't happen + + canonpath.setLength(idx + 1/*separator.length()*/); + pathdepth--; + continue; + } + + canonpath.append(s); + pathdepth++; //now it's more than root path + + if (st.hasMoreTokens()) + canonpath.append(separator); + } + while (st.hasMoreTokens()); + + if (endWithSeparator(path)) + canonpath.append(separator); + + String tmpstr = canonpath.toString(); + //if (pathdepth > 0 && endWithSeparator(tmpstr) ) + // tmpstr = tmpstr.substring(0, tmpstr.length() - 1/*separator.length()*/); + + return tmpstr; + } + + /** + * This routine canonicalizes input param "path" to formal path representation + * for current platform, and normalize all separators to "sepchar". + */ + public static final String toCanonicalForm(String path, char sepchar) + { + String tmpstr = toCanonicalForm(path); + tmpstr = tmpstr.replace(separatorChar, sepchar); + return tmpstr; + } + + /** + * This routine checks whether input param "path" ends with separator + */ + public static final boolean endWithSeparator(String path) + { + if (path.endsWith("\\") || path.endsWith("/")) + return true; + + return false; + } + + /** + * This routine removes from input param "path" the tail separator if it exists, + * and return the remain part. + */ + public static final String removeTailSeparator(String path) + { + if (endWithSeparator(path) && !isRootDirectory(path)) + return path.substring(0, path.length() - 1); + + return path; + } + + /** + * This routine returns last index of separator in input param "path", + * and return it. + */ + public static final int lastIndexOfSeparator(String path) + { + return Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")); + } + +} diff --git a/libjava/classpath/gnu/java/io/class-dependencies.conf b/libjava/classpath/gnu/java/io/class-dependencies.conf new file mode 100644 index 0000000..2500f6b --- /dev/null +++ b/libjava/classpath/gnu/java/io/class-dependencies.conf @@ -0,0 +1,75 @@ +# This property file contains dependencies of classes, methods, and +# field on other methods or classes. +# +# Syntax: +# +# <used>: <needed 1> [... <needed N>] +# +# means that when <used> is included, <needed 1> (... <needed N>) must +# be included as well. +# +# <needed X> and <used> are of the form +# +# <class.methodOrField(signature)> +# +# or just +# +# <class> +# +# Within dependencies, variables can be used. A variable is defined as +# follows: +# +# {variable}: value1 value2 ... value<n> +# +# variables can be used on the right side of dependencies as follows: +# +# <used>: com.bla.blu.{variable}.Class.m()V +# +# The use of the variable will expand to <n> dependencies of the form +# +# <used>: com.bla.blu.value1.Class.m()V +# <used>: com.bla.blu.value2.Class.m()V +# ... +# <used>: com.bla.blu.value<n>.Class.m()V +# +# Variables can be redefined when building a system to select the +# required support for features like encodings, protocols, etc. +# +# Hints: +# +# - For methods and fields, the signature is mandatory. For +# specification, please see the Java Virtual Machine Specification by +# SUN. Unlike in the spec, field signatures (types) are in brackets. +# +# - Package names must be separated by '/' (and not '.'). E.g., +# java/lang/Class (this is necessary, because the '.' is used to +# separate method or field names from classes) +# +# - In case <needed> refers to a class, only the class itself will be +# included in the resulting binary, NOT necessarily all its methods +# and fields. If you want to refer to all methods and fields, you can +# write class.* as an abbreviation. +# +# - Abbreviations for packages are also possible: my/package/* means all +# methods and fields of all classes in my/package. +# +# - A line with a trailing '\' continues in the next line. + + +# All encodings supported are loaded via gnu/java/io/EncodingManager.findEncoderConstructor +# or gnu/java/io/EncodingManager.findDecoderConstructor from class +# gnu/java/io/decode/Decoder<encoding>. +# +# This introduces a dependency for all encodings. To allow an easy selection +# and addition of encodings, the library variable {encodings} can be set to +# the set of supported encodings. +# +{encodings}: 8859_1 8859_2 8859_3 8859_4 8859_5 UTF8 + +gnu/java/io/EncodingManager.findEncoderConstructor(Ljava/lang/String;Z)Ljava/lang/reflect/Constructor;: \ + gnu/java/io/decode/Decoder{encodings}.* + +gnu/java/io/EncodingManager.findDecoderConstructor(Ljava/lang/String;Z)Ljava/lang/reflect/Constructor;: \ + gnu/java/io/encode/Encoder{encodings}.* \ + +# end of file diff --git a/libjava/classpath/gnu/java/io/package.html b/libjava/classpath/gnu/java/io/package.html new file mode 100644 index 0000000..74da827 --- /dev/null +++ b/libjava/classpath/gnu/java/io/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.io package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.io</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/lang/ArrayHelper.java b/libjava/classpath/gnu/java/lang/ArrayHelper.java new file mode 100644 index 0000000..5f67583 --- /dev/null +++ b/libjava/classpath/gnu/java/lang/ArrayHelper.java @@ -0,0 +1,78 @@ +/* ArrayHelper.java -- Helper methods for handling array operations + Copyright (C) 1998, 2002 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.java.lang; + +/** + * ArrayHelper helps you do things with arrays. + * + * @author John Keiser + */ +public class ArrayHelper +{ + /** + * Counterpart to java.util.Collection.contains. + * + * @param array the array to search + * @param searchFor the object to locate + * @return true if some array element <code>equals(searchFor)</code> + */ + public static boolean contains(Object[] array, Object searchFor) + { + return indexOf(array, searchFor) != -1; + } + + /** + * Counterpart to java.util.Collection.indexOf. + * + * @param array the array to search + * @param searchFor the object to locate + * @return the index of the first equal object, or -1 + */ + public static int indexOf(Object[] array, Object searchFor) + { + for (int i = 0; i < array.length; i++) + { + if(array[i].equals(searchFor)) + { + return i; + } + } + return -1; + } +} diff --git a/libjava/classpath/gnu/java/lang/CharData.java b/libjava/classpath/gnu/java/lang/CharData.java new file mode 100644 index 0000000..b12078d --- /dev/null +++ b/libjava/classpath/gnu/java/lang/CharData.java @@ -0,0 +1,1001 @@ +/* gnu/java/lang/CharData -- Database for java.lang.Character Unicode info + Copyright (C) 2002 Free Software Foundation, Inc. + *** This file is generated by scripts/unicode-muncher.pl *** + +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.java.lang; + +/** + * This contains the info about the unicode characters, that + * java.lang.Character needs. It is generated automatically from + * <code>doc/unicode/UnicodeData-3.0.0.txt</code> and + * <code>doc/unicode/SpecialCasing-2.txt</code>, by some + * perl scripts. These Unicode definition file can be found on the + * <a href="http://www.unicode.org">http://www.unicode.org</a> website. + * JDK 1.4 uses Unicode version 3.0.0. + * + * The data is stored as string constants, but Character will convert these + * Strings to their respective <code>char[]</code> components. The field + * <code>BLOCKS</code> stores the offset of a block of 2<sup>SHIFT</sup> + * characters within <code>DATA</code>. The DATA field, in turn, stores + * information about each character in the low order bits, and an offset + * into the attribute tables <code>UPPER</code>, <code>LOWER</code>, + * <code>NUM_VALUE</code>, and <code>DIRECTION</code>. Notice that the + * attribute tables are much smaller than 0xffff entries; as many characters + * in Unicode share common attributes. The DIRECTION table also contains + * a field for detecting characters with multi-character uppercase expansions. + * Next, there is a listing for <code>TITLE</code> exceptions (most characters + * just have the same title case as upper case). Finally, there are two + * tables for multi-character capitalization, <code>UPPER_SPECIAL</code> + * which lists the characters which are special cased, and + * <code>UPPER_EXPAND</code>, which lists their expansion. + * + * @author scripts/unicode-muncher.pl (written by Jochen Hoenicke, + * Eric Blake) + * @see Character + * @see String + */ +public interface CharData +{ + /** + * The Unicode definition file that was parsed to build this database. + */ + String SOURCE = "doc/unicode/UnicodeData-3.0.0.txt"; + + /** + * The character shift amount to look up the block offset. In other words, + * <code>(char) (BLOCKS.value[ch >> SHIFT] + ch)</code> is the index where + * <code>ch</code> is described in <code>DATA</code>. + */ + int SHIFT = 5; + + /** + * The mapping of character blocks to their location in <code>DATA</code>. + * Each entry has been adjusted so that the 16-bit sum with the desired + * character gives the actual index into <code>DATA</code>. + */ + String BLOCKS + = "\u01c2\u01c2\u01c1\u012c\u012b\u01a0\u01f8\u02dc\u025f\u02ee\u0215" + + "\u0346\u02dc\u0326\u02bc\u0216\u015f\u02d4\u0376\u0376\u0376\u0369" + + "\ufe8f\u0344\uff85\uff65\ufdb5\ufda1\033\u02c4\034G\ufea8" + + "\uff8c\u0235\ufeff\032\ufebf&\ufb20\ufe28\u0113\u0104\ufb61" + + "\ufb5a\u010b\u0109\u00fe\uff08\u0229\u025e\u01c7\u01fc\u01dc\ufc46" + + "\u0229\ufe27\ufb55\u0169\ufbc8\u00fc\u0103\ufb68\ufb48\ufb28\ufb08" + + "\ufae8\ufac8\ufaa8\ufa88\ufa68\ufa48eP\u00ab\u0139\ufe0e" + + "c\u0155\u01a8\uf669\u0129\u0128\uf91f\ufe56\u0108\u0107\ufac0" + + "\ufc8e\ufead\u00c6\ufca7\ufb95\uf47d\u009f\ufb17\ufe20\ufd28\ufb2f" + + ";\uf3b9\ufe57\ufcce\uffbb\uf339\ufa98\uff8b\uff3b\ufa54\uf7e3" + + "\uff2b\ufad7\ufb69\ufc3a\ufee5\uf4c8\ufcb0\ufa88\ufdbf\uf448\ufe45" + + "\ufcc7\ufe4f\uf7f1\uf715\uf2e8\ufd9f\uf348\uf96a\ufc02\ufd97\uf2c8" + + "\uf2a8\uf4b9\uf4b3\uef6b\uf86a\uf84a\ufc58\uf80a\uf7ea\ufc0f\uf7aa" + + "\uee9c\ufb90\uf74a\uf7fa\uf70a\uf7ca\uf792\uf471\uf4d2\uf732\uf64a" + + "\uf401\uf64d\uefa8\uf5ca\uf5aa\ueca1\uf569\uf54a\uf52a\uf50a\uf4ea" + + "\uf4ca\uf4aa\uf48a\uf46a\uf44a\uf42a\uf40a\uf3ea\uf3ca\uf3aa\uf38a" + + "\uf36a\uf34a\uf32a\uf289\uf777\uf2ca\uf2aa\uf737\uec28\uec08\uebe8" + + "\uebc8\uf1ea\uf4a2\uf545\uedc6\uf2d7\uf14a\ue8ed\ue81e\uf0ea\uf597" + + "\uea68\uea48\uea28\uea08\ue9e8\ue9c8\ue9a8\ue988\ue968\ue948\ue928" + + "\ue908\ue8e8\ue8c8\ue8a8\ue888\ue868\ue848\ue828\ue808\ue7e8\ue7c8" + + "\ue7a8\ue788\ue768\ue748\ue728\ue708\ue6e8\ue6c8\ue6a8\ue688\ue668" + + "\ue648\ue628\ue608\ue5e8\ue5c8\ue5a8\ue588\ue568\ue548\ue55f\ue53f" + + "\ue51f\ue4ff\uefd7\ue4bf\ue49f\ue485\uef87\uef57\uef57\uef57\uef57" + + "\uef47\ue1ad\uef46\uef46\uef46\ue1e0\ue3dd\uef06\ue9d9\uebeb\ue244" + + "\ueed4\uef65\ue1f5\uef45\ueee9\uef7c\uee74\uef70\uef7d\uef78\uee91" + + "\uefd3\uee7d\uee25\uee27\uef65\uefdd\uee96\uefd3\uefe1\uef69\udf88" + + "\udf68\udf48\ued2b\ued3d\ued19\uef1c\uef08\ued47\ued3d\ued33\uec2b" + + "\uec0b\uebeb\uebcb\uebce\uea7c\ueb69\ueb6c\ue9b6\ueb0b\ueaeb\ue9e9" + + "\udca8\udc88\udc68\udc48\ue910\uea23\ueb58\ueb4f\ueb45\ueae5\udb68" + + "\udb48\ue92b\ue90b\ue8eb\ue8cb\ue8ab\ue88b\ue86b\ue84b\uda28\uda08" + + "\ud9e8\ud9c8\ud9a8\ud988\ud968\ud948\ud928\ud908\ud8e8\ud8c8\ud8a8" + + "\ud888\ud868\ud848\ud828\ud808\ud7e8\ud7c8\ud7a8\ud788\ud768\ud748" + + "\ud728\ud708\ud6e8\ud6c8\ud6a8\ud688\ud668\ud648\ud628\ud608\ud5e8" + + "\ud5c8\ud5a8\ud588\ud568\ud548\ud528\ud508\ud4e8\ud4c8\ue2b1\ue28b" + + "\ue26b\ue270\ue22b\ue20b\ue1eb\ue1cb\ue1ab\ue18b\ue18e\udd8f\ue3a8" + + "\udfd3\ud929\ud90a\ue348\ud8c9\ud8aa\udcd7\udcb2\ud681\ud82a\ud80a" + + "\ue268\ucede\ud168\ud148\ue116\ue0e9\ue1cb\ue0b7\ue0b7\ue15e\udf17" + + "\ue034\ue013\udff3\udfd3\ude6c\udf93\udf73\udf55\udf34\ud56a\ud54a" + + "\ud52a\ud50a\ud4ea\ud4ca\ud4aa\ud48a\ud46a\ud44a\ud42a\ud40a\ud3ea" + + "\ud3ca\ud3aa\ud38a\ud36a\ud34a\ud32a\ud30a\ud2ea\ud2ca\ud2aa\ud28a" + + "\ud26a\ud24a\ud22a\ud20a\ud1ea\ud1ca\ud1aa\ud18a\ud16a\ud14a\ud12a" + + "\ud10a\ud0ea\ud0ca\ud0aa\ud08a\ud06a\ud04a\ud02a\ud00a\ucfea\ucfca" + + "\ucfaa\ucf8a\ucf6a\ucf4a\ucf2a\ucf0a\uceea\uceca\uceaa\uce8a\uce6a" + + "\uce4a\uce2a\uce0a\ucdea\ucdca\ucdaa\ucd8a\ucd6a\ucd4a\ucd2a\ucd0a" + + "\uccea\uccca\uccaa\ucc8a\ucc6a\ucc4a\ucc2a\ucc0a\ucbea\ucbca\ucbaa" + + "\ucb8a\ucb6a\ucb4a\ucb2a\ucb0a\ucaea\ucaca\ucaaa\uca8a\uca6a\uca4a" + + "\uca2a\uca0a\uc9ea\uc9ca\uc9aa\uc98a\uc96a\uc94a\uc92a\uc90a\uc8ea" + + "\uc8ca\uc8aa\uc88a\uc86a\uc84a\uc82a\uc80a\uc7ea\uc7ca\uc7aa\uc78a" + + "\uc76a\uc74a\uc72a\uc70a\uc6ea\uc6ca\uc6aa\uc68a\uc66a\uc64a\uc62a" + + "\uc60a\uc5ea\uc5ca\uc5aa\uc58a\uc56a\uc54a\uc52a\uc50a\uc4ea\uc4ca" + + "\uc4aa\uc48a\uc46a\uc44a\uc42a\uc40a\uc3ea\uc3ca\uc3aa\uc38a\uc36a" + + "\uc34a\uc32a\uc30a\uc2ea\uc2ca\uc2aa\uc28a\uc26a\uc24a\uc22a\uc20a" + + "\uc1ea\uc1ca\uc1aa\uc18a\uc16a\uc14a\uc12a\uc10a\uc0ea\uc0ca\uc0aa" + + "\uc08a\uc06a\uc04a\uc02a\uc00a\ubfea\ubfca\ubfaa\ubf8a\ubf6a\ubf4a" + + "\ubf2a\ubf0a\ubeea\ubeca\ubeaa\ube8a\ube6a\ube4a\ube2a\ube0a\ubdea" + + "\ubdca\ubdaa\ubd8a\ubd6a\ubd4a\ubd2a\ubd0a\ubcea\ubcca\ubcaa\ubc8a" + + "\ubc6a\ubc4a\ubc2a\ubc0a\ubbea\ub2e0\ub568\ub548\ubb6a\ubb4a\ubb2a" + + "\ubb0a\ubaea\ubaca\ubaaa\uba8a\uba6a\uba4a\uba2a\uba0a\ub9ea\ub9ca" + + "\ub9aa\ub98a\ub96a\ub94a\ub92a\ub90a\ub8ea\ub8ca\ub8aa\ub88a\ub86a" + + "\ub84a\ub82a\ub80a\ub7ea\ub7ca\ub7aa\ub78a\ub76a\ub74a\ub72a\ub70a" + + "\ub6ea\ub6ca\ub6aa\ub68a\ub66a\ub64a\ub62a\ub60a\ub5ea\ub5ca\ub5aa" + + "\ub58a\ub56a\ub54a\ub52a\ub50a\ub4ea\ub4ca\ub4aa\ub48a\ub46a\ub44a" + + "\ub42a\ub40a\ub3ea\ub3ca\ub3aa\ub38a\ub36a\ub34a\ub32a\ub30a\ub2ea" + + "\ub2ca\ub2aa\ub28a\ub26a\ub24a\ub22a\ub20a\ub1ea\ub1ca\ub1aa\ub18a" + + "\ub16a\ub14a\ub12a\ub10a\ub0ea\ub0ca\ub0aa\ub08a\ub06a\ub04a\ub02a" + + "\ub00a\uafea\uafca\uafaa\uaf8a\uaf6a\uaf4a\uaf2a\uaf0a\uaeea\uaeca" + + "\uaeaa\uae8a\uae6a\uae4a\uae2a\uae0a\uadea\uadca\uadaa\uad8a\uad6a" + + "\uad4a\uad2a\uad0a\uacea\uacca\uacaa\uac8a\uac6a\uac4a\uac2a\uac0a" + + "\uabea\uabca\uabaa\uab8a\uab6a\uab4a\uab2a\uab0a\uaaea\uaaca\uaaaa" + + "\uaa8a\uaa6a\uaa4a\uaa2a\uaa0a\ua9ea\ua9ca\ua9aa\ua98a\ua96a\ua94a" + + "\ua92a\ua90a\ua8ea\ua8ca\ua8aa\ua88a\ua86a\ua84a\ua82a\ua80a\ua7ea" + + "\ua7ca\ua7aa\ua78a\ua76a\ua74a\ua72a\ua70a\ua6ea\ua6ca\ua6aa\ua68a" + + "\ua66a\ua64a\ua62a\ua60a\ua5ea\ua5ca\ua5aa\ua58a\ua56a\ua54a\ua52a" + + "\ua50a\ua4ea\ua4ca\ua4aa\ua48a\ua46a\ua44a\ua42a\ua40a\ua3ea\ua3ca" + + "\ua3aa\ua38a\ua36a\ua34a\ua32a\ua30a\ua2ea\ua2ca\ua2aa\ua28a\ua26a" + + "\ua24a\ua22a\ua20a\ua1ea\ua1ca\ua1aa\ua18a\ua16a\ua14a\ua12a\ua10a" + + "\ua0ea\ua0ca\ua0aa\ua08a\ua06a\ua04a\ua02a\ua00a\u9fea\u9fca\u9faa" + + "\u9f8a\u9f6a\u9f4a\u9f2a\u9f0a\u9eea\u9eca\u9eaa\u9e8a\u9e6a\u9e4a" + + "\u9e2a\u9e0a\u9dea\u9dca\u9daa\u9d8a\u9d6a\u9d4a\u9d2a\u9d0a\u9cea" + + "\u9cca\u9caa\u9c8a\u9c6a\u9c4a\u9c2a\u9c0a\u9bea\u9bca\u9baa\u9b8a" + + "\u9b6a\u9b4a\u9b2a\u9b0a\u9aea\u9aca\u9aaa\u9a8a\u9a6a\u9a4a\u9a2a" + + "\u9a0a\u99ea\u99ca\u99aa\u998a\u996a\u994a\u992a\u990a\u98ea\u98ca" + + "\u98aa\u988a\u986a\u984a\u982a\u980a\u97ea\u97ca\u97aa\u978a\u976a" + + "\u974a\u972a\u970a\u96ea\u96ca\u96aa\u968a\u966a\u964a\u962a\u960a" + + "\u95ea\u95ca\u95aa\u958a\u956a\u954a\u952a\u950a\u94ea\u94ca\u94aa" + + "\u948a\u946a\u944a\u942a\u940a\u93ea\u93ca\u93aa\u938a\u936a\u934a" + + "\u932a\u930a\u92ea\u92ca\u92aa\u928a\u926a\u924a\u922a\u920a\u91ea" + + "\u91ca\u91aa\u918a\u916a\u914a\u912a\u910a\u90ea\u90ca\u90aa\u908a" + + "\u906a\u904a\u902a\u900a\u8fea\u8fca\u8faa\u8f8a\u8f6a\u8f4a\u8f2a" + + "\u8f0a\u8eea\u8eca\u8eaa\u8e8a\u8e6a\u8e4a\u8e2a\u8e0a\u8dea\u8dca" + + "\u8daa\u8d8a\u8d6a\u8d4a\u8d2a\u8d0a\u8cea\u8cca\u8caa\u8c8a\u8c6a" + + "\u8c4a\u8c2a\u8c0a\u8bea\u8bca\u8baa\u8b8a\u8b6a\u8b4a\u8b2a\u8b0a" + + "\u8aea\u8aca\u8aaa\u8a8a\u8a6a\u8a4a\u8a2a\u8a0a\u89ea\u89ca\u89aa" + + "\u898a\u896a\u894a\u892a\u890a\u88ea\u88ca\u88aa\u888a\u886a\u884a" + + "\u882a\u880a\u87ea\u87ca\u87aa\u878a\u876a\u874a\u872a\u870a\u86ea" + + "\u86ca\u86aa\u868a\u866a\u864a\u862a\u860a\u85ea\u85ca\u85aa\u858a" + + "\u856a\u854a\u852a\u850a\u84ea\u84ca\u84aa\u848a\u846a\u844a\u842a" + + "\u840a\u83ea\u83ca\u83aa\u838a\u836a\u834a\u832a\u830a\u82ea\u82ca" + + "\u82aa\u828a\u826a\u824a\u822a\u820a\u81ea\u81ca\u81aa\u818a\u816a" + + "\u814a\u812a\u810a\u80ea\u80ca\u80aa\u808a\u806a\u804a\u802a\u800a" + + "\u7fea\u7fca\u7faa\u7f8a\u7f6a\u7f4a\u7f2a\u7f0a\u7eea\u7eca\u7eaa" + + "\u7e8a\u7e6a\u7e4a\u7e2a\u7e0a\u7dea\u7dca\u7daa\u7d8a\u7d6a\u7d4a" + + "\u7d2a\u7d0a\u7cea\u7cca\u7caa\u7c8a\u7c6a\u7c4a\u7c2a\u7c0a\u7bea" + + "\u7bca\u7baa\u7b8a\u7b6a\u7b4a\u7b2a\u7b0a\u7aea\u7aca\u7aaa\u7a8a" + + "\u7a6a\u7a4a\u7a2a\u7a0a\u79ea\u79ca\u79aa\u798a\u796a\u794a\u792a" + + "\u790a\u78ea\u78ca\u78aa\u788a\u786a\u784a\u782a\u780a\u77ea\u77ca" + + "\u77aa\u778a\u776a\u774a\u772a\u770a\u76ea\u76ca\u76aa\u768a\u766a" + + "\u764a\u762a\u760a\u75ea\u75ca\u75aa\u758a\u756a\u754a\u752a\u750a" + + "\u74ea\u74ca\u74aa\u748a\u746a\u744a\u742a\u740a\u73ea\u73ca\u73aa" + + "\u738a\u736a\u734a\u732a\u730a\u72ea\u72ca\u72aa\u728a\u726a\u724a" + + "\u722a\u720a\u71ea\u71ca\u71aa\u718a\u716a\u714a\u712a\u710a\u70ea" + + "\u70ca\u70aa\u708a\u706a\u704a\u702a\u700a\u6fea\u6fca\u6faa\u6f8a" + + "\u6f6a\u6f4a\u6f2a\u6f0a\u6eea\u6eca\u6eaa\u6e8a\u6e6a\u6e4a\u6e2a" + + "\u6e0a\u6dea\u6dca\u6daa\u6d8a\u6d6a\u6d4a\u6d2a\u6d0a\u6cea\u6cca" + + "\u6caa\u6c8a\u6c6a\u6c4a\u6c2a\u6c0a\u6bea\u6bca\u6baa\u6b8a\u6b6a" + + "\u6b4a\u6b2a\u6b0a\u6aea\u6aca\u6aaa\u6a8a\u6a6a\u6a4a\u6a2a\u6a0a" + + "\u69ea\u60f0\u6368\u6348\u696a\u694a\u692a\u690a\u68ea\u68ca\u68aa" + + "\u688a\u686a\u684a\u682a\u680a\u67ea\u67ca\u67aa\u678a\u676a\u674a" + + "\u672a\u670a\u66ea\u66ca\u66aa\u668a\u666a\u664a\u662a\u660a\u65ea" + + "\u65ca\u65aa\u658a\u656a\u654a\u652a\u650a\u6b26\u6de1\u6e9c\u5e48" + + "\u5e28\u5e08\u5de8\u5dc8\u5da8\u5d88\u5d68\u5d48\u5d28\u5d08\u5ce8" + + "\u5cc8\u5ca8\u5c88\u5c68\u5c48\u5c28\u5c08\u5be8\u5bc8\u5ba8\u5b88" + + "\u5b68\u5b48\u5b28\u5b08\u5ae8\u5ac8\u5aa8\u5a88\u5a68\u5a48\u5a28" + + "\u5a08\u59e8\u59c8\u59a8\u5988\u5968\u5948\u5928\u5908\u58e8\u58c8" + + "\u58a8\u5888\u5868\u5848\u5828\u5808\u57e8\u57c8\u57a8\u5788\u5768" + + "\u5748\u5d6a\u5d4a\u5d2a\u5d0a\u5cea\u5cca\u5caa\u5c8a\u5c6a\u5c4a" + + "\u5c2a\u5c0a\u5bea\u5bca\u5baa\u5b8a\u5b6a\u5b4a\u5b2a\u5b0a\u5aea" + + "\u5aca\u5aaa\u5a8a\u5a6a\u5a4a\u5a2a\u5a0a\u59ea\u59ca\u59aa\u598a" + + "\u596a\u594a\u592a\u590a\u58ea\u58ca\u58aa\u588a\u586a\u584a\u582a" + + "\u580a\u57ea\u57ca\u57aa\u578a\u576a\u574a\u572a\u570a\u56ea\u56ca" + + "\u56aa\u568a\u566a\u564a\u562a\u560a\u55ea\u55ca\u55aa\u558a\u556a" + + "\u554a\u552a\u550a\u54ea\u54ca\u54aa\u548a\u546a\u544a\u542a\u540a" + + "\u53ea\u53ca\u53aa\u538a\u536a\u534a\u532a\u530a\u52ea\u52ca\u52aa" + + "\u528a\u526a\u524a\u522a\u520a\u51ea\u51ca\u51aa\u518a\u516a\u514a" + + "\u512a\u510a\u50ea\u50ca\u50aa\u508a\u506a\u504a\u502a\u500a\u4fea" + + "\u4fca\u4faa\u4f8a\u4f6a\u4f4a\u4f2a\u4f0a\u4eea\u4eca\u4eaa\u4e8a" + + "\u4e6a\u4e4a\u4e2a\u4e0a\u4dea\u4dca\u4daa\u4d8a\u4d6a\u4d4a\u4d2a" + + "\u4d0a\u4cea\u4cca\u4caa\u4c8a\u4c6a\u4c4a\u4c2a\u4c0a\u4bea\u4bca" + + "\u4baa\u4b8a\u4b6a\u4b4a\u4b2a\u4b0a\u4aea\u4aca\u4aaa\u4a8a\u4a6a" + + "\u4a4a\u4a2a\u4a0a\u49ea\u49ca\u49aa\u498a\u496a\u494a\u492a\u490a" + + "\u48ea\u48ca\u48aa\u488a\u486a\u484a\u482a\u480a\u47ea\u47ca\u47aa" + + "\u478a\u476a\u474a\u472a\u470a\u46ea\u46ca\u46aa\u468a\u466a\u464a" + + "\u462a\u460a\u45ea\u45ca\u45aa\u458a\u456a\u454a\u452a\u450a\u44ea" + + "\u44ca\u44aa\u448a\u446a\u444a\u442a\u440a\u43ea\u43ca\u43aa\u438a" + + "\u436a\u434a\u432a\u430a\u42ea\u42ca\u42aa\u428a\u426a\u424a\u422a" + + "\u420a\u41ea\u41ca\u41aa\u418a\u416a\u414a\u412a\u410a\u40ea\u40ca" + + "\u40aa\u408a\u406a\u404a\u402a\u400a\u3fea\u3fca\u3faa\u3f8a\u3f6a" + + "\u3f4a\u3f2a\u3f0a\u3eea\u3eca\u3eaa\u3e8a\u3e6a\u3e4a\u3e2a\u3e0a" + + "\u3dea\u3dca\u3daa\u3d8a\u3d6a\u3d4a\u3d2a\u3d0a\u3cea\u3cca\u3caa" + + "\u3c8a\u3c6a\u3c4a\u3c2a\u3c0a\u3bea\u3bca\u3baa\u3b8a\u3b6a\u3b4a" + + "\u3b2a\u3b0a\u3aea\u3aca\u3aaa\u3a8a\u3a6a\u3a4a\u3a2a\u3a0a\u39ea" + + "\u39ca\u39aa\u398a\u396a\u394a\u392a\u390a\u38ea\u38ca\u38aa\u388a" + + "\u386a\u384a\u382a\u380a\u37ea\u37ca\u37aa\u378a\u376a\u374a\u372a" + + "\u370a\u36ea\u36ca\u36aa\u368a\u366a\u364a\u362a\u360a\u35ea\u35ca" + + "\u35aa\u358a\u356a\u354a\u352a\u350a\u34ea\u34ca\u34aa\u348a\u346a" + + "\u344a\u342a\u340a\u33ea\u33ca\u33aa\u338a\u336a\u334a\u332a\u330a" + + "\u32ea\u32ca\u32aa\u328a\u326a\u324a\u322a\u320a\u31ea\u28f2\u2b68" + + "\u2b48\u3c2b\u3c0b\u3beb\u3bcb\u3bab\u3b8b\u3b6b\u3b4b\u3b2b\u3b0b" + + "\u3aeb\u3acb\u3aab\u3a8b\u3a6b\u3a4b\u3a2b\u3a0b\u39eb\u39cb\u39ab" + + "\u398b\u396b\u394b\u392b\u390b\u38eb\u38cb\u38ab\u388b\u386b\u384b" + + "\u382b\u380b\u37eb\u37cb\u37ab\u378b\u376b\u374b\u372b\u370b\u36eb" + + "\u36cb\u36ab\u368b\u366b\u364b\u362b\u360b\u35eb\u35cb\u35ab\u358b" + + "\u356b\u354b\u352b\u350b\u34eb\u34cb\u34ab\u348b\u346b\u344b\u344b" + + "\u342b\u340b\u33eb\u33cb\u33ab\u338b\u336b\u334b\u332b\u330b\u32eb" + + "\u32cb\u32ab\u328b\u326b\u324b\u322b\u320b\u31eb\u31cb\u31ab\u318b" + + "\u316b\u314b\u312b\u310b\u30eb\u30cb\u30ab\u308b\u306b\u304b\u302b" + + "\u300b\u2feb\u2fcb\u2fab\u2f8b\u2f6b\u2f4b\u2f2b\u2f0b\u2eeb\u2ecb" + + "\u2eab\u2e8b\u2e6b\u2e4b\u2e2b\u2e0b\u2deb\u2dcb\u2dab\u2d8b\u2d6b" + + "\u2d4b\u2d2b\u2d0b\u2ceb\u2ccb\u2cab\u2c8b\u2c6b\u2c4b\u2c2b\u2c0b" + + "\u2beb\u2bcb\u2bab\u2b8b\u2b6b\u2b4b\u2b2b\u2b0b\u2aeb\u2acb\u2aab" + + "\u2a8b\u2a6b\u2a4b\u2a2b\u2a0b\u29eb\u29cb\u29ab\u298b\u296b\u294b" + + "\u292b\u290b\u28eb\u28cb\u28ab\u288b\u286b\u284b\u282b\u280b\u27eb" + + "\u27cb\u27ab\u278b\u276b\u274b\u272b\u270b\u26eb\u26cb\u26ab\u268b" + + "\u266b\u264b\u262b\u260b\u25eb\u25cb\u25ab\u258b\u256b\u254b\u252b" + + "\u250b\u24eb\u24cb\u24ab\u248b\u246b\u244b\u242b\u240b\u23eb\u23cb" + + "\u23ab\u238b\u236b\u234b\u232b\u230b\u22eb\u22cb\u22ab\u228b\u226b" + + "\u224b\u222b\u220b\u21eb\u21cb\u21ab\u218b\u216b\u214b\u212b\u210b" + + "\u20eb\u20cb\u20ab\u208b\u206b\u204b\u202b\u200b\u1feb\u1fcb\u1fab" + + "\u1f8b\u1f6b\u1f4b\u1f2b\u1f0b\u1eeb\u1ecb\u1eab\u1e8b\u1e6b\u1e4b" + + "\u1e2b\u1e0b\u1deb\u1dcb\u1dab\u1d8b\u1d6b\u1d4b\u1d2b\u1d0b\u1ceb" + + "\u1ccb\u1cab\u1c8b\u1c6b\u1c4b\u1c2b\u1c0b\u1beb\u1bcb\u1bab\u1b8b" + + "\u1b6b\u106a\u104a\u102a\u100a\u0fea\u0fca\u0faa\u0f8a\u0f6a\u0668" + + "\u08e8\u08c8\u08a8\u0888\u0868\u0848\u07d7\u194b\u07b6\u0d1c\u0cfc" + + "\u0cb2\u0ca9\u0c9c\u0c7c\u0c5c\u0c3c\u0c1c\u0bfc\u0bdc\u0bbc\u0b9c" + + "\u0b7c\u0b5e\u0b2c\u0b1c\u0ab8\u0adc\u0a9c\u02c2\u0528\u166b\u1667" + + "\u03ff\u09fc\u09dc\u09bc\u0659\u0bb8\u15a7\u0fc6\u01c0\u01b1\u09cb" + + "\u082c\u1285"; + + /** + * Information about each character. The low order 5 bits form the + * character type, the next bit is a flag for non-breaking spaces, and the + * next bit is a flag for mirrored directionality. The high order 9 bits + * form the offset into the attribute tables. Note that this limits the + * number of unique character attributes to 512, which is not a problem + * as of Unicode version 3.2.0, but may soon become one. + */ + String DATA + = "\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3e80\u3e80\u3001\u3082\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85" + + "\u3a85\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85" + + "\u3e80\u3e80\u3e80\u3e80\u5b88\u5b88\u3e80\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80" + + "\u3e80\u3e80\u3e80\u5198\u3e80\u3e80\u3e80\u3e80\u4606\u3e80\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u3a85" + + "\u3a85\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u3e80\u3e80\u3e80\u3e80\u5202\u5202\u5202\u5202" + + "\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202" + + "\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202\u5202" + + "\u5202\u5202\u5202\u5202\u5202\u2e82\u3e80\u5198\u2a14\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4686\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u1a1b\u1a1b\u3e80\u3e80\u3e80\u3e80\u4584\u3e80\u3e80" + + "\u3e80\u0298\u3e80\u0298\u6615\u6696\u0298\u1a97\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u4584\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u4584\u4584\u1a1b\u1a1b\u1a1b\u1a1b" + + "\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u4584" + + "\u4584\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b" + + "\u1a1b\u1a1b\u1a1b\u1a1b\u2e82\u7282\u2e82\u3e80\u2e82\u4902\u7481" + + "\u7481\u7481\u7481\u7383\u1a1b\u1a1b\u1a1b\u6d82\u6d82\u4902\u4902" + + "\u3e80\u3e80\u2e82\u4902\u6e01\u6e01\u7501\u7501\u3e80\u1a1b\u1a1b" + + "\u1a1b\u1b02\u1b82\u1c02\u1c82\u1d02\u1d82\u1e02\u1e82\u1f02\u1f82" + + "\u2002\u2082\u2102\u2182\u2202\u2282\u2302\u2382\u2402\u2482\u2502" + + "\u2582\u2602\u2682\u2702\u2782\u0455\u0c99\u04d6\u0c99\017\017" + + "\017\017\017\u010f\017\017\017\017\017\017\017" + + "\017\017\017\017\017\017\017\017\017\017\017" + + "\017\017\017\017\017\017\017\017\u008f\u010f\u008f" + + "\u018f\u010f\017\017\017\017\017\017\017\017\017" + + "\017\017\017\017\017\u010f\u010f\u010f\u008f\u020c\u0298" + + "\u0298\u0318\u039a\u0318\u0298\u0298\u0455\u04d6\u0298\u0519\u0598" + + "\u0614\u0598\u0698\u0709\u0789\u0809\u0889\u0909\u0989\u0a09\u0a89" + + "\u0b09\u0b89\u0598\u0298\u0c59\u0c99\u0c59\u0298\u0d01\u0d81\u0e01" + + "\u0e81\u0f01\u0f81\u1001\u1081\u1101\u1181\u1201\u1281\u1301\u1381" + + "\u1401\u1481\u1501\u1581\u1601\u1681\u1701\u1781\u1801\u1881\u1901" + + "\u1981\u0455\u0298\u04d6\u1a1b\u1a97\u0298\u0298\u0298\u0c99\u0455" + + "\u04d6\u3e80\u0298\u0298\u0298\u0298\u0298\u0298\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u282c\u0298\u039a\u039a\u039a\u039a\u289c" + + "\u289c\u1a1b\u289c\u2902\u29dd\u0c99\u2a14\u289c\u1a1b\u2a9c\u0519" + + "\u2b0b\u2b8b\u1a1b\u2c02\u289c\u0298\u1a1b\u2c8b\u2902\u2d5e\u2d8b" + + "\u2d8b\u2d8b\u0298\u0298\u0519\u0614\u0c99\u0c99\u0c99\u3e80\u0298" + + "\u039a\u0318\u0298\u3e80\u3e80\u3e80\u3e80\u5405\u5405\u5405\u3e80" + + "\u5405\u3e80\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u3e80\u3e80\u3e80\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u3e80\u501c\u501c\u4f81\u4f81" + + "\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81\u4f81" + + "\u4f81\u4f81\u4f81\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01" + + "\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01" + + "\u2e01\u2e01\u2e01\u2e01\u0c99\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01" + + "\u2e01\u2e82\u2e82\u2e82\u4902\u4902\u2e82\u2e82\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u2e82\u2e82" + + "\u2e82\u2e82\u2e82\u3e80\u3e80\u3e80\u3e80\u3e80\u5305\u4606\u5305" + + "\u5305\u3e80\u5305\u5305\u3e80\u5305\u5305\u5305\u5305\u5305\u5305" + + "\u5305\u5305\u5305\u5305\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5398\u5405\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u5087\u5087\u4606\u5087\u5087\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u2d8b\u2d8b\u2d8b\u2d8b\u2d8b\u2d8b\u2d8b" + + "\u2d8b\u2d8b\u2d8b\u2d8b\u2d8b\u840b\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u2e82\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5c09" + + "\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u4606\u4606" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u1a1b\u1a1b\u4701\u0298\u4781\u4781\u4781\u3e80" + + "\u4801\u3e80\u4881\u4881\u4902\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01" + + "\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2f02" + + "\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02" + + "\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02" + + "\u0c99\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f82\u2f02\u2f02" + + "\u4a82\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u4b02" + + "\u4b82\u4b82\u3e80\u4c02\u4c82\u4d01\u4d01\u4d01\u4d82\u4e02\u2902" + + "\u3e80\u3e80\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u2e82\u3b81\u3c03\u3c82" + + "\u3001\u3082\u3d81\u3e01\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3101\u3182" + + "\u3001\u3082\u3001\u3082\u3001\u3082\u2902\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u4e82\u4f02\u3d02\u2902\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5b10\u5b10\u5b10\u5b10\u5b10" + + "\u5b10\u7f0b\u3e80\u3e80\u3e80\u7f8b\u800b\u808b\u810b\u818b\u820b" + + "\u0519\u0519\u0c99\u0455\u04d6\u2902\u3301\u3001\u3082\u3001\u3082" + + "\u3381\u3001\u3082\u3401\u3401\u3001\u3082\u2902\u3481\u3501\u3581" + + "\u3001\u3082\u3401\u3601\u3682\u3701\u3781\u3001\u3082\u2902\u2902" + + "\u3701\u3801\u2902\u3881\u3a85\u3a85\u3a85\u3a85\u3b81\u3c03\u3c82" + + "\u3b81\u3c03\u3c82\u3b81\u3c03\u3c82\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3d02\u3001\u3082\u501c\u4606\u4606\u4606\u4606\u3e80\u5087\u5087" + + "\u3e80\u3e80\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3201\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3282\u3001\u3082\u3001\u3082\u3001\u3082\u3901\u3001\u3082\u3901" + + "\u2902\u2902\u3001\u3082\u3901\u3001\u3082\u3981\u3981\u3001\u3082" + + "\u3001\u3082\u3a01\u3001\u3082\u2902\u3a85\u3001\u3082\u2902\u3b02" + + "\u4d01\u3001\u3082\u3001\u3082\u3e80\u3e80\u3001\u3082\u3e80\u3e80" + + "\u3001\u3082\u3e80\u3e80\u3e80\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001" + + "\u3082\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u0598\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5398\u3e80\u3e80\u3e80\u5398" + + "\u5398\u5398\u5398\u5398\u5398\u5398\u5398\u5398\u5398\u5398\u5398" + + "\u5398\u5398\u3e80\u5b10\u5405\u4606\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u3e80\u3e80\u5b10\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01" + + "\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01" + + "\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01\u4d01" + + "\u4d01\u4d01\u4d01\u4d01\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89" + + "\u5f09\u5f89\u6009\u6089\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u2902\u2902\u2902\u3f02\u3f82\u2902\u4002" + + "\u4002\u2902\u4082\u2902\u4102\u2902\u2902\u2902\u2902\u4002\u2902" + + "\u2902\u4182\u2902\u2902\u2902\u2902\u4202\u4282\u2902\u2902\u2902" + + "\u2902\u2902\u4282\u2902\u2902\u4302\u2902\u2902\u4382\u2902\u2902" + + "\u2902\u2902\u2902\u2902\u2902\u2902\u2902\u2902\u4402\u2902\u2902" + + "\u4402\u2902\u2902\u2902\u2902\u4402\u2902\u4482\u4482\u2902\u2902" + + "\u2902\u2902\u2902\u2902\u4502\u2902\u2902\u2902\u2902\u2902\u2902" + + "\u2902\u2902\u2902\u2902\u2902\u2902\u2902\u2902\u3e80\u3e80\u4584" + + "\u4584\u4584\u4584\u4584\u4584\u4584\u4584\u4584\u1a1b\u1a1b\u4584" + + "\u4584\u4584\u4584\u4584\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b\u1a1b" + + "\u1a1b\u1a1b\u4584\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5101\u5101" + + "\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101" + + "\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u5101\u3e80" + + "\u3e80\u4584\u5198\u5198\u5198\u5198\u5198\u5198\u2e01\u2e01\u3e80" + + "\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u2e01\u4982\u4a02" + + "\u4a02\u4a02\u4902\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02" + + "\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u2f02\u4f02\u4f02\u4f02" + + "\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02\u4f02" + + "\u4f02\u4f02\u4606\u4606\u4606\u4606\u4606\u5198\u4606\u4606\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u3e80\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u3e80\u4606\u4606\u4606\u5298" + + "\u4606\u4606\u5298\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u5305\u5305\u5305\u5305\u5305\u5305\u5305" + + "\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u5305\u5305\u5305\u5298\u5298\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5c89\u5d09\u5d89" + + "\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u640b\u648b\u650b\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u4606\u5b88\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80" + + "\u3e80\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80" + + "\u3e80\u3a85\u3a85\u3e80\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3e80" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u5b88\u5b88\u5b88\u5b88\u3e80\u4606\u4606\u4606\u3e80\u4606" + + "\u4606\u4606\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u4606" + + "\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u4606" + + "\u5b88\u5b88\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3e80\u3e80\u3a85\u3a85\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3e80\u3e80\u3e80\u3e80\u5b88\u5b88\u3e80\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3a85\u3a85\u3a85" + + "\u3e80\u3e80\u3e80\u3e80\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09" + + "\u5f89\u6009\u6089\u501c\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5509\u5589\u5609" + + "\u5689\u5709\u5789\u5809\u5889\u5909\u5989\u0318\u5a18\u5a18\u5398" + + "\u3e80\u3e80\u4606\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u3e80\u3e80\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u6615\u6696\u5484\u5405\u5405\u5405\u5405" + + "\u5405\u5405\u5405\u5405\u5405\u5405\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u5b88\u5b88\u5198\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u4606\u4606\u5b88" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3e80" + + "\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u5198\u5198\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u4606\u4606\u4606\u4606\u4606\u5484\u5484\u4606" + + "\u4606\u289c\u4606\u4606\u4606\u4606\u3e80\u3e80\u0709\u0789\u0809" + + "\u0889\u0909\u0989\u0a09\u0a89\u0b09\u0b89\u5405\u5405\u5405\u5a9c" + + "\u5a9c\u3e80\u3a85\u3a85\u3a85\u3e80\u3a85\u3e80\u3a85\u3e80\u3e80" + + "\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u4606\u3a85\u3a85\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u3e80\u4606\u4606\u3a85\u3e80\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u4606\u4606\u5b88" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3e80\u3e80\u4606\u3a85\u5b88\u5b88\u5b88\u5b88\u5b88\u3e80\u4606" + + "\u5b88\u5b88\u3e80\u5b88\u5b88\u4606\u4606\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u5b88\u5b88\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3a85\u3e80\u5198\u5198\u5198\u5198\u5198\u5198\u5198\u5198" + + "\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u640b\u670b" + + "\u678b\u680b\u688b\u690b\u698b\u6a0b\u6a8b\u648b\u6b0b\u3e80\u3e80" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3e80" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u4606\u3a85\u5b88\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u5b88\u5b88\u5b88\u5b88" + + "\u4606\u3e80\u3e80\u3a85\u4606\u4606\u4606\u4606\u3e80\u3e80\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3e80\u3e80\u3e80" + + "\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u4606\u3e80\u5b88\u5b88\u5b88" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3e80\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u4606\u3a85\u3a85\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u3e80\u3e80\u3e80\u3e80\u039a\u039a\u039a" + + "\u039a\u039a\u039a\u039a\u039a\u039a\u039a\u039a\u039a\u039a\u039a" + + "\u039a\u039a\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u4606\u4606" + + "\u5198\u5198\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009" + + "\u6089\u5198\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u0298\u0298\u0318\u039a\u0318" + + "\u0298\u0298\u6615\u6696\u0298\u0519\u0598\u0614\u0598\u0698\u0709" + + "\u0789\u0809\u0889\u0909\u0989\u0a09\u0a89\u0b09\u0b89\u0598\u0298" + + "\u0c99\u0c99\u0c99\u0298\u0298\u0298\u0298\u0298\u0298\u2a14\u0298" + + "\u0298\u0298\u0298\u5b10\u5b10\u5b10\u5b10\u3e80\u5c09\u5c89\u5d09" + + "\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u5b88" + + "\u4606\u4606\u4606\u4606\u3e80\u3e80\u5b88\u5b88\u3e80\u3e80\u5b88" + + "\u5b88\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u5b88\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u3e80\u3a85\u3e80\u3e80" + + "\u3a85\u3a85\u3e80\u3a85\u3e80\u3e80\u3a85\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3e80\u3a85\u3a85\u3e80\u3a85\u3a85\u3e80\u3a85\u3a85" + + "\u3e80\u3e80\u4606\u3e80\u5b88\u5b88\u4606\u4606\u3e80\u3e80\u3e80" + + "\u3e80\u4606\u4606\u3e80\u3e80\u4606\u4606\u4606\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85" + + "\u3a85\u3e80\u3a85\u3e80\u3a85\u3a85\u4606\u4606\u3e80\u3e80\u5c09" + + "\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u3a85\u3a85" + + "\u039a\u039a\u610b\u618b\u620b\u628b\u630b\u638b\u501c\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3a85" + + "\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u4606\u3a85" + + "\u5b88\u5b88\u4606\u4606\u4606\u4606\u4606\u3e80\u4606\u4606\u5b88" + + "\u3e80\u5b88\u5b88\u4606\u3e80\u3e80\u3a85\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u630b" + + "\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u501c\u4606" + + "\u501c\u4606\u501c\u4606\u6615\u6696\u6615\u6696\u5b88\u5b88\u4606" + + "\u4606\u4606\u3e80\u3e80\u3e80\u5b88\u5b88\u3e80\u3e80\u5b88\u5b88" + + "\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u4606\u5b88" + + "\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3e80\u3a85\u3a85\u3e80\u5b88\u4606\u4606\u4606\u4606\u5b88" + + "\u4606\u3e80\u3e80\u3e80\u4606\u4606\u5b88\u4606\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u5b88\u5b88\u5b88\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u5b88\u5b88\u3e80\u3e80\u3e80\u5b88\u5b88\u5b88\u3e80\u5b88\u5b88" + + "\u5b88\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u5b88\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u4584\u3e80\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u3e80\u3e80\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89" + + "\u6009\u6089\u3e80\u3e80\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u5c09" + + "\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u5087\u5087\u5087\u5b88\u4606\u4606" + + "\u4606\u3e80\u3e80\u5b88\u5b88\u5b88\u3e80\u5b88\u5b88\u5b88\u4606" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u5b88\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u4606\u3e80\u3e80\u3e80\u3e80" + + "\u5b88\u5b88\u5b88\u4606\u4606\u4606\u3e80\u4606\u3e80\u5b88\u5b88" + + "\u5b88\u5b88\u5b88\u5b88\u5b88\u5b88\u4606\u5b88\u5b88\u4606\u4606" + + "\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u4606\u5198\u5198" + + "\u5198\u5198\u5198\u5198\u5198\u039a\u5198\u3e80\u3e80\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u4584\u4606\u4606\u4606\u4606\u4606" + + "\u4606\u4606\u4606\u5198\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09" + + "\u5f89\u6009\u6089\u5198\u5198\u3e80\u3e80\u3e80\u3e80\u3a85\u501c" + + "\u501c\u501c\u5198\u5198\u5198\u5198\u5198\u5198\u5198\u5198\u65b8" + + "\u5198\u5198\u5198\u5198\u5198\u5198\u501c\u501c\u501c\u501c\u501c" + + "\u4606\u4606\u501c\u501c\u501c\u501c\u501c\u501c\u4606\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u3e80\u3e80\u501c\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u1a97\u4584\u4584\u4584" + + "\u3e80\u5c09\u5c89\u5d09\u5d89\u5e09\u5e89\u5f09\u5f89\u6009\u6089" + + "\u5198\u5198\u5198\u5198\u5198\u5198\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u5b88\u5b88\u4606\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u020c\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u6615\u6696\u3e80\u3e80\u3e80\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u5198" + + "\u5198\u5198\u6b8b\u6c0b\u6c8b\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u4606\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3001\u3082\u3001" + + "\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082" + + "\u3001\u3082\u3001\u3082\u3001\u3082\u3001\u3082\u2e82\u2e82\u2e82" + + "\u2e82\u2e82\u6d02\u3e80\u3e80\u3e80\u3e80\u6d82\u6d82\u6d82\u6d82" + + "\u6d82\u6d82\u6d82\u6d82\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01" + + "\u6e01\u6d82\u6d82\u6d82\u6d82\u6d82\u6d82\u6d82\u6d82\u6e01\u6e01" + + "\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u6d82\u6d82\u6d82\u6d82\u6d82" + + "\u6d82\u3e80\u3e80\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u3e80\u3e80" + + "\u2e82\u6d82\u4902\u6d82\u4902\u6d82\u4902\u6d82\u3e80\u6e01\u3e80" + + "\u6e01\u3e80\u6e01\u3e80\u6e01\u6d82\u6d82\u6d82\u6d82\u6d82\u6d82" + + "\u6d82\u6d82\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u6e01\u6e82" + + "\u6e82\u6f02\u6f02\u6f02\u6f02\u6f82\u6f82\u7002\u7002\u7082\u7082" + + "\u7102\u7102\u3e80\u3e80\u7182\u7182\u7182\u7182\u7182\u7182\u7182" + + "\u7182\u7203\u7203\u7203\u7203\u7203\u7203\u7203\u7203\u7182\u7182" + + "\u7182\u7182\u7182\u7182\u7182\u7182\u7203\u7203\u7203\u7203\u7203" + + "\u7203\u7203\u7203\u6d82\u6d82\u2e82\u7282\u2e82\u3e80\u2e82\u4902" + + "\u6e01\u6e01\u7301\u7301\u7383\u1a1b\u7402\u1a1b\u1b02\u1b82\u1c02" + + "\u1c82\u1d02\u1d82\u1e02\u1e82\u1f02\u1f82\u2002\u2082\u2102\u2182" + + "\u2202\u2282\u2302\u2382\u2402\u2482\u2502\u2582\u2602\u2682\u2702" + + "\u2782\u6615\u0c99\u6696\u0c99\u3e80\u6d82\u6d82\u4902\u4902\u2e82" + + "\u7582\u2e82\u4902\u6e01\u6e01\u7601\u7601\u7681\u1a1b\u1a1b\u1a1b" + + "\u3e80\u3e80\u2e82\u7282\u2e82\u3e80\u2e82\u4902\u7701\u7701\u7781" + + "\u7781\u7383\u1a1b\u1a1b\u3e80\u020c\u020c\u020c\u020c\u020c\u020c" + + "\u020c\u782c\u020c\u020c\u020c\u788c\u5b10\u5b10\u7910\u7990\u2a14" + + "\u7a34\u2a14\u2a14\u2a14\u2a14\u0298\u0298\u7a9d\u7b1e\u6615\u7a9d" + + "\u7a9d\u7b1e\u6615\u7a9d\u0298\u0298\u0298\u0298\u0298\u0298\u0298" + + "\u0298\u7b8d\u7c0e\u7c90\u7d10\u7d90\u7e10\u7e90\u782c\u0318\u0318" + + "\u0318\u0318\u0318\u0298\u0298\u0298\u0298\u29dd\u2d5e\u0298\u0298" + + "\u0298\u0298\u1a97\u7f0b\u2c8b\u2b0b\u2b8b\u7f8b\u800b\u808b\u810b" + + "\u818b\u820b\u0519\u0519\u0c99\u0455\u04d6\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u3e80\u3e80\u3e80\u3e80\u3e80\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u4d01\u289c\u289c\u289c\u289c" + + "\u4d01\u289c\u289c\u2902\u4d01\u4d01\u4d01\u2902\u2902\u4d01\u4d01" + + "\u4d01\u2902\u289c\u4d01\u289c\u289c\u289c\u4d01\u4d01\u4d01\u4d01" + + "\u4d01\u289c\u289c\ua20a\ua28a\ua30a\ua38a\ua40a\ua48a\ua50a\ua58a" + + "\ua60a\u4606\u4606\u4606\u4606\u4606\u4606\u2a14\u4584\u4584\u4584" + + "\u4584\u4584\u289c\u289c\ua68a\ua70a\ua78a\u3e80\u3e80\u3e80\u289c" + + "\u289c\u289c\u289c\u3e80\u289c\u289c\u289c\u289c\u3e80\u3e80\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u0c99\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u0c99\u0c99\u289c\u289c\u0c99\u289c\u0c99" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u0c99\u289c\u289c\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u948a" + + "\u950a\u958a\u960a\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u0c99\u0c99\u0c99\u0c99\u0c99\u289c\u289c" + + "\u289c\u289c\u289c\u0c99\u0c99\u289c\u289c\u289c\u289c\u4d01\u289c" + + "\u8281\u289c\u4d01\u289c\u8301\u8381\u4d01\u4d01\u2a9c\u2902\u4d01" + + "\u4d01\u289c\u4d01\u2902\u3a85\u3a85\u3a85\u3a85\u2902\u289c\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u848a\u850a\u858a\u860a\u868a\u870a\u878a" + + "\u880a\u888a\u890a\u898a\u8a0a\u8a8a\u8b0a\u8b8a\u8c0a\u8c8a\u8d0a" + + "\u8d8a\u8e0a\u8e8a\u8f0a\u8f8a\u900a\u908a\u910a\u918a\u920a\u928a" + + "\u930a\u938a\u940a\u0c99\u0c99\u0c59\u0c59\u0c99\u0c99\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c99\u0c99\u0c99" + + "\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c99\u0c99\u0c99\u0c99\u0c99" + + "\u0c99\u0c99\u0c59\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c59\u0c59" + + "\u0c99\u0c99\u0c99\u0c99\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c59\u0c59\u0c59" + + "\u0c59\u0c99\u0c99\u0c99\u0c99\u0c99\u0c59\u0c99\u0c99\u0c99\u0c99" + + "\u0c99\u0c99\u0c99\u289c\u289c\u0c99\u289c\u289c\u0c99\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u0c99\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u3e80\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u0c99\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c99\u0c59\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c99\u0c99\u0c99\u0c59\u0519\u0519\u0c99\u0c59" + + "\u0c59\u0c99\u0c99\u0c99\u0c59\u0c59\u0c59\u0c59\u0c99\u0c59\u0c99" + + "\u0c59\u0c99\u0c99\u0c99\u0c99\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c99\u0c99\u0c99\u0c99\u0c99\u0c59\u0c99\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u0455\u04d6\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u3e80\u3e80\u3e80\u3e80\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u9c1c\u9c1c\u9c1c\u9c1c" + + "\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c\u9c1c" + + "\u9c1c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c" + + "\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u9c9c\u7f0b\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u0c59\u0c99\u0c59\u0c99\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59\u0c59" + + "\u0c59\u0c59\u0c59\u0c59\u0c59\u0c99\u0c99\u0c59\u0c59\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u039a\u039a\u0c99\u1a1b\u289c\u039a\u039a\u3e80\u289c\u0c99" + + "\u0c99\u0c99\u0c99\u289c\u289c\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u5b10\u5b10\u5b10\u289c\u289c\u3e80\u3e80" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u3e80\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u3e80\u289c" + + "\u3e80\u289c\u289c\u289c\u289c\u3e80\u3e80\u3e80\u289c\u3e80\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u840b\u9d0b" + + "\u9d8b\u9e0b\u9e8b\u9f0b\u9f8b\ua00b\ua08b\ua10b\u840b\u9d0b\u9d8b" + + "\u9e0b\u9e8b\u9f0b\u9f8b\ua00b\ua08b\ua10b\u289c\u3e80\u3e80\u3e80" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u0c59\u0c59\u0c59" + + "\u0c59\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c\u289c" + + "\u501c\u289c\u289c\u289c\u289c\u289c\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u630b\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u3e80\u3e80" + + "\u3e80\u501c\u610b\u618b\u620b\u628b\ua80b\ua88b\ua90b\ua98b\uaa0b" + + "\u640b\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u289c\u3e80\u289c\u289c\u289c" + + "\u3e80\u289c\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u2c8b\u2b0b\u2b8b\u7f8b\u800b\u808b" + + "\u810b\u818b\u820b\u968b\u970b\u978b\u980b\u988b\u990b\u998b\u9a0b" + + "\u9a8b\u9b0b\u9b8b\u2c8b\u2b0b\u2b8b\u7f8b\u800b\u808b\u810b\u818b" + + "\u820b\u968b\u970b\u978b\u980b\u988b\u990b\u998b\u9a0b\u9a8b\u9b0b" + + "\u9b8b\u501c\u501c\u501c\u501c\u020c\u0298\u0298\u0298\u289c\u4584" + + "\u3a85\ua18a\u0455\u04d6\u0455\u04d6\u0455\u04d6\u0455\u04d6\u0455" + + "\u04d6\u289c\u289c\u0455\u04d6\u0455\u04d6\u0455\u04d6\u0455\u04d6" + + "\u2a14\u6615\u6696\u6696\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3e80\u3e80\u3e80\u3e80\u4606\u4606\u1a1b\u1a1b" + + "\u4584\u4584\u3e80\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85" + + "\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3a85\u3e80\u501c\u501c\u630b" + + "\u630b\u630b\u630b\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c" + + "\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u501c\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93" + + "\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93" + + "\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93\uaa93" + + "\uaa93\uaa93\uaa93\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12" + + "\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12" + + "\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12\uab12" + + "\uab12\uab12\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305" + + "\u0519\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305\u5305" + + "\u5305\u5305\u5305\u3e80\u5305\u5305\u5305\u5305\u5305\u3e80\u5305" + + "\u3e80\u4606\u4606\u4606\u4606\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80" + + "\u3e80\u3e80\u3e80\u3e80\u3e80\u3e80\u0298\u2a14\u2a14\u1a97\u1a97" + + "\u6615\u6696\u6615\u6696\u6615\u6696\u6615\u6696\u6615\u6696\u6615" + + "\u6696\u3e80\u3e80\u3e80\u3e80\u0298\u0298\u0298\u0298\u1a97\u1a97" + + "\u1a97\u0598\u0298\u0598\u3e80\u0298\u0598\u0298\u0298\u2a14\u6615" + + "\u6696\u6615\u6696\u6615\u6696\u0318\u0298\u0d01\u0d81\u0e01\u0e81" + + "\u0f01\u0f81\u1001\u1081\u1101\u1181\u1201\u1281\u1301\u1381\u1401" + + "\u1481\u1501\u1581\u1601\u1681\u1701\u1781\u1801\u1881\u1901\u1981" + + "\u6615\u0298\u6696\u1a1b\u1a97"; + + /** + * This is the attribute table for computing the numeric value of a + * character. The value is -1 if Unicode does not define a value, -2 + * if the value is not a positive integer, otherwise it is the value. + * Note that this is a signed value, but stored as an unsigned char + * since this is a String literal. + */ + String NUM_VALUE + = "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\000\001\002\003\004\005\006\007" + + "\010\011\uffff\uffff\012\013\014\015\016\017\020" + + "\021\022\023\024\025\026\027\030\031\032\033" + + "\034\035\036\037 !\"#\uffff\uffff\012" + + "\013\014\015\016\017\020\021\022\023\024\025" + + "\026\027\030\031\032\033\034\035\036\037 " + + "!\"#\uffff\uffff\uffff\uffff\uffff\uffff\002\003" + + "\uffff\001\uffff\ufffe\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\000\001\002\003\004\005" + + "\006\007\010\011\uffff\uffff\uffff\uffff\000\001\002" + + "\003\004\005\006\007\010\011\001\002\003\004" + + "\uffff\020\012d\u03e8\uffff\uffff\uffff\024\036(" + + "2<FPZ\u2710\021\022\023\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff" + + "\uffff\000\004\005\006\007\010\011\uffff\uffff\uffff" + + "\001\001\002\003\004\005\006\007\010\011\012" + + "\013\0142d\u01f4\u03e8\001\002\003\004\005" + + "\006\007\010\011\012\013\0142d\u01f4\u03e8" + + "\u03e8\u1388\u2710\uffff\012\013\014\015\016\017\020" + + "\021\022\023\024\uffff\uffff\002\003\004\005\006" + + "\007\010\011\012\000\001\002\003\004\005\006" + + "\007\010\011\012\024\036\005\006\007\010\011" + + "\uffff\uffff"; + + /** + * This is the attribute table for computing the single-character uppercase + * representation of a character. The value is the signed difference + * between the character and its uppercase version. Note that this is + * stored as an unsigned char since this is a String literal. When + * capitalizing a String, you must first check if a multi-character uppercase + * sequence exists before using this character. + */ + String UPPER + = "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\uffe0" + + "\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0" + + "\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0\uffe0" + + "\uffe0\uffe0\uffe0\000\000\000\000\000\000\000\000" + + "\u02e7\000\000\000\000\000\uffe0y\000\uffff\000" + + "\uff18\000\ufed4\000\000\000\000\000\000\000a" + + "\000\000\000\000\000\000\000\0008\000\uffff" + + "\ufffe\uffb1\000\000\000\uff2e\uff32\uff33\uff36\uff35\uff31" + + "\uff2f\uff2d\uff2b\uff2a\uff26\uff27\uff25\000\000T\000" + + "\000\000\000\000\uffda\uffdb\uffe1\uffc0\uffc1\uffc2\uffc7" + + "\000\uffd1\uffca\uffaa\uffb0\000\000\000\000\000\uffd0" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\uffc5\010" + + "\000JVd\u0080p~\010\000\011\000" + + "\000\ue3db\000\000\007\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\ufff0\ufff0\ufff0\ufff0\ufff0" + + "\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0\ufff0" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\uffe6\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000"; + + /** + * This is the attribute table for computing the lowercase representation + * of a character. The value is the signed difference between the + * character and its lowercase version. Note that this is stored as an + * unsigned char since this is a String literal. + */ + String LOWER + = "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + " " + + " " + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000 \000\000\000\001\000\uff39\000\uff87\000\u00d2\u00ce" + + "\u00cdO\u00ca\u00cb\u00cf\000\u00d3\u00d1\u00d5\u00d6\u00da\u00d9\u00db" + + "\000\000\002\001\000\000\uff9f\uffc8\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000&" + + "%@?\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000P\000\0000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\ufff8" + + "\000\000\000\000\000\000\000\ufff8\000\uffb6\ufff7\000\uffaa" + + "\uff9c\000\uff90\ufff9\uff80\uff82\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\ue2a3\udf41\udfba\000\020\020\020\020\020\020\020\020" + + "\020\020\020\020\020\020\020\020\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\032\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000"; + + /** + * This is the attribute table for computing the directionality class + * of a character, as well as a marker of characters with a multi-character + * capitalization. The direction is taken by performing a signed shift + * right by 2 (where a result of -1 means an unknown direction, such as + * for undefined characters). The lower 2 bits form a count of the + * additional characters that will be added to a String when performing + * multi-character uppercase expansion. This count is also used, along with + * the offset in UPPER_SPECIAL, to determine how much of UPPER_EXPAND to use + * when performing the case conversion. Note that this information is stored + * as an unsigned char since this is a String literal. + */ + String DIRECTION + = "$,(004\024\02444\024\034\024\020\014\014\014" + + "\014\014\014\014\014\014\01444\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\00044\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\0344\00044" + + "\024\014\014\000\01444\000\001\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\ufffc\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000 \000\000\000\000\002\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000 \000\000\000\004\004\010\010\010" + + "\030\030\030\030\030\030\030\030\030\030\030\010$\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "44\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\001\001\001\000\001\000\000\000\000\000\000" + + "\000\0000$\000\0044440(8@H<D\014" + + "\014\014\014\014\014\014\000\000\0004\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000\000\000\000\000\000\000\000\000\000\014\014\014\014\014" + + "\014\014\014\014\014\014\000\000444444444" + + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + + "\000\000\000"; + + /** + * This is the listing of titlecase special cases (all other characters + * can use <code>UPPER</code> to determine their titlecase). The listing + * is a sorted sequence of character pairs; converting the first character + * of the pair to titlecase produces the second character. + */ + String TITLE + = "\u01c4\u01c5\u01c5\u01c5\u01c6\u01c5\u01c7\u01c8\u01c8\u01c8\u01c9" + + "\u01c8\u01ca\u01cb\u01cb\u01cb\u01cc\u01cb\u01f1\u01f2\u01f2\u01f2" + + "\u01f3\u01f2"; + + /** + * This is a listing of characters with multi-character uppercase sequences. + * A character appears in this list exactly when it has a non-zero entry + * in the low-order 2-bit field of DIRECTION. The listing is a sorted + * sequence of pairs (hence a binary search on the even elements is an + * efficient way to lookup a character). The first element of a pair is the + * character with the expansion, and the second is the index into + * UPPER_EXPAND where the expansion begins. Use the 2-bit field of + * DIRECTION to determine where the expansion ends. + */ + String UPPER_SPECIAL + = "\u00df\000\u0149\002\u01f0\004\u0390\006\u03b0\011" + + "\u0587\014\u1e96\016\u1e97\020\u1e98\022\u1e99\024" + + "\u1e9a\026\u1f50\030\u1f52\032\u1f54\035\u1f56 " + + "\u1f80#\u1f81%\u1f82'\u1f83)\u1f84+" + + "\u1f85-\u1f86/\u1f871\u1f883\u1f895" + + "\u1f8a7\u1f8b9\u1f8c;\u1f8d=\u1f8e?" + + "\u1f8fA\u1f90C\u1f91E\u1f92G\u1f93I" + + "\u1f94K\u1f95M\u1f96O\u1f97Q\u1f98S" + + "\u1f99U\u1f9aW\u1f9bY\u1f9c[\u1f9d]" + + "\u1f9e_\u1f9fa\u1fa0c\u1fa1e\u1fa2g" + + "\u1fa3i\u1fa4k\u1fa5m\u1fa6o\u1fa7q" + + "\u1fa8s\u1fa9u\u1faaw\u1faby\u1fac{" + + "\u1fad}\u1fae\u007f\u1faf\u0081\u1fb2\u0083\u1fb3\u0085" + + "\u1fb4\u0087\u1fb6\u0089\u1fb7\u008b\u1fbc\u008e\u1fc2\u0090" + + "\u1fc3\u0092\u1fc4\u0094\u1fc6\u0096\u1fc7\u0098\u1fcc\u009b" + + "\u1fd2\u009d\u1fd3\u00a0\u1fd6\u00a3\u1fd7\u00a5\u1fe2\u00a8" + + "\u1fe3\u00ab\u1fe4\u00ae\u1fe6\u00b0\u1fe7\u00b2\u1ff2\u00b5" + + "\u1ff3\u00b7\u1ff4\u00b9\u1ff6\u00bb\u1ff7\u00bd\u1ffc\u00c0" + + "\ufb00\u00c2\ufb01\u00c4\ufb02\u00c6\ufb03\u00c8\ufb04\u00cb" + + "\ufb05\u00ce\ufb06\u00d0\ufb13\u00d2\ufb14\u00d4\ufb15\u00d6" + + "\ufb16\u00d8\ufb17\u00da"; + + /** + * This is the listing of special case multi-character uppercase sequences. + * Characters listed in UPPER_SPECIAL index into this table to find their + * uppercase expansion. Remember that you must also perform special-casing + * on two single-character sequences in the Turkish locale, which are not + * covered here in CharData. + */ + String UPPER_EXPAND + = "SS\u02bcNJ\u030c\u0399\u0308\u0301\u03a5\u0308" + + "\u0301\u0535\u0552H\u0331T\u0308W\u030aY\u030a" + + "A\u02be\u03a5\u0313\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5" + + "\u0313\u0342\u1f08\u0399\u1f09\u0399\u1f0a\u0399\u1f0b\u0399\u1f0c" + + "\u0399\u1f0d\u0399\u1f0e\u0399\u1f0f\u0399\u1f08\u0399\u1f09\u0399" + + "\u1f0a\u0399\u1f0b\u0399\u1f0c\u0399\u1f0d\u0399\u1f0e\u0399\u1f0f" + + "\u0399\u1f28\u0399\u1f29\u0399\u1f2a\u0399\u1f2b\u0399\u1f2c\u0399" + + "\u1f2d\u0399\u1f2e\u0399\u1f2f\u0399\u1f28\u0399\u1f29\u0399\u1f2a" + + "\u0399\u1f2b\u0399\u1f2c\u0399\u1f2d\u0399\u1f2e\u0399\u1f2f\u0399" + + "\u1f68\u0399\u1f69\u0399\u1f6a\u0399\u1f6b\u0399\u1f6c\u0399\u1f6d" + + "\u0399\u1f6e\u0399\u1f6f\u0399\u1f68\u0399\u1f69\u0399\u1f6a\u0399" + + "\u1f6b\u0399\u1f6c\u0399\u1f6d\u0399\u1f6e\u0399\u1f6f\u0399\u1fba" + + "\u0399\u0391\u0399\u0386\u0399\u0391\u0342\u0391\u0342\u0399\u0391" + + "\u0399\u1fca\u0399\u0397\u0399\u0389\u0399\u0397\u0342\u0397\u0342" + + "\u0399\u0397\u0399\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342" + + "\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313" + + "\u03a5\u0342\u03a5\u0308\u0342\u1ffa\u0399\u03a9\u0399\u038f\u0399" + + "\u03a9\u0342\u03a9\u0342\u0399\u03a9\u0399FFFI" + + "FLFFIFFLSTS" + + "T\u0544\u0546\u0544\u0535\u0544\u053b\u054e\u0546\u0544\u053d"; +} diff --git a/libjava/classpath/gnu/java/lang/ClassHelper.java b/libjava/classpath/gnu/java/lang/ClassHelper.java new file mode 100644 index 0000000..14c8a39 --- /dev/null +++ b/libjava/classpath/gnu/java/lang/ClassHelper.java @@ -0,0 +1,177 @@ +/* ClassHelper.java -- Utility methods to augment java.lang.Class + Copyright (C) 1998, 2002 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.java.lang; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * ClassHelper has various methods that ought to have been in Class. + * + * @author John Keiser + * @author Eric Blake (ebb9@email.byu.edu) + */ +public class ClassHelper +{ + /** + * Strip the package part from the class name. + * + * @param clazz the class to get the truncated name from + * @return the truncated class name + */ + public static String getTruncatedClassName(Class clazz) + { + return getTruncatedName(clazz.getName()); + } + + /** + * Strip the package part from the class name, or the class part from + * the method or field name. + * + * @param name the name to truncate + * @return the truncated name + */ + public static String getTruncatedName(String name) + { + int lastInd = name.lastIndexOf('.'); + if (lastInd == -1) + return name; + return name.substring(lastInd + 1); + } + + /** Cache of methods found in getAllMethods(). */ + private static Map allMethods = new HashMap(); + + /** + * Get all the methods, public, private and otherwise, from the class, + * getting them from the most recent class to find them. This may not + * be quite the correct approach, as this includes methods that are not + * inherited or accessible from clazz, so beware. + * + * @param clazz the class to start at + * @return all methods declared or inherited in clazz + */ + public static Method[] getAllMethods(Class clazz) + { + Method[] retval = (Method[]) allMethods.get(clazz); + if (retval == null) + { + Set methods = new HashSet(); + Class c = clazz; + while (c != null) + { + Method[] currentMethods = c.getDeclaredMethods(); + loop: + for (int i = 0; i < currentMethods.length; i++) + { + Method current = currentMethods[i]; + int size = methods.size(); + Iterator iter = methods.iterator(); + while (--size >= 0) + { + Method override = (Method) iter.next(); + if (current.getName().equals(override.getName()) + && Arrays.equals(current.getParameterTypes(), + override.getParameterTypes()) + && current.getReturnType() == override.getReturnType()) + continue loop; + } + methods.add(current); + } + c = c.getSuperclass(); + } + retval = new Method[methods.size()]; + methods.toArray(retval); + allMethods.put(clazz, retval); + } + return retval; + } + + /** Cache of fields found in getAllFields(). */ + private static Map allFields = new HashMap(); + + /** + * Get all the fields, public, private and otherwise, from the class, + * getting them from the most recent class to find them. This may not + * be quite the correct approach, as this includes fields that are not + * inherited or accessible from clazz, so beware. + * + * @param clazz the class to start at + * @return all fields declared or inherited in clazz + */ + public static Field[] getAllFields(Class clazz) + { + Field[] retval = (Field[]) allFields.get(clazz); + if (retval == null) + { + Set fields = new HashSet(); + Class c = clazz; + while (c != null) + { + Field[] currentFields = c.getDeclaredFields(); + loop: + for (int i = 0; i < currentFields.length; i++) + { + Field current = currentFields[i]; + int size = fields.size(); + Iterator iter = fields.iterator(); + while (--size >= 0) + { + Field override = (Field) iter.next(); + if (current.getName().equals(override.getName()) + && current.getType() == override.getType()) + continue loop; + } + fields.add(current); + } + c = c.getSuperclass(); + } + retval = new Field[fields.size()]; + fields.toArray(retval); + allFields.put(clazz, retval); + } + return retval; + } +} diff --git a/libjava/classpath/gnu/java/lang/MainThread.java b/libjava/classpath/gnu/java/lang/MainThread.java new file mode 100644 index 0000000..ab529ef --- /dev/null +++ b/libjava/classpath/gnu/java/lang/MainThread.java @@ -0,0 +1,83 @@ +/* MainThread.java -- + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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.java.lang; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * MainThread is a Thread which uses the main() method of some class. + * + * @author John Keiser + * @author Tom Tromey (tromey@redhat.com) + */ +public class MainThread +{ + // Private data. + String[] args; + Method mainMethod; + + public MainThread(String classname, String[] args) + throws ClassNotFoundException, NoSuchMethodException + { + Class found = Class.forName(classname, true, + ClassLoader.getSystemClassLoader()); + Class[] argTypes = new Class[1]; + argTypes[0] = args.getClass(); + mainMethod = found.getMethod("main", argTypes); + this.args = args; + } + + public void run() + { + try + { + mainMethod.invoke(null,args); + } + catch(IllegalAccessException e) + { + // Ignore. + } + catch(InvocationTargetException e) + { + // Ignore. + } + } +} diff --git a/libjava/classpath/gnu/java/lang/package.html b/libjava/classpath/gnu/java/lang/package.html new file mode 100644 index 0000000..1f16776 --- /dev/null +++ b/libjava/classpath/gnu/java/lang/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.lang package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.lang</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/lang/reflect/TypeSignature.java b/libjava/classpath/gnu/java/lang/reflect/TypeSignature.java new file mode 100644 index 0000000..842e5bd --- /dev/null +++ b/libjava/classpath/gnu/java/lang/reflect/TypeSignature.java @@ -0,0 +1,288 @@ +/* TypeSignature.java -- Class used to compute type signatures + Copyright (C) 1998, 2000, 2002 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.java.lang.reflect; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +/** + * This class provides static methods that can be used to compute + * type-signatures of <code>Class</code>s or <code>Member</code>s. + * More specific methods are also provided for computing the + * type-signature of <code>Constructor</code>s and + * <code>Method</code>s. Methods are also provided to go in the + * reverse direction. + * + * @author Eric Blake (ebb9@email.byu.edu) + */ +public class TypeSignature +{ + /** + * Returns a <code>String</code> representing the type-encoding of a class. + * The .class file format has different encodings for classes, depending + * on whether it must be disambiguated from primitive types or not; hence + * the descriptor parameter to choose between them. If you are planning + * on decoding primitive types along with classes, then descriptor should + * be true for correct results. Type-encodings are computed as follows: + * + * <pre> + * boolean -> "Z" + * byte -> "B" + * char -> "C" + * double -> "D" + * float -> "F" + * int -> "I" + * long -> "J" + * short -> "S" + * void -> "V" + * arrays -> "[" + descriptor format of component type + * object -> class format: fully qualified name with '.' replaced by '/' + * descriptor format: "L" + class format + ";" + * </pre> + * + * @param type the class name to encode + * @param descriptor true to return objects in descriptor format + * @return the class name, as it appears in bytecode constant pools + * @see #getClassForEncoding(String) + */ + public static String getEncodingOfClass(String type, boolean descriptor) + { + if (! descriptor || type.charAt(0) == '[') + return type.replace('.', '/'); + if (type.equals("boolean")) + return "Z"; + if (type.equals("byte")) + return "B"; + if (type.equals("short")) + return "S"; + if (type.equals("char")) + return "C"; + if (type.equals("int")) + return "I"; + if (type.equals("long")) + return "J"; + if (type.equals("float")) + return "F"; + if (type.equals("double")) + return "D"; + if (type.equals("void")) + return "V"; + return 'L' + type.replace('.', '/') + ';'; + } + + /** + * Gets the descriptor encoding for a class. + * + * @param clazz the class to encode + * @param descriptor true to return objects in descriptor format + * @return the class name, as it appears in bytecode constant pools + * @see #getEncodingOfClass(String, boolean) + */ + public static String getEncodingOfClass(Class clazz, boolean descriptor) + { + return getEncodingOfClass(clazz.getName(), descriptor); + } + + /** + * Gets the descriptor encoding for a class. + * + * @param clazz the class to encode + * @return the class name, as it appears in bytecode constant pools + * @see #getEncodingOfClass(String, boolean) + */ + public static String getEncodingOfClass(Class clazz) + { + return getEncodingOfClass(clazz.getName(), true); + } + + + /** + * This function is the inverse of <code>getEncodingOfClass</code>. This + * accepts both object and descriptor formats, but must know which style + * of string is being passed in (usually, descriptor should be true). In + * descriptor format, "I" is treated as int.class, in object format, it + * is treated as a class named I in the unnamed package. This method is + * strictly equivalent to {@link #getClassForEncoding(java.lang.String, boolean, java.lang.ClassLoader)} + * with a class loader equal to <code>null</code>. In that case, it + * uses the default class loader on the calling stack. + * + * @param type_code the class name to decode + * @param descriptor if the string is in descriptor format + * @return the corresponding Class object + * @throws ClassNotFoundException if the class cannot be located + * @see #getEncodingOfClass(Class, boolean) + */ + public static Class getClassForEncoding(String type_code, boolean descriptor) + throws ClassNotFoundException + { + return getClassForEncoding(type_code, descriptor, null); + } + + /** + * This function is the inverse of <code>getEncodingOfClass</code>. This + * accepts both object and descriptor formats, but must know which style + * of string is being passed in (usually, descriptor should be true). In + * descriptor format, "I" is treated as int.class, in object format, it + * is treated as a class named I in the unnamed package. + * + * @param type_code The class name to decode. + * @param descriptor If the string is in descriptor format. + * @param loader The class loader when resolving generic object name. If + * <code>loader</code> is null then it uses the default class loader on the + * calling stack. + * @return the corresponding Class object. + * @throws ClassNotFoundException if the class cannot be located. + * @see #getEncodingOfClass(Class, boolean) + * @see #getClassForEncoding(String, boolean) + */ + public static Class getClassForEncoding(String type_code, boolean descriptor, + ClassLoader loader) + throws ClassNotFoundException + { + if (descriptor) + { + switch (type_code.charAt(0)) + { + case 'B': + return byte.class; + case 'C': + return char.class; + case 'D': + return double.class; + case 'F': + return float.class; + case 'I': + return int.class; + case 'J': + return long.class; + case 'S': + return short.class; + case 'V': + return void.class; + case 'Z': + return boolean.class; + default: + throw new ClassNotFoundException("Invalid class name: " + + type_code); + case 'L': + type_code = type_code.substring(1, type_code.length() - 1); + // Fallthrough. + case '[': + } + } + return Class.forName(type_code.replace('/', '.'), true, loader); + } + + /** + * Gets the Class object for a type name. + * + * @param type_code the class name to decode + * @return the corresponding Class object + * @throws ClassNotFoundException if the class cannot be located + * @see #getClassForEncoding(String, boolean) + */ + public static Class getClassForEncoding(String type_code) + throws ClassNotFoundException + { + return getClassForEncoding(type_code, true); + } + + /** + * Returns a <code>String</code> representing the type-encoding of a + * method. The type-encoding of a method is: + * + * "(" + parameter type descriptors + ")" + return type descriptor + * + * XXX This could be faster if it were implemented natively. + * + * @param m the method to encode + * @return the encoding + */ + public static String getEncodingOfMethod(Method m) + { + Class[] paramTypes = m.getParameterTypes(); + StringBuffer buf = new StringBuffer().append('('); + for (int i = 0; i < paramTypes.length; i++) + buf.append(getEncodingOfClass(paramTypes[i].getName(), true)); + buf.append(')').append(getEncodingOfClass(m.getReturnType().getName(), + true)); + return buf.toString(); + } + + /** + * Returns a <code>String</code> representing the type-encoding of a + * constructor. The type-encoding of a method is: + * + * "(" + parameter type descriptors + ")V" + * + * XXX This could be faster if it were implemented natively. + * + * @param c the constructor to encode + * @return the encoding + */ + public static String getEncodingOfConstructor(Constructor c) + { + Class[] paramTypes = c.getParameterTypes(); + StringBuffer buf = new StringBuffer().append('('); + for (int i = 0; i < paramTypes.length; i++) + buf.append(getEncodingOfClass(paramTypes[i].getName(), true)); + buf.append(")V"); + return buf.toString(); + } + + /** + * Returns a <code>String</code> representing the type-encoding of a + * class member. This appropriately handles Constructors, Methods, and + * Fields. + * + * @param mem the member to encode + * @return the encoding + */ + public static String getEncodingOfMember(Member mem) + { + if (mem instanceof Constructor) + return getEncodingOfConstructor((Constructor) mem); + if (mem instanceof Method) + return getEncodingOfMethod((Method) mem); + else // Field + return getEncodingOfClass(((Field) mem).getType().getName(), true); + } +} // class TypeSignature diff --git a/libjava/classpath/gnu/java/lang/reflect/package.html b/libjava/classpath/gnu/java/lang/reflect/package.html new file mode 100644 index 0000000..a837d37 --- /dev/null +++ b/libjava/classpath/gnu/java/lang/reflect/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.lang.reflect package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.lang.reflect</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/locale/LocaleHelper.java b/libjava/classpath/gnu/java/locale/LocaleHelper.java new file mode 100644 index 0000000..ff00293 --- /dev/null +++ b/libjava/classpath/gnu/java/locale/LocaleHelper.java @@ -0,0 +1,158 @@ +/* LocaleHelper.java -- helper routines for localization + Copyright (C) 2004, 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.java.locale; + +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * This class provides common helper methods + * for handling localized data. + * + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * + * @see java.util.Locale + * @see java.util.ResourceBundle + */ +public class LocaleHelper +{ + /** + * This method is used by the localized name lookup methods to retrieve + * the localized name of a particular piece of locale data. + * If the display name can not be localized to the supplied + * locale, it will fall back on other output in the following order: + * + * <ul> + * <li>the localized name in the default locale</li> + * <li>the localized name in English (optional)</li> + * <li>the localized name in the root locale bundle (optional)</li> + * <li>the localized input string</li> + * </ul> + * <p> + * If the supplied key is merely the empty string, then the empty string is + * returned. + * </p> + * + * @param inLocale the locale to use for formatting the display string. + * @param key the locale data used as a key to the localized lookup tables. + * @param name the name of the hashtable containing the localized data. + * @param checkEnglish true if the method should fall back on data + * from the English locale. + * @param checkRoot true if the method should fall back on data from the + * unlocalized root locale. + * @return a <code>String</code>, hopefully containing the localized + * variant of the input data. + * @throws NullPointerException if <code>inLocale</code> is null. + */ + public static String getLocalizedString(Locale inLocale, String key, + String name, boolean checkEnglish, + boolean checkRoot) + { + String localizedString; + String property; + + if (key.equals("")) + return ""; + property = name + "." + key; + /* Localize to inLocale */ + try + { + localizedString = + ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + inLocale).getString(property); + } + catch (MissingResourceException exception) + { + localizedString = null; + } + /* Localize to default locale */ + if (localizedString == null) + { + try + { + ResourceBundle bundle; + + bundle = + ResourceBundle.getBundle("gnu.java.locale.LocaleInformation"); + localizedString = bundle.getString(property); + } + catch (MissingResourceException exception) + { + localizedString = null; + } + } + /* Localize to English */ + if (localizedString == null && checkEnglish) + { + try + { + localizedString = + ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + Locale.ENGLISH).getString(property); + } + catch (MissingResourceException exception) + { + localizedString = null; + } + } + /* Return unlocalized version */ + if (localizedString == null && checkRoot) + { + try + { + localizedString = + ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + new Locale("","","") + ).getString(property); + } + catch (MissingResourceException exception) + { + localizedString = null; + } + } + /* Return original input string */ + if (localizedString == null) + { + localizedString = key; + } + return localizedString; + } +} + diff --git a/libjava/classpath/gnu/java/locale/package.html b/libjava/classpath/gnu/java/locale/package.html new file mode 100644 index 0000000..c4bc7c3 --- /dev/null +++ b/libjava/classpath/gnu/java/locale/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.locale package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.locale</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/math/MPN.java b/libjava/classpath/gnu/java/math/MPN.java new file mode 100644 index 0000000..05491bb --- /dev/null +++ b/libjava/classpath/gnu/java/math/MPN.java @@ -0,0 +1,771 @@ +/* gnu.java.math.MPN + Copyright (C) 1999, 2000, 2001, 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. */ + +// Included from Kawa 1.6.62 with permission of the author, +// Per Bothner <per@bothner.com>. + +package gnu.java.math; + +/** This contains various low-level routines for unsigned bigints. + * The interfaces match the mpn interfaces in gmp, + * so it should be easy to replace them with fast native functions + * that are trivial wrappers around the mpn_ functions in gmp + * (at least on platforms that use 32-bit "limbs"). + */ + +public class MPN +{ + /** Add x[0:size-1] and y, and write the size least + * significant words of the result to dest. + * Return carry, either 0 or 1. + * All values are unsigned. + * This is basically the same as gmp's mpn_add_1. */ + public static int add_1 (int[] dest, int[] x, int size, int y) + { + long carry = (long) y & 0xffffffffL; + for (int i = 0; i < size; i++) + { + carry += ((long) x[i] & 0xffffffffL); + dest[i] = (int) carry; + carry >>= 32; + } + return (int) carry; + } + + /** Add x[0:len-1] and y[0:len-1] and write the len least + * significant words of the result to dest[0:len-1]. + * All words are treated as unsigned. + * @return the carry, either 0 or 1 + * This function is basically the same as gmp's mpn_add_n. + */ + public static int add_n (int dest[], int[] x, int[] y, int len) + { + long carry = 0; + for (int i = 0; i < len; i++) + { + carry += ((long) x[i] & 0xffffffffL) + + ((long) y[i] & 0xffffffffL); + dest[i] = (int) carry; + carry >>>= 32; + } + return (int) carry; + } + + /** Subtract Y[0:size-1] from X[0:size-1], and write + * the size least significant words of the result to dest[0:size-1]. + * Return borrow, either 0 or 1. + * This is basically the same as gmp's mpn_sub_n function. + */ + + public static int sub_n (int[] dest, int[] X, int[] Y, int size) + { + int cy = 0; + for (int i = 0; i < size; i++) + { + int y = Y[i]; + int x = X[i]; + y += cy; /* add previous carry to subtrahend */ + // Invert the high-order bit, because: (unsigned) X > (unsigned) Y + // iff: (int) (X^0x80000000) > (int) (Y^0x80000000). + cy = (y^0x80000000) < (cy^0x80000000) ? 1 : 0; + y = x - y; + cy += (y^0x80000000) > (x ^ 0x80000000) ? 1 : 0; + dest[i] = y; + } + return cy; + } + + /** Multiply x[0:len-1] by y, and write the len least + * significant words of the product to dest[0:len-1]. + * Return the most significant word of the product. + * All values are treated as if they were unsigned + * (i.e. masked with 0xffffffffL). + * OK if dest==x (not sure if this is guaranteed for mpn_mul_1). + * This function is basically the same as gmp's mpn_mul_1. + */ + + public static int mul_1 (int[] dest, int[] x, int len, int y) + { + long yword = (long) y & 0xffffffffL; + long carry = 0; + for (int j = 0; j < len; j++) + { + carry += ((long) x[j] & 0xffffffffL) * yword; + dest[j] = (int) carry; + carry >>>= 32; + } + return (int) carry; + } + + /** + * Multiply x[0:xlen-1] and y[0:ylen-1], and + * write the result to dest[0:xlen+ylen-1]. + * The destination has to have space for xlen+ylen words, + * even if the result might be one limb smaller. + * This function requires that xlen >= ylen. + * The destination must be distinct from either input operands. + * All operands are unsigned. + * This function is basically the same gmp's mpn_mul. */ + + public static void mul (int[] dest, + int[] x, int xlen, + int[] y, int ylen) + { + dest[xlen] = MPN.mul_1 (dest, x, xlen, y[0]); + + for (int i = 1; i < ylen; i++) + { + long yword = (long) y[i] & 0xffffffffL; + long carry = 0; + for (int j = 0; j < xlen; j++) + { + carry += ((long) x[j] & 0xffffffffL) * yword + + ((long) dest[i+j] & 0xffffffffL); + dest[i+j] = (int) carry; + carry >>>= 32; + } + dest[i+xlen] = (int) carry; + } + } + + /* Divide (unsigned long) N by (unsigned int) D. + * Returns (remainder << 32)+(unsigned int)(quotient). + * Assumes (unsigned int)(N>>32) < (unsigned int)D. + * Code transcribed from gmp-2.0's mpn_udiv_w_sdiv function. + */ + public static long udiv_qrnnd (long N, int D) + { + long q, r; + long a1 = N >>> 32; + long a0 = N & 0xffffffffL; + if (D >= 0) + { + if (a1 < ((D - a1 - (a0 >>> 31)) & 0xffffffffL)) + { + /* dividend, divisor, and quotient are nonnegative */ + q = N / D; + r = N % D; + } + else + { + /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ + long c = N - ((long) D << 31); + /* Divide (c1*2^32 + c0) by d */ + q = c / D; + r = c % D; + /* Add 2^31 to quotient */ + q += 1 << 31; + } + } + else + { + long b1 = D >>> 1; /* d/2, between 2^30 and 2^31 - 1 */ + //long c1 = (a1 >> 1); /* A/2 */ + //int c0 = (a1 << 31) + (a0 >> 1); + long c = N >>> 1; + if (a1 < b1 || (a1 >> 1) < b1) + { + if (a1 < b1) + { + q = c / b1; + r = c % b1; + } + else /* c1 < b1, so 2^31 <= (A/2)/b1 < 2^32 */ + { + c = ~(c - (b1 << 32)); + q = c / b1; /* (A/2) / (d/2) */ + r = c % b1; + q = (~q) & 0xffffffffL; /* (A/2)/b1 */ + r = (b1 - 1) - r; /* r < b1 => new r >= 0 */ + } + r = 2 * r + (a0 & 1); + if ((D & 1) != 0) + { + if (r >= q) { + r = r - q; + } else if (q - r <= ((long) D & 0xffffffffL)) { + r = r - q + D; + q -= 1; + } else { + r = r - q + D + D; + q -= 2; + } + } + } + else /* Implies c1 = b1 */ + { /* Hence a1 = d - 1 = 2*b1 - 1 */ + if (a0 >= ((long)(-D) & 0xffffffffL)) + { + q = -1; + r = a0 + D; + } + else + { + q = -2; + r = a0 + D + D; + } + } + } + + return (r << 32) | (q & 0xFFFFFFFFl); + } + + /** Divide divident[0:len-1] by (unsigned int)divisor. + * Write result into quotient[0:len-1. + * Return the one-word (unsigned) remainder. + * OK for quotient==dividend. + */ + + public static int divmod_1 (int[] quotient, int[] dividend, + int len, int divisor) + { + int i = len - 1; + long r = dividend[i]; + if ((r & 0xffffffffL) >= ((long)divisor & 0xffffffffL)) + r = 0; + else + { + quotient[i--] = 0; + r <<= 32; + } + + for (; i >= 0; i--) + { + int n0 = dividend[i]; + r = (r & ~0xffffffffL) | (n0 & 0xffffffffL); + r = udiv_qrnnd (r, divisor); + quotient[i] = (int) r; + } + return (int)(r >> 32); + } + + /* Subtract x[0:len-1]*y from dest[offset:offset+len-1]. + * All values are treated as if unsigned. + * @return the most significant word of + * the product, minus borrow-out from the subtraction. + */ + public static int submul_1 (int[] dest, int offset, int[] x, int len, int y) + { + long yl = (long) y & 0xffffffffL; + int carry = 0; + int j = 0; + do + { + long prod = ((long) x[j] & 0xffffffffL) * yl; + int prod_low = (int) prod; + int prod_high = (int) (prod >> 32); + prod_low += carry; + // Invert the high-order bit, because: (unsigned) X > (unsigned) Y + // iff: (int) (X^0x80000000) > (int) (Y^0x80000000). + carry = ((prod_low ^ 0x80000000) < (carry ^ 0x80000000) ? 1 : 0) + + prod_high; + int x_j = dest[offset+j]; + prod_low = x_j - prod_low; + if ((prod_low ^ 0x80000000) > (x_j ^ 0x80000000)) + carry++; + dest[offset+j] = prod_low; + } + while (++j < len); + return carry; + } + + /** Divide zds[0:nx] by y[0:ny-1]. + * The remainder ends up in zds[0:ny-1]. + * The quotient ends up in zds[ny:nx]. + * Assumes: nx>ny. + * (int)y[ny-1] < 0 (i.e. most significant bit set) + */ + + public static void divide (int[] zds, int nx, int[] y, int ny) + { + // This is basically Knuth's formulation of the classical algorithm, + // but translated from in scm_divbigbig in Jaffar's SCM implementation. + + // Correspondance with Knuth's notation: + // Knuth's u[0:m+n] == zds[nx:0]. + // Knuth's v[1:n] == y[ny-1:0] + // Knuth's n == ny. + // Knuth's m == nx-ny. + // Our nx == Knuth's m+n. + + // Could be re-implemented using gmp's mpn_divrem: + // zds[nx] = mpn_divrem (&zds[ny], 0, zds, nx, y, ny). + + int j = nx; + do + { // loop over digits of quotient + // Knuth's j == our nx-j. + // Knuth's u[j:j+n] == our zds[j:j-ny]. + int qhat; // treated as unsigned + if (zds[j]==y[ny-1]) + qhat = -1; // 0xffffffff + else + { + long w = (((long)(zds[j])) << 32) + ((long)zds[j-1] & 0xffffffffL); + qhat = (int) udiv_qrnnd (w, y[ny-1]); + } + if (qhat != 0) + { + int borrow = submul_1 (zds, j - ny, y, ny, qhat); + int save = zds[j]; + long num = ((long)save&0xffffffffL) - ((long)borrow&0xffffffffL); + while (num != 0) + { + qhat--; + long carry = 0; + for (int i = 0; i < ny; i++) + { + carry += ((long) zds[j-ny+i] & 0xffffffffL) + + ((long) y[i] & 0xffffffffL); + zds[j-ny+i] = (int) carry; + carry >>>= 32; + } + zds[j] += carry; + num = carry - 1; + } + } + zds[j] = qhat; + } while (--j >= ny); + } + + /** Number of digits in the conversion base that always fits in a word. + * For example, for base 10 this is 9, since 10**9 is the + * largest number that fits into a words (assuming 32-bit words). + * This is the same as gmp's __mp_bases[radix].chars_per_limb. + * @param radix the base + * @return number of digits */ + public static int chars_per_word (int radix) + { + if (radix < 10) + { + if (radix < 8) + { + if (radix <= 2) + return 32; + else if (radix == 3) + return 20; + else if (radix == 4) + return 16; + else + return 18 - radix; + } + else + return 10; + } + else if (radix < 12) + return 9; + else if (radix <= 16) + return 8; + else if (radix <= 23) + return 7; + else if (radix <= 40) + return 6; + // The following are conservative, but we don't care. + else if (radix <= 256) + return 4; + else + return 1; + } + + /** Count the number of leading zero bits in an int. */ + public static int count_leading_zeros (int i) + { + if (i == 0) + return 32; + int count = 0; + for (int k = 16; k > 0; k = k >> 1) { + int j = i >>> k; + if (j == 0) + count += k; + else + i = j; + } + return count; + } + + public static int set_str (int dest[], byte[] str, int str_len, int base) + { + int size = 0; + if ((base & (base - 1)) == 0) + { + // The base is a power of 2. Read the input string from + // least to most significant character/digit. */ + + int next_bitpos = 0; + int bits_per_indigit = 0; + for (int i = base; (i >>= 1) != 0; ) bits_per_indigit++; + int res_digit = 0; + + for (int i = str_len; --i >= 0; ) + { + int inp_digit = str[i]; + res_digit |= inp_digit << next_bitpos; + next_bitpos += bits_per_indigit; + if (next_bitpos >= 32) + { + dest[size++] = res_digit; + next_bitpos -= 32; + res_digit = inp_digit >> (bits_per_indigit - next_bitpos); + } + } + + if (res_digit != 0) + dest[size++] = res_digit; + } + else + { + // General case. The base is not a power of 2. + int indigits_per_limb = MPN.chars_per_word (base); + int str_pos = 0; + + while (str_pos < str_len) + { + int chunk = str_len - str_pos; + if (chunk > indigits_per_limb) + chunk = indigits_per_limb; + int res_digit = str[str_pos++]; + int big_base = base; + + while (--chunk > 0) + { + res_digit = res_digit * base + str[str_pos++]; + big_base *= base; + } + + int cy_limb; + if (size == 0) + cy_limb = res_digit; + else + { + cy_limb = MPN.mul_1 (dest, dest, size, big_base); + cy_limb += MPN.add_1 (dest, dest, size, res_digit); + } + if (cy_limb != 0) + dest[size++] = cy_limb; + } + } + return size; + } + + /** Compare x[0:size-1] with y[0:size-1], treating them as unsigned integers. + * @result -1, 0, or 1 depending on if x<y, x==y, or x>y. + * This is basically the same as gmp's mpn_cmp function. + */ + public static int cmp (int[] x, int[] y, int size) + { + while (--size >= 0) + { + int x_word = x[size]; + int y_word = y[size]; + if (x_word != y_word) + { + // Invert the high-order bit, because: + // (unsigned) X > (unsigned) Y iff + // (int) (X^0x80000000) > (int) (Y^0x80000000). + return (x_word ^ 0x80000000) > (y_word ^0x80000000) ? 1 : -1; + } + } + return 0; + } + + /** + * Compare x[0:xlen-1] with y[0:ylen-1], treating them as unsigned integers. + * + * @return -1, 0, or 1 depending on if x<y, x==y, or x>y. + */ + public static int cmp (int[] x, int xlen, int[] y, int ylen) + { + return xlen > ylen ? 1 : xlen < ylen ? -1 : cmp (x, y, xlen); + } + + /** + * Shift x[x_start:x_start+len-1] count bits to the "right" + * (i.e. divide by 2**count). + * Store the len least significant words of the result at dest. + * The bits shifted out to the right are returned. + * OK if dest==x. + * Assumes: 0 < count < 32 + */ + public static int rshift (int[] dest, int[] x, int x_start, + int len, int count) + { + int count_2 = 32 - count; + int low_word = x[x_start]; + int retval = low_word << count_2; + int i = 1; + for (; i < len; i++) + { + int high_word = x[x_start+i]; + dest[i-1] = (low_word >>> count) | (high_word << count_2); + low_word = high_word; + } + dest[i-1] = low_word >>> count; + return retval; + } + + /** + * Shift x[x_start:x_start+len-1] count bits to the "right" + * (i.e. divide by 2**count). + * Store the len least significant words of the result at dest. + * OK if dest==x. + * Assumes: 0 <= count < 32 + * Same as rshift, but handles count==0 (and has no return value). + */ + public static void rshift0 (int[] dest, int[] x, int x_start, + int len, int count) + { + if (count > 0) + rshift(dest, x, x_start, len, count); + else + for (int i = 0; i < len; i++) + dest[i] = x[i + x_start]; + } + + /** Return the long-truncated value of right shifting. + * @param x a two's-complement "bignum" + * @param len the number of significant words in x + * @param count the shift count + * @return (long)(x[0..len-1] >> count). + */ + public static long rshift_long (int[] x, int len, int count) + { + int wordno = count >> 5; + count &= 31; + int sign = x[len-1] < 0 ? -1 : 0; + int w0 = wordno >= len ? sign : x[wordno]; + wordno++; + int w1 = wordno >= len ? sign : x[wordno]; + if (count != 0) + { + wordno++; + int w2 = wordno >= len ? sign : x[wordno]; + w0 = (w0 >>> count) | (w1 << (32-count)); + w1 = (w1 >>> count) | (w2 << (32-count)); + } + return ((long)w1 << 32) | ((long)w0 & 0xffffffffL); + } + + /* Shift x[0:len-1] left by count bits, and store the len least + * significant words of the result in dest[d_offset:d_offset+len-1]. + * Return the bits shifted out from the most significant digit. + * Assumes 0 < count < 32. + * OK if dest==x. + */ + + public static int lshift (int[] dest, int d_offset, + int[] x, int len, int count) + { + int count_2 = 32 - count; + int i = len - 1; + int high_word = x[i]; + int retval = high_word >>> count_2; + d_offset++; + while (--i >= 0) + { + int low_word = x[i]; + dest[d_offset+i] = (high_word << count) | (low_word >>> count_2); + high_word = low_word; + } + dest[d_offset+i] = high_word << count; + return retval; + } + + /** Return least i such that word & (1<<i). Assumes word!=0. */ + + public static int findLowestBit (int word) + { + int i = 0; + while ((word & 0xF) == 0) + { + word >>= 4; + i += 4; + } + if ((word & 3) == 0) + { + word >>= 2; + i += 2; + } + if ((word & 1) == 0) + i += 1; + return i; + } + + /** Return least i such that words & (1<<i). Assumes there is such an i. */ + + public static int findLowestBit (int[] words) + { + for (int i = 0; ; i++) + { + if (words[i] != 0) + return 32 * i + findLowestBit (words[i]); + } + } + + /** Calculate Greatest Common Divisior of x[0:len-1] and y[0:len-1]. + * Assumes both arguments are non-zero. + * Leaves result in x, and returns len of result. + * Also destroys y (actually sets it to a copy of the result). */ + + public static int gcd (int[] x, int[] y, int len) + { + int i, word; + // Find sh such that both x and y are divisible by 2**sh. + for (i = 0; ; i++) + { + word = x[i] | y[i]; + if (word != 0) + { + // Must terminate, since x and y are non-zero. + break; + } + } + int initShiftWords = i; + int initShiftBits = findLowestBit (word); + // Logically: sh = initShiftWords * 32 + initShiftBits + + // Temporarily devide both x and y by 2**sh. + len -= initShiftWords; + MPN.rshift0 (x, x, initShiftWords, len, initShiftBits); + MPN.rshift0 (y, y, initShiftWords, len, initShiftBits); + + int[] odd_arg; /* One of x or y which is odd. */ + int[] other_arg; /* The other one can be even or odd. */ + if ((x[0] & 1) != 0) + { + odd_arg = x; + other_arg = y; + } + else + { + odd_arg = y; + other_arg = x; + } + + for (;;) + { + // Shift other_arg until it is odd; this doesn't + // affect the gcd, since we divide by 2**k, which does not + // divide odd_arg. + for (i = 0; other_arg[i] == 0; ) i++; + if (i > 0) + { + int j; + for (j = 0; j < len-i; j++) + other_arg[j] = other_arg[j+i]; + for ( ; j < len; j++) + other_arg[j] = 0; + } + i = findLowestBit(other_arg[0]); + if (i > 0) + MPN.rshift (other_arg, other_arg, 0, len, i); + + // Now both odd_arg and other_arg are odd. + + // Subtract the smaller from the larger. + // This does not change the result, since gcd(a-b,b)==gcd(a,b). + i = MPN.cmp(odd_arg, other_arg, len); + if (i == 0) + break; + if (i > 0) + { // odd_arg > other_arg + MPN.sub_n (odd_arg, odd_arg, other_arg, len); + // Now odd_arg is even, so swap with other_arg; + int[] tmp = odd_arg; odd_arg = other_arg; other_arg = tmp; + } + else + { // other_arg > odd_arg + MPN.sub_n (other_arg, other_arg, odd_arg, len); + } + while (odd_arg[len-1] == 0 && other_arg[len-1] == 0) + len--; + } + if (initShiftWords + initShiftBits > 0) + { + if (initShiftBits > 0) + { + int sh_out = MPN.lshift (x, initShiftWords, x, len, initShiftBits); + if (sh_out != 0) + x[(len++)+initShiftWords] = sh_out; + } + else + { + for (i = len; --i >= 0;) + x[i+initShiftWords] = x[i]; + } + for (i = initShiftWords; --i >= 0; ) + x[i] = 0; + len += initShiftWords; + } + return len; + } + + public static int intLength (int i) + { + return 32 - count_leading_zeros (i < 0 ? ~i : i); + } + + /** Calcaulte the Common Lisp "integer-length" function. + * Assumes input is canonicalized: len==BigInteger.wordsNeeded(words,len) */ + public static int intLength (int[] words, int len) + { + len--; + return intLength (words[len]) + 32 * len; + } + + /* DEBUGGING: + public static void dprint (BigInteger x) + { + if (x.words == null) + System.err.print(Long.toString((long) x.ival & 0xffffffffL, 16)); + else + dprint (System.err, x.words, x.ival); + } + public static void dprint (int[] x) { dprint (System.err, x, x.length); } + public static void dprint (int[] x, int len) { dprint (System.err, x, len); } + public static void dprint (java.io.PrintStream ps, int[] x, int len) + { + ps.print('('); + for (int i = 0; i < len; i++) + { + if (i > 0) + ps.print (' '); + ps.print ("#x" + Long.toString ((long) x[i] & 0xffffffffL, 16)); + } + ps.print(')'); + } + */ +} diff --git a/libjava/classpath/gnu/java/math/package.html b/libjava/classpath/gnu/java/math/package.html new file mode 100644 index 0000000..97e1018 --- /dev/null +++ b/libjava/classpath/gnu/java/math/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.math package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.math</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/net/BASE64.java b/libjava/classpath/gnu/java/net/BASE64.java new file mode 100644 index 0000000..901aa0c --- /dev/null +++ b/libjava/classpath/gnu/java/net/BASE64.java @@ -0,0 +1,190 @@ +/* BASE.java -- + Copyright (C) 2003, 2004, 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.java.net; + +/** + * Encodes and decodes text according to the BASE64 encoding. + * + * @author Chris Burdess (dog@gnu.org) + */ +public final class BASE64 +{ + private static final byte[] src = { + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x2b, 0x2f + }; + + private static final byte[] dst; + static + { + dst = new byte[0x100]; + for (int i = 0x0; i < 0xff; i++) + { + dst[i] = -1; + } + for (int i = 0; i < src.length; i++) + { + dst[src[i]] = (byte) i; + } + } + + private BASE64() + { + } + + /** + * Encode the specified byte array using the BASE64 algorithm. + * + * @param bs the source byte array + */ + public static byte[] encode(byte[] bs) + { + int si = 0, ti = 0; // source/target array indices + byte[] bt = new byte[((bs.length + 2) * 4) / 3]; // target byte array + for (; si < bs.length; si += 3) + { + int buflen = bs.length - si; + if (buflen == 1) + { + byte b = bs[si]; + int i = 0; + bt[ti++] = src[b >>> 2 & 0x3f]; + bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)]; + } + else if (buflen == 2) + { + byte b1 = bs[si], b2 = bs[si + 1]; + int i = 0; + bt[ti++] = src[b1 >>> 2 & 0x3f]; + bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)]; + bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)]; + } + else + { + byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2]; + bt[ti++] = src[b1 >>> 2 & 0x3f]; + bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)]; + bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)]; + bt[ti++] = src[b3 & 0x3f]; + } + } + if (ti < bt.length) + { + byte[] tmp = new byte[ti]; + System.arraycopy(bt, 0, tmp, 0, ti); + bt = tmp; + } + /*while (ti < bt.length) + { + bt[ti++] = 0x3d; + }*/ + return bt; + } + + /** + * Decode the specified byte array using the BASE64 algorithm. + * + * @param bs the source byte array + */ + public static byte[] decode(byte[] bs) + { + int srclen = bs.length; + while (srclen > 0 && bs[srclen - 1] == 0x3d) + { + srclen--; /* strip padding character */ + } + byte[] buffer = new byte[srclen]; + int buflen = 0; + int si = 0; + int len = srclen - si; + while (len > 0) + { + byte b0 = dst[bs[si++] & 0xff]; + byte b2 = dst[bs[si++] & 0xff]; + buffer[buflen++] = (byte) (b0 << 2 & 0xfc | b2 >>> 4 & 0x3); + if (len > 2) + { + b0 = b2; + b2 = dst[bs[si++] & 0xff]; + buffer[buflen++] = (byte) (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf); + if (len > 3) + { + b0 = b2; + b2 = dst[bs[si++] & 0xff]; + buffer[buflen++] = (byte) (b0 << 6 & 0xc0 | b2 & 0x3f); + } + } + len = srclen - si; + } + byte[] bt = new byte[buflen]; + System.arraycopy(buffer, 0, bt, 0, buflen); + return bt; + } + + public static void main(String[] args) + { + boolean decode = false; + for (int i = 0; i < args.length; i++) + { + if (args[i].equals("-d")) + { + decode = true; + } + else + { + try + { + byte[] in = args[i].getBytes("US-ASCII"); + byte[] out = decode ? decode(in) : encode(in); + System.out.println(args[i] + " = " + + new String(out, "US-ASCII")); + } + catch (java.io.UnsupportedEncodingException e) + { + e.printStackTrace(System.err); + } + } + } + } +} diff --git a/libjava/classpath/gnu/java/net/CRLFInputStream.java b/libjava/classpath/gnu/java/net/CRLFInputStream.java new file mode 100644 index 0000000..d0f9e8c --- /dev/null +++ b/libjava/classpath/gnu/java/net/CRLFInputStream.java @@ -0,0 +1,174 @@ +/* CRLFInputStream.java -- + Copyright (C) 2002, 2003, 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.java.net; + +import java.io.BufferedInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream that filters out CR/LF pairs into LFs. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class CRLFInputStream + extends FilterInputStream +{ + /** + * The CR octet. + */ + public static final int CR = 13; + + /** + * The LF octet. + */ + public static final int LF = 10; + + private boolean doReset; + + /** + * Constructs a CR/LF input stream connected to the specified input + * stream. + */ + public CRLFInputStream(InputStream in) + { + super(in.markSupported() ? in : new BufferedInputStream(in)); + } + + /** + * Reads the next byte of data from this input stream. + * Returns -1 if the end of the stream has been reached. + * @exception IOException if an I/O error occurs + */ + public int read() + throws IOException + { + int c = in.read(); + if (c == CR) + { + in.mark(1); + int d = in.read(); + if (d == LF) + { + c = d; + } + else + { + in.reset(); + } + } + return c; + } + + /** + * Reads up to b.length bytes of data from this input stream into + * an array of bytes. + * Returns -1 if the end of the stream has been reached. + * @exception IOException if an I/O error occurs + */ + public int read(byte[] b) + throws IOException + { + return read(b, 0, b.length); + } + + /** + * Reads up to len bytes of data from this input stream into an + * array of bytes, starting at the specified offset. + * Returns -1 if the end of the stream has been reached. + * @exception IOException if an I/O error occurs + */ + public int read(byte[] b, int off, int len) + throws IOException + { + in.mark(len + 1); + int l = in.read(b, off, len); + if (l > 0) + { + int i = indexOfCRLF(b, off, l); + if (doReset) + { + in.reset(); + if (i != -1) + { + l = in.read(b, off, i + 1); // read to CR + in.read(); // skip LF + b[i] = LF; // fix CR as LF + } + else + { + l = in.read(b, off, len); // CR(s) but no LF + } + } + } + return l; + } + + private int indexOfCRLF(byte[] b, int off, int len) + throws IOException + { + doReset = false; + int lm1 = len - 1; + for (int i = off; i < len; i++) + { + if (b[i] == CR) + { + int d; + if (i == lm1) + { + d = in.read(); + doReset = true; + } + else + { + d = b[i + 1]; + } + if (d == LF) + { + doReset = true; + return i; + } + } + } + return -1; + } + +} + diff --git a/libjava/classpath/gnu/java/net/CRLFOutputStream.java b/libjava/classpath/gnu/java/net/CRLFOutputStream.java new file mode 100644 index 0000000..f27e0f2 --- /dev/null +++ b/libjava/classpath/gnu/java/net/CRLFOutputStream.java @@ -0,0 +1,183 @@ +/* CRLFOutputStream.java -- + Copyright (C) 2002, 2003, 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.java.net; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +/** + * An output stream that filters LFs into CR/LF pairs. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class CRLFOutputStream + extends FilterOutputStream +{ + static final String US_ASCII = "US-ASCII"; + + /** + * The CR octet. + */ + public static final int CR = 13; + + /** + * The LF octet. + */ + public static final int LF = 10; + + /** + * The CR/LF pair. + */ + public static final byte[] CRLF = { CR, LF }; + + /** + * The last byte read. + */ + protected int last; + + /** + * Constructs a CR/LF output stream connected to the specified output stream. + */ + public CRLFOutputStream(OutputStream out) + { + super(out); + last = -1; + } + + /** + * Writes a character to the underlying stream. + * @exception IOException if an I/O error occurred + */ + public void write(int ch) throws IOException + { + if (ch == CR) + { + out.write(CRLF); + } + else if (ch == LF) + { + if (last != CR) + { + out.write(CRLF); + } + } + else + { + out.write(ch); + } + last = ch; + } + + /** + * Writes a byte array to the underlying stream. + * @exception IOException if an I/O error occurred + */ + public void write(byte[] b) + throws IOException + { + write(b, 0, b.length); + } + + /** + * Writes a portion of a byte array to the underlying stream. + * @exception IOException if an I/O error occurred + */ + public void write(byte[] b, int off, int len) + throws IOException + { + int d = off; + len += off; + for (int i = off; i < len; i++) + { + switch (b[i]) + { + case CR: + out.write (b, d, i - d); + out.write (CRLF, 0, 2); + d = i + 1; + break; + case LF: + if (last != CR) + { + out.write (b, d, i - d); + out.write (CRLF, 0, 2); + } + d = i + 1; + break; + } + last = b[i]; + } + if (len - d > 0) + { + out.write (b, d, len - d); + } + } + + /** + * Writes the specified ASCII string to the underlying stream. + * @exception IOException if an I/O error occurred + */ + public void write(String text) + throws IOException + { + try + { + byte[] bytes = text.getBytes(US_ASCII); + write(bytes, 0, bytes.length); + } + catch (UnsupportedEncodingException e) + { + throw new IOException("The US-ASCII encoding is not supported " + + "on this system"); + } + } + + /** + * Writes a newline to the underlying stream. + * @exception IOException if an I/O error occurred + */ + public void writeln() + throws IOException + { + out.write(CRLF, 0, 2); + } +} + diff --git a/libjava/classpath/gnu/java/net/EmptyX509TrustManager.java b/libjava/classpath/gnu/java/net/EmptyX509TrustManager.java new file mode 100644 index 0000000..b8faf41 --- /dev/null +++ b/libjava/classpath/gnu/java/net/EmptyX509TrustManager.java @@ -0,0 +1,70 @@ +/* EmptyX509TrustManager.java -- + Copyright (C) 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.java.net; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.X509TrustManager; + +/** + * Empty implementation of an X509 trust manager. + * This implementation does not check any certificates in the chain. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class EmptyX509TrustManager + implements X509TrustManager +{ + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException + { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException + { + } + + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[0]; + } +} + diff --git a/libjava/classpath/gnu/java/net/GetLocalHostAction.java b/libjava/classpath/gnu/java/net/GetLocalHostAction.java new file mode 100644 index 0000000..7483b02 --- /dev/null +++ b/libjava/classpath/gnu/java/net/GetLocalHostAction.java @@ -0,0 +1,65 @@ +/* GetLocalHostAction.java -- + Copyright (C) 2003, 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.java.net; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.PrivilegedAction; + +/** + * Privileged action to retrieve the local host InetAddress. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class GetLocalHostAction + implements PrivilegedAction +{ + public Object run() + { + try + { + return InetAddress.getLocalHost(); + } + catch (UnknownHostException e) + { + return null; + } + } +} + diff --git a/libjava/classpath/gnu/java/net/HeaderFieldHelper.java b/libjava/classpath/gnu/java/net/HeaderFieldHelper.java new file mode 100644 index 0000000..0fb8d95 --- /dev/null +++ b/libjava/classpath/gnu/java/net/HeaderFieldHelper.java @@ -0,0 +1,138 @@ +/* HeaderFieldHelper.java -- Helps manage headers fields + Copyright (C) 1998, 2003 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.java.net; + +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +/** + * This class manages header field keys and values. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class HeaderFieldHelper +{ + private Vector headerFieldKeys; + private Vector headerFieldValues; + + public HeaderFieldHelper() + { + this (10); + } + + public HeaderFieldHelper (int size) + { + headerFieldKeys = new Vector (size); + headerFieldValues = new Vector (size); + } + + public void addHeaderField (String key, String value) + { + headerFieldKeys.addElement (key); + headerFieldValues.addElement (value); + } + + public String getHeaderFieldKeyByIndex (int index) + { + String key = null; + + try + { + key = (String) headerFieldKeys.elementAt (index); + } + catch (ArrayIndexOutOfBoundsException e) + { + } + + return key; + } + + public String getHeaderFieldValueByIndex(int index) + { + String value = null; + + try + { + value = (String) headerFieldValues.elementAt (index); + } + catch (ArrayIndexOutOfBoundsException e) + { + } + + return value; + } + + public String getHeaderFieldValueByKey(String key) + { + String value = null; + + try + { + value = (String) headerFieldValues.elementAt + (headerFieldKeys.indexOf(key)); + } + catch (ArrayIndexOutOfBoundsException e) + { + } + + return value; + } + + public Map getHeaderFields() + { + HashMap headers = new HashMap(); + int max = headerFieldKeys.size(); + + for (int index = 0; index < max; index++) + { + headers.put(headerFieldKeys.elementAt(index), + headerFieldValues.elementAt(index)); + } + + return headers; + } + + public int getNumberOfEntries() + { + return headerFieldKeys.size(); + } + +} // class HeaderFieldHelper + diff --git a/libjava/classpath/gnu/java/net/LineInputStream.java b/libjava/classpath/gnu/java/net/LineInputStream.java new file mode 100644 index 0000000..5ca0686 --- /dev/null +++ b/libjava/classpath/gnu/java/net/LineInputStream.java @@ -0,0 +1,198 @@ +/* LineInputStream.java -- + Copyright (C) 2002, 2003, 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.java.net; + +import java.io.ByteArrayOutputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream that can read lines of input. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class LineInputStream + extends FilterInputStream +{ + /* + * Line buffer. + */ + private ByteArrayOutputStream buf; + + /* + * Encoding to use when translating bytes to characters. + */ + private String encoding; + + /* + * End-of-stream flag. + */ + private boolean eof; + + /** + * Whether we can use block reads. + */ + private final boolean blockReads; + + /** + * Constructor using the US-ASCII character encoding. + * @param in the underlying input stream + */ + public LineInputStream(InputStream in) + { + this(in, "US-ASCII"); + } + + /** + * Constructor. + * @param in the underlying input stream + * @param encoding the character encoding to use + */ + public LineInputStream(InputStream in, String encoding) + { + super(in); + buf = new ByteArrayOutputStream(); + this.encoding = encoding; + eof = false; + blockReads = in.markSupported(); + } + + /** + * Read a line of input. + */ + public String readLine() + throws IOException + { + if (eof) + { + return null; + } + do + { + if (blockReads) + { + // Use mark and reset to read chunks of bytes + final int MIN_LENGTH = 1024; + int len, pos; + + len = in.available(); + len = (len < MIN_LENGTH) ? MIN_LENGTH : len; + byte[] b = new byte[len]; + in.mark(len); + // Read into buffer b + len = in.read(b, 0, len); + // Handle EOF + if (len == -1) + { + eof = true; + if (buf.size() == 0) + { + return null; + } + else + { + // We don't care about resetting buf + return buf.toString(encoding); + } + } + // Get index of LF in b + pos = indexOf(b, len, (byte) 0x0a); + if (pos != -1) + { + // Write pos bytes to buf + buf.write(b, 0, pos); + // Reset stream, and read pos + 1 bytes + in.reset(); + pos += 1; + while (pos > 0) + { + len = in.read(b, 0, pos); + pos = (len == -1) ? -1 : pos - len; + } + // Return line + String ret = buf.toString(encoding); + buf.reset(); + return ret; + } + else + { + // Append everything to buf and fall through to re-read. + buf.write(b, 0, len); + } + } + else + { + // We must use character reads in order not to read too much + // from the underlying stream. + int c = in.read(); + switch (c) + { + case -1: + eof = true; + if (buf.size() == 0) + { + return null; + } + // Fall through and return contents of buffer. + case 0x0a: // LF + String ret = buf.toString(encoding); + buf.reset(); + return ret; + default: + buf.write(c); + } + } + } + while (true); + } + + private int indexOf(byte[] b, int len, byte c) + { + for (int pos = 0; pos < len; pos++) + { + if (b[pos] == c) + { + return pos; + } + } + return -1; + } +} + diff --git a/libjava/classpath/gnu/java/net/PlainDatagramSocketImpl.java b/libjava/classpath/gnu/java/net/PlainDatagramSocketImpl.java new file mode 100644 index 0000000..339b556 --- /dev/null +++ b/libjava/classpath/gnu/java/net/PlainDatagramSocketImpl.java @@ -0,0 +1,321 @@ +/* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation + Copyright (C) 1998, 1999, 2001, 2003, 2004, 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.java.net; + +import gnu.classpath.Configuration; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocketImpl; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketAddress; +import java.net.SocketException; + +/** + * Written using on-line Java Platform 1.2 API Specification, as well + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). + * Status: Believed complete and correct. + */ + +/** + * This is the default socket implementation for datagram sockets. + * It makes native calls to C routines that implement BSD style + * SOCK_DGRAM sockets in the AF_INET family. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Warren Levy (warrenl@cygnus.com) + */ +public final class PlainDatagramSocketImpl extends DatagramSocketImpl +{ + // Static initializer to load native library + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javanet"); + } + } + + /** + * Option id for the IP_TTL (time to live) value. + */ + private static final int IP_TTL = 0x1E61; // 7777 + + /** + * This is the actual underlying file descriptor + */ + int native_fd = -1; + + /** + * Lock object to serialize threads wanting to receive + */ + private final Object RECEIVE_LOCK = new Object(); + + /** + * Lock object to serialize threads wanting to send + */ + private final Object SEND_LOCK = new Object(); + + /** + * Default do nothing constructor + */ + public PlainDatagramSocketImpl() + { + } + + protected void finalize() throws Throwable + { + synchronized (this) + { + if (native_fd != -1) + close(); + } + super.finalize(); + } + + public int getNativeFD() + { + return native_fd; + } + + /** + * Binds this socket to a particular port and interface + * + * @param port The port to bind to + * @param addr The address to bind to + * + * @exception SocketException If an error occurs + */ + protected synchronized native void bind(int port, InetAddress addr) + throws SocketException; + + /** + * Creates a new datagram socket + * + * @exception SocketException If an error occurs + */ + protected synchronized native void create() throws SocketException; + + /** + * Sets the Time to Live value for the socket + * + * @param ttl The new TTL value + * + * @exception IOException If an error occurs + */ + protected synchronized void setTimeToLive(int ttl) throws IOException + { + setOption(IP_TTL, new Integer(ttl)); + } + + /** + * Gets the Time to Live value for the socket + * + * @return The TTL value + * + * @exception IOException If an error occurs + */ + protected synchronized int getTimeToLive() throws IOException + { + Object obj = getOption(IP_TTL); + + if (! (obj instanceof Integer)) + throw new IOException("Internal Error"); + + return ((Integer) obj).intValue(); + } + + /** + * Sends a packet of data to a remote host + * + * @param addr The address to send to + * @param port The port to send to + * @param buf The buffer to send + * @param offset The offset of the data in the buffer to send + * @param len The length of the data to send + * + * @exception IOException If an error occurs + */ + private native void sendto (InetAddress addr, int port, + byte[] buf, int offset, int len) + throws IOException; + + /** + * Sends a packet of data to a remote host + * + * @param packet The packet to send + * + * @exception IOException If an error occurs + */ + protected void send(DatagramPacket packet) throws IOException + { + synchronized(SEND_LOCK) + { + sendto(packet.getAddress(), packet.getPort(), packet.getData(), + packet.getOffset(), packet.getLength()); + } + + } + + /** + * Receives a UDP packet from the network + * + * @param packet The packet to fill in with the data received + * + * @exception IOException IOException If an error occurs + */ + protected void receive(DatagramPacket packet) + throws IOException + { + synchronized(RECEIVE_LOCK) + { + receive0(packet); + } + } + + /** + * Native call to receive a UDP packet from the network + * + * @param packet The packet to fill in with the data received + * + * @exception IOException IOException If an error occurs + */ + private native void receive0(DatagramPacket packet) throws IOException; + + /** + * Sets the value of an option on the socket + * + * @param option_id The identifier of the option to set + * @param val The value of the option to set + * + * @exception SocketException If an error occurs + */ + public synchronized native void setOption(int option_id, Object val) + throws SocketException; + + /** + * Retrieves the value of an option on the socket + * + * @param option_id The identifier of the option to retrieve + * + * @return The value of the option + * + * @exception SocketException If an error occurs + */ + public synchronized native Object getOption(int option_id) + throws SocketException; + + /** + * Closes the socket + */ + protected synchronized native void close(); + + /** + * Gets the Time to Live value for the socket + * + * @return The TTL value + * + * @exception IOException If an error occurs + * + * @deprecated 1.2 + */ + protected synchronized byte getTTL() throws IOException + { + return (byte) getTimeToLive(); + } + + /** + * Sets the Time to Live value for the socket + * + * @param ttl The new TTL value + * + * @exception IOException If an error occurs + * + * @deprecated 1.2 + */ + protected synchronized void setTTL(byte ttl) throws IOException + { + setTimeToLive(((int) ttl) & 0xFF); + } + + /** + * Joins a multicast group + * + * @param addr The group to join + * + * @exception IOException If an error occurs + */ + protected synchronized native void join(InetAddress addr) throws IOException; + + /** + * Leaves a multicast group + * + * @param addr The group to leave + * + * @exception IOException If an error occurs + */ + protected synchronized native void leave(InetAddress addr) throws IOException; + + /** + * What does this method really do? + */ + protected synchronized int peek(InetAddress addr) throws IOException + { + throw new IOException("Not Implemented Yet"); + } + + public int peekData(DatagramPacket packet) + { + throw new InternalError + ("PlainDatagramSocketImpl::peekData is not implemented"); + } + + public void joinGroup(SocketAddress address, NetworkInterface netIf) + { + throw new InternalError + ("PlainDatagramSocketImpl::joinGroup is not implemented"); + } + + public void leaveGroup(SocketAddress address, NetworkInterface netIf) + { + throw new InternalError + ("PlainDatagramSocketImpl::leaveGroup is not implemented"); + } +} diff --git a/libjava/classpath/gnu/java/net/PlainSocketImpl.java b/libjava/classpath/gnu/java/net/PlainSocketImpl.java new file mode 100644 index 0000000..05221ff --- /dev/null +++ b/libjava/classpath/gnu/java/net/PlainSocketImpl.java @@ -0,0 +1,498 @@ +/* PlainSocketImpl.java -- Default socket implementation + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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.java.net; + +import gnu.classpath.Configuration; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImpl; +import java.net.SocketOptions; + +/** + * Written using on-line Java Platform 1.2 API Specification, as well + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). + * Status: Believed complete and correct. + */ + +/** + * Unless the application installs its own SocketImplFactory, this is the + * default socket implemetation that will be used. It simply uses a + * combination of Java and native routines to implement standard BSD + * style sockets of family AF_INET and types SOCK_STREAM and SOCK_DGRAM + * + * @author Per Bothner (bothner@cygnus.com) + * @author Nic Ferrier (nferrier@tapsellferrier.co.uk) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public final class PlainSocketImpl extends SocketImpl +{ + // Static initializer to load native library. + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javanet"); + } + } + + /** + * The OS file handle representing the socket. + * This is used for reads and writes to/from the socket and + * to close it. + * + * When the socket is closed this is reset to -1. + */ + int native_fd = -1; + + /** + * A cached copy of the in stream for reading from the socket. + */ + private InputStream in; + + /** + * A cached copy of the out stream for writing to the socket. + */ + private OutputStream out; + + /** + * Indicates whether a channel initiated whatever operation + * is being invoked on this socket. + */ + private boolean inChannelOperation; + + /** + * Indicates whether we should ignore whether any associated + * channel is set to non-blocking mode. Certain operations + * throw an <code>IllegalBlockingModeException</code> if the + * associated channel is in non-blocking mode, <i>except</i> + * if the operation is invoked by the channel itself. + */ + public final boolean isInChannelOperation() + { + return inChannelOperation; + } + + /** + * Sets our indicator of whether an I/O operation is being + * initiated by a channel. + */ + public final void setInChannelOperation(boolean b) + { + inChannelOperation = b; + } + + /** + * Default do nothing constructor + */ + public PlainSocketImpl() + { + } + + protected void finalize() throws Throwable + { + synchronized (this) + { + if (native_fd != -1) + try + { + close(); + } + catch (IOException ex) + { + } + } + super.finalize(); + } + + public int getNativeFD() + { + return native_fd; + } + + /** + * Sets the specified option on a socket to the passed in object. For + * options that take an integer argument, the passed in object is an + * Integer. The option_id parameter is one of the defined constants in + * this interface. + * + * @param option_id The identifier of the option + * @param val The value to set the option to + * + * @exception SocketException If an error occurs + */ + public native void setOption(int optID, Object value) throws SocketException; + + /** + * Returns the current setting of the specified option. The Object returned + * will be an Integer for options that have integer values. The option_id + * is one of the defined constants in this interface. + * + * @param option_id The option identifier + * + * @return The current value of the option + * + * @exception SocketException If an error occurs + */ + public native Object getOption(int optID) throws SocketException; + + /** + * Flushes the input stream and closes it. If you read from the input stream + * after calling this method a <code>IOException</code> will be thrown. + * + * @throws IOException if an error occurs + */ + public native void shutdownInput() throws IOException; + + /** + * Flushes the output stream and closes it. If you write to the output stream + * after calling this method a <code>IOException</code> will be thrown. + * + * @throws IOException if an error occurs + */ + public native void shutdownOutput() throws IOException; + + /** + * Creates a new socket that is not bound to any local address/port and + * is not connected to any remote address/port. This will be created as + * a stream socket if the stream parameter is true, or a datagram socket + * if the stream parameter is false. + * + * @param stream true for a stream socket, false for a datagram socket + */ + protected synchronized native void create(boolean stream) throws IOException; + + /** + * Connects to the remote hostname and port specified as arguments. + * + * @param hostname The remote hostname to connect to + * @param port The remote port to connect to + * + * @exception IOException If an error occurs + */ + protected synchronized void connect(String host, int port) throws IOException + { + connect(InetAddress.getByName(host), port); + } + + /** + * Connects to the remote address and port specified as arguments. + * + * @param addr The remote address to connect to + * @param port The remote port to connect to + * + * @exception IOException If an error occurs + */ + protected native void connect(InetAddress addr, int port) throws IOException; + + /** + * Connects to the remote socket address with a specified timeout. + * + * @param timeout The timeout to use for this connect, 0 means infinite. + * + * @exception IOException If an error occurs + */ + protected synchronized void connect(SocketAddress address, int timeout) throws IOException + { + InetSocketAddress sockAddr = (InetSocketAddress) address; + InetAddress addr = sockAddr.getAddress(); + + if (addr == null) + throw new IllegalArgumentException("address is unresolved: " + sockAddr); + + int port = sockAddr.getPort(); + + if (timeout < 0) + throw new IllegalArgumentException("negative timeout"); + + Object oldTimeoutObj = null; + + try + { + oldTimeoutObj = this.getOption (SocketOptions.SO_TIMEOUT); + this.setOption (SocketOptions.SO_TIMEOUT, new Integer (timeout)); + connect (addr, port); + } + finally + { + if (oldTimeoutObj != null) + this.setOption (SocketOptions.SO_TIMEOUT, oldTimeoutObj); + } + } + + /** + * Binds to the specified port on the specified addr. Note that this addr + * must represent a local IP address. **** How bind to INADDR_ANY? **** + * + * @param addr The address to bind to + * @param port The port number to bind to + * + * @exception IOException If an error occurs + */ + protected synchronized native void bind(InetAddress addr, int port) + throws IOException; + + /** + * Starts listening for connections on a socket. The queuelen parameter + * is how many pending connections will queue up waiting to be serviced + * before being accept'ed. If the queue of pending requests exceeds this + * number, additional connections will be refused. + * + * @param queuelen The length of the pending connection queue + * + * @exception IOException If an error occurs + */ + protected synchronized native void listen(int queuelen) + throws IOException; + + /** + * Accepts a new connection on this socket and returns in in the + * passed in SocketImpl. + * + * @param impl The SocketImpl object to accept this connection. + */ + protected synchronized native void accept(SocketImpl impl) + throws IOException; + + /** + * Returns the number of bytes that the caller can read from this socket + * without blocking. + * + * @return The number of readable bytes before blocking + * + * @exception IOException If an error occurs + */ + protected native int available() throws IOException; + + /** + * Closes the socket. This will cause any InputStream or OutputStream + * objects for this Socket to be closed as well. + * <p> + * Note that if the SO_LINGER option is set on this socket, then the + * operation could block. + * + * @exception IOException If an error occurs + */ + protected native void close() throws IOException; + + public void sendUrgentData(int data) + { + throw new InternalError ("PlainSocketImpl::sendUrgentData not implemented"); + } + + /** + * Internal method used by SocketInputStream for reading data from + * the connection. Reads up to len bytes of data into the buffer + * buf starting at offset bytes into the buffer. + * + * @return The actual number of bytes read or -1 if end of stream. + * + * @exception IOException If an error occurs + */ + protected native int read(byte[] buf, int offset, int len) + throws IOException; + + /** + * Internal method used by SocketOuputStream for writing data to + * the connection. Writes up to len bytes of data from the buffer + * buf starting at offset bytes into the buffer. + * + * @exception IOException If an error occurs + */ + protected native void write(byte[] buf, int offset, int len) + throws IOException; + + /** + * Returns an InputStream object for reading from this socket. This will + * be an instance of SocketInputStream. + * + * @return An input stream attached to the socket. + * + * @exception IOException If an error occurs + */ + protected synchronized InputStream getInputStream() throws IOException + { + if (in == null) + in = new SocketInputStream(); + + return in; + } + + /** + * Returns an OutputStream object for writing to this socket. This will + * be an instance of SocketOutputStream. + * + * @return An output stream attached to the socket. + * + * @exception IOException If an error occurs + */ + protected synchronized OutputStream getOutputStream() throws IOException + { + if (out == null) + out = new SocketOutputStream(); + + return out; + } + + /** + * This class contains an implementation of <code>InputStream</code> for + * sockets. It in an internal only class used by <code>PlainSocketImpl</code>. + * + * @author Nic Ferrier (nferrier@tapsellferrier.co.uk) + */ + final class SocketInputStream + extends InputStream + { + /** + * Returns the number of bytes available to be read before blocking + */ + public int available() throws IOException + { + return PlainSocketImpl.this.available(); + } + + /** + * This method not only closes the stream, it closes the underlying socket + * (and thus any connection) and invalidates any other Input/Output streams + * for the underlying impl object + */ + public void close() throws IOException + { + PlainSocketImpl.this.close(); + } + + /** + * Reads the next byte of data and returns it as an int. + * + * @return The byte read (as an int) or -1 if end of stream); + * + * @exception IOException If an error occurs. + */ + public int read() throws IOException + { + byte buf[] = new byte [1]; + int bytes_read = read(buf, 0, 1); + + if (bytes_read == -1) + return -1; + + return buf[0] & 0xFF; + } + + /** + * Reads up to len bytes of data into the caller supplied buffer starting + * at offset bytes from the start of the buffer + * + * @param buf The buffer + * @param offset Offset into the buffer to start reading from + * @param len The number of bytes to read + * + * @return The number of bytes actually read or -1 if end of stream + * + * @exception IOException If an error occurs. + */ + public int read (byte[] buf, int offset, int len) throws IOException + { + int bytes_read = PlainSocketImpl.this.read (buf, offset, len); + + if (bytes_read == 0) + return -1; + + return bytes_read; + } + } + + /** + * This class is used internally by <code>PlainSocketImpl</code> to be the + * <code>OutputStream</code> subclass returned by its + * <code>getOutputStream method</code>. It expects only to be used in that + * context. + * + * @author Nic Ferrier (nferrier@tapsellferrier.co.uk) + */ + final class SocketOutputStream + extends OutputStream + { + /** + * This method closes the stream and the underlying socket connection. This + * action also effectively closes any other InputStream or OutputStream + * object associated with the connection. + * + * @exception IOException If an error occurs + */ + public void close() throws IOException + { + PlainSocketImpl.this.close(); + } + + /** + * Writes a byte (passed in as an int) to the given output stream + * + * @param b The byte to write + * + * @exception IOException If an error occurs + */ + public void write(int b) throws IOException + { + byte buf[] = { (byte) b }; + write(buf, 0, 1); + } + + /** + * Writes len number of bytes from the array buf to the stream starting + * at offset bytes into the buffer. + * + * @param buf The buffer + * @param offset Offset into the buffer to start writing from + * @param len The number of bytes to write + * + * @exception IOException If an error occurs. + */ + public void write (byte[] buf, int offset, int len) throws IOException + { + PlainSocketImpl.this.write (buf, offset, len); + } + } +} diff --git a/libjava/classpath/gnu/java/net/URLParseError.java b/libjava/classpath/gnu/java/net/URLParseError.java new file mode 100644 index 0000000..9090748 --- /dev/null +++ b/libjava/classpath/gnu/java/net/URLParseError.java @@ -0,0 +1,57 @@ +/* URLParseError.java -- Helps bypassing the exception limitation for + URLStreamHandler.parseURL(). + Copyright (C) 2003 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.java.net; + +/** + * This class helps the people writing protocols to report URL parse + * errors in parseUrl as this method cannot report other exceptions + * than Errors. + * + * The main drawback is that it uses the Error mechanism which should not + * be used for that type of error reporting. + * + * @author Guilhem Lavaux (guilhem@kaffe.org) + */ +public class URLParseError extends Error +{ + public URLParseError(String msg) + { + super(msg); + } +} diff --git a/libjava/classpath/gnu/java/net/package.html b/libjava/classpath/gnu/java/net/package.html new file mode 100644 index 0000000..5641fbd --- /dev/null +++ b/libjava/classpath/gnu/java/net/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/net/protocol/file/Connection.java b/libjava/classpath/gnu/java/net/protocol/file/Connection.java new file mode 100644 index 0000000..52bd048 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/file/Connection.java @@ -0,0 +1,319 @@ +/* FileURLConnection.java -- URLConnection class for "file" protocol + Copyright (C) 1998, 1999, 2003 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.java.net.protocol.file; + +import gnu.classpath.SystemProperties; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilePermission; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.ProtocolException; +import java.net.URL; +import java.net.URLConnection; +import java.security.Permission; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * This subclass of java.net.URLConnection models a URLConnection via + * the "file" protocol. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Nic Ferrier (nferrier@tapsellferrier.co.uk) + * @author Warren Levy (warrenl@cygnus.com) + */ +public class Connection extends URLConnection +{ + /** + * Default permission for a file + */ + private static final String DEFAULT_PERMISSION = "read"; + + private static class StaticData + { + /** + * HTTP-style DateFormat, used to format the last-modified header. + */ + static SimpleDateFormat dateFormat + = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", + new Locale ("En", "Us", "Unix")); + + static String lineSeparator = + SystemProperties.getProperty("line.separator"); + } + + + /** + * This is a File object for this connection + */ + private File file; + + /** + * If a directory, contains a list of files in the directory. + */ + private byte[] directoryListing; + + /** + * InputStream if we are reading from the file + */ + private InputStream inputStream; + + /** + * OutputStream if we are writing to the file + */ + private OutputStream outputStream; + + /** + * FilePermission to read the file + */ + private FilePermission permission; + + /** + * Calls superclass constructor to initialize. + */ + public Connection(URL url) + { + super (url); + + permission = new FilePermission(getURL().getFile(), DEFAULT_PERMISSION); + } + + /** + * "Connects" to the file by opening it. + */ + public void connect() throws IOException + { + // Call is ignored if already connected. + if (connected) + return; + + // If not connected, then file needs to be openned. + file = new File (getURL().getFile()); + + if (! file.isDirectory()) + { + if (doInput) + inputStream = new BufferedInputStream(new FileInputStream(file)); + + if (doOutput) + outputStream = new BufferedOutputStream(new FileOutputStream(file)); + } + else + { + if (doInput) + { + inputStream = new ByteArrayInputStream(getDirectoryListing()); + } + + if (doOutput) + throw new ProtocolException + ("file: protocol does not support output on directories"); + } + + connected = true; + } + + /** + * Populates the <code>directoryListing</code> field with a byte array + * containing a representation of the directory listing. + */ + byte[] getDirectoryListing() + throws IOException + { + if (directoryListing == null) + { + ByteArrayOutputStream sink = new ByteArrayOutputStream(); + // NB uses default character encoding for this system + Writer writer = new OutputStreamWriter(sink); + + String[] files = file.list(); + + for (int i = 0; i < files.length; i++) + { + writer.write(files[i]); + writer.write(StaticData.lineSeparator); + } + + directoryListing = sink.toByteArray(); + } + return directoryListing; + } + + /** + * Opens the file for reading and returns a stream for it. + * + * @return An InputStream for this connection. + * + * @exception IOException If an error occurs + */ + public InputStream getInputStream() + throws IOException + { + if (!doInput) + throw new ProtocolException("Can't open InputStream if doInput is false"); + + if (!connected) + connect(); + + return inputStream; + } + + /** + * Opens the file for writing and returns a stream for it. + * + * @return An OutputStream for this connection. + * + * @exception IOException If an error occurs. + */ + public OutputStream getOutputStream() + throws IOException + { + if (!doOutput) + throw new + ProtocolException("Can't open OutputStream if doOutput is false"); + + if (!connected) + connect(); + + return outputStream; + } + + /** + * Get the last modified time of the resource. + * + * @return the time since epoch that the resource was modified. + */ + public long getLastModified() + { + try + { + if (!connected) + connect(); + + return file.lastModified(); + } + catch (IOException e) + { + return -1; + } + } + + /** + * Get an http-style header field. Just handle a few common ones. + */ + public String getHeaderField(String field) + { + try + { + if (!connected) + connect(); + + if (field.equals("content-type")) + return guessContentTypeFromName(file.getName()); + else if (field.equals("content-length")) + { + if (file.isDirectory()) + { + return Integer.toString(getContentLength()); + } + return Long.toString(file.length()); + } + else if (field.equals("last-modified")) + { + synchronized (StaticData.dateFormat) + { + return StaticData.dateFormat.format( + new Date(file.lastModified())); + } + } + } + catch (IOException e) + { + // Fall through. + } + return null; + } + + /** + * Get the length of content. + * + * @return the length of the content. + */ + public int getContentLength() + { + try + { + if (!connected) + connect(); + + if (file.isDirectory()) + { + return getDirectoryListing().length; + } + return (int) file.length(); + } + catch (IOException e) + { + return -1; + } + } + + /** + * This method returns a <code>Permission</code> object representing the + * permissions required to access this URL. This method returns a + * <code>java.io.FilePermission</code> for the file's path with a read + * permission. + * + * @return A Permission object + */ + public Permission getPermission() throws IOException + { + return permission; + } +} diff --git a/libjava/classpath/gnu/java/net/protocol/file/Handler.java b/libjava/classpath/gnu/java/net/protocol/file/Handler.java new file mode 100644 index 0000000..fc56049 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/file/Handler.java @@ -0,0 +1,91 @@ +/* Handler.java -- "file" protocol handler for java.net + Copyright (C) 1998, 1999, 2000, 2002, 2003, 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.java.net.protocol.file; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * This is the protocol handler for the "file" protocol. + * It implements the abstract openConnection() method from + * URLStreamHandler by returning a new FileURLConnection object (from + * this package). All other methods are inherited + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Warren Levy (warrenl@cygnus.com) + */ +public class Handler extends URLStreamHandler +{ + /** + * A do nothing constructor + */ + public Handler() + { + } + + /** + * This method returs a new FileURLConnection for the specified URL + * + * @param url The URL to return a connection for + * + * @return The URLConnection + * + * @exception IOException If an error occurs + */ + protected URLConnection openConnection(URL url) throws IOException + { + // If a hostname is set, then we need to switch protocols to ftp + // in order to transfer this from the remote host. + String host = url.getHost(); + if ((host != null) && (! host.equals(""))) + { + // Reset the protocol (and implicitly the handler) for this URL. + // Then have the URL attempt the connection again, as it will + // get the changed handler the next time around. + // If the ftp protocol handler is not installed, an + // exception will be thrown from the new openConnection() call. + setURL (url, "ftp", url.getHost(), url.getPort(), url.getFile(), + url.getRef()); + return url.openConnection(); + } + + return new Connection(url); + } +} // class Handler diff --git a/libjava/classpath/gnu/java/net/protocol/file/package.html b/libjava/classpath/gnu/java/net/protocol/file/package.html new file mode 100644 index 0000000..cbce741 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/file/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net.protocol.file package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net.protocol.file</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/ActiveModeDTP.java b/libjava/classpath/gnu/java/net/protocol/ftp/ActiveModeDTP.java new file mode 100644 index 0000000..3755e8b --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/ActiveModeDTP.java @@ -0,0 +1,251 @@ +/* ActiveModeDTP.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * An active mode FTP data transfer process. + * This starts a server on the specified port listening for a data + * connection. It converts the socket input into a file stream for reading. + * + * @author Chris Burdess (dog@gnu.org) + */ +final class ActiveModeDTP + implements DTP, Runnable +{ + + ServerSocket server; + Socket socket; + DTPInputStream in; + DTPOutputStream out; + boolean completed; + boolean inProgress; + int transferMode; + IOException exception; + Thread acceptThread; + int connectionTimeout; + + ActiveModeDTP(InetAddress localhost, int port, + int connectionTimeout, int timeout) + throws IOException + { + completed = false; + inProgress = false; + server = new ServerSocket(port, 1, localhost); + if (timeout > 0) + { + server.setSoTimeout(timeout); + } + if (connectionTimeout <= 0) + { + connectionTimeout = 20000; + } + this.connectionTimeout = connectionTimeout; + acceptThread = new Thread(this, "ActiveModeDTP"); + acceptThread.start(); + } + + /** + * Start listening. + */ + public void run() + { + try + { + socket = server.accept(); + //System.err.println("Accepted connection from "+socket.getInetAddress()+":"+socket.getPort()); + } + catch (IOException e) + { + exception = e; + } + } + + /** + * Waits until a client has connected. + */ + public void waitFor() + throws IOException + { + try + { + acceptThread.join(connectionTimeout); + } + catch (InterruptedException e) + { + } + if (exception != null) + { + throw exception; + } + if (socket == null) + { + server.close(); + throw new IOException("client did not connect before timeout"); + } + acceptThread = null; + } + + /** + * Returns an input stream from which a remote file can be read. + */ + public InputStream getInputStream() + throws IOException + { + if (inProgress) + { + throw new IOException("Transfer in progress"); + } + if (acceptThread != null) + { + waitFor(); + } + switch (transferMode) + { + case FTPConnection.MODE_STREAM: + in = new StreamInputStream(this, socket.getInputStream()); + break; + case FTPConnection.MODE_BLOCK: + in = new BlockInputStream(this, socket.getInputStream()); + break; + case FTPConnection.MODE_COMPRESSED: + in = new CompressedInputStream(this, socket.getInputStream()); + break; + default: + throw new IllegalStateException("invalid transfer mode"); + } + in.setTransferComplete(false); + return in; + } + + /** + * Returns an output stream to which a local file can be written for + * upload. + */ + public OutputStream getOutputStream() throws IOException + { + if (inProgress) + { + throw new IOException("Transfer in progress"); + } + if (acceptThread != null) + { + waitFor(); + } + switch (transferMode) + { + case FTPConnection.MODE_STREAM: + out = new StreamOutputStream(this, socket.getOutputStream()); + break; + case FTPConnection.MODE_BLOCK: + out = new BlockOutputStream(this, socket.getOutputStream()); + break; + case FTPConnection.MODE_COMPRESSED: + out = new CompressedOutputStream(this, socket.getOutputStream()); + break; + default: + throw new IllegalStateException("invalid transfer mode"); + } + out.setTransferComplete(false); + return out; + } + + public void setTransferMode(int mode) + { + transferMode = mode; + } + + public void complete() + { + completed = true; + if (!inProgress) + { + transferComplete(); + } + } + + public boolean abort() + { + completed = true; + transferComplete(); + return inProgress; + } + + public void transferComplete() + { + if (socket == null) + { + return; + } + if (in != null) + { + in.setTransferComplete(true); + } + if (out != null) + { + out.setTransferComplete(true); + } + completed = completed || (transferMode == FTPConnection.MODE_STREAM); + if (completed && socket != null) + { + try + { + socket.close(); + } + catch (IOException e) + { + } + try + { + server.close(); + } + catch (IOException e) + { + } + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/BlockInputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/BlockInputStream.java new file mode 100644 index 0000000..63897f1 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/BlockInputStream.java @@ -0,0 +1,150 @@ +/* BlockInputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A DTP input stream that implements the FTP block transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class BlockInputStream + extends DTPInputStream +{ + + static final int EOF = 64; + + int descriptor; + int max = -1; + int count = -1; + + BlockInputStream(DTP dtp, InputStream in) + { + super(dtp, in); + } + + public int read() + throws IOException + { + if (transferComplete) + { + return -1; + } + if (count == -1) + { + readHeader(); + } + if (max < 1) + { + close(); + return -1; + } + int c = in.read(); + if (c == -1) + { + dtp.transferComplete(); + } + count++; + if (count >= max) + { + count = -1; + if (descriptor == EOF) + { + close(); + } + } + return c; + } + + public int read(byte[] buf) + throws IOException + { + return read(buf, 0, buf.length); + } + + public int read(byte[] buf, int off, int len) + throws IOException + { + if (transferComplete) + { + return -1; + } + if (count == -1) + { + readHeader(); + } + if (max < 1) + { + close(); + return -1; + } + int l = in.read(buf, off, len); + if (l == -1) + { + dtp.transferComplete(); + } + count += l; + if (count >= max) + { + count = -1; + if (descriptor == EOF) + { + close(); + } + } + return l; + } + + /** + * Reads the block header. + */ + void readHeader() + throws IOException + { + descriptor = in.read(); + int max_hi = in.read(); + int max_lo = in.read(); + max = (max_hi << 8) | max_lo; + count = 0; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/BlockOutputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/BlockOutputStream.java new file mode 100644 index 0000000..85481c9 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/BlockOutputStream.java @@ -0,0 +1,111 @@ +/* BlockOutputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A DTP output stream that implements the FTP block transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class BlockOutputStream + extends DTPOutputStream +{ + + static final byte RECORD = -128; // 0x80 + static final byte EOF = 64; // 0x40 + + BlockOutputStream(DTP dtp, OutputStream out) + { + super(dtp, out); + } + + public void write(int c) + throws IOException + { + if (transferComplete) + { + return; + } + byte[] buf = new byte[] + { + RECORD, /* record descriptor */ + 0x00, 0x01, /* one byte */ + (byte) c /* the byte */ + }; + out.write(buf, 0, 4); + } + + public void write(byte[] b) + throws IOException + { + write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) + throws IOException + { + if (transferComplete) + { + return; + } + byte[] buf = new byte[len + 3]; + buf[0] = RECORD; /* record descriptor */ + buf[1] = (byte) ((len & 0x00ff) >> 8); /* high byte of bytecount */ + buf[2] = (byte) (len & 0xff00); /* low byte of bytecount */ + System.arraycopy(b, off, buf, 3, len); + out.write(buf, 0, len); + } + + public void close() + throws IOException + { + byte[] buf = new byte[] + { + EOF, /* eof descriptor */ + 0x00, 0x00 /* no bytes */ + }; + out.write(buf, 0, 3); + super.close(); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/CompressedInputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/CompressedInputStream.java new file mode 100644 index 0000000..f2e65b7 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/CompressedInputStream.java @@ -0,0 +1,215 @@ +/* CompressedInputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.net.ProtocolException; + +/** + * A DTP input stream that implements the FTP compressed transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class CompressedInputStream + extends DTPInputStream +{ + + static final int EOF = 64; + + static final int RAW = 0x00; + static final int COMPRESSED = 0x80; + static final int FILLER = 0xc0; + + int descriptor; + int max = -1; + int count = -1; + + int state = RAW; // RAW | STATE | FILLER + int rep; // the compressed byte + int n = 0; // the number of compressed or raw bytes + + CompressedInputStream(DTP dtp, InputStream in) + { + super(dtp, in); + } + + public int read() + throws IOException + { + if (transferComplete) + { + return -1; + } + if (count == -1) + { + readHeader(); + } + if (max < 1) + { + close(); + return -1; + } + if (n > 0 && (state == COMPRESSED || state == FILLER)) + { + n--; + return rep; + } + int c = in.read(); + if (c == -1) + { + close(); + } + count++; + if (count >= max) + { + count = -1; + if (descriptor == EOF) + { + close(); + } + } + if (c == -1) + { + return c; + } + while (n == 0) // read code header + { + state = (c & 0xc0); + n = (c & 0x3f); + c = in.read(); + if (c == -1) + { + return -1; + } + } + switch (state) + { + case RAW: + break; + case COMPRESSED: + case FILLER: + rep = c; + break; + default: + throw new ProtocolException("Illegal state: " + state); + } + n--; + return c; + } + + public int read(byte[] buf) + throws IOException + { + return read(buf, 0, buf.length); + } + + public int read(byte[] buf, int off, int len) + throws IOException + { + if (transferComplete) + { + return -1; + } + if (count == -1) + { + readHeader(); + } + if (max < 1) + { + close(); + return -1; + } + // TODO improve performance + for (int i = off; i < len; i++) + { + int c = read(); + if (c == -1) + { + close(); + return i; + } + buf[i] = (byte) c; + } + return len; + /* + int l = in.read (buf, off, len); + if (l==-1) + { + close (); + } + count += l; + if (count>=max) + { + count = -1; + if (descriptor==EOF) + { + close (); + } + } + return l; + */ + } + + /** + * Reads the block header. + */ + void readHeader() + throws IOException + { + descriptor = in.read(); + int max_hi = in.read(); + int max_lo = in.read(); + max = (max_hi << 8) | max_lo; + count = 0; + } + + /** + * Reads the code header. + */ + void readCodeHeader() + throws IOException + { + int code = in.read(); + state = (code & 0xc0); + n = (code & 0x3f); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/CompressedOutputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/CompressedOutputStream.java new file mode 100644 index 0000000..b960fb3 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/CompressedOutputStream.java @@ -0,0 +1,228 @@ +/* CompressedOutputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A DTP output stream that implements the FTP compressed transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class CompressedOutputStream + extends DTPOutputStream +{ + + static final byte RECORD = -128; // 0x80 + static final byte EOF = 64; // 0x40 + + CompressedOutputStream(DTP dtp, OutputStream out) + { + super(dtp, out); + } + + /** + * Just one byte cannot be compressed. + * It takes 5 bytes to transmit - hardly very compressed! + */ + public void write(int c) + throws IOException + { + if (transferComplete) + { + return; + } + byte[] buf = new byte[] + { + RECORD, /* record descriptor */ + 0x00, 0x01, /* one byte */ + 0x01, /* one uncompressed byte */ + (byte) c /* the byte */ + }; + out.write(buf, 0, 5); + } + + public void write(byte[] b) + throws IOException + { + write(b, 0, b.length); + } + + /** + * The larger len is, the better. + */ + public void write(byte[] b, int off, int len) + throws IOException + { + if (transferComplete) + { + return; + } + byte[] buf = compress(b, off, len); + len = buf.length; + buf[0] = RECORD; /* record descriptor */ + buf[1] = (byte) ((len & 0x00ff) >> 8); /* high byte of bytecount */ + buf[2] = (byte) (len & 0xff00); /* low byte of bytecount */ + out.write(buf, 0, len); + } + + /** + * Returns the compressed form of the given byte array. + * The first 3 bytes are left free for header information. + */ + byte[] compress(byte[] b, int off, int len) + { + byte[] buf = new byte[len]; + byte last = 0; + int pos = 0, raw_count = 0, rep_count = 1; + for (int i = off; i < len; i++) + { + byte c = b[i]; + if (i > off && c == last) // compress + { + if (raw_count > 0) // flush raw bytes to buf + { + // need to add raw_count+1 bytes + if (pos + (raw_count + 1) > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_raw(buf, pos, b, (i - raw_count) - 1, + raw_count); + raw_count = 0; + } + rep_count++; // keep looking for same byte + } + else + { + if (rep_count > 1) // flush compressed bytes to buf + { + // need to add 2 bytes + if (pos + 2 > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_compressed(buf, pos, rep_count, last); + rep_count = 1; + } + raw_count++; // keep looking for raw bytes + } + if (rep_count == 127) // flush compressed bytes + { + // need to add 2 bytes + if (pos + 2 > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_compressed(buf, pos, rep_count, last); + rep_count = 1; + } + if (raw_count == 127) // flush raw bytes + { + // need to add raw_count+1 bytes + if (pos + (raw_count + 1) > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_raw(buf, pos, b, (i - raw_count), raw_count); + raw_count = 0; + } + last = c; + } + if (rep_count > 1) // flush compressed bytes + { + // need to add 2 bytes + if (pos + 2 > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_compressed(buf, pos, rep_count, last); + rep_count = 1; + } + if (raw_count > 0) // flush raw bytes + { + // need to add raw_count+1 bytes + if (pos + (raw_count + 1) > buf.length) + { + buf = realloc(buf, len); + } + pos = flush_raw(buf, pos, b, (len - raw_count), raw_count); + raw_count = 0; + } + byte[] ret = new byte[pos + 3]; + System.arraycopy(buf, 0, ret, 3, pos); + return ret; + } + + int flush_compressed(byte[] buf, int pos, int count, byte c) + { + buf[pos++] = (byte) (0x80 | count); + buf[pos++] = c; + return pos; + } + + int flush_raw(byte[] buf, int pos, byte[] src, int off, int len) + { + buf[pos++] = (byte) len; + System.arraycopy(src, off, buf, pos, len); + return pos + len; + } + + byte[] realloc(byte[] buf, int len) + { + byte[] ret = new byte[buf.length + len]; + System.arraycopy(buf, 0, ret, 0, buf.length); + return ret; + } + + public void close() + throws IOException + { + byte[] buf = new byte[] + { + EOF, /* eof descriptor */ + 0x00, 0x00 /* no bytes */ + }; + out.write(buf, 0, 3); + out.close(); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/DTP.java b/libjava/classpath/gnu/java/net/protocol/ftp/DTP.java new file mode 100644 index 0000000..25580af --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/DTP.java @@ -0,0 +1,92 @@ +/* DTP.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * An FTP data transfer process. + * + * @author Chris Burdess (dog@gnu.org) + */ +interface DTP +{ + + /** + * Returns an input stream from which a remote file can be read. + */ + InputStream getInputStream() + throws IOException; + + /** + * Returns an output stream to which a local file can be written for + * upload. + */ + OutputStream getOutputStream() + throws IOException; + + /** + * Sets the transfer mode to be used with this DTP. + */ + void setTransferMode(int mode); + + /** + * Marks this DTP completed. + * When the current transfer has finished, any resources will be released. + */ + void complete(); + + /** + * Aborts any current transfer and releases all resources held by this + * DTP. + * @return true if a transfer was interrupted, false otherwise + */ + boolean abort(); + + /** + * Used to notify the DTP that its current transfer is complete. + * This occurs either when end-of-stream is reached or a 226 response is + * received. + */ + void transferComplete(); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/DTPInputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/DTPInputStream.java new file mode 100644 index 0000000..363a559 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/DTPInputStream.java @@ -0,0 +1,88 @@ +/* DTPInputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream that notifies a DTP on completion. + * + * @author Chris Burdess (dog@gnu.org) + */ +abstract class DTPInputStream + extends FilterInputStream +{ + + DTP dtp; + boolean transferComplete; + + /** + * Constructor. + * @param dtp the controlling data transfer process + * @param in the underlying socket stream + */ + DTPInputStream (DTP dtp, InputStream in) + { + super(in); + this.dtp = dtp; + transferComplete = false; + } + + /** + * Marks this input stream complete. + * This is called by the DTP. + */ + void setTransferComplete(boolean flag) + { + transferComplete = flag; + } + + /** + * Notifies the controlling DTP that this stream has completed transfer. + */ + public void close() + throws IOException + { + dtp.transferComplete(); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/DTPOutputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/DTPOutputStream.java new file mode 100644 index 0000000..83f0be1 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/DTPOutputStream.java @@ -0,0 +1,85 @@ +/* DTPOutputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * An output stream that notifies a DTP on end of stream. + * + * @author Chris Burdess (dog@gnu.org) + */ +abstract class DTPOutputStream extends FilterOutputStream +{ + + DTP dtp; + boolean transferComplete; + + /** + * Constructor. + * @param dtp the controlling data transfer process + * @param out the socket output stream + */ + DTPOutputStream (DTP dtp, OutputStream out) + { + super (out); + this.dtp = dtp; + transferComplete = false; + } + + /** + * Tells this stream whether transfer has completed or not. + * @param flag true if the process has completed, false otherwise + */ + void setTransferComplete (boolean flag) + { + transferComplete = flag; + } + + /** + * Notifies the controlling DTP that this stream has been terminated. + */ + public void close () throws IOException + { + dtp.transferComplete (); + } + +} diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java new file mode 100644 index 0000000..d0f4872 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java @@ -0,0 +1,1348 @@ +/* FTPConnection.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import gnu.java.net.CRLFInputStream; +import gnu.java.net.CRLFOutputStream; +import gnu.java.net.EmptyX509TrustManager; +import gnu.java.net.LineInputStream; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ProtocolException; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.List; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +/** + * An FTP client connection, or PI. + * This implements RFC 959, with the following exceptions: + * <ul> + * <li>STAT, HELP, SITE, SMNT, and ACCT commands are not supported.</li> + * <li>the TYPE command does not allow alternatives to the default bytesize + * (Non-print), and local bytesize is not supported.</li> + * </ul> + * + * @author Chris Burdess (dog@gnu.org) + */ +public class FTPConnection +{ + + /** + * The default FTP transmission control port. + */ + public static final int FTP_PORT = 21; + + /** + * The FTP data port. + */ + public static final int FTP_DATA_PORT = 20; + + // -- FTP vocabulary -- + protected static final String USER = "USER"; + protected static final String PASS = "PASS"; + protected static final String ACCT = "ACCT"; + protected static final String CWD = "CWD"; + protected static final String CDUP = "CDUP"; + protected static final String SMNT = "SMNT"; + protected static final String REIN = "REIN"; + protected static final String QUIT = "QUIT"; + + protected static final String PORT = "PORT"; + protected static final String PASV = "PASV"; + protected static final String TYPE = "TYPE"; + protected static final String STRU = "STRU"; + protected static final String MODE = "MODE"; + + protected static final String RETR = "RETR"; + protected static final String STOR = "STOR"; + protected static final String STOU = "STOU"; + protected static final String APPE = "APPE"; + protected static final String ALLO = "ALLO"; + protected static final String REST = "REST"; + protected static final String RNFR = "RNFR"; + protected static final String RNTO = "RNTO"; + protected static final String ABOR = "ABOR"; + protected static final String DELE = "DELE"; + protected static final String RMD = "RMD"; + protected static final String MKD = "MKD"; + protected static final String PWD = "PWD"; + protected static final String LIST = "LIST"; + protected static final String NLST = "NLST"; + protected static final String SITE = "SITE"; + protected static final String SYST = "SYST"; + protected static final String STAT = "STAT"; + protected static final String HELP = "HELP"; + protected static final String NOOP = "NOOP"; + + protected static final String AUTH = "AUTH"; + protected static final String PBSZ = "PBSZ"; + protected static final String PROT = "PROT"; + protected static final String CCC = "CCC"; + protected static final String TLS = "TLS"; + + public static final int TYPE_ASCII = 1; + public static final int TYPE_EBCDIC = 2; + public static final int TYPE_BINARY = 3; + + public static final int STRUCTURE_FILE = 1; + public static final int STRUCTURE_RECORD = 2; + public static final int STRUCTURE_PAGE = 3; + + public static final int MODE_STREAM = 1; + public static final int MODE_BLOCK = 2; + public static final int MODE_COMPRESSED = 3; + + // -- Telnet constants -- + private static final String US_ASCII = "US-ASCII"; + + /** + * The socket used to communicate with the server. + */ + protected Socket socket; + + /** + * The socket input stream. + */ + protected LineInputStream in; + + /** + * The socket output stream. + */ + protected CRLFOutputStream out; + + /** + * The timeout when attempting to connect a socket. + */ + protected int connectionTimeout; + + /** + * The read timeout on sockets. + */ + protected int timeout; + + /** + * If true, print debugging information. + */ + protected boolean debug; + + /** + * The current data transfer process in use by this connection. + */ + protected DTP dtp; + + /** + * The current representation type. + */ + protected int representationType = TYPE_ASCII; + + /** + * The current file structure type. + */ + protected int fileStructure = STRUCTURE_FILE; + + /** + * The current transfer mode. + */ + protected int transferMode = MODE_STREAM; + + /** + * If true, use passive mode. + */ + protected boolean passive = false; + + /** + * Creates a new connection to the server using the default port. + * @param hostname the hostname of the server to connect to + */ + public FTPConnection(String hostname) + throws UnknownHostException, IOException + { + this(hostname, -1, 0, 0, false); + } + + /** + * Creates a new connection to the server. + * @param hostname the hostname of the server to connect to + * @param port the port to connect to(if <=0, use default port) + */ + public FTPConnection(String hostname, int port) + throws UnknownHostException, IOException + { + this(hostname, port, 0, 0, false); + } + + /** + * Creates a new connection to the server. + * @param hostname the hostname of the server to connect to + * @param port the port to connect to(if <=0, use default port) + * @param connectionTimeout the connection timeout, in milliseconds + * @param timeout the I/O timeout, in milliseconds + * @param debug print debugging information + */ + public FTPConnection(String hostname, int port, + int connectionTimeout, int timeout, boolean debug) + throws UnknownHostException, IOException + { + this.connectionTimeout = connectionTimeout; + this.timeout = timeout; + this.debug = debug; + if (port <= 0) + { + port = FTP_PORT; + } + + // Set up socket + socket = new Socket(); + InetSocketAddress address = new InetSocketAddress(hostname, port); + if (connectionTimeout > 0) + { + socket.connect(address, connectionTimeout); + } + else + { + socket.connect(address); + } + if (timeout > 0) + { + socket.setSoTimeout(timeout); + } + + InputStream in = socket.getInputStream(); + in = new BufferedInputStream(in); + in = new CRLFInputStream(in); + this.in = new LineInputStream(in); + OutputStream out = socket.getOutputStream(); + out = new BufferedOutputStream(out); + this.out = new CRLFOutputStream(out); + + // Read greeting + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 220: // hello + break; + default: + throw new FTPException(response); + } + } + + /** + * Authenticate using the specified username and password. + * If the username suffices for the server, the password will not be used + * and may be null. + * @param username the username + * @param password the optional password + * @return true on success, false otherwise + */ + public boolean authenticate(String username, String password) + throws IOException + { + String cmd = USER + ' ' + username; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 230: // User logged in + return true; + case 331: // User name okay, need password + break; + case 332: // Need account for login + case 530: // No such user + return false; + default: + throw new FTPException(response); + } + cmd = PASS + ' ' + password; + send(cmd); + response = getResponse(); + switch (response.getCode()) + { + case 230: // User logged in + case 202: // Superfluous + return true; + case 332: // Need account for login + case 530: // Bad password + return false; + default: + throw new FTPException(response); + } + } + + /** + * Negotiates TLS over the current connection. + * See IETF draft-murray-auth-ftp-ssl-15.txt for details. + * @param confidential whether to provide confidentiality for the + * connection + */ + public boolean starttls(boolean confidential) + throws IOException + { + return starttls(confidential, new EmptyX509TrustManager()); + } + + /** + * Negotiates TLS over the current connection. + * See IETF draft-murray-auth-ftp-ssl-15.txt for details. + * @param confidential whether to provide confidentiality for the + * connection + * @param tm the trust manager used to validate the server certificate. + */ + public boolean starttls(boolean confidential, TrustManager tm) + throws IOException + { + try + { + // Use SSLSocketFactory to negotiate a TLS session and wrap the + // current socket. + SSLContext context = SSLContext.getInstance("TLS"); + // We don't require strong validation of the server certificate + TrustManager[] trust = new TrustManager[] { tm }; + context.init(null, trust, null); + SSLSocketFactory factory = context.getSocketFactory(); + + send(AUTH + ' ' + TLS); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 500: + case 502: + case 504: + case 534: + case 431: + return false; + case 234: + break; + default: + throw new FTPException(response); + } + + String hostname = socket.getInetAddress().getHostName(); + int port = socket.getPort(); + SSLSocket ss = + (SSLSocket) factory.createSocket(socket, hostname, port, true); + String[] protocols = { "TLSv1", "SSLv3" }; + ss.setEnabledProtocols(protocols); + ss.setUseClientMode(true); + ss.startHandshake(); + + // PBSZ:PROT sequence + send(PBSZ + ' ' + Integer.MAX_VALUE); + response = getResponse(); + switch (response.getCode()) + { + case 501: // syntax error + case 503: // not authenticated + return false; + case 200: + break; + default: + throw new FTPException(response); + } + send(PROT + ' ' +(confidential ? 'P' : 'C')); + response = getResponse(); + switch (response.getCode()) + { + case 503: // not authenticated + case 504: // invalid level + case 536: // level not supported + return false; + case 200: + break; + default: + throw new FTPException(response); + } + + if (confidential) + { + // Set up streams + InputStream in = ss.getInputStream(); + in = new BufferedInputStream(in); + in = new CRLFInputStream(in); + this.in = new LineInputStream(in); + OutputStream out = ss.getOutputStream(); + out = new BufferedOutputStream(out); + this.out = new CRLFOutputStream(out); + } + return true; + } + catch (GeneralSecurityException e) + { + return false; + } + } + + /** + * Changes directory to the specified path. + * @param path an absolute or relative pathname + * @return true on success, false if the specified path does not exist + */ + public boolean changeWorkingDirectory(String path) + throws IOException + { + String cmd = CWD + ' ' + path; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 250: + return true; + case 550: + return false; + default: + throw new FTPException(response); + } + } + + /** + * Changes directory to the parent of the current working directory. + * @return true on success, false otherwise + */ + public boolean changeToParentDirectory() + throws IOException + { + send(CDUP); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 250: + return true; + case 550: + return false; + default: + throw new FTPException(response); + } + } + + /** + * Terminates an authenticated login. + * If file transfer is in progress, it remains active for result response + * only. + */ + public void reinitialize() + throws IOException + { + send(REIN); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 220: + if (dtp != null) + { + dtp.complete(); + dtp = null; + } + break; + default: + throw new FTPException(response); + } + } + + /** + * Terminates the control connection. + * The file transfer connection remains open for result response only. + * This connection is invalid and no further commands may be issued. + */ + public void logout() + throws IOException + { + send(QUIT); + try + { + getResponse(); // not required + } + catch (IOException e) + { + } + if (dtp != null) + { + dtp.complete(); + dtp = null; + } + try + { + socket.close(); + } + catch (IOException e) + { + } + } + + /** + * Initialise the data transfer process. + */ + protected void initialiseDTP() + throws IOException + { + if (dtp != null) + { + dtp.complete(); + dtp = null; + } + + InetAddress localhost = socket.getLocalAddress(); + if (passive) + { + send(PASV); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 227: + String message = response.getMessage(); + try + { + int start = message.indexOf(','); + char c = message.charAt(start - 1); + while (c >= 0x30 && c <= 0x39) + { + c = message.charAt((--start) - 1); + } + int mid1 = start; + for (int i = 0; i < 4; i++) + { + mid1 = message.indexOf(',', mid1 + 1); + } + int mid2 = message.indexOf(',', mid1 + 1); + if (mid1 == -1 || mid2 < mid1) + { + throw new ProtocolException("Malformed 227: " + + message); + } + int end = mid2; + c = message.charAt(end + 1); + while (c >= 0x30 && c <= 0x39) + { + c = message.charAt((++end) + 1); + } + + String address = + message.substring(start, mid1).replace(',', '.'); + int port_hi = + Integer.parseInt(message.substring(mid1 + 1, mid2)); + int port_lo = + Integer.parseInt(message.substring(mid2 + 1, end + 1)); + int port = (port_hi << 8) | port_lo; + + /*System.out.println("Entering passive mode: " + address + + ":" + port);*/ + dtp = new PassiveModeDTP(address, port, localhost, + connectionTimeout, timeout); + break; + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new ProtocolException(e.getMessage() + ": " + + message); + } + catch (NumberFormatException e) + { + throw new ProtocolException(e.getMessage() + ": " + + message); + } + default: + throw new FTPException(response); + } + } + else + { + // Get the local port + int port = socket.getLocalPort() + 1; + int tries = 0; + // Bind the active mode DTP + while (dtp == null) + { + try + { + dtp = new ActiveModeDTP(localhost, port, + connectionTimeout, timeout); + /*System.out.println("Listening on: " + port);*/ + } + catch (BindException e) + { + port++; + tries++; + if (tries > 9) + { + throw e; + } + } + } + + // Send PORT command + StringBuffer buf = new StringBuffer(PORT); + buf.append(' '); + // Construct the address/port string form + byte[] address = localhost.getAddress(); + for (int i = 0; i < address.length; i++) + { + int a =(int) address[i]; + if (a < 0) + { + a += 0x100; + } + buf.append(a); + buf.append(','); + } + int port_hi =(port & 0xff00) >> 8; + int port_lo =(port & 0x00ff); + buf.append(port_hi); + buf.append(','); + buf.append(port_lo); + send(buf.toString()); + // Get response + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: // OK + break; + default: + dtp.abort(); + dtp = null; + throw new FTPException(response); + } + } + dtp.setTransferMode(transferMode); + } + + /** + * Set passive mode. + * @param flag true if we should use passive mode, false otherwise + */ + public void setPassive(boolean flag) + throws IOException + { + if (passive != flag) + { + passive = flag; + initialiseDTP(); + } + } + + /** + * Returns the current representation type of the transfer data. + * @return TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY + */ + public int getRepresentationType() + { + return representationType; + } + + /** + * Sets the desired representation type of the transfer data. + * @param type TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY + */ + public void setRepresentationType(int type) + throws IOException + { + StringBuffer buf = new StringBuffer(TYPE); + buf.append(' '); + switch (type) + { + case TYPE_ASCII: + buf.append('A'); + break; + case TYPE_EBCDIC: + buf.append('E'); + break; + case TYPE_BINARY: + buf.append('I'); + break; + default: + throw new IllegalArgumentException(Integer.toString(type)); + } + //buf.append(' '); + //buf.append('N'); + send(buf.toString()); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: + representationType = type; + break; + default: + throw new FTPException(response); + } + } + + /** + * Returns the current file structure type. + * @return STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE + */ + public int getFileStructure() + { + return fileStructure; + } + + /** + * Sets the desired file structure type. + * @param structure STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE + */ + public void setFileStructure(int structure) + throws IOException + { + StringBuffer buf = new StringBuffer(STRU); + buf.append(' '); + switch (structure) + { + case STRUCTURE_FILE: + buf.append('F'); + break; + case STRUCTURE_RECORD: + buf.append('R'); + break; + case STRUCTURE_PAGE: + buf.append('P'); + break; + default: + throw new IllegalArgumentException(Integer.toString(structure)); + } + send(buf.toString()); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: + fileStructure = structure; + break; + default: + throw new FTPException(response); + } + } + + /** + * Returns the current transfer mode. + * @return MODE_STREAM, MODE_BLOCK, or MODE_COMPRESSED + */ + public int getTransferMode() + { + return transferMode; + } + + /** + * Sets the desired transfer mode. + * @param mode MODE_STREAM, MODE_BLOCK, or MODE_COMPRESSED + */ + public void setTransferMode(int mode) + throws IOException + { + StringBuffer buf = new StringBuffer(MODE); + buf.append(' '); + switch (mode) + { + case MODE_STREAM: + buf.append('S'); + break; + case MODE_BLOCK: + buf.append('B'); + break; + case MODE_COMPRESSED: + buf.append('C'); + break; + default: + throw new IllegalArgumentException(Integer.toString(mode)); + } + send(buf.toString()); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: + transferMode = mode; + if (dtp != null) + { + dtp.setTransferMode(mode); + } + break; + default: + throw new FTPException(response); + } + } + + /** + * Retrieves the specified file. + * @param filename the filename of the file to retrieve + * @return an InputStream containing the file content + */ + public InputStream retrieve(String filename) + throws IOException + { + if (dtp == null || transferMode == MODE_STREAM) + { + initialiseDTP(); + } + /* + int size = -1; + String cmd = SIZE + ' ' + filename; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 213: + size = Integer.parseInt(response.getMessage()); + break; + case 550: // File not found + default: + throw new FTPException(response); + } + */ + String cmd = RETR + ' ' + filename; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 125: // Data connection already open; transfer starting + case 150: // File status okay; about to open data connection + return dtp.getInputStream(); + default: + throw new FTPException(response); + } + } + + /** + * Returns a stream for uploading a file. + * If a file with the same filename already exists on the server, it will + * be overwritten. + * @param filename the name of the file to save the content as + * @return an OutputStream to write the file data to + */ + public OutputStream store(String filename) + throws IOException + { + if (dtp == null || transferMode == MODE_STREAM) + { + initialiseDTP(); + } + String cmd = STOR + ' ' + filename; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 125: // Data connection already open; transfer starting + case 150: // File status okay; about to open data connection + return dtp.getOutputStream(); + default: + throw new FTPException(response); + } + } + + /** + * Returns a stream for uploading a file. + * If a file with the same filename already exists on the server, the + * content specified will be appended to the existing file. + * @param filename the name of the file to save the content as + * @return an OutputStream to write the file data to + */ + public OutputStream append(String filename) + throws IOException + { + if (dtp == null || transferMode == MODE_STREAM) + { + initialiseDTP(); + } + String cmd = APPE + ' ' + filename; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 125: // Data connection already open; transfer starting + case 150: // File status okay; about to open data connection + return dtp.getOutputStream(); + default: + throw new FTPException(response); + } + } + + /** + * This command may be required by some servers to reserve sufficient + * storage to accommodate the new file to be transferred. + * It should be immediately followed by a <code>store</code> or + * <code>append</code>. + * @param size the number of bytes of storage to allocate + */ + public void allocate(long size) + throws IOException + { + String cmd = ALLO + ' ' + size; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: // OK + case 202: // Superfluous + break; + default: + throw new FTPException(response); + } + } + + /** + * Renames a file. + * @param oldName the current name of the file + * @param newName the new name + * @return true if successful, false otherwise + */ + public boolean rename(String oldName, String newName) + throws IOException + { + String cmd = RNFR + ' ' + oldName; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 450: // File unavailable + case 550: // File not found + return false; + case 350: // Pending + break; + default: + throw new FTPException(response); + } + cmd = RNTO + ' ' + newName; + send(cmd); + response = getResponse(); + switch (response.getCode()) + { + case 250: // OK + return true; + case 450: + case 550: + return false; + default: + throw new FTPException(response); + } + } + + /** + * Aborts the transfer in progress. + * @return true if a transfer was in progress, false otherwise + */ + public boolean abort() + throws IOException + { + send(ABOR); + FTPResponse response = getResponse(); + // Abort client DTP + if (dtp != null) + { + dtp.abort(); + } + switch (response.getCode()) + { + case 226: // successful abort + return false; + case 426: // interrupted + response = getResponse(); + if (response.getCode() == 226) + { + return true; + } + // Otherwise fall through to throw exception + default: + throw new FTPException(response); + } + } + + /** + * Causes the file specified to be deleted at the server site. + * @param filename the file to delete + */ + public boolean delete(String filename) + throws IOException + { + String cmd = DELE + ' ' + filename; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 250: // OK + return true; + case 450: // File unavailable + case 550: // File not found + return false; + default: + throw new FTPException(response); + } + } + + /** + * Causes the directory specified to be deleted. + * This may be an absolute or relative pathname. + * @param pathname the directory to delete + */ + public boolean removeDirectory(String pathname) + throws IOException + { + String cmd = RMD + ' ' + pathname; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 250: // OK + return true; + case 550: // File not found + return false; + default: + throw new FTPException(response); + } + } + + /** + * Causes the directory specified to be created at the server site. + * This may be an absolute or relative pathname. + * @param pathname the directory to create + */ + public boolean makeDirectory(String pathname) + throws IOException + { + String cmd = MKD + ' ' + pathname; + send(cmd); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 257: // Directory created + return true; + case 550: // File not found + return false; + default: + throw new FTPException(response); + } + } + + /** + * Returns the current working directory. + */ + public String getWorkingDirectory() + throws IOException + { + send(PWD); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 257: + String message = response.getMessage(); + if (message.charAt(0) == '"') + { + int end = message.indexOf('"', 1); + if (end == -1) + { + throw new ProtocolException(message); + } + return message.substring(1, end); + } + else + { + int end = message.indexOf(' '); + if (end == -1) + { + return message; + } + else + { + return message.substring(0, end); + } + } + default: + throw new FTPException(response); + } + } + + /** + * Returns a listing of information about the specified pathname. + * If the pathname specifies a directory or other group of files, the + * server should transfer a list of files in the specified directory. + * If the pathname specifies a file then the server should send current + * information on the file. A null argument implies the user's + * current working or default directory. + * @param pathname the context pathname, or null + */ + public InputStream list(String pathname) + throws IOException + { + if (dtp == null || transferMode == MODE_STREAM) + { + initialiseDTP(); + } + if (pathname == null) + { + send(LIST); + } + else + { + String cmd = LIST + ' ' + pathname; + send(cmd); + } + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 125: // Data connection already open; transfer starting + case 150: // File status okay; about to open data connection + return dtp.getInputStream(); + default: + throw new FTPException(response); + } + } + + /** + * Returns a directory listing. The pathname should specify a + * directory or other system-specific file group descriptor; a null + * argument implies the user's current working or default directory. + * @param pathname the directory pathname, or null + * @return a list of filenames(strings) + */ + public List nameList(String pathname) + throws IOException + { + if (dtp == null || transferMode == MODE_STREAM) + { + initialiseDTP(); + } + if (pathname == null) + { + send(NLST); + } + else + { + String cmd = NLST + ' ' + pathname; + send(cmd); + } + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 125: // Data connection already open; transfer starting + case 150: // File status okay; about to open data connection + InputStream in = dtp.getInputStream(); + in = new BufferedInputStream(in); + in = new CRLFInputStream(in); // TODO ensure that TYPE is correct + LineInputStream li = new LineInputStream(in); + List ret = new ArrayList(); + for (String line = li.readLine(); + line != null; + line = li.readLine()) + { + ret.add(line); + } + li.close(); + return ret; + default: + throw new FTPException(response); + } + } + + /** + * Returns the type of operating system at the server. + */ + public String system() + throws IOException + { + send(SYST); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 215: + String message = response.getMessage(); + int end = message.indexOf(' '); + if (end == -1) + { + return message; + } + else + { + return message.substring(0, end); + } + default: + throw new FTPException(response); + } + } + + /** + * Does nothing. + * This method can be used to ensure that the connection does not time + * out. + */ + public void noop() + throws IOException + { + send(NOOP); + FTPResponse response = getResponse(); + switch (response.getCode()) + { + case 200: + break; + default: + throw new FTPException(response); + } + } + + // -- I/O -- + + /** + * Sends the specified command line to the server. + * The CRLF sequence is automatically appended. + * @param cmd the command line to send + */ + protected void send(String cmd) + throws IOException + { + byte[] data = cmd.getBytes(US_ASCII); + out.write(data); + out.writeln(); + out.flush(); + } + + /** + * Reads the next response from the server. + * If the server sends the "transfer complete" code, this is handled here, + * and the next response is passed to the caller. + */ + protected FTPResponse getResponse() + throws IOException + { + FTPResponse response = readResponse(); + if (response.getCode() == 226) + { + if (dtp != null) + { + dtp.transferComplete(); + } + response = readResponse(); + } + return response; + } + + /** + * Reads and parses the next response from the server. + */ + protected FTPResponse readResponse() + throws IOException + { + String line = in.readLine(); + if (line == null) + { + throw new ProtocolException( "EOF"); + } + if (line.length() < 4) + { + throw new ProtocolException(line); + } + int code = parseCode(line); + if (code == -1) + { + throw new ProtocolException(line); + } + char c = line.charAt(3); + if (c == ' ') + { + return new FTPResponse(code, line.substring(4)); + } + else if (c == '-') + { + StringBuffer buf = new StringBuffer(line.substring(4)); + buf.append('\n'); + while(true) + { + line = in.readLine(); + if (line == null) + { + throw new ProtocolException("EOF"); + } + if (line.length() >= 4 && + line.charAt(3) == ' ' && + parseCode(line) == code) + { + return new FTPResponse(code, line.substring(4), + buf.toString()); + } + else + { + buf.append(line); + buf.append('\n'); + } + } + } + else + { + throw new ProtocolException(line); + } + } + + /* + * Parses the 3-digit numeric code at the beginning of the given line. + * Returns -1 on failure. + */ + static final int parseCode(String line) + { + char[] c = { line.charAt(0), line.charAt(1), line.charAt(2) }; + int ret = 0; + for (int i = 0; i < 3; i++) + { + int digit =((int) c[i]) - 0x30; + if (digit < 0 || digit > 9) + { + return -1; + } + // Computing integer powers is way too expensive in Java! + switch (i) + { + case 0: + ret +=(100 * digit); + break; + case 1: + ret +=(10 * digit); + break; + case 2: + ret += digit; + break; + } + } + return ret; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPException.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPException.java new file mode 100644 index 0000000..14ad381 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPException.java @@ -0,0 +1,76 @@ +/* FTPException.java -- + Copyright (C) 2003. 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.java.net.protocol.ftp; + +import java.io.IOException; + +/** + * An FTP control exception. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class FTPException + extends IOException +{ + + /** + * The response that provoked this exception. + */ + protected final FTPResponse response; + + /** + * Constructs a new FTP exception. + * @param response the response that provoked this exception + */ + public FTPException(FTPResponse response) + { + super(response.getMessage()); + this.response = response; + } + + /** + * Returns the response that provoked this exception. + */ + public FTPResponse getResponse() + { + return response; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPResponse.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPResponse.java new file mode 100644 index 0000000..ec72c73 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPResponse.java @@ -0,0 +1,112 @@ +/* FTPResponse.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +/** + * An FTP control response. + * + * @author Chris Burdess (dog@gnu.org) + */ +public final class FTPResponse +{ + + /** + * The 3-digit status code. + */ + protected final int code; + + /** + * The human-readable message. + */ + protected final String message; + + /** + * Multiline data, if present. + */ + protected final String data; + + /** + * Constructs a new FTP response. + * @param code the status code + * @param message the message + */ + public FTPResponse(int code, String message) + { + this(code, message, null); + } + + /** + * Constructs a new multiline FTP response. + * @param code the status code + * @param message the message + * @param data multiline data + */ + public FTPResponse(int code, String message, String data) + { + this.code = code; + this.message = message; + this.data = data; + } + + /** + * Returns the 3-digit status code. + */ + public int getCode() + { + return code; + } + + /** + * Returns the human-readable message. + */ + public String getMessage() + { + return message; + } + + /** + * Returns the multiline data, or null if there was no such data. + */ + public String getData() + { + return data; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java new file mode 100644 index 0000000..62c40f1 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java @@ -0,0 +1,398 @@ +/* FTPURLConnection.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import gnu.java.net.GetLocalHostAction; +import gnu.java.security.action.GetPropertyAction; + +import java.io.FileNotFoundException; +import java.io.FilterInputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.URL; +import java.net.URLConnection; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.HashMap; +import java.util.Map; + +/** + * An FTP URL connection. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class FTPURLConnection + extends URLConnection +{ + + /** + * The connection managing the protocol exchange. + */ + protected FTPConnection connection; + + protected boolean passive; + protected int representationType; + protected int fileStructure; + protected int transferMode; + + /** + * Constructs an FTP connection to the specified URL. + * @param url the URL + */ + public FTPURLConnection(URL url) + { + super(url); + passive = true; + representationType = FTPConnection.TYPE_BINARY; + fileStructure = -1; + transferMode = -1; + } + + /** + * Establishes the connection. + */ + public void connect() + throws IOException + { + if (connected) + { + return; + } + String host = url.getHost(); + int port = url.getPort(); + String username = url.getUserInfo(); + String password = null; + if (username != null) + { + int ci = username.indexOf(':'); + if (ci != -1) + { + password = username.substring(ci + 1); + username = username.substring(0, ci); + } + } + else + { + username = "anonymous"; + PrivilegedAction a = new GetPropertyAction("user.name"); + String systemUsername =(String) AccessController.doPrivileged(a); + a = new GetLocalHostAction(); + InetAddress localhost =(InetAddress) AccessController.doPrivileged(a); + password = systemUsername + "@" + + ((localhost == null) ? "localhost" : localhost.getHostName()); + } + connection = new FTPConnection(host, port); + if (!connection.authenticate(username, password)) + { + throw new SecurityException("Authentication failed"); + } + connection.setPassive(passive); + if (representationType != -1) + { + connection.setRepresentationType(representationType); + } + if (fileStructure != -1) + { + connection.setFileStructure(fileStructure); + } + if (transferMode != -1) + { + connection.setTransferMode(transferMode); + } + } + + /** + * This connection supports doInput. + */ + public void setDoInput(boolean doinput) + { + doInput = doinput; + } + + /** + * This connection supports doOutput. + */ + public void setDoOutput(boolean dooutput) + { + doOutput = dooutput; + } + + /** + * Returns an input stream that reads from this open connection. + */ + public InputStream getInputStream() + throws IOException + { + if (!connected) + { + connect(); + } + String path = url.getPath(); + String filename = null; + int lsi = path.lastIndexOf('/'); + if (lsi != -1) + { + filename = path.substring(lsi + 1); + path = path.substring(0, lsi); + if (!connection.changeWorkingDirectory(path)) + { + throw new FileNotFoundException(path); + } + } + if (filename != null && filename.length() > 0) + { + return this.new ClosingInputStream(connection.retrieve(filename)); + } + else + { + return this.new ClosingInputStream(connection.list(null)); + } + } + + /** + * Returns an output stream that writes to this connection. + */ + public OutputStream getOutputStream() + throws IOException + { + if (!connected) + { + connect(); + } + String dir = url.getPath(); + String filename = url.getFile(); + if (!connection.changeWorkingDirectory(dir)) + { + throw new FileNotFoundException(dir); + } + if (filename != null) + { + return this.new ClosingOutputStream(connection.store(filename)); + } + else + { + throw new FileNotFoundException(filename); + } + } + + public String getRequestProperty(String key) + { + if ("passive".equals(key)) + { + return Boolean.toString(passive); + } + else if ("representationType".equals(key)) + { + switch (representationType) + { + case FTPConnection.TYPE_ASCII: + return "ASCII"; + case FTPConnection.TYPE_EBCDIC: + return "EBCDIC"; + case FTPConnection.TYPE_BINARY: + return "BINARY"; + } + } + else if ("fileStructure".equals(key)) + { + switch (fileStructure) + { + case FTPConnection.STRUCTURE_FILE: + return "FILE"; + case FTPConnection.STRUCTURE_RECORD: + return "RECORD"; + case FTPConnection.STRUCTURE_PAGE: + return "PAGE"; + } + } + else if ("transferMode".equals(key)) + { + switch (transferMode) + { + case FTPConnection.MODE_STREAM: + return "STREAM"; + case FTPConnection.MODE_BLOCK: + return "BLOCK"; + case FTPConnection.MODE_COMPRESSED: + return "COMPRESSED"; + } + } + return null; + } + + public Map getRequestProperties() + { + Map map = new HashMap(); + addRequestPropertyValue(map, "passive"); + addRequestPropertyValue(map, "representationType"); + addRequestPropertyValue(map, "fileStructure"); + addRequestPropertyValue(map, "transferMode"); + return map; + } + + private void addRequestPropertyValue(Map map, String key) + { + String value = getRequestProperty(key); + map.put(key, value); + } + + public void setRequestProperty(String key, String value) + { + if (connected) + { + throw new IllegalStateException(); + } + if ("passive".equals(key)) + { + passive = Boolean.valueOf(value).booleanValue(); + } + else if ("representationType".equals(key)) + { + if ("A".equalsIgnoreCase(value) || + "ASCII".equalsIgnoreCase(value)) + { + representationType = FTPConnection.TYPE_ASCII; + } + else if ("E".equalsIgnoreCase(value) || + "EBCDIC".equalsIgnoreCase(value)) + { + representationType = FTPConnection.TYPE_EBCDIC; + } + else if ("I".equalsIgnoreCase(value) || + "BINARY".equalsIgnoreCase(value)) + { + representationType = FTPConnection.TYPE_BINARY; + } + else + { + throw new IllegalArgumentException(value); + } + } + else if ("fileStructure".equals(key)) + { + if ("F".equalsIgnoreCase(value) || + "FILE".equalsIgnoreCase(value)) + { + fileStructure = FTPConnection.STRUCTURE_FILE; + } + else if ("R".equalsIgnoreCase(value) || + "RECORD".equalsIgnoreCase(value)) + { + fileStructure = FTPConnection.STRUCTURE_RECORD; + } + else if ("P".equalsIgnoreCase(value) || + "PAGE".equalsIgnoreCase(value)) + { + fileStructure = FTPConnection.STRUCTURE_PAGE; + } + else + { + throw new IllegalArgumentException(value); + } + } + else if ("transferMode".equals(key)) + { + if ("S".equalsIgnoreCase(value) || + "STREAM".equalsIgnoreCase(value)) + { + transferMode = FTPConnection.MODE_STREAM; + } + else if ("B".equalsIgnoreCase(value) || + "BLOCK".equalsIgnoreCase(value)) + { + transferMode = FTPConnection.MODE_BLOCK; + } + else if ("C".equalsIgnoreCase(value) || + "COMPRESSED".equalsIgnoreCase(value)) + { + transferMode = FTPConnection.MODE_COMPRESSED; + } + else + { + throw new IllegalArgumentException(value); + } + } + } + + public void addRequestProperty(String key, String value) + { + setRequestProperty(key, value); + } + + class ClosingInputStream + extends FilterInputStream + { + + ClosingInputStream(InputStream in) + { + super(in); + } + + public void close() + throws IOException + { + super.close(); + connection.logout(); + } + + } + + class ClosingOutputStream + extends FilterOutputStream + { + + ClosingOutputStream(OutputStream out) + { + super(out); + } + + public void close() + throws IOException + { + super.close(); + connection.logout(); + } + + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/Handler.java b/libjava/classpath/gnu/java/net/protocol/ftp/Handler.java new file mode 100644 index 0000000..88491b3 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/Handler.java @@ -0,0 +1,70 @@ +/* Handler.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * An FTP URL stream handler. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Handler + extends URLStreamHandler +{ + + protected int getDefaultPort() + { + return FTPConnection.FTP_PORT; + } + + /** + * Returns an FTPURLConnection for the given URL. + */ + public URLConnection openConnection(URL url) + throws IOException + { + return new FTPURLConnection(url); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/PassiveModeDTP.java b/libjava/classpath/gnu/java/net/protocol/ftp/PassiveModeDTP.java new file mode 100644 index 0000000..6f4fd63 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/PassiveModeDTP.java @@ -0,0 +1,201 @@ +/* PassiveModeDTP.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; + +/** + * A passive mode FTP data transfer process. + * This connects to the host specified and proxies the resulting socket's + * input and output streams. + * + * @author Chris Burdess (dog@gnu.org) + */ +final class PassiveModeDTP + implements DTP +{ + + final String address; + final int port; + Socket socket; + DTPInputStream in; + DTPOutputStream out; + boolean completed; + boolean inProgress; + int transferMode; + + PassiveModeDTP(String address, int port, InetAddress localhost, + int connectionTimeout, int timeout) + throws IOException + { + this.address = address; + this.port = port; + completed = false; + inProgress = false; + socket = new Socket(); + InetSocketAddress remote = new InetSocketAddress(address, port); + InetSocketAddress local = new InetSocketAddress(localhost, port + 1); + socket.bind(local); + if (connectionTimeout > 0) + { + socket.connect(remote, connectionTimeout); + } + else + { + socket.connect(remote); + } + if (timeout > 0) + { + socket.setSoTimeout(timeout); + } + } + + /** + * Returns an input stream from which a remote file can be read. + */ + public InputStream getInputStream() + throws IOException + { + if (inProgress) + { + throw new IOException("Transfer in progress"); + } + switch (transferMode) + { + case FTPConnection.MODE_STREAM: + in = new StreamInputStream(this, socket.getInputStream()); + break; + case FTPConnection.MODE_BLOCK: + in = new BlockInputStream(this, socket.getInputStream()); + break; + case FTPConnection.MODE_COMPRESSED: + in = new CompressedInputStream(this, socket.getInputStream()); + break; + default: + throw new IllegalStateException("Invalid transfer mode"); + } + in.setTransferComplete(false); + return in; + } + + /** + * Returns an output stream to which a local file can be written for + * upload. + */ + public OutputStream getOutputStream() + throws IOException + { + if (inProgress) + { + throw new IOException("Transfer in progress"); + } + switch (transferMode) + { + case FTPConnection.MODE_STREAM: + out = new StreamOutputStream(this, socket.getOutputStream()); + break; + case FTPConnection.MODE_BLOCK: + out = new BlockOutputStream(this, socket.getOutputStream()); + break; + case FTPConnection.MODE_COMPRESSED: + out = new CompressedOutputStream(this, socket.getOutputStream()); + break; + default: + throw new IllegalStateException("Invalid transfer mode"); + } + out.setTransferComplete(false); + return out; + } + + public void setTransferMode(int mode) + { + transferMode = mode; + } + + public void complete() + { + completed = true; + if (!inProgress) + { + transferComplete(); + } + } + + public boolean abort() + { + completed = true; + transferComplete(); + return inProgress; + } + + /* + * Called by DTPInputStream or DTPOutputStream when end of + * stream is reached. + */ + public void transferComplete() + { + if (in != null) + { + in.setTransferComplete(true); + } + if (out != null) + { + out.setTransferComplete(true); + } + inProgress = false; + completed = completed ||(transferMode == FTPConnection.MODE_STREAM); + if (completed && socket != null) + { + try + { + socket.close(); + } + catch (IOException e) + { + } + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/StreamInputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/StreamInputStream.java new file mode 100644 index 0000000..93eee4e --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/StreamInputStream.java @@ -0,0 +1,95 @@ +/* StreamInputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A DTP input stream that implements the FTP stream data transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class StreamInputStream + extends DTPInputStream +{ + + StreamInputStream(DTP dtp, InputStream in) + { + super(dtp, in); + } + + public int read() + throws IOException + { + if (transferComplete) + { + return -1; + } + int c = in.read(); + if (c == -1) + { + close(); + } + return c; + } + + public int read(byte[] buf) + throws IOException + { + return read(buf, 0, buf.length); + } + + public int read(byte[] buf, int off, int len) + throws IOException + { + if (transferComplete) + { + return -1; + } + int l = in.read(buf, off, len); + if (l == -1) + { + close(); + } + return l; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/StreamOutputStream.java b/libjava/classpath/gnu/java/net/protocol/ftp/StreamOutputStream.java new file mode 100644 index 0000000..a6e28ec --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/StreamOutputStream.java @@ -0,0 +1,85 @@ +/* StreamOutputStream.java -- + Copyright (C) 2003, 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.java.net.protocol.ftp; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A DTP output stream that implements the FTP stream transfer mode. + * + * @author Chris Burdess (dog@gnu.org) + */ +class StreamOutputStream + extends DTPOutputStream +{ + + StreamOutputStream(DTP dtp, OutputStream out) + { + super(dtp, out); + } + + public void write(int c) + throws IOException + { + if (transferComplete) + { + return; + } + out.write(c); + } + + public void write(byte[] b) + throws IOException + { + write(b, 0, b.length); + } + + public void write(byte[] b, int off, int len) + throws IOException + { + if (transferComplete) + { + return; + } + out.write(b, off, len); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/package.html b/libjava/classpath/gnu/java/net/protocol/ftp/package.html new file mode 100644 index 0000000..fa3e34d --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/ftp/package.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net.protocol.ftp package. + Copyright (C) 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net.protocol.ftp</title></head> + +<body> + +<p> +This package contains an FTP client. It can handle both active and passive +mode connections and the various transfer modes and representation types. +</p> + +<p> +Interaction with the server is via a simple stream interface. Only one +concurrent stream (input or output) is supported. +</p> + +<p> +The control connection to the server can be protected using TLS +(the starttls method). +</p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/net/protocol/http/Authenticator.java b/libjava/classpath/gnu/java/net/protocol/http/Authenticator.java new file mode 100644 index 0000000..0d7c988 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Authenticator.java @@ -0,0 +1,59 @@ +/* Authenticator.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Callback interface for managing authentication. + * @see Request#setAuthenticator + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface Authenticator +{ + + /** + * Returns the credentials to supply for the given realm. + * @param realm the authentication realm + * @param attempt zero on first authentication attempt, increments on each + * unsuccessful attempt + */ + Credentials getCredentials(String realm, int attempt); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/ByteArrayRequestBodyWriter.java b/libjava/classpath/gnu/java/net/protocol/http/ByteArrayRequestBodyWriter.java new file mode 100644 index 0000000..35ad2bc --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/ByteArrayRequestBodyWriter.java @@ -0,0 +1,107 @@ +/* ByteArrayRequestBodyWriter.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * A simple request body writer using a byte array. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class ByteArrayRequestBodyWriter + implements RequestBodyWriter +{ + + /** + * The content. + */ + protected byte[] content; + + /** + * The position within the content at which the next read will occur. + */ + protected int pos; + + /** + * Constructs a new byte array request body writer with the specified + * content. + * @param content the content buffer + */ + public ByteArrayRequestBodyWriter(byte[] content) + { + this.content = content; + pos = 0; + } + + /** + * Returns the total number of bytes that will be written in a single pass + * by this writer. + */ + public int getContentLength() + { + return content.length; + } + + /** + * Initialises the writer. + * This will be called before each pass. + */ + public void reset() + { + pos = 0; + } + + /** + * Writes body content to the supplied buffer. + * @param buffer the content buffer + * @return the number of bytes written + */ + public int write(byte[] buffer) + { + int len = content.length - pos; + len = (buffer.length < len) ? buffer.length : len; + if (len > -1) + { + System.arraycopy(content, pos, buffer, 0, len); + pos += len; + } + return len; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java b/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java new file mode 100644 index 0000000..680e45d --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java @@ -0,0 +1,123 @@ +/* Authenticator.java --ByteArrayResponseBodyReader.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Simple response body reader that stores content in a byte array. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class ByteArrayResponseBodyReader + implements ResponseBodyReader +{ + + /** + * The content. + */ + protected byte[] content; + + /** + * The position in the content at which the next write will occur. + */ + protected int pos; + + /** + * The length of the buffer. + */ + protected int len; + + /** + * Constructs a new byte array response body reader. + */ + public ByteArrayResponseBodyReader() + { + this(4096); + } + + /** + * Constructs a new byte array response body reader with the specified + * initial buffer size. + * @param size the initial buffer size + */ + public ByteArrayResponseBodyReader(int size) + { + content = new byte[size]; + pos = len = 0; + } + + /** + * This reader accepts all responses. + */ + public boolean accept(Request request, Response response) + { + return true; + } + + public void read(byte[] buffer, int offset, int length) + { + int l = length - offset; + if (pos + l > content.length) + { + byte[] tmp = new byte[content.length * 2]; + System.arraycopy(content, 0, tmp, 0, pos); + content = tmp; + } + System.arraycopy(buffer, offset, content, pos, l); + pos += l; + len = pos; + } + + public void close() + { + pos = 0; + } + + /** + * Retrieves the content of this reader as a byte array. + * The size of the returned array is the number of bytes read. + */ + public byte[] toByteArray() + { + byte[] ret = new byte[len]; + System.arraycopy(content, 0, ret, 0, len); + return ret; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java new file mode 100644 index 0000000..c0706b7 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java @@ -0,0 +1,172 @@ +/* ChunkedInputStream.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.ProtocolException; + +/** + * Input stream wrapper for the "chunked" transfer-coding. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class ChunkedInputStream + extends FilterInputStream +{ + + private static final byte CR = 0x0d; + private static final byte LF = 0x0a; + + int size; + int count; + boolean meta; + boolean eof; + Headers headers; + + /** + * Constructor. + * @param in the response socket input stream + * @param headers the headers to receive additional header lines + */ + public ChunkedInputStream(InputStream in, Headers headers) + { + super(in); + this.headers = headers; + size = -1; + count = 0; + meta = true; + } + + public int read() + throws IOException + { + byte[] buf = new byte[1]; + int len = read(buf, 0, 1); + if (len == -1) + { + return -1; + } + int ret = (int) buf[0]; + if (ret < 0) + { + ret += 0x100; + } + return ret; + } + + public int read(byte[] buffer) + throws IOException + { + return read(buffer, 0, buffer.length); + } + + public int read(byte[] buffer, int offset, int length) + throws IOException + { + if (eof) + { + return -1; + } + if (meta) + { + // Read chunk header + int c, last = 0; + boolean seenSemi = false; + StringBuffer buf = new StringBuffer(); + do + { + c = in.read(); + if (c == 0x3b) // ; + { + seenSemi = true; + } + else if (c == 0x0a && last == 0x0d) // CRLF + { + size = Integer.parseInt(buf.toString(), 16); + break; + } + else if (!seenSemi && c >= 0x30) + { + buf.append ((char) c); + } + last = c; + } + while(c != -1); + count = 0; + meta = false; + } + if (size == 0) + { + // Read trailer + headers.parse(in); + eof = true; + return -1; + } + else + { + int diff = length - offset; + int max = size - count; + max = (diff < max) ? diff : max; + int len = (max > 0) ? in.read(buffer, offset, max) : 0; + count += len; + if (count == size) + { + // Read CRLF + int c1 = in.read(); + int c2 = in.read(); + if (c1 == -1 && c2 == -1) + { + // EOF before CRLF: bad, but ignore + eof = true; + return -1; + } + if (c1 != 0x0d || c2 != 0x0a) + { + throw new ProtocolException("expecting CRLF: " + c1 + "," + c2); + } + meta = true; + } + return len; + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/Cookie.java b/libjava/classpath/gnu/java/net/protocol/http/Cookie.java new file mode 100644 index 0000000..45e2f73 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Cookie.java @@ -0,0 +1,160 @@ +/* Cookie.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.util.Date; + +/** + * An HTTP cookie, as specified in RFC 2109. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Cookie +{ + + /** + * The name of the cookie. + */ + protected final String name; + + /** + * The value of the cookie. + */ + protected final String value; + + /** + * Optional documentation of the intended use of the cookie. + */ + protected final String comment; + + /** + * The domain for which the cookie is valid. + */ + protected final String domain; + + /** + * Optional subset of URL paths within the domain for which the cookie is + * valid. + */ + protected final String path; + + /** + * Indicates that the user-agent should only use secure means to transmit + * this cookie to the server. + */ + protected final boolean secure; + + /** + * The date at which this cookie expires. + */ + protected final Date expires; + + public Cookie(String name, String value, String comment, String domain, + String path, boolean secure, Date expires) + { + this.name = name; + this.value = value; + this.comment = comment; + this.domain = domain; + this.path = path; + this.secure = secure; + this.expires = expires; + } + + public String getName() + { + return name; + } + + public String getValue() + { + return value; + } + + public String getComment() + { + return comment; + } + + public String getDomain() + { + return domain; + } + + public String getPath() + { + return path; + } + + public boolean isSecure() + { + return secure; + } + + public Date getExpiryDate() + { + return expires; + } + + public String toString() + { + return toString(true, true); + } + + public String toString(boolean showPath, boolean showDomain) + { + StringBuffer buf = new StringBuffer(); + buf.append(name); + buf.append('='); + buf.append(value); + if (showPath) + { + buf.append("; $Path="); + buf.append(path); + } + if (showDomain) + { + buf.append("; $Domain="); + buf.append(domain); + } + return buf.toString(); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/CookieManager.java b/libjava/classpath/gnu/java/net/protocol/http/CookieManager.java new file mode 100644 index 0000000..cc1225c --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/CookieManager.java @@ -0,0 +1,65 @@ +/* CookieManager.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Cookie manager interface. + * If an application wants to handle cookies, they should implement this + * interface and register the instance with each HTTPConnection they use. + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface CookieManager +{ + + /** + * Stores a cookie in the cookie manager. + * @param cookie the cookie to store + */ + void setCookie(Cookie cookie); + + /** + * Retrieves the cookies matching the specified criteria. + * @param host the host name + * @param secure whether the connection is secure + * @param path the path to access + */ + Cookie[] getCookies(String host, boolean secure, String path); + +} diff --git a/libjava/classpath/gnu/java/net/protocol/http/Credentials.java b/libjava/classpath/gnu/java/net/protocol/http/Credentials.java new file mode 100644 index 0000000..9e5fcd1 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Credentials.java @@ -0,0 +1,88 @@ +/* Credentials.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Represents a username/password combination that can be used to + * authenticate to an HTTP server. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Credentials +{ + + /** + * The username. + */ + private String username; + + /** + * The password. + */ + private String password; + + /** + * Constructor. + * @param username the username + * @param password the password + */ + public Credentials(String username, String password) + { + this.username = username; + this.password = password; + } + + /** + * Returns the username. + */ + public String getUsername() + { + return username; + } + + /** + * Returns the password. + */ + public String getPassword() + { + return password; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java new file mode 100644 index 0000000..6d9f447 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java @@ -0,0 +1,681 @@ +/* HTTPConnection.java -- + Copyright (C) 2004, 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.java.net.protocol.http; + +import gnu.classpath.Configuration; +import gnu.classpath.SystemProperties; +import gnu.java.net.EmptyX509TrustManager; +import gnu.java.net.protocol.http.event.ConnectionEvent; +import gnu.java.net.protocol.http.event.ConnectionListener; +import gnu.java.net.protocol.http.event.RequestEvent; +import gnu.java.net.protocol.http.event.RequestListener; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + +/** + * A connection to an HTTP server. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class HTTPConnection +{ + + /** + * The default HTTP port. + */ + public static final int HTTP_PORT = 80; + + /** + * The default HTTPS port. + */ + public static final int HTTPS_PORT = 443; + + private static final String userAgent = SystemProperties.getProperty("http.agent"); + + /** + * The host name of the server to connect to. + */ + protected final String hostname; + + /** + * The port to connect to. + */ + protected final int port; + + /** + * Whether the connection should use transport level security (HTTPS). + */ + protected final boolean secure; + + /** + * The connection timeout for connecting the underlying socket. + */ + protected final int connectionTimeout; + + /** + * The read timeout for reads on the underlying socket. + */ + protected final int timeout; + + /** + * The host name of the proxy to connect to. + */ + protected String proxyHostname; + + /** + * The port on the proxy to connect to. + */ + protected int proxyPort; + + /** + * The major version of HTTP supported by this client. + */ + protected int majorVersion; + + /** + * The minor version of HTTP supported by this client. + */ + protected int minorVersion; + + private final List connectionListeners; + private final List requestListeners; + private final List handshakeCompletedListeners; + + /** + * The socket this connection communicates on. + */ + protected Socket socket; + + /** + * The SSL socket factory to use. + */ + private SSLSocketFactory sslSocketFactory; + + /** + * The socket input stream. + */ + protected InputStream in; + + /** + * The socket output stream. + */ + protected OutputStream out; + + /** + * Nonce values seen by this connection. + */ + private Map nonceCounts; + + /** + * The cookie manager for this connection. + */ + protected CookieManager cookieManager; + + /** + * Creates a new HTTP connection. + * @param hostname the name of the host to connect to + */ + public HTTPConnection(String hostname) + { + this(hostname, HTTP_PORT, false, 0, 0); + } + + /** + * Creates a new HTTP or HTTPS connection. + * @param hostname the name of the host to connect to + * @param secure whether to use a secure connection + */ + public HTTPConnection(String hostname, boolean secure) + { + this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure, 0, 0); + } + + /** + * Creates a new HTTP or HTTPS connection on the specified port. + * @param hostname the name of the host to connect to + * @param secure whether to use a secure connection + * @param connectionTimeout the connection timeout + * @param timeout the socket read timeout + */ + public HTTPConnection(String hostname, boolean secure, + int connectionTimeout, int timeout) + { + this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure, + connectionTimeout, timeout); + } + + /** + * Creates a new HTTP connection on the specified port. + * @param hostname the name of the host to connect to + * @param port the port on the host to connect to + */ + public HTTPConnection(String hostname, int port) + { + this(hostname, port, false, 0, 0); + } + + /** + * Creates a new HTTP or HTTPS connection on the specified port. + * @param hostname the name of the host to connect to + * @param port the port on the host to connect to + * @param secure whether to use a secure connection + */ + public HTTPConnection(String hostname, int port, boolean secure) + { + this(hostname, port, secure, 0, 0); + } + + /** + * Creates a new HTTP or HTTPS connection on the specified port. + * @param hostname the name of the host to connect to + * @param port the port on the host to connect to + * @param secure whether to use a secure connection + * @param connectionTimeout the connection timeout + * @param timeout the socket read timeout + */ + public HTTPConnection(String hostname, int port, boolean secure, + int connectionTimeout, int timeout) + { + this.hostname = hostname; + this.port = port; + this.secure = secure; + this.connectionTimeout = connectionTimeout; + this.timeout = timeout; + majorVersion = minorVersion = 1; + connectionListeners = new ArrayList(4); + requestListeners = new ArrayList(4); + handshakeCompletedListeners = new ArrayList(2); + } + + /** + * Returns the name of the host to connect to. + */ + public String getHostName() + { + return hostname; + } + + /** + * Returns the port on the host to connect to. + */ + public int getPort() + { + return port; + } + + /** + * Indicates whether to use a secure connection or not. + */ + public boolean isSecure() + { + return secure; + } + + /** + * Returns the HTTP version string supported by this connection. + * @see #version + */ + public String getVersion() + { + return "HTTP/" + majorVersion + '.' + minorVersion; + } + + /** + * Sets the HTTP version supported by this connection. + * @param majorVersion the major version + * @param minorVersion the minor version + */ + public void setVersion(int majorVersion, int minorVersion) + { + if (majorVersion != 1) + { + throw new IllegalArgumentException("major version not supported: " + + majorVersion); + } + if (minorVersion < 0 || minorVersion > 1) + { + throw new IllegalArgumentException("minor version not supported: " + + minorVersion); + } + this.majorVersion = majorVersion; + this.minorVersion = minorVersion; + } + + /** + * Directs this connection to use the specified proxy. + * @param hostname the proxy host name + * @param port the port on the proxy to connect to + */ + public void setProxy(String hostname, int port) + { + proxyHostname = hostname; + proxyPort = port; + } + + /** + * Indicates whether this connection is using an HTTP proxy. + */ + public boolean isUsingProxy() + { + return (proxyHostname != null && proxyPort > 0); + } + + /** + * Sets the cookie manager to use for this connection. + * @param cookieManager the cookie manager + */ + public void setCookieManager(CookieManager cookieManager) + { + this.cookieManager = cookieManager; + } + + /** + * Returns the cookie manager in use for this connection. + */ + public CookieManager getCookieManager() + { + return cookieManager; + } + + /** + * Creates a new request using this connection. + * @param method the HTTP method to invoke + * @param path the URI-escaped RFC2396 <code>abs_path</code> with + * optional query part + */ + public Request newRequest(String method, String path) + { + if (method == null || method.length() == 0) + { + throw new IllegalArgumentException("method must have non-zero length"); + } + if (path == null || path.length() == 0) + { + path = "/"; + } + Request ret = new Request(this, method, path); + if ((secure && port != HTTPS_PORT) || + (!secure && port != HTTP_PORT)) + { + ret.setHeader("Host", hostname + ":" + port); + } + else + { + ret.setHeader("Host", hostname); + } + ret.setHeader("User-Agent", userAgent); + ret.setHeader("Connection", "keep-alive"); + ret.setHeader("Accept-Encoding", + "chunked;q=1.0, gzip;q=0.9, deflate;q=0.8, " + + "identity;q=0.6, *;q=0"); + if (cookieManager != null) + { + Cookie[] cookies = cookieManager.getCookies(hostname, secure, path); + if (cookies != null && cookies.length > 0) + { + StringBuffer buf = new StringBuffer(); + buf.append("$Version=1"); + for (int i = 0; i < cookies.length; i++) + { + buf.append(','); + buf.append(' '); + buf.append(cookies[i].toString()); + } + ret.setHeader("Cookie", buf.toString()); + } + } + fireRequestEvent(RequestEvent.REQUEST_CREATED, ret); + return ret; + } + + /** + * Closes this connection. + */ + public void close() + throws IOException + { + try + { + closeConnection(); + } + finally + { + fireConnectionEvent(ConnectionEvent.CONNECTION_CLOSED); + } + } + + /** + * Retrieves the socket associated with this connection. + * This creates the socket if necessary. + */ + protected synchronized Socket getSocket() + throws IOException + { + if (socket == null) + { + String connectHostname = hostname; + int connectPort = port; + if (isUsingProxy()) + { + connectHostname = proxyHostname; + connectPort = proxyPort; + } + socket = new Socket(); + InetSocketAddress address = + new InetSocketAddress(connectHostname, connectPort); + if (connectionTimeout > 0) + { + socket.connect(address, connectionTimeout); + } + else + { + socket.connect(address); + } + if (timeout > 0) + { + socket.setSoTimeout(timeout); + } + if (secure) + { + try + { + SSLSocketFactory factory = getSSLSocketFactory(); + SSLSocket ss = + (SSLSocket) factory.createSocket(socket, connectHostname, + connectPort, true); + String[] protocols = { "TLSv1", "SSLv3" }; + ss.setEnabledProtocols(protocols); + ss.setUseClientMode(true); + synchronized (handshakeCompletedListeners) + { + if (!handshakeCompletedListeners.isEmpty()) + { + for (Iterator i = + handshakeCompletedListeners.iterator(); + i.hasNext(); ) + { + HandshakeCompletedListener l = + (HandshakeCompletedListener) i.next(); + ss.addHandshakeCompletedListener(l); + } + } + } + ss.startHandshake(); + socket = ss; + } + catch (GeneralSecurityException e) + { + throw new IOException(e.getMessage()); + } + } + in = socket.getInputStream(); + in = new BufferedInputStream(in); + out = socket.getOutputStream(); + out = new BufferedOutputStream(out); + } + return socket; + } + + SSLSocketFactory getSSLSocketFactory() + throws GeneralSecurityException + { + if (sslSocketFactory == null) + { + TrustManager tm = new EmptyX509TrustManager(); + SSLContext context = SSLContext.getInstance("SSL"); + TrustManager[] trust = new TrustManager[] { tm }; + context.init(null, trust, null); + sslSocketFactory = context.getSocketFactory(); + } + return sslSocketFactory; + } + + void setSSLSocketFactory(SSLSocketFactory factory) + { + sslSocketFactory = factory; + } + + protected synchronized InputStream getInputStream() + throws IOException + { + if (socket == null) + { + getSocket(); + } + return in; + } + + protected synchronized OutputStream getOutputStream() + throws IOException + { + if (socket == null) + { + getSocket(); + } + return out; + } + + /** + * Closes the underlying socket, if any. + */ + protected synchronized void closeConnection() + throws IOException + { + if (socket != null) + { + try + { + socket.close(); + } + finally + { + socket = null; + } + } + } + + /** + * Returns a URI representing the connection. + * This does not include any request path component. + */ + protected String getURI() + { + StringBuffer buf = new StringBuffer(); + buf.append(secure ? "https://" : "http://"); + buf.append(hostname); + if (secure) + { + if (port != HTTPConnection.HTTPS_PORT) + { + buf.append(':'); + buf.append(port); + } + } + else + { + if (port != HTTPConnection.HTTP_PORT) + { + buf.append(':'); + buf.append(port); + } + } + return buf.toString(); + } + + /** + * Get the number of times the specified nonce has been seen by this + * connection. + */ + int getNonceCount(String nonce) + { + if (nonceCounts == null) + { + return 0; + } + return((Integer) nonceCounts.get(nonce)).intValue(); + } + + /** + * Increment the number of times the specified nonce has been seen. + */ + void incrementNonce(String nonce) + { + int current = getNonceCount(nonce); + if (nonceCounts == null) + { + nonceCounts = new HashMap(); + } + nonceCounts.put(nonce, new Integer(current + 1)); + } + + // -- Events -- + + public void addConnectionListener(ConnectionListener l) + { + synchronized (connectionListeners) + { + connectionListeners.add(l); + } + } + + public void removeConnectionListener(ConnectionListener l) + { + synchronized (connectionListeners) + { + connectionListeners.remove(l); + } + } + + protected void fireConnectionEvent(int type) + { + ConnectionEvent event = new ConnectionEvent(this, type); + ConnectionListener[] l = null; + synchronized (connectionListeners) + { + l = new ConnectionListener[connectionListeners.size()]; + connectionListeners.toArray(l); + } + for (int i = 0; i < l.length; i++) + { + switch (type) + { + case ConnectionEvent.CONNECTION_CLOSED: + l[i].connectionClosed(event); + break; + } + } + } + + public void addRequestListener(RequestListener l) + { + synchronized (requestListeners) + { + requestListeners.add(l); + } + } + + public void removeRequestListener(RequestListener l) + { + synchronized (requestListeners) + { + requestListeners.remove(l); + } + } + + protected void fireRequestEvent(int type, Request request) + { + RequestEvent event = new RequestEvent(this, type, request); + RequestListener[] l = null; + synchronized (requestListeners) + { + l = new RequestListener[requestListeners.size()]; + requestListeners.toArray(l); + } + for (int i = 0; i < l.length; i++) + { + switch (type) + { + case RequestEvent.REQUEST_CREATED: + l[i].requestCreated(event); + break; + case RequestEvent.REQUEST_SENDING: + l[i].requestSent(event); + break; + case RequestEvent.REQUEST_SENT: + l[i].requestSent(event); + break; + } + } + } + + void addHandshakeCompletedListener(HandshakeCompletedListener l) + { + synchronized (handshakeCompletedListeners) + { + handshakeCompletedListeners.add(l); + } + } + void removeHandshakeCompletedListener(HandshakeCompletedListener l) + { + synchronized (handshakeCompletedListeners) + { + handshakeCompletedListeners.remove(l); + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPDateFormat.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPDateFormat.java new file mode 100644 index 0000000..2f59e43 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPDateFormat.java @@ -0,0 +1,441 @@ +/* HTTPDateFormat.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.FieldPosition; +import java.text.NumberFormat; +import java.text.ParsePosition; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +/** + * HTTP date formatter and parser. + * Formats dates according to RFC 822 (updated by RFC 1123). + * Parses dates according to the above, <i>or</i> RFC 1036, <i>or</i> the + * ANSI C <code>asctime()</code> format. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class HTTPDateFormat + extends DateFormat +{ + + static final String[] DAYS_OF_WEEK = { + null, "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + + static final String[] MONTHS = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + public HTTPDateFormat() + { + calendar = new GregorianCalendar(TimeZone.getTimeZone ("GMT")); + numberFormat = new DecimalFormat(); + } + + /** + * Appends the textual value for the specified field to the given string + * buffer. This method should be avoided, use <code>format(Date)</code> + * instead. + * @param date the Date object + * @param buf the buffer to append to + * @param field the current field position + * @return the modified buffer + */ + public StringBuffer format(Date date, StringBuffer buf, + FieldPosition field) + { + calendar.clear(); + calendar.setTime(date); + buf.setLength(0); + + // Day of week + buf.append(DAYS_OF_WEEK[calendar.get(Calendar.DAY_OF_WEEK)]); + buf.append(','); + buf.append(' '); + + // Day of month + int day = calendar.get(Calendar.DAY_OF_MONTH); + buf.append(Character.forDigit(day / 10, 10)); + buf.append(Character.forDigit(day % 10, 10)); + buf.append(' '); + + // Month + buf.append(MONTHS[calendar.get(Calendar.MONTH)]); + buf.append(' '); + + // Year + int year = calendar.get(Calendar.YEAR); + if (year < 1000) + { + buf.append('0'); + if (year < 100) + { + buf.append('0'); + if (year < 10) + { + buf.append('0'); + } + } + } + buf.append(Integer.toString(year)); + buf.append(' '); + + // Hour + int hour = calendar.get(Calendar.HOUR_OF_DAY); + buf.append(Character.forDigit(hour / 10, 10)); + buf.append(Character.forDigit(hour % 10, 10)); + buf.append(':'); + + // Minute + int minute = calendar.get(Calendar.MINUTE); + buf.append(Character.forDigit(minute / 10, 10)); + buf.append(Character.forDigit(minute % 10, 10)); + buf.append(':'); + + // Second + int second = calendar.get(Calendar.SECOND); + buf.append(Character.forDigit(second / 10, 10)); + buf.append(Character.forDigit(second % 10, 10)); + buf.append(' '); + + // Timezone + // Get time offset in minutes + int zoneOffset =(calendar.get(Calendar.ZONE_OFFSET) + + calendar.get(Calendar.DST_OFFSET)) / 60000; + + // Apply + or - appropriately + if (zoneOffset < 0) + { + zoneOffset = -zoneOffset; + buf.append('-'); + } + else + { + buf.append('+'); + } + + // Set the 2 2-char fields as specified above + int tzhours = zoneOffset / 60; + buf.append(Character.forDigit(tzhours / 10, 10)); + buf.append(Character.forDigit(tzhours % 10, 10)); + int tzminutes = zoneOffset % 60; + buf.append(Character.forDigit(tzminutes / 10, 10)); + buf.append(Character.forDigit(tzminutes % 10, 10)); + + field.setBeginIndex(0); + field.setEndIndex(buf.length()); + return buf; + } + + /** + * Parses the given date in the current TimeZone. + * @param text the formatted date to be parsed + * @param pos the current parse position + */ + public Date parse(String text, ParsePosition pos) + { + int date, month, year, hour, minute, second; + String monthText; + int start = 0, end = -1; + int len = text.length(); + calendar.clear(); + pos.setIndex(start); + try + { + // Advance to date + if (Character.isLetter(text.charAt(start))) + { + start = skipNonWhitespace(text, start); + } + // Determine mode + switch(start) + { + case 3: + // asctime + start = skipWhitespace(text, start); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + monthText = text.substring(start, end); + month = -1; + for (int i = 0; i < 12; i++) + { + if (MONTHS[i].equals(monthText)) + { + month = i; + break; + } + } + if (month == -1) + { + pos.setErrorIndex(end); + return null; + } + // Advance to date + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + date = Integer.parseInt(text.substring(start, end)); + // Advance to hour + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + hour = Integer.parseInt(text.substring(start, end)); + // Advance to minute + start = end + 1; + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + minute = Integer.parseInt(text.substring(start, end)); + // Advance to second + start = end + 1; + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + second = Integer.parseInt(text.substring(start, end)); + // Advance to year + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + year = Integer.parseInt(text.substring(start, end)); + break; + case 0: + case 4: + // rfc822 + start = skipWhitespace(text, start); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + date = Integer.parseInt(text.substring(start, end)); + // Advance to month + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + monthText = text.substring(start, end); + month = -1; + for (int i = 0; i < 12; i++) + { + if (MONTHS[i].equals(monthText)) + { + month = i; + break; + } + } + if (month == -1) + { + pos.setErrorIndex(end); + return null; + } + // Advance to year + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + year = Integer.parseInt(text.substring(start, end)); + // Advance to hour + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + hour = Integer.parseInt(text.substring(start, end)); + // Advance to minute + start = end + 1; + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + minute = Integer.parseInt(text.substring(start, end)); + // Advance to second + start = end + 1; + pos.setIndex(start); + end = start + 1; + while (end < len && !Character.isWhitespace(text.charAt(end))) + { + end++; + } + second = Integer.parseInt(text.substring(start, end)); + break; + default: + // rfc850(obsolete) + start = skipWhitespace(text, start); + pos.setIndex(start); + end = skipTo(text, start + 1, '-'); + date = Integer.parseInt(text.substring(start, end)); + // Advance to month + start = end + 1; + pos.setIndex(start); + end = skipTo(text, start + 1, '-'); + monthText = text.substring(start, end); + month = -1; + for (int i = 0; i < 12; i++) + { + if (MONTHS[i].equals(monthText)) + { + month = i; + break; + } + } + if (month == -1) + { + pos.setErrorIndex(end); + return null; + } + // Advance to year + start = end + 1; + pos.setIndex(start); + end = skipNonWhitespace(text, start + 1); + year = 1900 + Integer.parseInt(text.substring(start, end)); + // Advance to hour + start = skipWhitespace(text, end + 1); + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + hour = Integer.parseInt(text.substring(start, end)); + // Advance to minute + start = end + 1; + pos.setIndex(start); + end = skipTo(text, start + 1, ':'); + minute = Integer.parseInt(text.substring(start, end)); + // Advance to second + start = end + 1; + pos.setIndex(start); + end = start + 1; + while (end < len && !Character.isWhitespace(text.charAt(end))) + { + end++; + } + second = Integer.parseInt(text.substring(start, end)); + } + + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month); + calendar.set(Calendar.DAY_OF_MONTH, date); + calendar.set(Calendar.HOUR, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, second); + + if (end != len) + { + // Timezone + start = skipWhitespace(text, end + 1); + end = start + 1; + while (end < len && !Character.isWhitespace(text.charAt(end))) + { + end++; + } + char pm = text.charAt(start); + if (Character.isLetter(pm)) + { + TimeZone tz = + TimeZone.getTimeZone(text.substring(start, end)); + calendar.set(Calendar.ZONE_OFFSET, tz.getRawOffset()); + } + else + { + int zoneOffset = 0; + zoneOffset += 600 * Character.digit(text.charAt(++start), 10); + zoneOffset += 60 * Character.digit(text.charAt(++start), 10); + zoneOffset += 10 * Character.digit(text.charAt(++start), 10); + zoneOffset += Character.digit(text.charAt(++start), 10); + zoneOffset *= 60000; // minutes -> ms + if ('-' == pm) + { + zoneOffset = -zoneOffset; + } + calendar.set(Calendar.ZONE_OFFSET, zoneOffset); + } + } + pos.setIndex(end); + + return calendar.getTime(); + } + catch (NumberFormatException e) + { + pos.setErrorIndex(Math.max(start, end)); + } + catch (StringIndexOutOfBoundsException e) + { + pos.setErrorIndex(Math.max(start, end)); + } + return null; + } + + private int skipWhitespace(String text, int pos) + { + while(Character.isWhitespace(text.charAt(pos))) + { + pos++; + } + return pos; + } + + private int skipNonWhitespace(String text, int pos) + { + while(!Character.isWhitespace(text.charAt(pos))) + { + pos++; + } + return pos; + } + + private int skipTo(String text, int pos, char c) + { + while(text.charAt(pos) != c) + { + pos++; + } + return pos; + } + + /** + * Don't allow setting the calendar. + */ + public void setCalendar(Calendar newCalendar) + { + throw new UnsupportedOperationException(); + } + + /** + * Don't allow setting the NumberFormat. + */ + public void setNumberFormat(NumberFormat newNumberFormat) + { + throw new UnsupportedOperationException(); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java new file mode 100644 index 0000000..9f2055f --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java @@ -0,0 +1,688 @@ +/* HTTPURLConnection.java -- + Copyright (C) 2004, 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.java.net.protocol.http; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ProtocolException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.cert.Certificate; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.net.ssl.HandshakeCompletedEvent; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSocketFactory; + +/** + * A URLConnection that uses the HTTPConnection class. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class HTTPURLConnection + extends HttpsURLConnection + implements HandshakeCompletedListener +{ + + /** + * Pool of reusable connections, used if keepAlive is true. + */ + private static final Map connectionPool = new LinkedHashMap(); + + /* + * The underlying connection. + */ + private HTTPConnection connection; + + // These are package private for use in anonymous inner classes. + String proxyHostname; + int proxyPort; + String agent; + boolean keepAlive; + int maxConnections; + + private Request request; + private Headers requestHeaders; + private ByteArrayOutputStream requestSink; + private boolean requestMethodSetExplicitly; + + private Response response; + private ByteArrayInputStream responseSink; + private ByteArrayInputStream errorSink; + + private HandshakeCompletedEvent handshakeEvent; + + /** + * Constructor. + * @param url the URL + */ + public HTTPURLConnection(URL url) + throws IOException + { + super(url); + requestHeaders = new Headers(); + AccessController.doPrivileged(this.new GetHTTPPropertiesAction()); + } + + class GetHTTPPropertiesAction + implements PrivilegedAction + { + + public Object run() + { + proxyHostname = System.getProperty("http.proxyHost"); + if (proxyHostname != null && proxyHostname.length() > 0) + { + String port = System.getProperty("http.proxyPort"); + if (port != null && port.length() > 0) + { + proxyPort = Integer.parseInt(port); + } + else + { + proxyHostname = null; + proxyPort = -1; + } + } + agent = System.getProperty("http.agent"); + String ka = System.getProperty("http.keepAlive"); + keepAlive = !(ka != null && "false".equals(ka)); + String mc = System.getProperty("http.maxConnections"); + maxConnections = (mc != null && mc.length() > 0) ? + Math.max(Integer.parseInt(mc), 1) : 5; + return null; + } + + } + + public void connect() + throws IOException + { + if (connected) + { + return; + } + String protocol = url.getProtocol(); + boolean secure = "https".equals(protocol); + String host = url.getHost(); + int port = url.getPort(); + if (port < 0) + { + port = secure ? HTTPConnection.HTTPS_PORT : + HTTPConnection.HTTP_PORT; + } + String file = url.getFile(); + String username = url.getUserInfo(); + String password = null; + if (username != null) + { + int ci = username.indexOf(':'); + if (ci != -1) + { + password = username.substring(ci + 1); + username = username.substring(0, ci); + } + } + final Credentials creds = (username == null) ? null : + new Credentials (username, password); + + boolean retry; + do + { + retry = false; + if (connection == null) + { + connection = getConnection(host, port, secure); + if (secure) + { + SSLSocketFactory factory = getSSLSocketFactory(); + HostnameVerifier verifier = getHostnameVerifier(); + if (factory != null) + { + connection.setSSLSocketFactory(factory); + } + connection.addHandshakeCompletedListener(this); + // TODO verifier + } + } + if (proxyHostname != null) + { + if (proxyPort < 0) + { + proxyPort = secure ? HTTPConnection.HTTPS_PORT : + HTTPConnection.HTTP_PORT; + } + connection.setProxy(proxyHostname, proxyPort); + } + request = connection.newRequest(method, file); + if (!keepAlive) + { + request.setHeader("Connection", "close"); + } + if (agent != null) + { + request.setHeader("User-Agent", agent); + } + request.getHeaders().putAll(requestHeaders); + if (requestSink != null) + { + byte[] content = requestSink.toByteArray(); + RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content); + request.setRequestBodyWriter(writer); + } + ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader(); + request.setResponseBodyReader(reader); + if (creds != null) + { + request.setAuthenticator(new Authenticator() { + public Credentials getCredentials(String realm, int attempts) + { + return (attempts < 2) ? creds : null; + } + }); + } + response = request.dispatch(); + if (response.getCodeClass() == 3 && getInstanceFollowRedirects()) + { + // Follow redirect + String location = response.getHeader("Location"); + if (location != null) + { + String connectionUri = connection.getURI(); + int start = connectionUri.length(); + if (location.startsWith(connectionUri) && + location.charAt(start) == '/') + { + file = location.substring(start); + retry = true; + } + else if (location.startsWith("http:")) + { + connection.close(); + connection = null; + secure = false; + start = 7; + int end = location.indexOf('/', start); + host = location.substring(start, end); + int ci = host.lastIndexOf(':'); + if (ci != -1) + { + port = Integer.parseInt(host.substring (ci + 1)); + host = host.substring(0, ci); + } + else + { + port = HTTPConnection.HTTP_PORT; + } + file = location.substring(end); + retry = true; + } + else if (location.startsWith("https:")) + { + connection.close(); + connection = null; + secure = true; + start = 8; + int end = location.indexOf('/', start); + host = location.substring(start, end); + int ci = host.lastIndexOf(':'); + if (ci != -1) + { + port = Integer.parseInt(host.substring (ci + 1)); + host = host.substring(0, ci); + } + else + { + port = HTTPConnection.HTTPS_PORT; + } + file = location.substring(end); + retry = true; + } + else if (location.length() > 0) + { + // Malformed absolute URI, treat as file part of URI + if (location.charAt(0) == '/') + { + // Absolute path + file = location; + } + else + { + // Relative path + int lsi = file.lastIndexOf('/'); + file = (lsi == -1) ? "/" : file.substring(0, lsi + 1); + file += location; + } + retry = true; + } + } + } + else + { + responseSink = new ByteArrayInputStream(reader.toByteArray ()); + if (response.getCode() == 404) + { + errorSink = responseSink; + throw new FileNotFoundException(url.toString()); + } + } + } + while (retry); + connected = true; + } + + /** + * Returns a connection, from the pool if necessary. + */ + HTTPConnection getConnection(String host, int port, boolean secure) + throws IOException + { + HTTPConnection connection; + if (keepAlive) + { + StringBuffer buf = new StringBuffer(secure ? "https://" : "http://"); + buf.append(Thread.currentThread().hashCode()); + buf.append('@'); + buf.append(host); + buf.append(':'); + buf.append(port); + String key = buf.toString(); + synchronized (connectionPool) + { + connection = (HTTPConnection) connectionPool.get(key); + if (connection == null) + { + connection = new HTTPConnection(host, port, secure); + // Good housekeeping + if (connectionPool.size() == maxConnections) + { + // maxConnections must always be >= 1 + Object lru = connectionPool.keySet().iterator().next(); + connectionPool.remove(lru); + } + connectionPool.put(key, connection); + } + } + } + else + { + connection = new HTTPConnection(host, port, secure); + } + return connection; + } + + public void disconnect() + { + if (connection != null) + { + try + { + connection.close(); + } + catch (IOException e) + { + } + } + } + + public boolean usingProxy() + { + return (proxyHostname != null); + } + + /** + * Overrides the corresponding method in HttpURLConnection to permit + * arbitrary methods, as long as they're valid ASCII alphabetic + * characters. This is to permit WebDAV and other HTTP extensions to + * function. + * @param method the method + */ + public void setRequestMethod(String method) + throws ProtocolException + { + if (connected) + { + throw new ProtocolException("Already connected"); + } + // Validate + method = method.toUpperCase(); + int len = method.length(); + if (len == 0) + { + throw new ProtocolException("Empty method name"); + } + for (int i = 0; i < len; i++) + { + char c = method.charAt(i); + if (c < 0x41 || c > 0x5a) + { + throw new ProtocolException("Illegal character '" + c + + "' at index " + i); + } + } + // OK + this.method = method; + requestMethodSetExplicitly = true; + } + + public String getRequestProperty(String key) + { + return requestHeaders.getValue(key); + } + + public Map getRequestProperties() + { + return requestHeaders; + } + + public void setRequestProperty(String key, String value) + { + requestHeaders.put(key, value); + } + + public void addRequestProperty(String key, String value) + { + String old = requestHeaders.getValue(key); + if (old == null) + { + requestHeaders.put(key, value); + } + else + { + requestHeaders.put(key, old + "," + value); + } + } + + public OutputStream getOutputStream() + throws IOException + { + if (connected) + { + throw new ProtocolException("Already connected"); + } + if (!doOutput) + { + throw new ProtocolException("doOutput is false"); + } + else if (!requestMethodSetExplicitly) + { + /* + * Silently change the method to POST if no method was set + * explicitly. This is due to broken applications depending on this + * behaviour (Apache XMLRPC for one). + */ + method = "POST"; + } + if (requestSink == null) + { + requestSink = new ByteArrayOutputStream(); + } + return requestSink; + } + + // -- Response -- + + public InputStream getInputStream() + throws IOException + { + if (!connected) + { + connect(); + } + if (!doInput) + { + throw new ProtocolException("doInput is false"); + } + return responseSink; + } + + public InputStream getErrorStream() + { + return errorSink; + } + + public Map getHeaderFields() + { + if (!connected) + { + try + { + connect(); + } + catch (IOException e) + { + return null; + } + } + Map headers = response.getHeaders(); + Map ret = new LinkedHashMap(); + ret.put("", Collections.singletonList(getStatusLine(response))); + for (Iterator i = headers.entrySet().iterator(); i.hasNext(); ) + { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + ret.put(key, Collections.singletonList(value)); + } + return ret; + } + + String getStatusLine(Response response) + { + return "HTTP/" + response.getMajorVersion() + + "." + response.getMinorVersion() + + " " + response.getCode() + + " " + response.getMessage(); + } + + public String getHeaderField(int index) + { + if (!connected) + { + try + { + connect(); + } + catch (IOException e) + { + return null; + } + } + if (index == 0) + { + return getStatusLine(response); + } + Iterator i = response.getHeaders().entrySet().iterator(); + Map.Entry entry; + int count = 1; + do + { + if (!i.hasNext()) + { + return null; + } + entry = (Map.Entry) i.next(); + count++; + } + while (count <= index); + return (String) entry.getValue(); + } + + public String getHeaderFieldKey(int index) + { + if (!connected) + { + try + { + connect(); + } + catch (IOException e) + { + return null; + } + } + if (index == 0) + { + return null; + } + Iterator i = response.getHeaders().entrySet().iterator(); + Map.Entry entry; + int count = 1; + do + { + if (!i.hasNext()) + { + return null; + } + entry = (Map.Entry) i.next(); + count++; + } + while (count <= index); + return (String) entry.getKey(); + } + + public String getHeaderField(String name) + { + if (!connected) + { + try + { + connect(); + } + catch (IOException e) + { + return null; + } + } + return (String) response.getHeader(name); + } + + public long getHeaderFieldDate(String name, long def) + { + if (!connected) + { + try + { + connect(); + } + catch (IOException e) + { + return def; + } + } + Date date = response.getDateHeader(name); + return (date == null) ? def : date.getTime(); + } + + public String getContentType() + { + return getHeaderField("Content-Type"); + } + + public int getResponseCode() + throws IOException + { + if (!connected) + { + connect(); + } + return response.getCode(); + } + + public String getResponseMessage() + throws IOException + { + if (!connected) + { + connect(); + } + return response.getMessage(); + } + + // -- HTTPS specific -- + + public String getCipherSuite() + { + if (!connected) + { + throw new IllegalStateException("not connected"); + } + return handshakeEvent.getCipherSuite(); + } + + public Certificate[] getLocalCertificates() + { + if (!connected) + { + throw new IllegalStateException("not connected"); + } + return handshakeEvent.getLocalCertificates(); + } + + public Certificate[] getServerCertificates() + throws SSLPeerUnverifiedException + { + if (!connected) + { + throw new IllegalStateException("not connected"); + } + return handshakeEvent.getPeerCertificates(); + } + + // HandshakeCompletedListener + + public void handshakeCompleted(HandshakeCompletedEvent event) + { + handshakeEvent = event; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/Handler.java b/libjava/classpath/gnu/java/net/protocol/http/Handler.java new file mode 100644 index 0000000..6405425 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Handler.java @@ -0,0 +1,73 @@ +/* Handler.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * An HTTP URL stream handler. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Handler + extends URLStreamHandler +{ + + /** + * Returns the default HTTP port (80). + */ + protected int getDefaultPort() + { + return HTTPConnection.HTTP_PORT; + } + + /** + * Returns an HTTPURLConnection for the given URL. + */ + public URLConnection openConnection(URL url) + throws IOException + { + return new HTTPURLConnection(url); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/Headers.java b/libjava/classpath/gnu/java/net/protocol/http/Headers.java new file mode 100644 index 0000000..847ebef --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Headers.java @@ -0,0 +1,369 @@ +/* Headers.java -- + Copyright (C) 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.java.net.protocol.http; + +import gnu.java.net.LineInputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * A collection of HTTP header names and associated values. + * Retrieval of values is case insensitive. An iteration over the keys + * returns the header names in the order they were received. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Headers + implements Map +{ + + static final DateFormat dateFormat = new HTTPDateFormat(); + + static class Header + { + + final String name; + + Header(String name) + { + if (name == null || name.length() == 0) + { + throw new IllegalArgumentException(name); + } + this.name = name; + } + + public int hashCode() + { + return name.toLowerCase().hashCode(); + } + + public boolean equals(Object other) + { + if (other instanceof Header) + { + return ((Header) other).name.equalsIgnoreCase(name); + } + return false; + } + + public String toString() + { + return name; + } + + } + + static class HeaderEntry + implements Map.Entry + { + + final Map.Entry entry; + + HeaderEntry(Map.Entry entry) + { + this.entry = entry; + } + + public Object getKey() + { + return ((Header) entry.getKey()).name; + } + + public Object getValue() + { + return entry.getValue(); + } + + public Object setValue(Object value) + { + return entry.setValue(value); + } + + public int hashCode() + { + return entry.hashCode(); + } + + public boolean equals(Object other) + { + return entry.equals(other); + } + + public String toString() + { + return getKey().toString() + "=" + getValue(); + } + + } + + private LinkedHashMap headers; + + public Headers() + { + headers = new LinkedHashMap(); + } + + public int size() + { + return headers.size(); + } + + public boolean isEmpty() + { + return headers.isEmpty(); + } + + public boolean containsKey(Object key) + { + return headers.containsKey(new Header((String) key)); + } + + public boolean containsValue(Object value) + { + return headers.containsValue(value); + } + + public Object get(Object key) + { + return headers.get(new Header((String) key)); + } + + /** + * Returns the value of the specified header as a string. + */ + public String getValue(String header) + { + return (String) headers.get(new Header(header)); + } + + /** + * Returns the value of the specified header as an integer, + * or -1 if the header is not present or not an integer. + */ + public int getIntValue(String header) + { + String val = getValue(header); + if (val == null) + { + return -1; + } + try + { + return Integer.parseInt(val); + } + catch (NumberFormatException e) + { + } + return -1; + } + + /** + * Returns the value of the specified header as a date, + * or <code>null</code> if the header is not present or not a date. + */ + public Date getDateValue(String header) + { + String val = getValue(header); + if (val == null) + { + return null; + } + try + { + return dateFormat.parse(val); + } + catch (ParseException e) + { + return null; + } + } + + public Object put(Object key, Object value) + { + return headers.put(new Header((String) key), value); + } + + public Object remove(Object key) + { + return headers.remove(new Header((String) key)); + } + + public void putAll(Map t) + { + for (Iterator i = t.keySet().iterator(); i.hasNext(); ) + { + String key = (String) i.next(); + String value = (String) t.get(key); + headers.put(new Header(key), value); + } + } + + public void clear() + { + headers.clear(); + } + + public Set keySet() + { + Set keys = headers.keySet(); + Set ret = new LinkedHashSet(); + for (Iterator i = keys.iterator(); i.hasNext(); ) + { + ret.add(((Header) i.next()).name); + } + return ret; + } + + public Collection values() + { + return headers.values(); + } + + public Set entrySet() + { + Set entries = headers.entrySet(); + Set ret = new LinkedHashSet(); + for (Iterator i = entries.iterator(); i.hasNext(); ) + { + Map.Entry entry = (Map.Entry) i.next(); + ret.add(new HeaderEntry(entry)); + } + return ret; + } + + public boolean equals(Object other) + { + return headers.equals(other); + } + + public int hashCode() + { + return headers.hashCode(); + } + + /** + * Parse the specified input stream, adding headers to this collection. + */ + public void parse(InputStream in) + throws IOException + { + LineInputStream lin = (in instanceof LineInputStream) ? + (LineInputStream) in : new LineInputStream(in); + + String name = null; + StringBuffer value = new StringBuffer(); + while (true) + { + String line = lin.readLine(); + if (line == null) + { + if (name != null) + { + addValue(name, value.toString()); + } + break; + } + int len = line.length(); + if (len < 2) + { + if (name != null) + { + addValue(name, value.toString()); + } + break; + } + char c1 = line.charAt(0); + if (c1 == ' ' || c1 == '\t') + { + // Continuation + int last = len - 1; + if (line.charAt(last) != '\r') + ++last; + value.append(line.substring(0, last)); + } + else + { + if (name != null) + { + addValue(name, value.toString()); + } + + int di = line.indexOf(':'); + name = line.substring(0, di); + value.setLength(0); + do + { + di++; + } + while (di < len && line.charAt(di) == ' '); + int last = len - 1; + if (line.charAt(last) != '\r') + ++last; + value.append(line.substring(di, last)); + } + } + } + + private void addValue(String name, String value) + { + Header key = new Header(name); + String old = (String) headers.get(key); + if (old == null) + { + headers.put(key, value); + } + else + { + headers.put(key, old + ", " + value); + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/Request.java b/libjava/classpath/gnu/java/net/protocol/http/Request.java new file mode 100644 index 0000000..21205e6 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Request.java @@ -0,0 +1,915 @@ +/* Request.java -- + Copyright (C) 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.java.net.protocol.http; + +import gnu.java.net.BASE64; +import gnu.java.net.LineInputStream; +import gnu.java.net.protocol.http.event.RequestEvent; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ProtocolException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +/** + * A single HTTP request. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Request +{ + + /** + * The connection context in which this request is invoked. + */ + protected final HTTPConnection connection; + + /** + * The HTTP method to invoke. + */ + protected final String method; + + /** + * The path identifying the resource. + * This string must conform to the abs_path definition given in RFC2396, + * with an optional "?query" part, and must be URI-escaped by the caller. + */ + protected final String path; + + /** + * The headers in this request. + */ + protected final Headers requestHeaders; + + /** + * The request body provider. + */ + protected RequestBodyWriter requestBodyWriter; + + /** + * Request body negotiation threshold for 100-continue expectations. + */ + protected int requestBodyNegotiationThreshold; + + /** + * The response body reader. + */ + protected ResponseBodyReader responseBodyReader; + + /** + * Map of response header handlers. + */ + protected Map responseHeaderHandlers; + + /** + * The authenticator. + */ + protected Authenticator authenticator; + + /** + * Whether this request has been dispatched yet. + */ + private boolean dispatched; + + /** + * Constructor for a new request. + * @param connection the connection context + * @param method the HTTP method + * @param path the resource path including query part + */ + protected Request(HTTPConnection connection, String method, + String path) + { + this.connection = connection; + this.method = method; + this.path = path; + requestHeaders = new Headers(); + responseHeaderHandlers = new HashMap(); + requestBodyNegotiationThreshold = 4096; + } + + /** + * Returns the connection associated with this request. + * @see #connection + */ + public HTTPConnection getConnection() + { + return connection; + } + + /** + * Returns the HTTP method to invoke. + * @see #method + */ + public String getMethod() + { + return method; + } + + /** + * Returns the resource path. + * @see #path + */ + public String getPath() + { + return path; + } + + /** + * Returns the full request-URI represented by this request, as specified + * by HTTP/1.1. + */ + public String getRequestURI() + { + return connection.getURI() + path; + } + + /** + * Returns the headers in this request. + */ + public Headers getHeaders() + { + return requestHeaders; + } + + /** + * Returns the value of the specified header in this request. + * @param name the header name + */ + public String getHeader(String name) + { + return requestHeaders.getValue(name); + } + + /** + * Returns the value of the specified header in this request as an integer. + * @param name the header name + */ + public int getIntHeader(String name) + { + return requestHeaders.getIntValue(name); + } + + /** + * Returns the value of the specified header in this request as a date. + * @param name the header name + */ + public Date getDateHeader(String name) + { + return requestHeaders.getDateValue(name); + } + + /** + * Sets the specified header in this request. + * @param name the header name + * @param value the header value + */ + public void setHeader(String name, String value) + { + requestHeaders.put(name, value); + } + + /** + * Convenience method to set the entire request body. + * @param requestBody the request body content + */ + public void setRequestBody(byte[] requestBody) + { + setRequestBodyWriter(new ByteArrayRequestBodyWriter(requestBody)); + } + + /** + * Sets the request body provider. + * @param requestBodyWriter the handler used to obtain the request body + */ + public void setRequestBodyWriter(RequestBodyWriter requestBodyWriter) + { + this.requestBodyWriter = requestBodyWriter; + } + + /** + * Sets the response body reader. + * @param responseBodyReader the handler to receive notifications of + * response body content + */ + public void setResponseBodyReader(ResponseBodyReader responseBodyReader) + { + this.responseBodyReader = responseBodyReader; + } + + /** + * Sets a callback handler to be invoked for the specified header name. + * @param name the header name + * @param handler the handler to receive the value for the header + */ + public void setResponseHeaderHandler(String name, + ResponseHeaderHandler handler) + { + responseHeaderHandlers.put(name, handler); + } + + /** + * Sets an authenticator that can be used to handle authentication + * automatically. + * @param authenticator the authenticator + */ + public void setAuthenticator(Authenticator authenticator) + { + this.authenticator = authenticator; + } + + /** + * Sets the request body negotiation threshold. + * If this is set, it determines the maximum size that the request body + * may be before body negotiation occurs(via the + * <code>100-continue</code> expectation). This ensures that a large + * request body is not sent when the server wouldn't have accepted it + * anyway. + * @param threshold the body negotiation threshold, or <=0 to disable + * request body negotation entirely + */ + public void setRequestBodyNegotiationThreshold(int threshold) + { + requestBodyNegotiationThreshold = threshold; + } + + /** + * Dispatches this request. + * A request can only be dispatched once; calling this method a second + * time results in a protocol exception. + * @exception IOException if an I/O error occurred + * @return an HTTP response object representing the result of the operation + */ + public Response dispatch() + throws IOException + { + if (dispatched) + { + throw new ProtocolException("request already dispatched"); + } + final String CRLF = "\r\n"; + final String HEADER_SEP = ": "; + final String US_ASCII = "US-ASCII"; + final String version = connection.getVersion(); + Response response; + int contentLength = -1; + boolean retry = false; + int attempts = 0; + boolean expectingContinue = false; + if (requestBodyWriter != null) + { + contentLength = requestBodyWriter.getContentLength(); + if (contentLength > requestBodyNegotiationThreshold) + { + expectingContinue = true; + setHeader("Expect", "100-continue"); + } + else + { + setHeader("Content-Length", Integer.toString(contentLength)); + } + } + + try + { + // Loop while authentication fails or continue + do + { + retry = false; + // Send request + connection.fireRequestEvent(RequestEvent.REQUEST_SENDING, this); + + // Get socket output and input streams + OutputStream out = connection.getOutputStream(); + LineInputStream in = + new LineInputStream(connection.getInputStream()); + // Request line + String requestUri = path; + if (connection.isUsingProxy() && + !"*".equals(requestUri) && + !"CONNECT".equals(method)) + { + requestUri = getRequestURI(); + } + String line = method + ' ' + requestUri + ' ' + version + CRLF; + out.write(line.getBytes(US_ASCII)); + // Request headers + for (Iterator i = requestHeaders.keySet().iterator(); + i.hasNext(); ) + { + String name =(String) i.next(); + String value =(String) requestHeaders.get(name); + line = name + HEADER_SEP + value + CRLF; + out.write(line.getBytes(US_ASCII)); + } + out.write(CRLF.getBytes(US_ASCII)); + // Request body + if (requestBodyWriter != null && !expectingContinue) + { + byte[] buffer = new byte[4096]; + int len; + int count = 0; + + requestBodyWriter.reset(); + do + { + len = requestBodyWriter.write(buffer); + if (len > 0) + { + out.write(buffer, 0, len); + } + count += len; + } + while (len > -1 && count < contentLength); + out.write(CRLF.getBytes(US_ASCII)); + } + out.flush(); + // Sent event + connection.fireRequestEvent(RequestEvent.REQUEST_SENT, this); + // Get response + response = readResponse(in); + int sc = response.getCode(); + if (sc == 401 && authenticator != null) + { + if (authenticate(response, attempts++)) + { + retry = true; + } + } + else if (sc == 100 && expectingContinue) + { + requestHeaders.remove("Expect"); + setHeader("Content-Length", Integer.toString(contentLength)); + expectingContinue = false; + retry = true; + } + } + while (retry); + } + catch (IOException e) + { + connection.close(); + throw e; + } + return response; + } + + Response readResponse(LineInputStream in) + throws IOException + { + String line; + int len; + + // Read response status line + line = in.readLine(); + if (line == null) + { + throw new ProtocolException("Peer closed connection"); + } + if (!line.startsWith("HTTP/")) + { + throw new ProtocolException(line); + } + len = line.length(); + int start = 5, end = 6; + while (line.charAt(end) != '.') + { + end++; + } + int majorVersion = Integer.parseInt(line.substring(start, end)); + start = end + 1; + end = start + 1; + while (line.charAt(end) != ' ') + { + end++; + } + int minorVersion = Integer.parseInt(line.substring(start, end)); + start = end + 1; + end = start + 3; + int code = Integer.parseInt(line.substring(start, end)); + String message = line.substring(end + 1, len - 1); + // Read response headers + Headers responseHeaders = new Headers(); + responseHeaders.parse(in); + notifyHeaderHandlers(responseHeaders); + // Construct response + int codeClass = code / 100; + Response ret = new Response(majorVersion, minorVersion, code, + codeClass, message, responseHeaders); + switch (code) + { + case 204: + case 205: + case 304: + break; + default: + // Does response body reader want body? + boolean notify = (responseBodyReader != null); + if (notify) + { + if (!responseBodyReader.accept(this, ret)) + { + notify = false; + } + } + readResponseBody(ret, in, notify); + } + return ret; + } + + void notifyHeaderHandlers(Headers headers) + { + for (Iterator i = headers.entrySet().iterator(); i.hasNext(); ) + { + Map.Entry entry = (Map.Entry) i.next(); + String name =(String) entry.getKey(); + // Handle Set-Cookie + if ("Set-Cookie".equalsIgnoreCase(name)) + { + String value = (String) entry.getValue(); + handleSetCookie(value); + } + ResponseHeaderHandler handler = + (ResponseHeaderHandler) responseHeaderHandlers.get(name); + if (handler != null) + { + String value = (String) entry.getValue(); + handler.setValue(value); + } + } + } + + void readResponseBody(Response response, InputStream in, + boolean notify) + throws IOException + { + byte[] buffer = new byte[4096]; + int contentLength = -1; + Headers trailer = null; + + String transferCoding = response.getHeader("Transfer-Encoding"); + if ("chunked".equalsIgnoreCase(transferCoding)) + { + trailer = new Headers(); + in = new ChunkedInputStream(in, trailer); + } + else + { + contentLength = response.getIntHeader("Content-Length"); + } + String contentCoding = response.getHeader("Content-Encoding"); + if (contentCoding != null && !"identity".equals(contentCoding)) + { + if ("gzip".equals(contentCoding)) + { + in = new GZIPInputStream(in); + } + else if ("deflate".equals(contentCoding)) + { + in = new InflaterInputStream(in); + } + else + { + throw new ProtocolException("Unsupported Content-Encoding: " + + contentCoding); + } + } + + // Persistent connections are the default in HTTP/1.1 + boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) || + "close".equalsIgnoreCase(response.getHeader("Connection")) || + (connection.majorVersion == 1 && connection.minorVersion == 0) || + (response.majorVersion == 1 && response.minorVersion == 0); + + int count = contentLength; + int len = (count > -1) ? count : buffer.length; + len = (len > buffer.length) ? buffer.length : len; + while (len > -1) + { + len = in.read(buffer, 0, len); + if (len < 0) + { + // EOF + connection.closeConnection(); + break; + } + if (notify) + { + responseBodyReader.read(buffer, 0, len); + } + if (count > -1) + { + count -= len; + if (count < 1) + { + if (doClose) + { + connection.closeConnection(); + } + break; + } + } + } + if (notify) + { + responseBodyReader.close(); + } + if (trailer != null) + { + response.getHeaders().putAll(trailer); + notifyHeaderHandlers(trailer); + } + } + + boolean authenticate(Response response, int attempts) + throws IOException + { + String challenge = response.getHeader("WWW-Authenticate"); + if (challenge == null) + { + challenge = response.getHeader("Proxy-Authenticate"); + } + int si = challenge.indexOf(' '); + String scheme = (si == -1) ? challenge : challenge.substring(0, si); + if ("Basic".equalsIgnoreCase(scheme)) + { + Properties params = parseAuthParams(challenge.substring(si + 1)); + String realm = params.getProperty("realm"); + Credentials creds = authenticator.getCredentials(realm, attempts); + String userPass = creds.getUsername() + ':' + creds.getPassword(); + byte[] b_userPass = userPass.getBytes("US-ASCII"); + byte[] b_encoded = BASE64.encode(b_userPass); + String authorization = + scheme + " " + new String(b_encoded, "US-ASCII"); + setHeader("Authorization", authorization); + return true; + } + else if ("Digest".equalsIgnoreCase(scheme)) + { + Properties params = parseAuthParams(challenge.substring(si + 1)); + String realm = params.getProperty("realm"); + String nonce = params.getProperty("nonce"); + String qop = params.getProperty("qop"); + String algorithm = params.getProperty("algorithm"); + String digestUri = getRequestURI(); + Credentials creds = authenticator.getCredentials(realm, attempts); + String username = creds.getUsername(); + String password = creds.getPassword(); + connection.incrementNonce(nonce); + try + { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + final byte[] COLON = { 0x3a }; + + // Calculate H(A1) + md5.reset(); + md5.update(username.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(realm.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(password.getBytes("US-ASCII")); + byte[] ha1 = md5.digest(); + if ("md5-sess".equals(algorithm)) + { + byte[] cnonce = generateNonce(); + md5.reset(); + md5.update(ha1); + md5.update(COLON); + md5.update(nonce.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(cnonce); + ha1 = md5.digest(); + } + String ha1Hex = toHexString(ha1); + + // Calculate H(A2) + md5.reset(); + md5.update(method.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(digestUri.getBytes("US-ASCII")); + if ("auth-int".equals(qop)) + { + byte[] hEntity = null; // TODO hash of entity body + md5.update(COLON); + md5.update(hEntity); + } + byte[] ha2 = md5.digest(); + String ha2Hex = toHexString(ha2); + + // Calculate response + md5.reset(); + md5.update(ha1Hex.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(nonce.getBytes("US-ASCII")); + if ("auth".equals(qop) || "auth-int".equals(qop)) + { + String nc = getNonceCount(nonce); + byte[] cnonce = generateNonce(); + md5.update(COLON); + md5.update(nc.getBytes("US-ASCII")); + md5.update(COLON); + md5.update(cnonce); + md5.update(COLON); + md5.update(qop.getBytes("US-ASCII")); + } + md5.update(COLON); + md5.update(ha2Hex.getBytes("US-ASCII")); + String digestResponse = toHexString(md5.digest()); + + String authorization = scheme + + " username=\"" + username + "\"" + + " realm=\"" + realm + "\"" + + " nonce=\"" + nonce + "\"" + + " uri=\"" + digestUri + "\"" + + " response=\"" + digestResponse + "\""; + setHeader("Authorization", authorization); + return true; + } + catch (NoSuchAlgorithmException e) + { + return false; + } + } + // Scheme not recognised + return false; + } + + Properties parseAuthParams(String text) + { + int len = text.length(); + String key = null; + StringBuffer buf = new StringBuffer(); + Properties ret = new Properties(); + boolean inQuote = false; + for (int i = 0; i < len; i++) + { + char c = text.charAt(i); + if (c == '"') + { + inQuote = !inQuote; + } + else if (c == '=' && key == null) + { + key = buf.toString().trim(); + buf.setLength(0); + } + else if (c == ' ' && !inQuote) + { + String value = unquote(buf.toString().trim()); + ret.put(key, value); + key = null; + buf.setLength(0); + } + else if (c != ',' || (i <(len - 1) && text.charAt(i + 1) != ' ')) + { + buf.append(c); + } + } + if (key != null) + { + String value = unquote(buf.toString().trim()); + ret.put(key, value); + } + return ret; + } + + String unquote(String text) + { + int len = text.length(); + if (len > 0 && text.charAt(0) == '"' && text.charAt(len - 1) == '"') + { + return text.substring(1, len - 1); + } + return text; + } + + /** + * Returns the number of times the specified nonce value has been seen. + * This always returns an 8-byte 0-padded hexadecimal string. + */ + String getNonceCount(String nonce) + { + int nc = connection.getNonceCount(nonce); + String hex = Integer.toHexString(nc); + StringBuffer buf = new StringBuffer(); + for (int i = 8 - hex.length(); i > 0; i--) + { + buf.append('0'); + } + buf.append(hex); + return buf.toString(); + } + + /** + * Client nonce value. + */ + byte[] nonce; + + /** + * Generates a new client nonce value. + */ + byte[] generateNonce() + throws IOException, NoSuchAlgorithmException + { + if (nonce == null) + { + long time = System.currentTimeMillis(); + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(Long.toString(time).getBytes("US-ASCII")); + nonce = md5.digest(); + } + return nonce; + } + + String toHexString(byte[] bytes) + { + char[] ret = new char[bytes.length * 2]; + for (int i = 0, j = 0; i < bytes.length; i++) + { + int c =(int) bytes[i]; + if (c < 0) + { + c += 0x100; + } + ret[j++] = Character.forDigit(c / 0x10, 0x10); + ret[j++] = Character.forDigit(c % 0x10, 0x10); + } + return new String(ret); + } + + /** + * Parse the specified cookie list and notify the cookie manager. + */ + void handleSetCookie(String text) + { + CookieManager cookieManager = connection.getCookieManager(); + if (cookieManager == null) + { + return; + } + String name = null; + String value = null; + String comment = null; + String domain = connection.getHostName(); + String path = this.path; + int lsi = path.lastIndexOf('/'); + if (lsi != -1) + { + path = path.substring(0, lsi); + } + boolean secure = false; + Date expires = null; + + int len = text.length(); + String attr = null; + StringBuffer buf = new StringBuffer(); + boolean inQuote = false; + for (int i = 0; i <= len; i++) + { + char c =(i == len) ? '\u0000' : text.charAt(i); + if (c == '"') + { + inQuote = !inQuote; + } + else if (!inQuote) + { + if (c == '=' && attr == null) + { + attr = buf.toString().trim(); + buf.setLength(0); + } + else if (c == ';' || i == len || c == ',') + { + String val = unquote(buf.toString().trim()); + if (name == null) + { + name = attr; + value = val; + } + else if ("Comment".equalsIgnoreCase(attr)) + { + comment = val; + } + else if ("Domain".equalsIgnoreCase(attr)) + { + domain = val; + } + else if ("Path".equalsIgnoreCase(attr)) + { + path = val; + } + else if ("Secure".equalsIgnoreCase(val)) + { + secure = true; + } + else if ("Max-Age".equalsIgnoreCase(attr)) + { + int delta = Integer.parseInt(val); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(System.currentTimeMillis()); + cal.add(Calendar.SECOND, delta); + expires = cal.getTime(); + } + else if ("Expires".equalsIgnoreCase(attr)) + { + DateFormat dateFormat = new HTTPDateFormat(); + try + { + expires = dateFormat.parse(val); + } + catch (ParseException e) + { + // if this isn't a valid date, it may be that + // the value was returned unquoted; in that case, we + // want to continue buffering the value + buf.append(c); + continue; + } + } + attr = null; + buf.setLength(0); + // case EOL + if (i == len || c == ',') + { + Cookie cookie = new Cookie(name, value, comment, domain, + path, secure, expires); + cookieManager.setCookie(cookie); + } + if (c == ',') + { + // Reset cookie fields + name = null; + value = null; + comment = null; + domain = connection.getHostName(); + path = this.path; + if (lsi != -1) + { + path = path.substring(0, lsi); + } + secure = false; + expires = null; + } + } + else + { + buf.append(c); + } + } + else + { + buf.append(c); + } + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/RequestBodyWriter.java b/libjava/classpath/gnu/java/net/protocol/http/RequestBodyWriter.java new file mode 100644 index 0000000..05d98eb --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/RequestBodyWriter.java @@ -0,0 +1,69 @@ +/* RequestBodyWriter.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Callback interface for writing request body content. + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface RequestBodyWriter +{ + + /** + * Returns the total number of bytes that will be written in a single pass + * by this writer. + */ + int getContentLength(); + + /** + * Initialises the writer. + * This will be called before each pass. + */ + void reset(); + + /** + * Writes body content to the supplied buffer. + * @param buffer the content buffer + * @return the number of bytes written + */ + int write(byte[] buffer); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/Response.java b/libjava/classpath/gnu/java/net/protocol/http/Response.java new file mode 100644 index 0000000..29dc28b --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Response.java @@ -0,0 +1,185 @@ +/* Response.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.util.Date; + +/** + * An HTTP response. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Response +{ + + /** + * The HTTP major version of the server issuing the response. + */ + protected final int majorVersion; + + /** + * The HTTP minor version of the server issuing the response. + */ + protected final int minorVersion; + + /** + * The HTTP status code of the response. + */ + protected final int code; + + /** + * The class of the response. This is the most significant digit of the + * status code. + * <dl> + * <dt><code>1xx</code></dt> <dd>Informational response</dd> + * <dt><code>2xx</code></dt> <dd>Success</dd> + * <dt><code>3xx</code></dt> <dd>Redirection</dd> + * <dt><code>4xx</code></dt> <dd>Client error</dd> + * <dt><code>5xx</code></dt> <dd>Server error</dd> + * </dl> + */ + protected final int codeClass; + + /** + * Human-readable text of the response. + */ + protected final String message; + + /** + * The response headers. + */ + protected final Headers headers; + + /** + * Constructs a new response with the specified parameters. + */ + protected Response(int majorVersion, int minorVersion, int code, + int codeClass, String message, + Headers headers) + { + this.majorVersion = majorVersion; + this.minorVersion = minorVersion; + this.code = code; + this.codeClass = codeClass; + this.message = message; + this.headers = headers; + } + + /** + * Returns the HTTP major version of the server issuing the response. + * @see #majorVersion + */ + public int getMajorVersion() + { + return majorVersion; + } + + /** + * Returns the HTTP minor version of the server issuing the response. + * @see #minorVersion + */ + public int getMinorVersion() + { + return minorVersion; + } + + /** + * Returns the HTTP status code of the response. + * @see #code + */ + public int getCode() + { + return code; + } + + /** + * Returns the class of the response. + * @see #codeClass + */ + public int getCodeClass() + { + return codeClass; + } + + /** + * Returns the human-readable text of the response. + * @see #message + */ + public String getMessage() + { + return message; + } + + /** + * Returns the headers in the response. + */ + public Headers getHeaders() + { + return headers; + } + + /** + * Returns the header value for the specified name. + * @param name the header name + */ + public String getHeader(String name) + { + return headers.getValue(name); + } + + /** + * Returns the header value for the specified name as an integer. + * @param name the header name + */ + public int getIntHeader(String name) + { + return headers.getIntValue(name); + } + + /** + * Returns the header value for the specified name as a date. + * @param name the header name + */ + public Date getDateHeader(String name) + { + return headers.getDateValue(name); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java b/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java new file mode 100644 index 0000000..49e1b37 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java @@ -0,0 +1,70 @@ +/* ResponseBodyReader.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Callback interface for receiving notification of response body content. + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface ResponseBodyReader +{ + + /** + * Indicate whether this reader is interested in the specified response. + * If it returns false, it will not receive body content notifications for + * that response. + */ + boolean accept(Request request, Response response); + + /** + * Receive notification of body content. + * @param buffer the content buffer + * @param offset the offset within the buffer that content starts + * @param length the length of the content + */ + void read(byte[] buffer, int offset, int length); + + /** + * Notifies the reader that the end of the content was reached. + */ + void close(); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/ResponseHeaderHandler.java b/libjava/classpath/gnu/java/net/protocol/http/ResponseHeaderHandler.java new file mode 100644 index 0000000..8e4e649 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/ResponseHeaderHandler.java @@ -0,0 +1,57 @@ +/* ResponseHeaderHandler.java -- + Copyright (C) 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.java.net.protocol.http; + +/** + * Callback interface for objects that wish to be notified of response + * header values. + * @see Request#setHeaderHandler(String) + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface ResponseHeaderHandler +{ + + /** + * Sets the value for the header associated with this handler. + */ + void setValue(String value); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java b/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java new file mode 100644 index 0000000..8947471 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java @@ -0,0 +1,140 @@ +/* CookieManager.java -- + Copyright (C) 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.java.net.protocol.http; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * A simple non-persistent cookie manager. This class can be extended to + * provide cookie persistence. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class SimpleCookieManager + implements CookieManager +{ + + /** + * The cookie cache. + * This is a dictionary mapping domains to maps of cookies by name. + */ + protected Map cookies; + + /** + * Constructor. + */ + public SimpleCookieManager() + { + cookies = new HashMap(); + } + + public void setCookie(Cookie cookie) + { + String domain = cookie.getDomain(); + Map map =(Map) cookies.get(domain); + if (map == null) + { + map = new HashMap(); + cookies.put(domain, map); + } + String name = cookie.getName(); + map.put(name, cookie); // will replace a cookie of the same name + } + + public Cookie[] getCookies(String host, boolean secure, String path) + { + List matches = new ArrayList(); + Date now = new Date(); + if (Character.isLetter(host.charAt(0))) + { + int di = host.indexOf('.'); + while (di != -1) + { + addCookies(matches, host, secure, path, now); + host = host.substring(di); + di = host.indexOf('.', 1); + } + } + addCookies(matches, host, secure, path, now); + Cookie[] ret = new Cookie[matches.size()]; + matches.toArray(ret); + return ret; + } + + private void addCookies(List matches, String domain, boolean secure, + String path, Date now) + { + Map map = (Map) cookies.get(domain); + if (map != null) + { + List expired = new ArrayList(); + for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) + { + Map.Entry entry = (Map.Entry) i.next(); + Cookie cookie = (Cookie) entry.getValue(); + Date expires = cookie.getExpiryDate(); + if (expires != null && expires.before(now)) + { + expired.add(entry.getKey()); + continue; + } + if (secure && !cookie.isSecure()) + { + continue; + } + if (path.startsWith(cookie.getPath())) + { + matches.add(cookie); + } + } + // Good housekeeping + for (Iterator i = expired.iterator(); i.hasNext(); ) + { + map.remove(i.next()); + } + } + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java new file mode 100644 index 0000000..3f6f545 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java @@ -0,0 +1,81 @@ +/* ConnectionEvent.java -- + Copyright (C) 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.java.net.protocol.http.event; + +import java.util.EventObject; + +/** + * A connection event. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class ConnectionEvent + extends EventObject +{ + + /** + * The connection closed event type. + */ + public static final int CONNECTION_CLOSED = 0; + + /** + * The type of this event. + */ + protected int type; + + /** + * Constructs a connection event with the specified source and type. + */ + public ConnectionEvent(Object source, int type) + { + super(source); + this.type = type; + } + + /** + * Returns the type of this event. + * @see #type + */ + public int getType() + { + return type; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java new file mode 100644 index 0000000..073e89d --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java @@ -0,0 +1,58 @@ +/* ConnectionListener.java -- + Copyright (C) 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.java.net.protocol.http.event; + +import java.util.EventListener; + +/** + * A connection listener. + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface ConnectionListener + extends EventListener +{ + + /** + * Callback invoked when the associated connection is closed. + */ + void connectionClosed(ConnectionEvent event); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java b/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java new file mode 100644 index 0000000..281c621 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java @@ -0,0 +1,107 @@ +/* RequestEvent.java -- + Copyright (C) 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.java.net.protocol.http.event; + +import gnu.java.net.protocol.http.Request; + +import java.util.EventObject; + +/** + * A request event. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class RequestEvent + extends EventObject +{ + + /** + * The request created event type. + */ + public static final int REQUEST_CREATED = 0; + + /** + * The request sending event type. + */ + public static final int REQUEST_SENDING = 1; + + /** + * The request sent event type. + */ + public static final int REQUEST_SENT = 2; + + /** + * The type of this event. + */ + protected int type; + + /** + * The request associated with this event. + */ + protected Request request; + + /** + * Constructs a request event with the specified source, type, and request. + */ + public RequestEvent(Object source, int type, Request request) + { + super(source); + this.type = type; + this.request = request; + } + + /** + * Returns the type of this event. + * @see #type + */ + public int getType() + { + return type; + } + + /** + * Returns the request associated with this event. + */ + public Request getRequest() + { + return request; + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java b/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java new file mode 100644 index 0000000..c880fbc --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java @@ -0,0 +1,70 @@ +/* RequestListener.java -- + Copyright (C) 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.java.net.protocol.http.event; + +import java.util.EventListener; + +/** + * A request listener. + * + * @author Chris Burdess (dog@gnu.org) + */ +public interface RequestListener + extends EventListener +{ + + /** + * Callback invoked when a request is created from the associated + * connection. + */ + void requestCreated(RequestEvent event); + + /** + * Callback invoked when the request has been initialised with all data + * and before sending this data to the server. + */ + void requestSending(RequestEvent event); + + /** + * Callback invoked after all request data has been sent to the server. + */ + void requestSent(RequestEvent event); + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/package.html b/libjava/classpath/gnu/java/net/protocol/http/event/package.html new file mode 100644 index 0000000..6aed0fc --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/event/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net.protocol.http.event package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net.protocol.http.event</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/net/protocol/http/package.html b/libjava/classpath/gnu/java/net/protocol/http/package.html new file mode 100644 index 0000000..8cf7c1e --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/package.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net.protocol.http package. + Copyright (C) 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net.protocol.http</title></head> + +<body> + +<p> +This package contains an HTTP/1.1 client, as described in RFC 2616. +It supports the following features: +<ul> +<li>Persistent connections</li> +<li>Basic and Digest authentication (RFC 2617)</li> +<li>HTTPS</li> +<li>HTTP proxies</li> +<li>HTTP/1.0 compatibility</li> +<li>Support for WebDAV methods and other HTTP extensions</li> +<li>Automatic decoding of the chunked transfer-coding</li> +<li>Parsing of HTTP date headers</li> +<li>Support for the 100-continue expectation</li> +</ul> +</p> + +<p> +The API is similar to the <a href='http://www.webdav.org/neon/'>neon</a> +WebDAV/HTTP library. A logical connection to the server is instantiated, +and multiple requests can be issued for this connection. Each request +has an atomic <code>dispatch</code> method which returns the response. +All I/O, authentication, etc is handled by registering callback objects +with the request prior to dispatch, which are notified during the dispatch +procedure as necessary. Simple byte-array content callbacks are supplied +which can manage any request/response content that fits in available memory. +</p> + +<p> +An URL stream handler is provided, supporting the full HttpURLConnection +specification. +</p> + +</body> diff --git a/libjava/classpath/gnu/java/net/protocol/https/Handler.java b/libjava/classpath/gnu/java/net/protocol/https/Handler.java new file mode 100644 index 0000000..2b13751 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/https/Handler.java @@ -0,0 +1,76 @@ +/* Handler.java -- + Copyright (C) 2004, 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.java.net.protocol.https; + +import gnu.java.net.protocol.http.HTTPConnection; +import gnu.java.net.protocol.http.HTTPURLConnection; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * An HTTPS URL stream handler. + * + * @author Chris Burdess (dog@gnu.org) + */ +public class Handler + extends URLStreamHandler +{ + + /** + * Returns the default HTTPS port (443). + */ + protected int getDefaultPort() + { + return HTTPConnection.HTTPS_PORT; + } + + /** + * Returns an HTTPURLConnection for the given URL. + */ + public URLConnection openConnection(URL url) + throws IOException + { + return new HTTPURLConnection(url); + } + +} + diff --git a/libjava/classpath/gnu/java/net/protocol/jar/Connection.java b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java new file mode 100644 index 0000000..bd7a80d --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java @@ -0,0 +1,170 @@ +/* Connection - jar url connection for java.net + Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.net.protocol.jar; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Hashtable; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.zip.ZipFile; + +/** + * This subclass of java.net.JarURLConnection models a URLConnection via + * the "jar" protocol. + * + * @author Kresten Krab Thorup (krab@gnu.org) + */ +public final class Connection extends JarURLConnection +{ + private JarFile jar_file; + private JarEntry jar_entry; + private URL jar_url; + + public static class JarFileCache + { + private static Hashtable cache = new Hashtable(); + private static final int READBUFSIZE = 4*1024; + + public static synchronized JarFile get (URL url) throws IOException + { + JarFile jf = (JarFile) cache.get (url); + + if (jf != null) + return jf; + + if ("file".equals (url.getProtocol())) + { + File f = new File (url.getFile()); + jf = new JarFile (f, true, ZipFile.OPEN_READ); + } + else + { + URLConnection urlconn = url.openConnection(); + InputStream is = urlconn.getInputStream(); + byte[] buf = new byte [READBUFSIZE]; + File f = File.createTempFile ("cache", "jar"); + FileOutputStream fos = new FileOutputStream (f); + int len = 0; + + while ((len = is.read (buf)) != -1) + { + fos.write (buf, 0, len); + } + + fos.close(); + // Always verify the Manifest, open read only and delete when done. + jf = new JarFile (f, true, + ZipFile.OPEN_READ | ZipFile.OPEN_DELETE); + } + + cache.put (url, jf); + + return jf; + } + } + + protected Connection(URL url) + throws MalformedURLException + { + super(url); + } + + public synchronized void connect() throws IOException + { + // Call is ignored if already connected. + if (connected) + return; + + jar_url = getJarFileURL(); + jar_file = JarFileCache.get (jar_url); + String entry_name = getEntryName(); + + if (entry_name != null + && !entry_name.equals ("")) + { + jar_entry = (JarEntry) jar_file.getEntry (entry_name); + + if(jar_entry == null) + throw new IOException ("No entry for " + entry_name + " exists."); + } + + connected = true; + } + + public InputStream getInputStream() throws IOException + { + if (!connected) + connect(); + + if (! doInput) + throw new ProtocolException("Can't open InputStream if doInput is false"); + + if (jar_entry == null) + throw new IOException (jar_url + " couldn't be found."); + + return jar_file.getInputStream (jar_entry); + } + + public synchronized JarFile getJarFile() throws IOException + { + if (!connected) + connect(); + + if (! doInput) + throw new ProtocolException("Can't open JarFile if doInput is false"); + + return jar_file; + } + + public int getContentLength() + { + if (!connected) + return -1; + + return (int) jar_entry.getSize(); + } +} diff --git a/libjava/classpath/gnu/java/net/protocol/jar/Handler.java b/libjava/classpath/gnu/java/net/protocol/jar/Handler.java new file mode 100644 index 0000000..316d8cb --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/jar/Handler.java @@ -0,0 +1,173 @@ +/* gnu.java.net.protocol.jar.Handler - jar protocol handler for java.net + Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.net.protocol.jar; + +import gnu.java.net.URLParseError; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +/** + * @author Kresten Krab Thorup (krab@gnu.org) + */ +public class Handler extends URLStreamHandler +{ + /** + * A do nothing constructor + */ + public Handler() + { + } + + /** + * This method returs a new JarURLConnection for the specified URL + * + * @param url The URL to return a connection for + * + * @return The URLConnection + * + * @exception IOException If an error occurs + */ + protected URLConnection openConnection(URL url) throws IOException + { + return new Connection(url); + } + + /** + * This method overrides URLStreamHandler's for parsing url of protocol "jar" + * + * @param url The URL object in which to store the results + * @param url_string The String-ized URL to parse + * @param start The position in the string to start scanning from + * @param end The position in the string to stop scanning + */ + protected void parseURL (URL url, String url_string, int start, int end) + { + // This method does not throw an exception or return a value. Thus our + // strategy when we encounter an error in parsing is to return without + // doing anything. + String file = url.getFile(); + + if (!file.equals("")) + { //has context url + url_string = url_string.substring (start, end); + if (url_string.startsWith("/")) + { //url string is an absolute path + int idx = file.lastIndexOf ("!/"); + + if (idx < 0) + throw new URLParseError("no !/ in spec"); + + file = file.substring (0, idx + 1) + url_string; + } + else if (url_string.length() > 0) + { + int idx = file.lastIndexOf ("/"); + if (idx == -1) //context path is weird + file = "/" + url_string; + else if (idx == (file.length() - 1)) + //just concatenate two parts + file = file + url_string; + else + // according to Java API Documentation, here is a little different + // with URLStreamHandler.parseURL + // but JDK seems doesn't handle it well + file = file.substring(0, idx + 1) + url_string; + } + + setURL (url, "jar", url.getHost(), url.getPort(), file, null); + return; + } + + // Bunches of things should be true. Make sure. + if (end < start) + return; + if (end - start < 2) + return; + if (start > url_string.length()) + return; + + // Skip remains of protocol + url_string = url_string.substring (start, end); + + int jar_stop; + if ((jar_stop = url_string.indexOf("!/")) < 0) + throw new URLParseError("no !/ in spec"); + + try + { + new URL(url_string.substring (0, jar_stop)); + } + catch (MalformedURLException e) + { + throw new URLParseError("invalid inner URL: " + e.getMessage()); + } + + if (!url.getProtocol().equals ("jar") ) + throw new URLParseError("unexpected protocol " + url.getProtocol()); + + setURL (url, "jar", url.getHost(), url.getPort(), url_string, null); + } + + /** + * This method converts a Jar URL object into a String. + * + * @param url The URL object to convert + */ + protected String toExternalForm (URL url) + { + String file = url.getFile(); + String ref = url.getRef(); + + // return "jar:" + file; + // Performance!!: + // Do the concatenation manually to avoid resize StringBuffer's + // internal buffer. The length of ref is not taken into consideration + // as it's a rare path. + StringBuffer sb = new StringBuffer (file.length() + 5); + sb.append ("jar:"); + sb.append (file); + if (ref != null) + sb.append('#').append(ref); + return sb.toString(); + } +} diff --git a/libjava/classpath/gnu/java/net/protocol/jar/package.html b/libjava/classpath/gnu/java/net/protocol/jar/package.html new file mode 100644 index 0000000..dcd263d --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/jar/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.net.protocol.jar package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.net.protocol.jar</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/nio/ChannelInputStream.java b/libjava/classpath/gnu/java/nio/ChannelInputStream.java new file mode 100644 index 0000000..675a62f3 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/ChannelInputStream.java @@ -0,0 +1,79 @@ +/* ChannelInputStream.java -- + Copyright (C) 2003 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.java.nio; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.IllegalBlockingModeException; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.SelectableChannel; + +/** + * @author Michael Koch + */ +public final class ChannelInputStream extends InputStream +{ + private ReadableByteChannel ch; + + public ChannelInputStream (ReadableByteChannel ch) + { + super(); + + this.ch = ch; + } + + public int read() throws IOException + { + if (ch instanceof SelectableChannel + && (! ((SelectableChannel) ch).isBlocking())) + throw new IllegalBlockingModeException(); + + ByteBuffer buffer = ByteBuffer.allocate(1); + int result = ch.read(buffer); + + if (result == -1) + return -1; + + if (result == 0) + throw new IOException("Could not read from channel"); + + return buffer.get(0); + } +} diff --git a/libjava/classpath/gnu/java/nio/ChannelOutputStream.java b/libjava/classpath/gnu/java/nio/ChannelOutputStream.java new file mode 100644 index 0000000..08323ea --- /dev/null +++ b/libjava/classpath/gnu/java/nio/ChannelOutputStream.java @@ -0,0 +1,67 @@ +/* ChannelOutputStream.java -- + Copyright (C) 2003 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.java.nio; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.WritableByteChannel; + +/** + * @author Michael Koch + */ +public final class ChannelOutputStream extends OutputStream +{ + private WritableByteChannel ch; + + public ChannelOutputStream (WritableByteChannel ch) + { + super(); + + this.ch = ch; + } + + public void write (int value) throws IOException + { + ByteBuffer buffer = ByteBuffer.allocate (1); + buffer.put ((byte) (value & 0xff)); + buffer.flip(); + ch.write (buffer); + } +} diff --git a/libjava/classpath/gnu/java/nio/ChannelReader.java b/libjava/classpath/gnu/java/nio/ChannelReader.java new file mode 100644 index 0000000..44fe662 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/ChannelReader.java @@ -0,0 +1,211 @@ +/* ChannelReader.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.java.nio; + +import java.io.IOException; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/** + * A Reader implementation that works using a ReadableByteChannel and a + * CharsetDecoder. + * + * <p> + * This is a bridge between NIO <-> IO character decoding. + * </p> + * + * @author Robert Schuster + */ +public class ChannelReader extends Reader +{ + + private static final int DEFAULT_BUFFER_CAP = 8192; + + private ReadableByteChannel channel; + + private CharsetDecoder decoder; + + private ByteBuffer byteBuffer; + + private CharBuffer charBuffer; + + public ChannelReader(ReadableByteChannel channel, CharsetDecoder decoder, + int minBufferCap) + { + this.channel = channel; + this.decoder = decoder; + + // JDK reports errors, so we do the same. + decoder.onMalformedInput(CodingErrorAction.REPORT); + decoder.onUnmappableCharacter(CodingErrorAction.REPORT); + decoder.reset(); + + int size = (minBufferCap == -1) ? DEFAULT_BUFFER_CAP : minBufferCap; + + // Allocates the buffers and prepares them for reading, because that is the + // first operation being done on them. + byteBuffer = ByteBuffer.allocate(size); + byteBuffer.flip(); + charBuffer = CharBuffer.allocate((int) (size * decoder.averageCharsPerByte())); + } + + public int read(char[] buf, int offset, int count) throws IOException + { + // I declared channel being null meaning that the reader is closed. + if (!channel.isOpen()) + throw new IOException("Reader was already closed."); + + // I declared decoder being null meaning that there is no more data to read + // and convert. + if (decoder == null) + return -1; + + // Stores the amount of character being read. It -1 so that if no conversion + // occured the caller will see this as an 'end of file'. + int sum = -1; + + // Copies any characters which may be left from the last invocation into the + // destination array. + if (charBuffer.remaining() > 0) + { + sum = Math.min(count, charBuffer.remaining()); + charBuffer.get(buf, offset, sum); + + // Updates the control variables according to the latest copy operation. + offset += sum; + count -= sum; + } + + // Copies the character which have not been put in the destination array to + // the beginning. If data is actually copied count will be 0. If no data is + // copied count is >0 and we can now convert some more characters. + charBuffer.compact(); + + int converted = 0; + boolean last = false; + + while (count != 0) + { + // Tries to convert some bytes (Which will intentionally fail in the + // first place because we have not read any bytes yet.) + CoderResult result = decoder.decode(byteBuffer, charBuffer, last); + if (result.isMalformed() || result.isUnmappable()) + { + // JDK throws exception when bytes are malformed for sure. + // FIXME: Unsure what happens when a character is simply + // unmappable. + result.throwException(); + } + + // Marks that we should end this loop regardless whether the caller + // wants more chars or not, when this was the last conversion. + if (last) + { + decoder = null; + } + else if (result.isUnderflow()) + { + // We need more bytes to do the conversion. + + // Copies the not yet converted bytes to the beginning making it + // being able to receive more bytes. + byteBuffer.compact(); + + // Reads in another bunch of bytes for being converted. + if (channel.read(byteBuffer) == -1) + { + // If there is no more data available in the channel we mark + // that state for the final character conversion run which is + // done in the next loop iteration. + last = true; + } + + // Prepares the byteBuffer for the next character conversion run. + byteBuffer.flip(); + } + + // Prepares the charBuffer for being drained. + charBuffer.flip(); + + converted = Math.min(count, charBuffer.remaining()); + charBuffer.get(buf, offset, converted); + + // Copies characters which have not yet being copied into the char-Array + // to the beginning making it possible to read them later (If data is + // really copied here, then the caller has received enough characters so + // far.). + charBuffer.compact(); + + // Updates the control variables according to the latest copy operation. + offset += converted; + count -= converted; + + // Updates the amount of transferred characters. + sum += converted; + + if (decoder == null) + { + break; + } + + // Now that more characters have been transfered we let the loop decide + // what to do next. + } + + // Makes the charBuffer ready for reading on the next invocation. + charBuffer.flip(); + + return sum; + } + + public void close() throws IOException + { + channel.close(); + + // Makes sure all intermediate data is released by the decoder. + if (decoder != null) + decoder.reset(); + } + +} diff --git a/libjava/classpath/gnu/java/nio/DatagramChannelImpl.java b/libjava/classpath/gnu/java/nio/DatagramChannelImpl.java new file mode 100644 index 0000000..51c7031 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/DatagramChannelImpl.java @@ -0,0 +1,297 @@ +/* DatagramChannelImpl.java -- + Copyright (C) 2002, 2003, 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.java.nio; + +import gnu.java.net.PlainDatagramSocketImpl; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.spi.SelectorProvider; + +/** + * @author Michael Koch + */ +public final class DatagramChannelImpl extends DatagramChannel +{ + private NIODatagramSocket socket; + + /** + * Indicates whether this channel initiated whatever operation + * is being invoked on our datagram socket. + */ + private boolean inChannelOperation; + + /** + * Indicates whether our datagram socket should ignore whether + * we are set to non-blocking mode. Certain operations on our + * socket throw an <code>IllegalBlockingModeException</code> if + * we are in non-blocking mode, <i>except</i> if the operation + * is initiated by us. + */ + public final boolean isInChannelOperation() + { + return inChannelOperation; + } + + /** + * Sets our indicator of whether we are initiating an I/O operation + * on our socket. + */ + public final void setInChannelOperation(boolean b) + { + inChannelOperation = b; + } + + protected DatagramChannelImpl (SelectorProvider provider) + throws IOException + { + super (provider); + socket = new NIODatagramSocket (new PlainDatagramSocketImpl(), this); + configureBlocking(true); + } + + public DatagramSocket socket () + { + return socket; + } + + protected void implCloseSelectableChannel () + throws IOException + { + socket.close (); + } + + protected void implConfigureBlocking (boolean blocking) + throws IOException + { + socket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT); + } + + public DatagramChannel connect (SocketAddress remote) + throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + socket.connect (remote); + return this; + } + + public DatagramChannel disconnect () + throws IOException + { + socket.disconnect (); + return this; + } + + public boolean isConnected () + { + return socket.isConnected (); + } + + public int write (ByteBuffer src) + throws IOException + { + if (!isConnected ()) + throw new NotYetConnectedException (); + + return send (src, socket.getRemoteSocketAddress()); + } + + public long write (ByteBuffer[] srcs, int offset, int length) + throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + if ((offset < 0) + || (offset > srcs.length) + || (length < 0) + || (length > (srcs.length - offset))) + throw new IndexOutOfBoundsException(); + + long result = 0; + + for (int index = offset; index < offset + length; index++) + result += write (srcs [index]); + + return result; + } + + public int read (ByteBuffer dst) + throws IOException + { + if (!isConnected ()) + throw new NotYetConnectedException (); + + int remaining = dst.remaining(); + receive (dst); + return remaining - dst.remaining(); + } + + public long read (ByteBuffer[] dsts, int offset, int length) + throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + if ((offset < 0) + || (offset > dsts.length) + || (length < 0) + || (length > (dsts.length - offset))) + throw new IndexOutOfBoundsException(); + + long result = 0; + + for (int index = offset; index < offset + length; index++) + result += read (dsts [index]); + + return result; + } + + public SocketAddress receive (ByteBuffer dst) + throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + try + { + DatagramPacket packet; + int len = dst.capacity() - dst.position(); + + if (dst.hasArray()) + { + packet = new DatagramPacket (dst.array(), + dst.arrayOffset() + dst.position(), + len); + } + else + { + packet = new DatagramPacket (new byte [len], len); + } + + boolean completed = false; + + try + { + begin(); + setInChannelOperation(true); + socket.receive (packet); + completed = true; + } + finally + { + end (completed); + setInChannelOperation(false); + } + + if (!dst.hasArray()) + { + dst.put (packet.getData(), packet.getOffset(), packet.getLength()); + } + else + { + dst.position (dst.position() + packet.getLength()); + } + + return packet.getSocketAddress(); + } + catch (SocketTimeoutException e) + { + return null; + } + } + + public int send (ByteBuffer src, SocketAddress target) + throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + if (target instanceof InetSocketAddress + && ((InetSocketAddress) target).isUnresolved()) + throw new IOException("Target address not resolved"); + + byte[] buffer; + int offset = 0; + int len = src.remaining(); + + if (src.hasArray()) + { + buffer = src.array(); + offset = src.arrayOffset() + src.position(); + } + else + { + buffer = new byte [len]; + src.get (buffer); + } + + DatagramPacket packet = new DatagramPacket (buffer, offset, len, target); + + boolean completed = false; + try + { + begin(); + setInChannelOperation(true); + socket.send(packet); + completed = true; + } + finally + { + end (completed); + setInChannelOperation(false); + } + + if (src.hasArray()) + { + src.position (src.position() + len); + } + + return len; + } +} diff --git a/libjava/classpath/gnu/java/nio/DatagramChannelSelectionKey.java b/libjava/classpath/gnu/java/nio/DatagramChannelSelectionKey.java new file mode 100644 index 0000000..698e07e34 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/DatagramChannelSelectionKey.java @@ -0,0 +1,61 @@ +/* DatagramChannelSelectionKey.java -- + Copyright (C) 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.nio; + +import java.nio.channels.spi.AbstractSelectableChannel; + +/** + * @author Michael Koch + */ +public final class DatagramChannelSelectionKey + extends SelectionKeyImpl +{ + public DatagramChannelSelectionKey (AbstractSelectableChannel channel, + SelectorImpl selector) + { + super (channel, selector); + } + + public int getNativeFD() + { + NIODatagramSocket socket = + (NIODatagramSocket) ((DatagramChannelImpl) ch).socket(); + return socket.getPlainDatagramSocketImpl().getNativeFD(); + } +} diff --git a/libjava/classpath/gnu/java/nio/FileLockImpl.java b/libjava/classpath/gnu/java/nio/FileLockImpl.java new file mode 100644 index 0000000..245fa73 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/FileLockImpl.java @@ -0,0 +1,82 @@ +/* FileLockImpl.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.java.nio; + +import gnu.java.nio.channels.FileChannelImpl; + +import java.io.IOException; +import java.nio.channels.FileLock; + +/** + * @author Michael Koch + * @since 1.4 + */ +public class FileLockImpl extends FileLock +{ + private FileChannelImpl ch; + + public FileLockImpl (FileChannelImpl channel, long position, + long size, boolean shared) + { + super (channel, position, size, shared); + ch = channel; + } + + protected void finalize() + { + try + { + release(); + } + catch (IOException e) + { + // Ignore this. + } + } + + public boolean isValid () + { + return channel().isOpen(); + } + + public synchronized void release () throws IOException + { + ch.unlock(position(), size()); + } +} diff --git a/libjava/classpath/gnu/java/nio/InputStreamChannel.java b/libjava/classpath/gnu/java/nio/InputStreamChannel.java new file mode 100644 index 0000000..a3dffe2 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/InputStreamChannel.java @@ -0,0 +1,88 @@ +/* InputStreamChannel.java -- + Copyright (C) 2003 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.java.nio; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ReadableByteChannel; + +/** + * @author Michael Koch + */ +public final class InputStreamChannel implements ReadableByteChannel +{ + private boolean closed = false; + private InputStream in; + + public InputStreamChannel (InputStream in) + { + super(); + this.in = in; + } + + public void close() throws IOException + { + if (!closed) + { + in.close(); + closed = true; + } + } + + public boolean isOpen() + { + return !closed; + } + + public int read (ByteBuffer dst) throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + byte[] buffer = new byte [dst.remaining()]; + int readBytes = in.read (buffer); + + if (readBytes > 0) + dst.put (buffer, 0, readBytes); + + return readBytes; + } +} diff --git a/libjava/classpath/gnu/java/nio/NIOConstants.java b/libjava/classpath/gnu/java/nio/NIOConstants.java new file mode 100644 index 0000000..bb5b3b7 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/NIOConstants.java @@ -0,0 +1,47 @@ +/* NIOConstants.java -- + Copyright (C) 2003 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.java.nio; + +/** + * @author Michael Koch + */ +public final class NIOConstants +{ + public static final int DEFAULT_TIMEOUT = 50; +} diff --git a/libjava/classpath/gnu/java/nio/NIODatagramSocket.java b/libjava/classpath/gnu/java/nio/NIODatagramSocket.java new file mode 100644 index 0000000..f23236e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/NIODatagramSocket.java @@ -0,0 +1,71 @@ +/* NIODatagramSocket.java -- + Copyright (C) 2003 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.java.nio; + +import gnu.java.net.PlainDatagramSocketImpl; + +import java.net.DatagramSocket; +import java.nio.channels.DatagramChannel; + +/** + * @author Michael Koch + */ +public final class NIODatagramSocket extends DatagramSocket +{ + private PlainDatagramSocketImpl impl; + private DatagramChannelImpl channel; + + public NIODatagramSocket (PlainDatagramSocketImpl impl, + DatagramChannelImpl channel) + { + super (impl); + this.impl = impl; + this.channel = channel; + } + + public final PlainDatagramSocketImpl getPlainDatagramSocketImpl() + { + return impl; + } + + public final DatagramChannel getChannel() + { + return channel; + } +} diff --git a/libjava/classpath/gnu/java/nio/NIOServerSocket.java b/libjava/classpath/gnu/java/nio/NIOServerSocket.java new file mode 100644 index 0000000..fc4d0db --- /dev/null +++ b/libjava/classpath/gnu/java/nio/NIOServerSocket.java @@ -0,0 +1,106 @@ +/* NIOServerSocket.java -- + Copyright (C) 2003, 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.java.nio; + +import gnu.java.net.PlainSocketImpl; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; + +/** + * @author Michael Koch (konqueror@gmx.de) + */ +public final class NIOServerSocket extends ServerSocket +{ + private ServerSocketChannelImpl channel; + + protected NIOServerSocket (ServerSocketChannelImpl channel) + throws IOException + { + super(); + this.channel = channel; + } + + public PlainSocketImpl getPlainSocketImpl() + { + try + { + final Object t = this; + final Method method = ServerSocket.class.getDeclaredMethod("getImpl", new Class[0]); + method.setAccessible(true); + PrivilegedExceptionAction action = new PrivilegedExceptionAction() + { + public Object run() throws Exception + { + return method.invoke(t, new Object[0]); + } + }; + return (PlainSocketImpl) AccessController.doPrivileged(action); + } + catch (Exception e) + { + // This should never happen. + Error error = new InternalError("unable to invoke method ServerSocket.getImpl()"); + error.initCause(e); + throw error; + } + } + + public ServerSocketChannel getChannel() + { + return channel; + } + + public Socket accept() throws IOException + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkListen (getLocalPort()); + + SocketChannel socketChannel = channel.provider().openSocketChannel(); + implAccept (socketChannel.socket()); + return socketChannel.socket(); + } +} diff --git a/libjava/classpath/gnu/java/nio/NIOSocket.java b/libjava/classpath/gnu/java/nio/NIOSocket.java new file mode 100644 index 0000000..4d812bf --- /dev/null +++ b/libjava/classpath/gnu/java/nio/NIOSocket.java @@ -0,0 +1,77 @@ +/* NIOSocket.java -- + Copyright (C) 2003 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.java.nio; + +import gnu.java.net.PlainSocketImpl; +import java.io.IOException; +import java.net.Socket; +import java.nio.channels.SocketChannel; + +/** + * @author Michael Koch + */ +public final class NIOSocket extends Socket +{ + private PlainSocketImpl impl; + private SocketChannelImpl channel; + + protected NIOSocket (PlainSocketImpl impl, SocketChannelImpl channel) + throws IOException + { + super (impl); + this.impl = impl; + this.channel = channel; + } + + public final PlainSocketImpl getPlainSocketImpl() + { + return impl; + } + + final void setChannel (SocketChannelImpl channel) + { + this.impl = channel.getPlainSocketImpl(); + this.channel = channel; + } + + public final SocketChannel getChannel() + { + return channel; + } +} diff --git a/libjava/classpath/gnu/java/nio/OutputStreamChannel.java b/libjava/classpath/gnu/java/nio/OutputStreamChannel.java new file mode 100644 index 0000000..8167426 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/OutputStreamChannel.java @@ -0,0 +1,87 @@ +/* OutputStreamChannel.java -- + Copyright (C) 2003 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.java.nio; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.WritableByteChannel; + +/** + * @author Michael Koch + */ +public final class OutputStreamChannel implements WritableByteChannel +{ + private boolean closed = false; + private OutputStream out; + + public OutputStreamChannel (OutputStream out) + { + super(); + + this.out = out; + } + + public void close() throws IOException + { + if (!closed) + { + out.close(); + closed = true; + } + } + + public boolean isOpen() + { + return !closed; + } + + public int write (ByteBuffer src) throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + int len = src.remaining(); + byte[] buffer = new byte [len]; + src.get (buffer); + out.write (buffer); + return len; + } +} diff --git a/libjava/classpath/gnu/java/nio/PipeImpl.java b/libjava/classpath/gnu/java/nio/PipeImpl.java new file mode 100644 index 0000000..f7b01c8 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/PipeImpl.java @@ -0,0 +1,184 @@ +/* PipeImpl.java -- + Copyright (C) 2002, 2003, 2004, 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.java.nio; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Pipe; +import java.nio.channels.spi.SelectorProvider; + +class PipeImpl extends Pipe +{ + public static final class SourceChannelImpl extends Pipe.SourceChannel + { + private int native_fd; + + public SourceChannelImpl (SelectorProvider selectorProvider, + int native_fd) + { + super (selectorProvider); + this.native_fd = native_fd; + } + + protected final void implCloseSelectableChannel() + throws IOException + { + throw new Error ("Not implemented"); + } + + protected void implConfigureBlocking (boolean blocking) + throws IOException + { + throw new Error ("Not implemented"); + } + + public final int read (ByteBuffer src) + throws IOException + { + throw new Error ("Not implemented"); + } + + public final long read (ByteBuffer[] srcs) + throws IOException + { + return read (srcs, 0, srcs.length); + } + + public final synchronized long read (ByteBuffer[] srcs, int offset, + int len) + throws IOException + { + if (offset < 0 + || offset > srcs.length + || len < 0 + || len > srcs.length - offset) + throw new IndexOutOfBoundsException(); + + long bytesRead = 0; + + for (int index = 0; index < len; index++) + bytesRead += read (srcs [offset + index]); + + return bytesRead; + + } + + public final int getNativeFD() + { + return native_fd; + } + } + + public static final class SinkChannelImpl extends Pipe.SinkChannel + { + private int native_fd; + + public SinkChannelImpl (SelectorProvider selectorProvider, + int native_fd) + { + super (selectorProvider); + this.native_fd = native_fd; + } + + protected final void implCloseSelectableChannel() + throws IOException + { + throw new Error ("Not implemented"); + } + + protected final void implConfigureBlocking (boolean blocking) + throws IOException + { + throw new Error ("Not implemented"); + } + + public final int write (ByteBuffer dst) + throws IOException + { + throw new Error ("Not implemented"); + } + + public final long write (ByteBuffer[] srcs) + throws IOException + { + return write (srcs, 0, srcs.length); + } + + public final synchronized long write (ByteBuffer[] srcs, int offset, int len) + throws IOException + { + if (offset < 0 + || offset > srcs.length + || len < 0 + || len > srcs.length - offset) + throw new IndexOutOfBoundsException(); + + long bytesWritten = 0; + + for (int index = 0; index < len; index++) + bytesWritten += write (srcs [offset + index]); + + return bytesWritten; + } + + public final int getNativeFD() + { + return native_fd; + } + } + + private SinkChannelImpl sink; + private SourceChannelImpl source; + + public PipeImpl (SelectorProvider provider) + throws IOException + { + super(); + VMPipe.init (this, provider); + } + + public Pipe.SinkChannel sink() + { + return sink; + } + + public Pipe.SourceChannel source() + { + return source; + } +} diff --git a/libjava/classpath/gnu/java/nio/SelectionKeyImpl.java b/libjava/classpath/gnu/java/nio/SelectionKeyImpl.java new file mode 100644 index 0000000..a1f125e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/SelectionKeyImpl.java @@ -0,0 +1,104 @@ +/* SelectionKeyImpl.java -- + Copyright (C) 2002, 2003 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.java.nio; + +import java.nio.channels.CancelledKeyException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectionKey; + +public abstract class SelectionKeyImpl extends AbstractSelectionKey +{ + private int readyOps; + private int interestOps; + private SelectorImpl impl; + SelectableChannel ch; + + public SelectionKeyImpl (SelectableChannel ch, SelectorImpl impl) + { + this.ch = ch; + this.impl = impl; + } + + public SelectableChannel channel () + { + return ch; + } + + public int readyOps () + { + if (!isValid()) + throw new CancelledKeyException(); + + return readyOps; + } + + public SelectionKey readyOps (int ops) + { + if (!isValid()) + throw new CancelledKeyException(); + + readyOps = ops; + return this; + } + + public int interestOps () + { + if (!isValid()) + throw new CancelledKeyException(); + + return interestOps; + } + + public SelectionKey interestOps (int ops) + { + if (!isValid()) + throw new CancelledKeyException(); + + interestOps = ops; + return this; + } + + public Selector selector () + { + return impl; + } + + public abstract int getNativeFD(); +} diff --git a/libjava/classpath/gnu/java/nio/SelectorImpl.java b/libjava/classpath/gnu/java/nio/SelectorImpl.java new file mode 100644 index 0000000..dcafede --- /dev/null +++ b/libjava/classpath/gnu/java/nio/SelectorImpl.java @@ -0,0 +1,394 @@ +/* SelectorImpl.java -- + Copyright (C) 2002, 2003, 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.java.nio; + +import java.io.IOException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.spi.AbstractSelectableChannel; +import java.nio.channels.spi.AbstractSelector; +import java.nio.channels.spi.SelectorProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class SelectorImpl extends AbstractSelector +{ + private Set keys; + private Set selected; + + /** + * A dummy object whose monitor regulates access to both our + * selectThread and unhandledWakeup fields. + */ + private Object selectThreadMutex = new Object (); + + /** + * Any thread that's currently blocked in a select operation. + */ + private Thread selectThread; + + /** + * Indicates whether we have an unhandled wakeup call. This can + * be due to either wakeup() triggering a thread interruption while + * a thread was blocked in a select operation (in which case we need + * to reset this thread's interrupt status after interrupting the + * select), or else that no thread was on a select operation at the + * time that wakeup() was called, in which case the following select() + * operation should return immediately with nothing selected. + */ + private boolean unhandledWakeup; + + public SelectorImpl (SelectorProvider provider) + { + super (provider); + + keys = new HashSet (); + selected = new HashSet (); + } + + protected void finalize() throws Throwable + { + close(); + } + + protected final void implCloseSelector() + throws IOException + { + // Cancel any pending select operation. + wakeup(); + + synchronized (keys) + { + synchronized (selected) + { + synchronized (cancelledKeys ()) + { + // FIXME: Release resources here. + } + } + } + } + + public final Set keys() + { + if (!isOpen()) + throw new ClosedSelectorException(); + + return Collections.unmodifiableSet (keys); + } + + public final int selectNow() + throws IOException + { + // FIXME: We're simulating an immediate select + // via a select with a timeout of one millisecond. + return select (1); + } + + public final int select() + throws IOException + { + return select (0); + } + + private final int[] getFDsAsArray (int ops) + { + int[] result; + int counter = 0; + Iterator it = keys.iterator (); + + // Count the number of file descriptors needed + while (it.hasNext ()) + { + SelectionKeyImpl key = (SelectionKeyImpl) it.next (); + + if ((key.interestOps () & ops) != 0) + { + counter++; + } + } + + result = new int[counter]; + + counter = 0; + it = keys.iterator (); + + // Fill the array with the file descriptors + while (it.hasNext ()) + { + SelectionKeyImpl key = (SelectionKeyImpl) it.next (); + + if ((key.interestOps () & ops) != 0) + { + result[counter] = key.getNativeFD(); + counter++; + } + } + + return result; + } + + public synchronized int select (long timeout) + throws IOException + { + if (!isOpen()) + throw new ClosedSelectorException(); + + synchronized (keys) + { + synchronized (selected) + { + deregisterCancelledKeys(); + + // Set only keys with the needed interest ops into the arrays. + int[] read = getFDsAsArray (SelectionKey.OP_READ + | SelectionKey.OP_ACCEPT); + int[] write = getFDsAsArray (SelectionKey.OP_WRITE + | SelectionKey.OP_CONNECT); + + // FIXME: We dont need to check this yet + int[] except = new int [0]; + + // Test to see if we've got an unhandled wakeup call, + // in which case we return immediately. Otherwise, + // remember our current thread and jump into the select. + // The monitor for dummy object selectThreadMutex regulates + // access to these fields. + + // FIXME: Not sure from the spec at what point we should + // return "immediately". Is it here or immediately upon + // entry to this function? + + // NOTE: There's a possibility of another thread calling + // wakeup() immediately after our thread releases + // selectThreadMutex's monitor here, in which case we'll + // do the select anyway. Since calls to wakeup() and select() + // among different threads happen in non-deterministic order, + // I don't think this is an issue. + synchronized (selectThreadMutex) + { + if (unhandledWakeup) + { + unhandledWakeup = false; + return 0; + } + else + { + selectThread = Thread.currentThread (); + } + } + + // Call the native select() on all file descriptors. + int result = 0; + try + { + begin(); + result = VMSelector.select (read, write, except, timeout); + } + finally + { + end(); + } + + // If our unhandled wakeup flag is set at this point, + // reset our thread's interrupt flag because we were + // awakened by wakeup() instead of an external thread + // interruption. + // + // NOTE: If we were blocked in a select() and one thread + // called Thread.interrupt() on the blocked thread followed + // by another thread calling Selector.wakeup(), then race + // conditions could make it so that the thread's interrupt + // flag is reset even though the Thread.interrupt() call + // "was there first". I don't think we need to care about + // this scenario. + synchronized (selectThreadMutex) + { + if (unhandledWakeup) + { + unhandledWakeup = false; + Thread.interrupted (); + } + selectThread = null; + } + + Iterator it = keys.iterator (); + + while (it.hasNext ()) + { + int ops = 0; + SelectionKeyImpl key = (SelectionKeyImpl) it.next (); + + // If key is already selected retrieve old ready ops. + if (selected.contains (key)) + { + ops = key.readyOps (); + } + + // Set new ready read/accept ops + for (int i = 0; i < read.length; i++) + { + if (key.getNativeFD() == read[i]) + { + if (key.channel () instanceof ServerSocketChannelImpl) + { + ops = ops | SelectionKey.OP_ACCEPT; + } + else + { + ops = ops | SelectionKey.OP_READ; + } + } + } + + // Set new ready write ops + for (int i = 0; i < write.length; i++) + { + if (key.getNativeFD() == write[i]) + { + ops = ops | SelectionKey.OP_WRITE; + + // if (key.channel ().isConnected ()) + // { + // ops = ops | SelectionKey.OP_WRITE; + // } + // else + // { + // ops = ops | SelectionKey.OP_CONNECT; + // } + } + } + + // FIXME: We dont handle exceptional file descriptors yet. + + // If key is not yet selected add it. + if (!selected.contains (key)) + { + selected.add (key); + } + + // Set new ready ops + key.readyOps (key.interestOps () & ops); + } + deregisterCancelledKeys(); + + return result; + } + } + } + + public final Set selectedKeys() + { + if (!isOpen()) + throw new ClosedSelectorException(); + + return selected; + } + + public final Selector wakeup() + { + // IMPLEMENTATION NOTE: Whereas the specification says that + // thread interruption should trigger a call to wakeup, we + // do the reverse under the covers: wakeup triggers a thread + // interrupt followed by a subsequent reset of the thread's + // interrupt status within select(). + + // First, acquire the monitor of the object regulating + // access to our selectThread and unhandledWakeup fields. + synchronized (selectThreadMutex) + { + unhandledWakeup = true; + + // Interrupt any thread which is currently blocked in + // a select operation. + if (selectThread != null) + selectThread.interrupt (); + } + + return this; + } + + private final void deregisterCancelledKeys() + { + Set ckeys = cancelledKeys (); + synchronized (ckeys) + { + Iterator it = ckeys.iterator(); + + while (it.hasNext ()) + { + keys.remove ((SelectionKeyImpl) it.next ()); + it.remove (); + } + } + } + + protected SelectionKey register (SelectableChannel ch, int ops, Object att) + { + return register ((AbstractSelectableChannel) ch, ops, att); + } + + protected final SelectionKey register (AbstractSelectableChannel ch, int ops, + Object att) + { + SelectionKeyImpl result; + + if (ch instanceof SocketChannelImpl) + result = new SocketChannelSelectionKey (ch, this); + else if (ch instanceof DatagramChannelImpl) + result = new DatagramChannelSelectionKey (ch, this); + else if (ch instanceof ServerSocketChannelImpl) + result = new ServerSocketChannelSelectionKey (ch, this); + else + throw new InternalError ("No known channel type"); + + synchronized (keys) + { + keys.add (result); + } + + result.interestOps (ops); + result.attach (att); + return result; + } +} diff --git a/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java b/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java new file mode 100644 index 0000000..4752110 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java @@ -0,0 +1,83 @@ +/* SelectorProviderImpl.java -- + Copyright (C) 2002, 2003 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.java.nio; + +import java.io.IOException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.Pipe; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.AbstractSelector; +import java.nio.channels.spi.SelectorProvider; + +public class SelectorProviderImpl extends SelectorProvider +{ + public SelectorProviderImpl () + { + } + + public DatagramChannel openDatagramChannel () + throws IOException + { + return new DatagramChannelImpl (this); + } + + public Pipe openPipe () + throws IOException + { + return new PipeImpl (this); + } + + public AbstractSelector openSelector () + throws IOException + { + return new SelectorImpl (this); + } + + public ServerSocketChannel openServerSocketChannel () + throws IOException + { + return new ServerSocketChannelImpl (this); + } + + public SocketChannel openSocketChannel () + throws IOException + { + return new SocketChannelImpl (this); + } +} diff --git a/libjava/classpath/gnu/java/nio/ServerSocketChannelImpl.java b/libjava/classpath/gnu/java/nio/ServerSocketChannelImpl.java new file mode 100644 index 0000000..c538ea8 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/ServerSocketChannelImpl.java @@ -0,0 +1,124 @@ +/* ServerSocketChannelImpl.java -- + Copyright (C) 2002, 2003, 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.java.nio; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.SocketTimeoutException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetBoundException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.channels.spi.SelectorProvider; + +public final class ServerSocketChannelImpl extends ServerSocketChannel +{ + private NIOServerSocket serverSocket; + private boolean connected; + + protected ServerSocketChannelImpl (SelectorProvider provider) + throws IOException + { + super (provider); + serverSocket = new NIOServerSocket (this); + configureBlocking(true); + } + + public void finalizer() + { + if (connected) + { + try + { + close (); + } + catch (Exception e) + { + } + } + } + + protected void implCloseSelectableChannel () throws IOException + { + connected = false; + serverSocket.close(); + } + + protected void implConfigureBlocking (boolean blocking) throws IOException + { + serverSocket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT); + } + + public SocketChannel accept () throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + if (!serverSocket.isBound()) + throw new NotYetBoundException(); + + boolean completed = false; + + try + { + begin(); + serverSocket.getPlainSocketImpl().setInChannelOperation(true); + // indicate that a channel is initiating the accept operation + // so that the socket ignores the fact that we might be in + // non-blocking mode. + NIOSocket socket = (NIOSocket) serverSocket.accept(); + completed = true; + return socket.getChannel(); + } + catch (SocketTimeoutException e) + { + return null; + } + finally + { + serverSocket.getPlainSocketImpl().setInChannelOperation(false); + end (completed); + } + } + + public ServerSocket socket () + { + return serverSocket; + } +} diff --git a/libjava/classpath/gnu/java/nio/ServerSocketChannelSelectionKey.java b/libjava/classpath/gnu/java/nio/ServerSocketChannelSelectionKey.java new file mode 100644 index 0000000..d00c2b7 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/ServerSocketChannelSelectionKey.java @@ -0,0 +1,58 @@ +/* ServerSocketChannelSelectionKey.java -- + Copyright (C) 2003 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.java.nio; + +import java.nio.channels.spi.AbstractSelectableChannel; + +public final class ServerSocketChannelSelectionKey + extends SelectionKeyImpl +{ + public ServerSocketChannelSelectionKey (AbstractSelectableChannel channel, + SelectorImpl selector) + { + super (channel, selector); + } + + public int getNativeFD() + { + NIOServerSocket socket = + (NIOServerSocket) ((ServerSocketChannelImpl) ch).socket(); + return socket.getPlainSocketImpl().getNativeFD(); + } +} diff --git a/libjava/classpath/gnu/java/nio/SocketChannelImpl.java b/libjava/classpath/gnu/java/nio/SocketChannelImpl.java new file mode 100644 index 0000000..9fb71c1 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/SocketChannelImpl.java @@ -0,0 +1,351 @@ +/* SocketChannelImpl.java -- + Copyright (C) 2002, 2003, 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.java.nio; + +import gnu.java.net.PlainSocketImpl; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; +import java.nio.channels.AlreadyConnectedException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ConnectionPendingException; +import java.nio.channels.NoConnectionPendingException; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.nio.channels.UnresolvedAddressException; +import java.nio.channels.UnsupportedAddressTypeException; +import java.nio.channels.spi.SelectorProvider; + +public final class SocketChannelImpl extends SocketChannel +{ + private PlainSocketImpl impl; + private NIOSocket socket; + private boolean connectionPending; + + SocketChannelImpl (SelectorProvider provider) + throws IOException + { + super (provider); + impl = new PlainSocketImpl(); + socket = new NIOSocket (impl, this); + configureBlocking(true); + } + + SocketChannelImpl (SelectorProvider provider, + NIOSocket socket) + throws IOException + { + super (provider); + this.impl = socket.getPlainSocketImpl(); + this.socket = socket; + } + + public void finalizer() + { + if (isConnected()) + { + try + { + close (); + } + catch (Exception e) + { + } + } + } + + PlainSocketImpl getPlainSocketImpl() + { + return impl; + } + + protected void implCloseSelectableChannel () throws IOException + { + socket.close(); + } + + protected void implConfigureBlocking (boolean blocking) throws IOException + { + socket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT); + } + + public boolean connect (SocketAddress remote) throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + if (isConnected()) + throw new AlreadyConnectedException(); + + if (connectionPending) + throw new ConnectionPendingException(); + + if (!(remote instanceof InetSocketAddress)) + throw new UnsupportedAddressTypeException(); + + if (((InetSocketAddress) remote).isUnresolved()) + throw new UnresolvedAddressException(); + + try + { + socket.getPlainSocketImpl().setInChannelOperation(true); + // indicate that a channel is initiating the accept operation + // so that the socket ignores the fact that we might be in + // non-blocking mode. + + if (isBlocking()) + { + // Do blocking connect. + socket.connect (remote); + return true; + } + + // Do non-blocking connect. + try + { + socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT); + return true; + } + catch (SocketTimeoutException e) + { + connectionPending = true; + return false; + } + } + finally + { + socket.getPlainSocketImpl().setInChannelOperation(false); + } + } + + public boolean finishConnect () + throws IOException + { + if (!isOpen()) + throw new ClosedChannelException(); + + if (!isConnected() && !connectionPending) + throw new NoConnectionPendingException(); + + if (isConnected()) + return true; + + // FIXME: Handle blocking/non-blocking mode. + + Selector selector = provider().openSelector(); + register(selector, SelectionKey.OP_CONNECT); + + if (isBlocking()) + { + selector.select(); // blocking until channel is connected. + connectionPending = false; + return true; + } + + int ready = selector.selectNow(); // non-blocking + if (ready == 1) + { + connectionPending = false; + return true; + } + + return false; + } + + public boolean isConnected () + { + return socket.isConnected(); + } + + public boolean isConnectionPending () + { + return connectionPending; + } + + public Socket socket () + { + return socket; + } + + public int read(ByteBuffer dst) throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + byte[] data; + int offset = 0; + InputStream input = socket.getInputStream(); + int available = input.available(); + int len = dst.capacity() - dst.position(); + + if ((! isBlocking()) && available == 0) + return 0; + + if (dst.hasArray()) + { + offset = dst.arrayOffset() + dst.position(); + data = dst.array(); + } + else + { + data = new byte [len]; + } + + int readBytes = 0; + boolean completed = false; + + try + { + begin(); + socket.getPlainSocketImpl().setInChannelOperation(true); + readBytes = input.read (data, offset, len); + completed = true; + } + finally + { + end (completed); + socket.getPlainSocketImpl().setInChannelOperation(false); + } + + if (readBytes > 0) + if (dst.hasArray()) + { + dst.position (dst.position() + readBytes); + } + else + { + dst.put (data, offset, len); + } + + return readBytes; + } + + public long read (ByteBuffer[] dsts, int offset, int length) + throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + if ((offset < 0) + || (offset > dsts.length) + || (length < 0) + || (length > (dsts.length - offset))) + throw new IndexOutOfBoundsException(); + + long readBytes = 0; + + for (int index = offset; index < length; index++) + readBytes += read (dsts [index]); + + return readBytes; + } + + public int write (ByteBuffer src) + throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + byte[] data; + int offset = 0; + int len = src.remaining(); + + if (!src.hasArray()) + { + data = new byte [len]; + src.get (data, 0, len); + } + else + { + offset = src.arrayOffset() + src.position(); + data = src.array(); + } + + OutputStream output = socket.getOutputStream(); + boolean completed = false; + + try + { + begin(); + socket.getPlainSocketImpl().setInChannelOperation(true); + output.write (data, offset, len); + completed = true; + } + finally + { + end (completed); + socket.getPlainSocketImpl().setInChannelOperation(false); + } + + if (src.hasArray()) + { + src.position (src.position() + len); + } + + return len; + } + + public long write (ByteBuffer[] srcs, int offset, int length) + throws IOException + { + if (!isConnected()) + throw new NotYetConnectedException(); + + if ((offset < 0) + || (offset > srcs.length) + || (length < 0) + || (length > (srcs.length - offset))) + throw new IndexOutOfBoundsException(); + + long writtenBytes = 0; + + for (int index = offset; index < length; index++) + writtenBytes += write (srcs [index]); + + return writtenBytes; + } +} diff --git a/libjava/classpath/gnu/java/nio/SocketChannelSelectionKey.java b/libjava/classpath/gnu/java/nio/SocketChannelSelectionKey.java new file mode 100644 index 0000000..75b4dfd --- /dev/null +++ b/libjava/classpath/gnu/java/nio/SocketChannelSelectionKey.java @@ -0,0 +1,58 @@ +/* SocketChannelSelectionKey.java -- + Copyright (C) 2003 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.java.nio; + +import java.nio.channels.spi.AbstractSelectableChannel; + +public final class SocketChannelSelectionKey + extends SelectionKeyImpl +{ + public SocketChannelSelectionKey (AbstractSelectableChannel channel, + SelectorImpl selector) + { + super (channel, selector); + } + + public int getNativeFD() + { + NIOSocket socket = + (NIOSocket) ((SocketChannelImpl) ch).socket(); + return socket.getPlainSocketImpl().getNativeFD(); + } +} diff --git a/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java new file mode 100644 index 0000000..a87a2e8 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java @@ -0,0 +1,535 @@ +/* FileChannelImpl.java -- + Copyright (C) 2002, 2004, 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.java.nio.channels; + +import gnu.classpath.Configuration; +import gnu.java.nio.FileLockImpl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.channels.NonReadableChannelException; +import java.nio.channels.NonWritableChannelException; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +/** + * This file is not user visible ! + * But alas, Java does not have a concept of friendly packages + * so this class is public. + * Instances of this class are created by invoking getChannel + * Upon a Input/Output/RandomAccessFile object. + */ +public final class FileChannelImpl extends FileChannel +{ + // These are mode values for open(). + public static final int READ = 1; + public static final int WRITE = 2; + public static final int APPEND = 4; + + // EXCL is used only when making a temp file. + public static final int EXCL = 8; + public static final int SYNC = 16; + public static final int DSYNC = 32; + + private static native void init(); + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javanio"); + } + + init(); + } + + /** + * This is the actual native file descriptor value + */ + // System's notion of file descriptor. It might seem redundant to + // initialize this given that it is reassigned in the constructors. + // However, this is necessary because if open() throws an exception + // we want to make sure this has the value -1. This is the most + // efficient way to accomplish that. + private int fd = -1; + + private int mode; + + /* Open a file. MODE is a combination of the above mode flags. */ + /* This is a static factory method, so that VM implementors can decide + * substitute subclasses of FileChannelImpl. */ + public static FileChannelImpl create(File file, int mode) + throws FileNotFoundException + { + return new FileChannelImpl(file, mode); + } + + private FileChannelImpl(File file, int mode) + throws FileNotFoundException + { + final String path = file.getPath(); + fd = open (path, mode); + this.mode = mode; + + // First open the file and then check if it is a a directory + // to avoid race condition. + if (file.isDirectory()) + { + try + { + close(); + } + catch (IOException e) + { + /* ignore it */ + } + + throw new FileNotFoundException(path + " is a directory"); + } + } + + /* Used by init() (native code) */ + FileChannelImpl (int fd, int mode) + { + this.fd = fd; + this.mode = mode; + } + + public static FileChannelImpl in; + public static FileChannelImpl out; + public static FileChannelImpl err; + + private native int open (String path, int mode) throws FileNotFoundException; + + public native int available () throws IOException; + private native long implPosition () throws IOException; + private native void seek (long newPosition) throws IOException; + private native void implTruncate (long size) throws IOException; + + public native void unlock (long pos, long len) throws IOException; + + public native long size () throws IOException; + + protected native void implCloseChannel() throws IOException; + + /** + * Makes sure the Channel is properly closed. + */ + protected void finalize() throws IOException + { + this.close(); + } + + public int read (ByteBuffer dst) throws IOException + { + int result; + byte[] buffer = new byte [dst.remaining ()]; + + result = read (buffer, 0, buffer.length); + + if (result > 0) + dst.put (buffer, 0, result); + + return result; + } + + public int read (ByteBuffer dst, long position) + throws IOException + { + if (position < 0) + throw new IllegalArgumentException (); + long oldPosition = implPosition (); + position (position); + int result = read(dst); + position (oldPosition); + + return result; + } + + public native int read () + throws IOException; + + public native int read (byte[] buffer, int offset, int length) + throws IOException; + + public long read (ByteBuffer[] dsts, int offset, int length) + throws IOException + { + long result = 0; + + for (int i = offset; i < offset + length; i++) + { + result += read (dsts [i]); + } + + return result; + } + + public int write (ByteBuffer src) throws IOException + { + int len = src.remaining (); + if (src.hasArray()) + { + byte[] buffer = src.array(); + write(buffer, src.arrayOffset() + src.position(), len); + src.position(src.position() + len); + } + else + { + // Use a more efficient native method! FIXME! + byte[] buffer = new byte [len]; + src.get (buffer, 0, len); + write (buffer, 0, len); + } + return len; + } + + public int write (ByteBuffer src, long position) + throws IOException + { + if (position < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + if ((mode & WRITE) == 0) + throw new NonWritableChannelException (); + + int result; + long oldPosition; + + oldPosition = implPosition (); + seek (position); + result = write(src); + seek (oldPosition); + + return result; + } + + public native void write (byte[] buffer, int offset, int length) + throws IOException; + + public native void write (int b) throws IOException; + + public long write(ByteBuffer[] srcs, int offset, int length) + throws IOException + { + long result = 0; + + for (int i = offset;i < offset + length;i++) + { + result += write (srcs[i]); + } + + return result; + } + + public native MappedByteBuffer mapImpl (char mode, long position, int size) + throws IOException; + + public MappedByteBuffer map (FileChannel.MapMode mode, + long position, long size) + throws IOException + { + char nmode = 0; + if (mode == MapMode.READ_ONLY) + { + nmode = 'r'; + if ((this.mode & READ) == 0) + throw new NonReadableChannelException(); + } + else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE) + { + nmode = mode == MapMode.READ_WRITE ? '+' : 'c'; + if ((this.mode & (READ|WRITE)) != (READ|WRITE)) + throw new NonWritableChannelException(); + } + else + throw new IllegalArgumentException (); + + if (position < 0 || size < 0 || size > Integer.MAX_VALUE) + throw new IllegalArgumentException (); + return mapImpl(nmode, position, (int) size); + } + + /** + * msync with the disk + */ + public void force (boolean metaData) throws IOException + { + if (!isOpen ()) + throw new ClosedChannelException (); + + force (); + } + + private native void force (); + + // like transferTo, but with a count of less than 2Gbytes + private int smallTransferTo (long position, int count, + WritableByteChannel target) + throws IOException + { + ByteBuffer buffer; + try + { + // Try to use a mapped buffer if we can. If this fails for + // any reason we'll fall back to using a ByteBuffer. + buffer = map (MapMode.READ_ONLY, position, count); + } + catch (IOException e) + { + buffer = ByteBuffer.allocate (count); + read (buffer, position); + buffer.flip(); + } + + return target.write (buffer); + } + + public long transferTo (long position, long count, + WritableByteChannel target) + throws IOException + { + if (position < 0 + || count < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + if ((mode & READ) == 0) + throw new NonReadableChannelException (); + + final int pageSize = 65536; + long total = 0; + + while (count > 0) + { + int transferred + = smallTransferTo (position, (int)Math.min (count, pageSize), + target); + if (transferred < 0) + break; + total += transferred; + position += transferred; + count -= transferred; + } + + return total; + } + + // like transferFrom, but with a count of less than 2Gbytes + private int smallTransferFrom (ReadableByteChannel src, long position, + int count) + throws IOException + { + ByteBuffer buffer = null; + + if (src instanceof FileChannel) + { + try + { + // Try to use a mapped buffer if we can. If this fails + // for any reason we'll fall back to using a ByteBuffer. + buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position, + count); + } + catch (IOException e) + { + } + } + + if (buffer == null) + { + buffer = ByteBuffer.allocate ((int) count); + src.read (buffer); + buffer.flip(); + } + + return write (buffer, position); + } + + public long transferFrom (ReadableByteChannel src, long position, + long count) + throws IOException + { + if (position < 0 + || count < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + if ((mode & WRITE) == 0) + throw new NonWritableChannelException (); + + final int pageSize = 65536; + long total = 0; + + while (count > 0) + { + int transferred = smallTransferFrom (src, position, + (int)Math.min (count, pageSize)); + if (transferred < 0) + break; + total += transferred; + position += transferred; + count -= transferred; + } + + return total; + } + + public FileLock tryLock (long position, long size, boolean shared) + throws IOException + { + if (position < 0 + || size < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + if (shared && (mode & READ) == 0) + throw new NonReadableChannelException (); + + if (!shared && (mode & WRITE) == 0) + throw new NonWritableChannelException (); + + boolean completed = false; + + try + { + begin(); + boolean lockable = lock(position, size, shared, false); + completed = true; + return (lockable + ? new FileLockImpl(this, position, size, shared) + : null); + } + finally + { + end(completed); + } + } + + /** Try to acquire a lock at the given position and size. + * On success return true. + * If wait as specified, block until we can get it. + * Otherwise return false. + */ + private native boolean lock(long position, long size, + boolean shared, boolean wait) throws IOException; + + public FileLock lock (long position, long size, boolean shared) + throws IOException + { + if (position < 0 + || size < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + boolean completed = false; + + try + { + boolean lockable = lock(position, size, shared, true); + completed = true; + return (lockable + ? new FileLockImpl(this, position, size, shared) + : null); + } + finally + { + end(completed); + } + } + + public long position () + throws IOException + { + if (!isOpen ()) + throw new ClosedChannelException (); + + return implPosition (); + } + + public FileChannel position (long newPosition) + throws IOException + { + if (newPosition < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + // FIXME note semantics if seeking beyond eof. + // We should seek lazily - only on a write. + seek (newPosition); + return this; + } + + public FileChannel truncate (long size) + throws IOException + { + if (size < 0) + throw new IllegalArgumentException (); + + if (!isOpen ()) + throw new ClosedChannelException (); + + if ((mode & WRITE) == 0) + throw new NonWritableChannelException (); + + if (size < size ()) + implTruncate (size); + + return this; + } +} diff --git a/libjava/classpath/gnu/java/nio/channels/package.html b/libjava/classpath/gnu/java/nio/channels/package.html new file mode 100644 index 0000000..0c3821b --- /dev/null +++ b/libjava/classpath/gnu/java/nio/channels/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.nio.channels package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.nio.channels</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/nio/charset/ByteCharset.java b/libjava/classpath/gnu/java/nio/charset/ByteCharset.java new file mode 100644 index 0000000..2cc91b8 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ByteCharset.java @@ -0,0 +1,187 @@ +/* ByteCharset.java -- Abstract class for generic 1-byte encodings. + 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +/** + * A generic encoding framework for single-byte encodings, + * utilizing a look-up table. + * + * This replaces the gnu.java.io.EncoderEightBitLookup class, + * created by Aron Renn. + * + * @author Sven de Marothy + */ +abstract class ByteCharset extends Charset +{ + protected char[] lookupTable; + /** + * Char to signify the character in the table is undefined + */ + protected static final char NONE = (char)0xFFFD; + + ByteCharset (String canonicalName, String[] aliases) + { + super (canonicalName, aliases); + } + + /** + * Most western charsets include ASCII, but this should + * be overloaded for others. + */ + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || (cs.getClass() == getClass()); + } + + char[] getLookupTable() + { + return lookupTable; + } + + public CharsetDecoder newDecoder () + { + return new Decoder (this); + } + + public CharsetEncoder newEncoder () + { + return new Encoder (this); + } + + private static final class Decoder extends CharsetDecoder + { + private char[] lookup; + + // Package-private to avoid a trampoline constructor. + Decoder (ByteCharset cs) + { + super (cs, 1.0f, 1.0f); + lookup = cs.getLookupTable(); + } + + protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + byte b = in.get (); + char c; + + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + if((c = lookup[(int) (b & 0xFF)]) == NONE); + // return CoderResult.unmappableForLength (1); + out.put (c); + } + + return CoderResult.UNDERFLOW; + } + } + + private static final class Encoder extends CharsetEncoder + { + private byte[] lookup; + + // Package-private to avoid a trampoline constructor. + Encoder (ByteCharset cs) + { + super (cs, 1.0f, 1.0f); + + char[] lookup_table = cs.getLookupTable(); + + // Create the inverse look-up table. + // determine required size of encoding_table: + int max = 0; + for (int i = 0; i < lookup_table.length; i++) + { + int c = (int)lookup_table[i]; + max = (c > max && c < NONE) ? c : max; + } + + lookup = new byte[max+1]; + + for (int i = 0; i < lookup_table.length; i++) + { + int c = (int)lookup_table[i]; + if (c != 0 && c < NONE) + { + lookup[c] = (byte)i; + } + } + } + + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + int c = (int)in.get (); + + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + // lookup byte encoding + byte b = (c < lookup.length) ? lookup[c] : (byte)0; + + if ((int)b != 0 || (int)c == 0) + { + out.put (b); + } else { + in.position (in.position () - 1); + return CoderResult.unmappableForLength (1); + } + } + + return CoderResult.UNDERFLOW; + } + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/Cp424.java b/libjava/classpath/gnu/java/nio/charset/Cp424.java new file mode 100644 index 0000000..9733a76 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp424.java @@ -0,0 +1,89 @@ +/* Cp424.java -- Charset implementation for the Cp424 character set. + 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.java.nio.charset; + +public class Cp424 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, + 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A, + 0x0020, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, + 0x05D7, 0x05D8, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C, + 0x0026, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC, + 0x002D, 0x002F, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F, + NONE, 0x05EA, NONE, NONE, 0x00A0, NONE, NONE, NONE, + 0x2017, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022, + NONE, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00AB, 0x00BB, NONE, NONE, NONE, 0x00B1, + 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, + 0x0071, 0x0072, NONE, NONE, NONE, 0x00B8, NONE, 0x00A4, + 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007A, NONE, NONE, NONE, NONE, NONE, 0x00AE, + 0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, + 0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7, + 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00AD, NONE, NONE, NONE, NONE, NONE, + 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x00B9, NONE, NONE, NONE, NONE, NONE, + 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005A, 0x00B2, NONE, NONE, NONE, NONE, NONE, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00B3, NONE, NONE, NONE, NONE, 0x009F + }; + + public Cp424() + { + super("Cp424", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp424 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp437.java b/libjava/classpath/gnu/java/nio/charset/Cp437.java new file mode 100644 index 0000000..d608357 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp437.java @@ -0,0 +1,89 @@ +/* Cp437.java -- Charset implementation for the Cp437 character set. + 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.java.nio.charset; + +public class Cp437 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp437() + { + super("Cp437", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp437 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp737.java b/libjava/classpath/gnu/java/nio/charset/Cp737.java new file mode 100644 index 0000000..548da21 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp737.java @@ -0,0 +1,89 @@ +/* Cp737.java -- Charset implementation for the Cp737 character set. + 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.java.nio.charset; + +public class Cp737 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, + 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, + 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, + 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, + 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp737() + { + super("Cp737", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp737 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp775.java b/libjava/classpath/gnu/java/nio/charset/Cp775.java new file mode 100644 index 0000000..4d3f1c3 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp775.java @@ -0,0 +1,89 @@ +/* Cp775.java -- Charset implementation for the Cp775 character set. + 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.java.nio.charset; + +public class Cp775 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, + 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, + 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, + 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, + 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, + 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, + 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, + 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, + 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, + 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp775() + { + super("Cp775", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp775 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp850.java b/libjava/classpath/gnu/java/nio/charset/Cp850.java new file mode 100644 index 0000000..9122105 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp850.java @@ -0,0 +1,89 @@ +/* Cp850.java -- Charset implementation for the Cp850 character set. + 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.java.nio.charset; + +public class Cp850 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp850() + { + super("Cp850", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp850 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp852.java b/libjava/classpath/gnu/java/nio/charset/Cp852.java new file mode 100644 index 0000000..a859530 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp852.java @@ -0,0 +1,89 @@ +/* Cp852.java -- Charset implementation for the Cp852 character set. + 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.java.nio.charset; + +public class Cp852 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, + 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, + 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, + 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, + 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 + }; + + public Cp852() + { + super("Cp852", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp852 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp855.java b/libjava/classpath/gnu/java/nio/charset/Cp855.java new file mode 100644 index 0000000..fbec999 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp855.java @@ -0,0 +1,90 @@ +/* Cp855.java -- Charset implementation for the Cp855 character set. + 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.java.nio.charset; + +public class Cp855 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, + 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, + 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, + 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, + 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, + 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 + }; + + public Cp855() + { + super("Cp855", new String[] { + "cp-855", + }); + lookupTable = lookup; + } + +} // class Cp855 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp857.java b/libjava/classpath/gnu/java/nio/charset/Cp857.java new file mode 100644 index 0000000..78f8dbd --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp857.java @@ -0,0 +1,91 @@ +/* Cp857.java -- Charset implementation for the Cp857 character set. + 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.java.nio.charset; + +public class Cp857 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, NONE, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, NONE, + 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, NONE, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp857() + { + super("Cp857", new String[] { + "cp-857" + }); + lookupTable = lookup; + } + +} // class Cp857 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp860.java b/libjava/classpath/gnu/java/nio/charset/Cp860.java new file mode 100644 index 0000000..e3c7f46 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp860.java @@ -0,0 +1,91 @@ +/* Cp860.java -- Charset implementation for the Cp860 character set. + 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.java.nio.charset; + +public class Cp860 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, + 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, + 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, + 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp860() + { + super("Cp860", new String[] { + "cp-860" + }); + lookupTable = lookup; + } + +} // class Cp860 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp861.java b/libjava/classpath/gnu/java/nio/charset/Cp861.java new file mode 100644 index 0000000..6e17ea2 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp861.java @@ -0,0 +1,91 @@ +/* Cp861.java -- Charset implementation for the Cp861 character set. + 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.java.nio.charset; + +public class Cp861 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, + 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp861() + { + super("Cp861", new String[] { + "cp-861" + }); + lookupTable = lookup; + } + +} // class Cp861 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp862.java b/libjava/classpath/gnu/java/nio/charset/Cp862.java new file mode 100644 index 0000000..ccd74fa --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp862.java @@ -0,0 +1,91 @@ +/* Cp862.java -- Charset implementation for the Cp862 character set. + 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.java.nio.charset; + +public class Cp862 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp862() + { + super("Cp862", new String[] { + "Cp-862" + }); + lookupTable = lookup; + } + +} // class Cp862 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp863.java b/libjava/classpath/gnu/java/nio/charset/Cp863.java new file mode 100644 index 0000000..97812a6 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp863.java @@ -0,0 +1,91 @@ +/* Cp863.java -- Charset implementation for the Cp863 character set. + 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.java.nio.charset; + +public class Cp863 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x2017, 0x00C0, 0x00A7, + 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, + 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, + 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00B8, 0x00B3, 0x00AF, + 0x00CE, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp863() + { + super("Cp863", new String[] { + "Cp-863" + }); + lookupTable = lookup; + } + +} // class Cp863 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp864.java b/libjava/classpath/gnu/java/nio/charset/Cp864.java new file mode 100644 index 0000000..f136f43 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp864.java @@ -0,0 +1,91 @@ +/* Cp864.java -- Charset implementation for the Cp864 character set. + 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.java.nio.charset; + +public class Cp864 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x066A, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, + 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518, + 0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, + 0x00BB, 0xFEF7, 0xFEF8, NONE, NONE, 0xFEFB, 0xFEFC, NONE, + 0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, NONE, NONE, + 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F, + 0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, + 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9, + 0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, + 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9, + 0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, + 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1, + 0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, + 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, NONE + }; + + public Cp864() + { + super("Cp864", new String[] { + "Cp-864" + }); + lookupTable = lookup; + } + +} // class Cp864 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp865.java b/libjava/classpath/gnu/java/nio/charset/Cp865.java new file mode 100644 index 0000000..a1332a7 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp865.java @@ -0,0 +1,91 @@ +/* Cp865.java -- Charset implementation for the Cp865 character set. + 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.java.nio.charset; + +public class Cp865 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 + }; + + public Cp865() + { + super("Cp865", new String[] { + "Cp-865" + }); + lookupTable = lookup; + } + +} // class Cp865 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp866.java b/libjava/classpath/gnu/java/nio/charset/Cp866.java new file mode 100644 index 0000000..ca69589 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp866.java @@ -0,0 +1,91 @@ +/* Cp866.java -- Charset implementation for the Cp866 character set. + 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.java.nio.charset; + +public class Cp866 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 + }; + + public Cp866() + { + super("Cp866", new String[] { + "cp-866" + }); + lookupTable = lookup; + } + +} // class Cp866 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp869.java b/libjava/classpath/gnu/java/nio/charset/Cp869.java new file mode 100644 index 0000000..f5e0529 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp869.java @@ -0,0 +1,91 @@ +/* Cp869.java -- Charset implementation for the Cp869 character set. + 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.java.nio.charset; + +public class Cp869 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + NONE, NONE, NONE, NONE, NONE, NONE, 0x0386, NONE, + 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, + 0x038A, 0x03AA, 0x038C, NONE, NONE, 0x038E, 0x03AB, 0x00A9, + 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF, + 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, + 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x03A0, 0x03A1, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3, + 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, + 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580, + 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, + 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384, + 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, + 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0 + }; + + public Cp869() + { + super("Cp869", new String[] { + "Cp-869" + }); + lookupTable = lookup; + } + +} // class Cp869 diff --git a/libjava/classpath/gnu/java/nio/charset/Cp874.java b/libjava/classpath/gnu/java/nio/charset/Cp874.java new file mode 100644 index 0000000..d81755c --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Cp874.java @@ -0,0 +1,89 @@ +/* Cp874.java -- Charset implementation for the Cp874 character set. + 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.java.nio.charset; + +public class Cp874 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, NONE, NONE, NONE, 0x2026, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, NONE, NONE, NONE, NONE, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, NONE, NONE, NONE, NONE + }; + + public Cp874() + { + super("Cp874", new String[] { + }); + lookupTable = lookup; + } + +} // class Cp874 diff --git a/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java b/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java new file mode 100644 index 0000000..033440d --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java @@ -0,0 +1,154 @@ +/* EncodingHelper.java -- Useful character encoding methods. + 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.java.nio.charset; + +import java.util.HashMap; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.nio.charset.Charset; +import java.io.UnsupportedEncodingException; + +/** + * This class provides some useful utility methods + * for charset encoding for the java.lang and java.io methods. + * + * @author Sven de Marothy + */ +public class EncodingHelper +{ + + /** + * Contains the mapping from java.io canonical names + * to java.nio canonical names. + */ + private static HashMap canonicalNames; + + static { + canonicalNames = new HashMap(); + canonicalNames.put("US-ASCII", "ASCII"); + canonicalNames.put("windows-1250", "Cp1250"); + canonicalNames.put("windows-1251", "Cp1251"); + canonicalNames.put("windows-1252", "Cp1252"); + canonicalNames.put("windows-1253", "Cp1253"); + canonicalNames.put("windows-1254", "Cp1254"); + canonicalNames.put("windows-1257", "Cp1257"); + canonicalNames.put("ISO-8859-1", "ISO8859_1"); + canonicalNames.put("ISO-8859-2", "ISO8859_2"); + canonicalNames.put("ISO-8859-4", "ISO8859_4"); + canonicalNames.put("ISO-8859-5", "ISO8859_5"); + canonicalNames.put("ISO-8859-7", "ISO8859_7"); + canonicalNames.put("ISO-8859-9", "ISO8859_9"); + canonicalNames.put("ISO-8859-13", "ISO8859_13"); + canonicalNames.put("ISO-8859-15", "ISO8859_15"); + canonicalNames.put("KOI8-R", "KOI8_R"); + canonicalNames.put("UTF-8", "UTF8"); + canonicalNames.put("UTF-16BE", "UnicodeBigUnmarked"); + canonicalNames.put("UTF-16LE", "UnicodeLittleUnmarked"); + canonicalNames.put("windows-1255", "Cp1255"); + canonicalNames.put("windows-1256", "Cp1256"); + canonicalNames.put("windows-1258", "Cp1258"); + canonicalNames.put("ISO-8859-3", "ISO8859_3"); + canonicalNames.put("ISO-8859-6", "ISO8859_6"); + canonicalNames.put("ISO-8859-8", "ISO8859_8"); + } + + /** + * Returns the name of the default encoding, + * falls back on defaults to Latin-1 if there's a problem. + */ + public static String getDefaultEncoding() + { + String encoding; + try + { + return System.getProperty("file.encoding"); + } catch(SecurityException e) { + } catch(IllegalArgumentException e) { + } + // XXX - Throw an error here? For now, default to the 'safe' encoding. + return "8859_1"; + } + + /** + * Returns the java.io canonical name of a charset given with the + * java.nio canonical name. If the charset does not have a java.io + * canonical name, the input string is returned. + */ + public static String getOldCanonical(String newCanonical) + { + String oldCanonical = (String) canonicalNames.get(newCanonical); + return (oldCanonical != null)?oldCanonical : newCanonical; + } + + public static boolean isISOLatin1(String s) + { + if(s.equals("ISO-8859-1") || + s.equals("8859_1") || + s.equals("ISO_8859-1") || + s.equals("latin1") || + s.equals("ISO8859_1") || + s.equals("ISO_8859_1")) + return true; + return false; + } + + /** + * Gets a charset, throwing the java.io exception and not + * the java.nio exception if an error occurs. + */ + public static Charset getCharset(String name) + throws UnsupportedEncodingException + { + try + { + return Charset.forName(name); + } + catch(IllegalCharsetNameException e) + { + throw new UnsupportedEncodingException("Charset "+name+" not found."); + } + catch(UnsupportedCharsetException e) + { + throw new UnsupportedEncodingException("Charset "+name+" not found."); + } + } +} + + + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_1.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_1.java new file mode 100644 index 0000000..cc06ecd --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_1.java @@ -0,0 +1,155 @@ +/* ISO_8859_1.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +/** + * ISO-8859-1 charset. + * + * @author Jesse Rosenstock + */ +final class ISO_8859_1 extends Charset +{ + ISO_8859_1 () + { + /* Canonical charset name chosen according to: + * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + */ + super ("ISO-8859-1", new String[] { + /* These names are provided by + * http://www.iana.org/assignments/character-sets + */ + "iso-ir-100", + "ISO_8859-1", + "latin1", + "l1", + "IBM819", + "CP819", + "csISOLatin1", + "8859_1", + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "ISO8859_1", "ISO_8859_1", "ibm-819", "ISO_8859-1:1987", + "819" + }); + + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1; + } + + public CharsetDecoder newDecoder () + { + return new Decoder (this); + } + + public CharsetEncoder newEncoder () + { + return new Encoder (this); + } + + private static final class Decoder extends CharsetDecoder + { + // Package-private to avoid a trampoline constructor. + Decoder (Charset cs) + { + super (cs, 1.0f, 1.0f); + } + + protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + byte b = in.get (); + + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + out.put ((char) (b & 0xFF)); + } + + return CoderResult.UNDERFLOW; + } + } + + private static final class Encoder extends CharsetEncoder + { + // Package-private to avoid a trampoline constructor. + Encoder (Charset cs) + { + super (cs, 1.0f, 1.0f); + } + + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + char c = in.get (); + + if (c > 0xFF) + { + in.position (in.position () - 1); + return CoderResult.unmappableForLength (1); + } + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + out.put ((byte) c); + } + + return CoderResult.UNDERFLOW; + } + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_13.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_13.java new file mode 100644 index 0000000..c10eef3 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_13.java @@ -0,0 +1,104 @@ +/* ISO_8859_13.java -- Charset for ISO-8859-13 iso latin character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-13, ISO Latin-7 char set. + */ +public class ISO_8859_13 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, + 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019 + }; + + public ISO_8859_13() + { + super("ISO-8859-13", new String[] { + "ISO8859_13", + "8859_13", + "ibm-921_P100-1995", + "ibm-921", + "iso_8859_13", + "iso8859_13", + "iso-8859-13", + "8859_13", + "cp921", + "921" + }); + lookupTable = lookup; + } + +} // class ISO_8859_13 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_15.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_15.java new file mode 100644 index 0000000..973fe1c --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_15.java @@ -0,0 +1,111 @@ +/* ISO_8859_15.java -- Charset for ISO-8859-15 iso latin character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-15, ISO Latin-9 char set. + */ +public class ISO_8859_15 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, + 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, + 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF + }; + + public ISO_8859_15() + { + super("ISO-8859-15", new String[] { + "8859_15", + "iso8859_15", + "iso-8859-15", + "8859-15", + "latin9", + "iso_8859_15", + "ibm-923_P100-1998", + "ibm-923", + "Latin-9", + "l9", + "latin0", + "csisolatin0", + "csisolatin9", + "iso8859_15_fdis", + "cp923", + "923", + "windows-28605" + }); + lookupTable = lookup; + } + +} // class ISO_8859_15 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_2.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_2.java new file mode 100644 index 0000000..2de96df --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_2.java @@ -0,0 +1,110 @@ +/* ISO_8859_2.java -- Charset for ISO-8859-2 Character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-2, ISO Latin-2 char set. + */ +public class ISO_8859_2 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + * Note: ranges 0-1F and 7f-97 aren't defined in the spec file aron used. + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, + 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, + 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, + 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 + }; + + public ISO_8859_2() + { + super("ISO-8859-2", new String[] { + "ISO8859_2", + "8859_2", + "ibm-912_P100-1995", + "ibm-912", + "iso_8859_2", + "iso8859_2", + "iso-8859-2", + "ISO_8859-2:1987", + "latin2", + "csISOLatin2", + "iso-ir-101", + "l2", + "cp912", + "912", + "windows-28592" + }); + lookupTable = lookup; + } + +} // class ISO_8859_2 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_3.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_3.java new file mode 100644 index 0000000..6e71871 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_3.java @@ -0,0 +1,109 @@ +/* ISO_8859_3.java -- Charset for ISO-8859-3 Character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-3, ISO Latin-3 char set. + */ +public class ISO_8859_3 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, NONE, 0x0124, 0x00A7, + 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, NONE, 0x017B, + 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, + 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, NONE, 0x017C, + 0x00C0, 0x00C1, 0x00C2, NONE, 0x00C4, 0x010A, 0x0108, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + NONE, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, + 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, NONE, 0x00E4, 0x010B, 0x0109, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + NONE, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, + 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 + }; + + public ISO_8859_3() + { + super("ISO-8859-3", new String[] { + "ISO8859_3", + "8859_3", + "ibm-913_P100-2000", + "ibm-913", + "iso_8859_3", + "iso8859_3", + "iso-8859-3", + "ISO_8859-3:1988", + "latin3", + "csISOLatin3", + "iso-ir-109", + "l3", + "cp913", + "913", + "windows-28593" + }); + lookupTable = lookup; + } + +} // class ISO_8859_3 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_4.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_4.java new file mode 100644 index 0000000..96dc467 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_4.java @@ -0,0 +1,110 @@ +/* ISO_8859_4.java -- Charset for ISO-8859-4 Character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-4, ISO Latin-4 char set. + */ +public class ISO_8859_4 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + * Note: ranges 0-1F and 7f-9f aren't defined in the spec file aron used. + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, + 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, + 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, + 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, + 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, + 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9 + }; + + public ISO_8859_4() + { + super("ISO-8859-4", new String[] { + "ISO8859_4", + "8859_4", + "ibm-914_P100-1995", + "ibm-914", + "iso_8859_4", + "iso8859_4", + "iso-8859-4", + "latin4", + "csISOLatin4", + "iso-ir-110", + "ISO_8859-4:1988", + "l4", + "cp914", + "914", + "windows-28594" + }); + lookupTable = lookup; + } + +} // class ISO_8859_4 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_5.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_5.java new file mode 100644 index 0000000..ad20872 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_5.java @@ -0,0 +1,108 @@ +/* ISO_8859_5.java -- Charset for ISO-8859-5 cyrillic character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-5, ISO cyrillic char set. + */ +public class ISO_8859_5 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F + }; + + public ISO_8859_5() + { + super("ISO-8859-5", new String[] { + "ISO8859_5", + "8859_5", + "ibm-915_P100-1995", + "ibm-915", + "iso_8859_5", + "iso8859_5", + "iso-8859-5", + "cyrillic", + "csISOLatinCyrillic", + "iso-ir-144", + "ISO_8859-5:1988", + "cp915", + "915", + "windows-28595" + }); + lookupTable = lookup; + } + +} // class ISO_8859_5 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_6.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_6.java new file mode 100644 index 0000000..5600e79 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_6.java @@ -0,0 +1,112 @@ +/* ISO_8859_6.java -- Charset for ISO-8859-6 iso Arabic character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-6, ISO Arabic char set. + */ +public class ISO_8859_6 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, NONE, NONE, NONE, 0x00A4, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, 0x060C, 0x00AD, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, 0x061B, NONE, NONE, NONE, 0x061F, + NONE, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063A, NONE, NONE, NONE, NONE, NONE, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, + 0x0650, 0x0651, 0x0652, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE + }; + + public ISO_8859_6() + { + super("ISO-8859-6", new String[] { + "8859_6", + "ibm-1089_P100-1995", + "ibm-1089", + "iso_8859_6", + "iso8859_6", + "iso-8859-6", + "arabic", + "csISOLatinArabic", + "iso-ir-127", + "ISO_8859-6:1987", + "ECMA-114", + "ASMO-708", + "8859_6", + "cp1089", + "1089", + "windows-28596", + "ISO-8859-6-I", + "ISO-8859-6-E" + }); + lookupTable = lookup; + } + +} // class ISO_8859_6 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_7.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_7.java new file mode 100644 index 0000000..9262a60 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_7.java @@ -0,0 +1,111 @@ +/* ISO_8859_7.java -- Charset for ISO-8859-7 Character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-7, ISO Latin/Greek char set. + */ +public class ISO_8859_7 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x02BD, 0x02BC, 0x00A3, NONE, NONE, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, NONE, 0x00AB, 0x00AC, 0x00AD, NONE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, NONE, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, NONE + }; + + public ISO_8859_7() + { + super("ISO-8859-7", new String[] { + "ISO8859_7", + "8859_7", + "ibm-813_P100-1995", + "ibm-813", + "iso_8859_7", + "iso8859_7", + "iso-8859-7", + "greek", + "greek8", + "ELOT_928", + "ECMA-118", + "csISOLatinGreek", + "iso-ir-126", + "ISO_8859-7:1987", + "cp813", + "813", + "windows-28597" + }); + lookupTable = lookup; + } + +} // class ISO_8859_7 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_8.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_8.java new file mode 100644 index 0000000..96fb0f4 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_8.java @@ -0,0 +1,110 @@ +/* ISO_8859_8.java -- Charset for ISO-8859-8 iso Hebrew character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-8, ISO Latin/Hebrew char set. + */ +public class ISO_8859_8 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, NONE, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, 0x2017, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, NONE, NONE, NONE, NONE, NONE + }; + + public ISO_8859_8() + { + super("ISO-8859-8", new String[] { + "ISO8859_8", + "8859_8", + "ibm-916_P100-1995", + "ibm-916", + "iso_8859_8", + "iso8859_8", + "iso-8859-8", + "hebrew", + "csISOLatinHebrew", + "iso-ir-138", + "ISO_8859-8:1988", + "ISO-8859-8-I", + "ISO-8859-8-E", + "cp916", + "916", + "windows-28598" + }); + lookupTable = lookup; + } + +} // class ISO_8859_8 + diff --git a/libjava/classpath/gnu/java/nio/charset/ISO_8859_9.java b/libjava/classpath/gnu/java/nio/charset/ISO_8859_9.java new file mode 100644 index 0000000..28be34c --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/ISO_8859_9.java @@ -0,0 +1,110 @@ +/* ISO_8859_9.java -- Charset for ISO-8859-9 iso latin character set. + 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.java.nio.charset; + +/** + * Encoding table for ISO-8859-9, ISO Latin-5 char set. + */ +public class ISO_8859_9 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF + }; + + public ISO_8859_9() + { + super("ISO-8859-9", new String[] { + "ISO8859_9", + "8859_9", + "ibm-920_P100-1995", + "ibm-920", + "iso8859_9", + "iso-8859-9", + "iso_8859_9", + "latin5", + "csISOLatin5", + "iso-ir-148", + "ISO_8859-9:1989", + "l5", + "cp920", + "920", + "windows-28599", + "ECMA-128" + }); + lookupTable = lookup; + } + +} // class ISO_8859_9 + diff --git a/libjava/classpath/gnu/java/nio/charset/KOI_8.java b/libjava/classpath/gnu/java/nio/charset/KOI_8.java new file mode 100644 index 0000000..c670656 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/KOI_8.java @@ -0,0 +1,102 @@ +/* KOI_8.java -- Charset for KOI-8 cyrillic character set. + 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.java.nio.charset; + +/** + * Encoding table for the KOI8 cyrillic char set. + */ +public class KOI_8 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, + 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, + 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, + 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, + 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, + 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, + 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, + 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A + }; + + public KOI_8() + { + super("KOI8-R", new String[] { + "KOI8_R", + "KOI8", + "KOI-8", + "KOI_8", + "koi8-r", + "koi8r", + "koi-8-r", + "koi" + }); + lookupTable = lookup; + } + +} // class KOI_8 + diff --git a/libjava/classpath/gnu/java/nio/charset/MS874.java b/libjava/classpath/gnu/java/nio/charset/MS874.java new file mode 100644 index 0000000..b16e53f --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MS874.java @@ -0,0 +1,89 @@ +/* MS874.java -- Charset implementation for the MS874 Thai character set. + 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.java.nio.charset; + +public class MS874 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, NONE, NONE, NONE, 0x2026, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, NONE, NONE, NONE, NONE, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, NONE, NONE, NONE, NONE + }; + + public MS874() + { + super("MS874", new String[] { + }); + lookupTable = lookup; + } + +} // class MS874 diff --git a/libjava/classpath/gnu/java/nio/charset/MacCentralEurope.java b/libjava/classpath/gnu/java/nio/charset/MacCentralEurope.java new file mode 100644 index 0000000..5496db2 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacCentralEurope.java @@ -0,0 +1,89 @@ +/* MacCentralEurope.java -- Charset implementation for the MacCentralEurope character set. + 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.java.nio.charset; + +public class MacCentralEurope extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x0100, 0x0101, 0x00C9, 0x0104, 0x00D6, 0x00DC, 0x00E1, + 0x0105, 0x010C, 0x00E4, 0x010D, 0x0106, 0x0107, 0x00E9, 0x0179, + 0x017A, 0x010E, 0x00ED, 0x010F, 0x0112, 0x0113, 0x0116, 0x00F3, + 0x0117, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x011A, 0x011B, 0x00FC, + 0x2020, 0x00B0, 0x0118, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x0119, 0x00A8, 0x2260, 0x0123, 0x012E, + 0x012F, 0x012A, 0x2264, 0x2265, 0x012B, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013B, 0x013C, 0x013D, 0x013E, 0x0139, 0x013A, 0x0145, + 0x0146, 0x0143, 0x00AC, 0x221A, 0x0144, 0x0147, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x0148, 0x0150, 0x00D5, 0x0151, 0x014C, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x014D, 0x0154, 0x0155, 0x0158, 0x2039, 0x203A, 0x0159, 0x0156, + 0x0157, 0x0160, 0x201A, 0x201E, 0x0161, 0x015A, 0x015B, 0x00C1, + 0x0164, 0x0165, 0x00CD, 0x017D, 0x017E, 0x016A, 0x00D3, 0x00D4, + 0x016B, 0x016E, 0x00DA, 0x016F, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00DD, 0x00FD, 0x0137, 0x017B, 0x0141, 0x017C, 0x0122, 0x02C7 + }; + + public MacCentralEurope() + { + super("MacCentralEurope", new String[] { + }); + lookupTable = lookup; + } + +} // class MacCentralEurope diff --git a/libjava/classpath/gnu/java/nio/charset/MacCroatian.java b/libjava/classpath/gnu/java/nio/charset/MacCroatian.java new file mode 100644 index 0000000..f71ac51 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacCroatian.java @@ -0,0 +1,89 @@ +/* MacCroatian.java -- Charset implementation for the MacCroatian character set. + 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.java.nio.charset; + +public class MacCroatian extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x0160, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x017D, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x2206, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x0161, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x017E, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x0106, 0x00AB, + 0x010C, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x0110, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0xF8FF, 0x00A9, 0x2044, 0x20AC, 0x2039, 0x203A, 0x00C6, 0x00BB, + 0x2013, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x0107, 0x00C1, + 0x010D, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0x0111, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x03C0, 0x00CB, 0x02DA, 0x00B8, 0x00CA, 0x00E6, 0x02C7 + }; + + public MacCroatian() + { + super("MacCroatian", new String[] { + }); + lookupTable = lookup; + } + +} // class MacCroatian diff --git a/libjava/classpath/gnu/java/nio/charset/MacCyrillic.java b/libjava/classpath/gnu/java/nio/charset/MacCyrillic.java new file mode 100644 index 0000000..f152f6b --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacCyrillic.java @@ -0,0 +1,89 @@ +/* MacCyrillic.java -- Charset implementation for the MacCyrillic character set. + 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.java.nio.charset; + +public class MacCyrillic extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x2020, 0x00B0, 0x0490, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x0406, + 0x00AE, 0x00A9, 0x2122, 0x0402, 0x0452, 0x2260, 0x0403, 0x0453, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x0456, 0x00B5, 0x0491, 0x0408, + 0x0404, 0x0454, 0x0407, 0x0457, 0x0409, 0x0459, 0x040A, 0x045A, + 0x0458, 0x0405, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x040B, 0x045B, 0x040C, 0x045C, 0x0455, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x201E, + 0x040E, 0x045E, 0x040F, 0x045F, 0x2116, 0x0401, 0x0451, 0x044F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x20AC + }; + + public MacCyrillic() + { + super("MacCyrillic", new String[] { + }); + lookupTable = lookup; + } + +} // class MacCyrillic diff --git a/libjava/classpath/gnu/java/nio/charset/MacDingbat.java b/libjava/classpath/gnu/java/nio/charset/MacDingbat.java new file mode 100644 index 0000000..84102d5 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacDingbat.java @@ -0,0 +1,89 @@ +/* MacDingbat.java -- Charset implementation for the MacDingbat character set. + 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.java.nio.charset; + +public class MacDingbat extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x2701, 0x2702, 0x2703, 0x2704, 0x260E, 0x2706, 0x2707, + 0x2708, 0x2709, 0x261B, 0x261E, 0x270C, 0x270D, 0x270E, 0x270F, + 0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717, + 0x2718, 0x2719, 0x271A, 0x271B, 0x271C, 0x271D, 0x271E, 0x271F, + 0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2727, + 0x2605, 0x2729, 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, + 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, + 0x2738, 0x2739, 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F, + 0x2740, 0x2741, 0x2742, 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, + 0x2748, 0x2749, 0x274A, 0x274B, 0x25CF, 0x274D, 0x25A0, 0x274F, + 0x2750, 0x2751, 0x2752, 0x25B2, 0x25BC, 0x25C6, 0x2756, 0x25D7, + 0x2758, 0x2759, 0x275A, 0x275B, 0x275C, 0x275D, 0x275E, NONE, + 0x2768, 0x2769, 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F, + 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, + 0x2663, 0x2666, 0x2665, 0x2660, 0x2460, 0x2461, 0x2462, 0x2463, + 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x2776, 0x2777, + 0x2778, 0x2779, 0x277A, 0x277B, 0x277C, 0x277D, 0x277E, 0x277F, + 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786, 0x2787, + 0x2788, 0x2789, 0x278A, 0x278B, 0x278C, 0x278D, 0x278E, 0x278F, + 0x2790, 0x2791, 0x2792, 0x2793, 0x2794, 0x2192, 0x2194, 0x2195, + 0x2798, 0x2799, 0x279A, 0x279B, 0x279C, 0x279D, 0x279E, 0x279F, + 0x27A0, 0x27A1, 0x27A2, 0x27A3, 0x27A4, 0x27A5, 0x27A6, 0x27A7, + 0x27A8, 0x27A9, 0x27AA, 0x27AB, 0x27AC, 0x27AD, 0x27AE, 0x27AF, + NONE, 0x27B1, 0x27B2, 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, + 0x27B8, 0x27B9, 0x27BA, 0x27BB, 0x27BC, 0x27BD, 0x27BE, NONE + }; + + public MacDingbat() + { + super("MacDingbat", new String[] { + }); + lookupTable = lookup; + } + +} // class MacDingbat diff --git a/libjava/classpath/gnu/java/nio/charset/MacGreek.java b/libjava/classpath/gnu/java/nio/charset/MacGreek.java new file mode 100644 index 0000000..07624d5 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacGreek.java @@ -0,0 +1,89 @@ +/* MacGreek.java -- Charset implementation for the MacGreek character set. + 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.java.nio.charset; + +public class MacGreek extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00B9, 0x00B2, 0x00C9, 0x00B3, 0x00D6, 0x00DC, 0x0385, + 0x00E0, 0x00E2, 0x00E4, 0x0384, 0x00A8, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00A3, 0x2122, 0x00EE, 0x00EF, 0x2022, 0x00BD, + 0x2030, 0x00F4, 0x00F6, 0x00A6, 0x20AC, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x0393, 0x0394, 0x0398, 0x039B, 0x039E, 0x03A0, 0x00DF, + 0x00AE, 0x00A9, 0x03A3, 0x03AA, 0x00A7, 0x2260, 0x00B0, 0x00B7, + 0x0391, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x0392, 0x0395, 0x0396, + 0x0397, 0x0399, 0x039A, 0x039C, 0x03A6, 0x03AB, 0x03A8, 0x03A9, + 0x03AC, 0x039D, 0x00AC, 0x039F, 0x03A1, 0x2248, 0x03A4, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x03A5, 0x03A7, 0x0386, 0x0388, 0x0153, + 0x2013, 0x2015, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x0389, + 0x038A, 0x038C, 0x038E, 0x03AD, 0x03AE, 0x03AF, 0x03CC, 0x038F, + 0x03CD, 0x03B1, 0x03B2, 0x03C8, 0x03B4, 0x03B5, 0x03C6, 0x03B3, + 0x03B7, 0x03B9, 0x03BE, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, + 0x03C0, 0x03CE, 0x03C1, 0x03C3, 0x03C4, 0x03B8, 0x03C9, 0x03C2, + 0x03C7, 0x03C5, 0x03B6, 0x03CA, 0x03CB, 0x0390, 0x03B0, 0x00AD + }; + + public MacGreek() + { + super("MacGreek", new String[] { + }); + lookupTable = lookup; + } + +} // class MacGreek diff --git a/libjava/classpath/gnu/java/nio/charset/MacIceland.java b/libjava/classpath/gnu/java/nio/charset/MacIceland.java new file mode 100644 index 0000000..7918e02 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacIceland.java @@ -0,0 +1,89 @@ +/* MacIceland.java -- Charset implementation for the MacIceland character set. + 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.java.nio.charset; + +public class MacIceland extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x00DD, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x00D0, 0x00F0, 0x00DE, 0x00FE, + 0x00FD, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + + public MacIceland() + { + super("MacIceland", new String[] { + }); + lookupTable = lookup; + } + +} // class MacIceland diff --git a/libjava/classpath/gnu/java/nio/charset/MacRoman.java b/libjava/classpath/gnu/java/nio/charset/MacRoman.java new file mode 100644 index 0000000..b413caf --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacRoman.java @@ -0,0 +1,89 @@ +/* MacRoman.java -- Charset implementation for the MacRoman character set. + 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.java.nio.charset; + +public class MacRoman extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + + public MacRoman() + { + super("MacRoman", new String[] { + }); + lookupTable = lookup; + } + +} // class MacRoman diff --git a/libjava/classpath/gnu/java/nio/charset/MacRomania.java b/libjava/classpath/gnu/java/nio/charset/MacRomania.java new file mode 100644 index 0000000..d1779a4 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacRomania.java @@ -0,0 +1,89 @@ +/* MacRomania.java -- Charset implementation for the MacRomania character set. + 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.java.nio.charset; + +public class MacRomania extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x0102, 0x0218, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x0103, 0x0219, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0x021A, 0x021B, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + + public MacRomania() + { + super("MacRomania", new String[] { + }); + lookupTable = lookup; + } + +} // class MacRomania diff --git a/libjava/classpath/gnu/java/nio/charset/MacSymbol.java b/libjava/classpath/gnu/java/nio/charset/MacSymbol.java new file mode 100644 index 0000000..869de19 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacSymbol.java @@ -0,0 +1,89 @@ +/* MacSymbol.java -- Charset implementation for the MacSymbol character set. + 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.java.nio.charset; + +public class MacSymbol extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x2200, 0x0023, 0x2203, 0x0025, 0x0026, 0x220D, + 0x0028, 0x0029, 0x2217, 0x002B, 0x002C, 0x2212, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x2245, 0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393, + 0x0397, 0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F, + 0x03A0, 0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03C2, 0x03A9, + 0x039E, 0x03A8, 0x0396, 0x005B, 0x2234, 0x005D, 0x22A5, 0x005F, + 0xF8E5, 0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03C6, 0x03B3, + 0x03B7, 0x03B9, 0x03D5, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, + 0x03C0, 0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03C9, + 0x03BE, 0x03C8, 0x03B6, 0x007B, 0x007C, 0x007D, 0x223C, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + 0x20AC, 0x03D2, 0x2032, 0x2264, 0x2044, 0x221E, 0x0192, 0x2663, + 0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, + 0x00B0, 0x00B1, 0x2033, 0x2265, 0x00D7, 0x221D, 0x2202, 0x2022, + 0x00F7, 0x2260, 0x2261, 0x2248, 0x2026, 0xF8E6, 0x23AF, 0x21B5, + 0x2135, 0x2111, 0x211C, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229, + 0x222A, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209, + 0x2220, 0x2207, 0x00AE, 0x00A9, 0x2122, 0x220F, 0x221A, 0x22C5, + 0x00AC, 0x2227, 0x2228, 0x21D4, 0x21D0, 0x21D1, 0x21D2, 0x21D3, + 0x22C4, 0x3008, NONE, NONE, NONE, 0x2211, 0x239B, 0x239C, + 0x239D, 0x23A1, 0x23A2, 0x23A3, 0x23A7, 0x23A8, 0x23A9, 0x23AA, + 0xF8FF, 0x3009, 0x222B, 0x2320, 0x23AE, 0x2321, 0x239E, 0x239F, + 0x23A0, 0x23A4, 0x23A5, 0x23A6, 0x23AB, 0x23AC, 0x23AD, NONE + }; + + public MacSymbol() + { + super("MacSymbol", new String[] { + }); + lookupTable = lookup; + } + +} // class MacSymbol diff --git a/libjava/classpath/gnu/java/nio/charset/MacThai.java b/libjava/classpath/gnu/java/nio/charset/MacThai.java new file mode 100644 index 0000000..498b9e6 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacThai.java @@ -0,0 +1,89 @@ +/* MacThai.java -- Charset implementation for the MacThai character set. + 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.java.nio.charset; + +public class MacThai extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00AB, 0x00BB, 0x2026, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, 0x201C, 0x201D, NONE, + NONE, 0x2022, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, 0x2018, 0x2019, NONE, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, 0x2060, 0x200B, 0x2013, 0x2014, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x2122, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x00AE, 0x00A9, NONE, NONE, NONE, NONE + }; + + public MacThai() + { + super("MacThai", new String[] { + }); + lookupTable = lookup; + } + +} // class MacThai diff --git a/libjava/classpath/gnu/java/nio/charset/MacTurkish.java b/libjava/classpath/gnu/java/nio/charset/MacTurkish.java new file mode 100644 index 0000000..68ea27b --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/MacTurkish.java @@ -0,0 +1,89 @@ +/* MacTurkish.java -- Charset implementation for the MacTurkish character set. + 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.java.nio.charset; + +public class MacTurkish extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, NONE, + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x011E, 0x011F, 0x0130, 0x0131, 0x015E, 0x015F, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0xF8A0, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + + public MacTurkish() + { + super("MacTurkish", new String[] { + }); + lookupTable = lookup; + } + +} // class MacTurkish diff --git a/libjava/classpath/gnu/java/nio/charset/Provider.java b/libjava/classpath/gnu/java/nio/charset/Provider.java new file mode 100644 index 0000000..3f25c59 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Provider.java @@ -0,0 +1,239 @@ +/* Provider.java -- + Copyright (C) 2002, 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.java.nio.charset; + +import java.nio.charset.Charset; +import java.nio.charset.spi.CharsetProvider; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; + +/** + * Charset provider for the required charsets. Used by + * {@link Charset#charsetForName} and * {@link Charset#availableCharsets}. + * + * @author Jesse Rosenstock + * @author Robert Schuster (thebohemian@gmx.net) + * @see Charset + */ +public final class Provider extends CharsetProvider +{ + private static Provider singleton; + + static + { + synchronized (Provider.class) + { + singleton = null; + } + } + + /** + * Map from charset name to charset canonical name. The strings + * are all lower-case to allow case-insensitive retrieval of + * Charset instances. + */ + private final HashMap canonicalNames; + + /** + * Map from lower-case canonical name to Charset. + * TODO: We may want to use soft references. We would then need to keep + * track of the class name to regenerate the object. + */ + private final HashMap charsets; + + /** + * We don't load all available charsets at the start + */ + private boolean extendedLoaded; + + private Provider () + { + extendedLoaded = false; + canonicalNames = new HashMap (); + charsets = new HashMap (); + + // US-ASCII aka ISO646-US + addCharset (new US_ASCII ()); + + // ISO-8859-1 aka ISO-LATIN-1 + addCharset (new ISO_8859_1 ()); + + // UTF-8 + addCharset (new UTF_8 ()); + + // UTF-16BE + addCharset (new UTF_16BE ()); + + // UTF-16LE + addCharset (new UTF_16LE ()); + + // UTF-16 + addCharset (new UTF_16 ()); + + // UTF-16LE (marked) + addCharset (new UnicodeLittle ()); + + // Windows-1250 aka cp-1250 (East European) + addCharset (new Windows1250 ()); + + // Windows-1251 (Cyrillic) + addCharset (new Windows1251 ()); + + // Windows-1252 aka cp-1252 (Latin-1) + addCharset (new Windows1252 ()); + + // Windows-1253 (Greek) + addCharset (new Windows1253 ()); + + // Windows-1254 (Turkish) + addCharset (new Windows1254 ()); + + // Windows-1257 (Baltic) + addCharset (new Windows1257 ()); + + // ISO-8859-2 aka ISO-LATIN-2 + addCharset (new ISO_8859_2 ()); + + // ISO-8859-4 aka ISO-LATIN-4 + addCharset (new ISO_8859_4 ()); + + // ISO-8859-5 (Cyrillic) + addCharset (new ISO_8859_5 ()); + + // ISO-8859-7 (Greek) + addCharset (new ISO_8859_7 ()); + + // ISO-8859-9 aka ISO-LATIN-5 + addCharset (new ISO_8859_9 ()); + + // ISO-8859-13 aka ISO-LATIN-7 + addCharset (new ISO_8859_13 ()); + + // ISO-8859-15 aka ISO-LATIN-9 + addCharset (new ISO_8859_15 ()); + + // KOI8 (Cyrillic) + addCharset (new KOI_8 ()); + } + + /** + * Load non-mandatory charsets. + */ + private void loadExtended () + { + if(extendedLoaded) + return; + + addCharset (new ISO_8859_3 ()); // ISO-8859-3 aka ISO-LATIN-3 + addCharset (new ISO_8859_6 ()); // ISO-8859-6 (Arabic) + addCharset (new ISO_8859_8 ()); // ISO-8859-8 (Hebrew) + + // Some more codepages + addCharset (new Cp855()); // IBM Cyrillic + addCharset (new Cp857()); // IBM Turkish + addCharset (new Cp860()); // MSDOS Portugese + addCharset (new Cp861()); // MSDOS Icelandic + addCharset (new Cp862()); // PC Hebrew + addCharset (new Cp863()); // MSDOS Can. French + addCharset (new Cp864()); // PC Arabic + addCharset (new Cp865()); // MSDOS Nordic + addCharset (new Cp866()); // MSDOS Russian + addCharset (new Cp869()); // IBM modern Greek + addCharset (new Cp874()); // IBM Thai + extendedLoaded = true; + } + + public Iterator charsets () + { + loadExtended(); + return Collections.unmodifiableCollection (charsets.values ()) + .iterator (); + } + + /** + * Returns a Charset instance by converting the given + * name to lower-case, looking up the canonical charset + * name and finally looking up the Charset with that name. + * + * <p>The lookup is therefore case-insensitive.</p> + * + * @returns The Charset having <code>charsetName</code> + * as its alias or null if no such Charset exist. + */ + public Charset charsetForName (String charsetName) + { + Charset cs = (Charset) charsets.get(canonicalNames.get(charsetName.toLowerCase())); + if(cs == null && !extendedLoaded) + { + loadExtended(); + cs = (Charset) charsets.get(canonicalNames.get(charsetName.toLowerCase())); + } + return cs; + } + + /** + * Puts a Charset under its canonical name into the 'charsets' map. + * Then puts a mapping from all its alias names to the canonical name. + * + * <p>All names are converted to lower-case</p>. + * + * @param cs + */ + private void addCharset (Charset cs) + { + String canonicalName = cs.name().toLowerCase(); + charsets.put (canonicalName, cs); + + /* Adds a mapping between the canonical name + * itself making a lookup using that name + * no special case. + */ + canonicalNames.put(canonicalName, canonicalName); + + for (Iterator i = cs.aliases ().iterator (); i.hasNext (); ) + canonicalNames.put (((String) i.next()).toLowerCase(), canonicalName); + } + + public static synchronized Provider provider () + { + if (singleton == null) + singleton = new Provider (); + return singleton; + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/US_ASCII.java b/libjava/classpath/gnu/java/nio/charset/US_ASCII.java new file mode 100644 index 0000000..d26f7ff --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/US_ASCII.java @@ -0,0 +1,161 @@ +/* US_ASCII.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +/** + * US-ASCII charset. + * + * @author Jesse Rosenstock + */ +final class US_ASCII extends Charset +{ + US_ASCII () + { + /* Canonical charset name chosen according to: + * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + */ + super ("US-ASCII", new String[] { + /* These names are provided by + * http://www.iana.org/assignments/character-sets + */ + "iso-ir-6", + "ANSI_X3.4-1986", + "ISO_646.irv:1991", + "ASCII", + "ISO646-US", + "ASCII", + "us", + "IBM367", + "cp367", + "csASCII", + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "ANSI_X3.4-1968", "iso_646.irv:1983", "ascii7", "646", + "windows-20127" + }); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII; + } + + public CharsetDecoder newDecoder () + { + return new Decoder (this); + } + + public CharsetEncoder newEncoder () + { + return new Encoder (this); + } + + private static final class Decoder extends CharsetDecoder + { + // Package-private to avoid a trampoline constructor. + Decoder (Charset cs) + { + super (cs, 1.0f, 1.0f); + } + + protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + byte b = in.get (); + + if (b < 0) + { + in.position (in.position () - 1); + return CoderResult.malformedForLength (1); + } + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + out.put ((char) b); + } + + return CoderResult.UNDERFLOW; + } + } + + private static final class Encoder extends CharsetEncoder + { + // Package-private to avoid a trampoline constructor. + Encoder (Charset cs) + { + super (cs, 1.0f, 1.0f); + } + + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + char c = in.get (); + + if (c > Byte.MAX_VALUE) + { + in.position (in.position () - 1); + return CoderResult.unmappableForLength (1); + } + if (!out.hasRemaining ()) + { + in.position (in.position () - 1); + return CoderResult.OVERFLOW; + } + + out.put ((byte) c); + } + + return CoderResult.UNDERFLOW; + } + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16.java b/libjava/classpath/gnu/java/nio/charset/UTF_16.java new file mode 100644 index 0000000..b1d7705 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16.java @@ -0,0 +1,80 @@ +/* UTF_16.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; + +/** + * UTF-16 charset. + * + * @author Jesse Rosenstock + */ +final class UTF_16 extends Charset +{ + UTF_16 () + { + super ("UTF-16", new String[] { + // witnessed by the internet + "UTF16", + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "ISO-10646-UCS-2", "unicode", "csUnicode", "ucs-2", "UnicodeBig" + }); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1 + || cs instanceof UTF_8 || cs instanceof UTF_16BE + || cs instanceof UTF_16LE || cs instanceof UTF_16; + } + + public CharsetDecoder newDecoder () + { + return new UTF_16Decoder (this, UTF_16Decoder.UNKNOWN_ENDIAN); + } + + public CharsetEncoder newEncoder () + { + return new UTF_16Encoder (this, UTF_16Encoder.BIG_ENDIAN, true); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16BE.java b/libjava/classpath/gnu/java/nio/charset/UTF_16BE.java new file mode 100644 index 0000000..1fe3b5d --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16BE.java @@ -0,0 +1,84 @@ +/* UTF_16BE.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; + +/** + * UTF-16BE charset. + * + * @author Jesse Rosenstock + */ +final class UTF_16BE extends Charset +{ + UTF_16BE () + { + super ("UTF-16BE", new String[] { + // witnessed by the internet + "UTF16BE", + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "x-utf-16be", "ibm-1200", "ibm-1201", "ibm-5297", + "ibm-13488", "ibm-17584", "windows-1201", "cp1200", "cp1201", + "UTF16_BigEndian", + // see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + "UnicodeBigUnmarked" + }); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1 + || cs instanceof UTF_8 || cs instanceof UTF_16BE + || cs instanceof UTF_16LE || cs instanceof UTF_16; + } + + public CharsetDecoder newDecoder () + { + return new UTF_16Decoder (this, UTF_16Decoder.BIG_ENDIAN); + } + + public CharsetEncoder newEncoder () + { + return new UTF_16Encoder (this, UTF_16Encoder.BIG_ENDIAN, false); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java new file mode 100644 index 0000000..302c83e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java @@ -0,0 +1,152 @@ +/* UTF_16Decoder.java -- + Copyright (C) 2002 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; + +/** + * Decoder for UTF-16, UTF-15LE, and UTF-16BE. + * + * @author Jesse Rosenstock + */ +final class UTF_16Decoder extends CharsetDecoder +{ + // byte orders + static final int BIG_ENDIAN = 0; + static final int LITTLE_ENDIAN = 1; + static final int UNKNOWN_ENDIAN = 2; + + private static final char BYTE_ORDER_MARK = 0xFEFF; + private static final char REVERSED_BYTE_ORDER_MARK = 0xFFFE; + + private final int originalByteOrder; + private int byteOrder; + + UTF_16Decoder (Charset cs, int byteOrder) + { + super (cs, 0.5f, 1.0f); + this.originalByteOrder = byteOrder; + this.byteOrder = byteOrder; + } + + protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + + int inPos = in.position (); + try + { + while (in.remaining () >= 2) + { + byte b1 = in.get (); + byte b2 = in.get (); + + // handle byte order mark + if (byteOrder == UNKNOWN_ENDIAN) + { + char c = (char) (((b1 & 0xFF) << 8) | (b2 & 0xFF)); + if (c == BYTE_ORDER_MARK) + { + byteOrder = BIG_ENDIAN; + inPos += 2; + continue; + } + else if (c == REVERSED_BYTE_ORDER_MARK) + { + byteOrder = LITTLE_ENDIAN; + inPos += 2; + continue; + } + else + { + // assume big endian, do not consume bytes, + // continue with normal processing + byteOrder = BIG_ENDIAN; + } + } + + // FIXME: Change so you only do a single comparison here. + char c = byteOrder == BIG_ENDIAN ? (char) ((b1 << 8) | b2) + : (char) ((b2 << 8) | b1); + + if (0xD800 <= c && c <= 0xDFFF) + { + // c is a surrogate + + // make sure c is a high surrogate + if (c > 0xDBFF) + return CoderResult.malformedForLength (2); + if (in.remaining () < 2) + return CoderResult.UNDERFLOW; + byte b3 = in.get (); + byte b4 = in.get (); + char d = byteOrder == BIG_ENDIAN ? (char) ((b3 << 8) | b4) + : (char) ((b4 << 8) | b3); + // make sure d is a low surrogate + if (d < 0xDC00 || d > 0xDFFF) + return CoderResult.malformedForLength (2); + out.put (c); + out.put (d); + inPos += 4; + } + else + { + if (!out.hasRemaining ()) + return CoderResult.UNDERFLOW; + out.put (c); + inPos += 2; + } + } + + return CoderResult.UNDERFLOW; + } + finally + { + in.position (inPos); + } + } + + protected void implReset () + { + byteOrder = originalByteOrder; + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16Encoder.java b/libjava/classpath/gnu/java/nio/charset/UTF_16Encoder.java new file mode 100644 index 0000000..d5ab744 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16Encoder.java @@ -0,0 +1,145 @@ +/* UTF_16Encoder.java -- + Copyright (C) 2002 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +/** + * Encoder for UTF-16, UTF-15LE, and UTF-16BE. + * + * @author Jesse Rosenstock + */ +final class UTF_16Encoder extends CharsetEncoder +{ + // byte orders + static final int BIG_ENDIAN = 0; + static final int LITTLE_ENDIAN = 1; + + private static final char BYTE_ORDER_MARK = 0xFEFF; + + private final ByteOrder byteOrder; + private final boolean useByteOrderMark; + private boolean needsByteOrderMark; + + UTF_16Encoder (Charset cs, int byteOrder, boolean useByteOrderMark) + { + super (cs, 2.0f, + useByteOrderMark ? 4.0f : 2.0f, + byteOrder == BIG_ENDIAN + ? new byte[] { (byte) 0xFF, (byte) 0xFD } + : new byte[] { (byte) 0xFD, (byte) 0xFF }); + this.byteOrder = (byteOrder == BIG_ENDIAN) ? + ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; + this.useByteOrderMark = useByteOrderMark; + this.needsByteOrderMark = useByteOrderMark; + } + + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + + ByteOrder originalBO = out.order(); + out.order(byteOrder); + + if (needsByteOrderMark) + { + if (out.remaining () < 2) + { + out.order(originalBO); + return CoderResult.OVERFLOW; + } + out.putChar (BYTE_ORDER_MARK); + needsByteOrderMark = false; + } + + int inPos = in.position (); + try + { + while (in.hasRemaining ()) + { + char c = in.get (); + if (0xD800 <= c && c <= 0xDFFF) + { + // c is a surrogate + + // make sure c is a high surrogate + if (c > 0xDBFF) + return CoderResult.malformedForLength (1); + if (in.remaining () < 1) + return CoderResult.UNDERFLOW; + char d = in.get (); + // make sure d is a low surrogate + if (d < 0xDC00 || d > 0xDFFF) + return CoderResult.malformedForLength (1); + out.putChar (c); + out.putChar (d); + inPos += 2; + } + else + { + if (out.remaining () < 2) + { + out.order(originalBO); + return CoderResult.OVERFLOW; + } + out.putChar (c); + inPos++; + } + } + out.order(originalBO); + return CoderResult.UNDERFLOW; + } + finally + { + in.position (inPos); + } + } + + protected void implReset () + { + needsByteOrderMark = useByteOrderMark; + } + + // TODO: override canEncode(char) and canEncode(CharSequence) + // for performance +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16LE.java b/libjava/classpath/gnu/java/nio/charset/UTF_16LE.java new file mode 100644 index 0000000..6d72a32 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16LE.java @@ -0,0 +1,83 @@ +/* UTF_16LE.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; + +/** + * UTF-16LE charset. + * + * @author Jesse Rosenstock + */ +final class UTF_16LE extends Charset +{ + UTF_16LE () + { + super ("UTF-16LE", new String[] { + // witnessed by the internet + "UTF16LE", + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "x-utf-16le", "ibm-1202", "ibm-13490", "ibm-17586", + "UTF16_LittleEndian", + // see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + "UnicodeLittleUnmarked" + }); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1 + || cs instanceof UTF_8 || cs instanceof UTF_16BE + || cs instanceof UTF_16LE || cs instanceof UTF_16; + } + + public CharsetDecoder newDecoder () + { + return new UTF_16Decoder (this, UTF_16Decoder.LITTLE_ENDIAN); + } + + public CharsetEncoder newEncoder () + { + return new UTF_16Encoder (this, UTF_16Encoder.LITTLE_ENDIAN, false); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_8.java b/libjava/classpath/gnu/java/nio/charset/UTF_8.java new file mode 100644 index 0000000..0e0730e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UTF_8.java @@ -0,0 +1,311 @@ +/* UTF_8.java -- + Copyright (C) 2002, 2004, 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.java.nio.charset; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +/** + * UTF-8 charset. + * + * <p> UTF-8 references: + * <ul> + * <li> <a href="http://ietf.org/rfc/rfc2279.txt">RFC 2279</a> + * <li> The <a href="http://www.unicode.org/unicode/standard/standard.html"> + * Unicode standard</a> and + * <a href="http://www.unicode.org/versions/corrigendum1.html"> + * Corrigendum</a> + * </ul> + * + * @author Jesse Rosenstock + */ +final class UTF_8 extends Charset +{ + UTF_8 () + { + super ("UTF-8", new String[] { + /* These names are provided by + * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL + */ + "ibm-1208", "ibm-1209", "ibm-5304", "ibm-5305", + "windows-65001", "cp1208", + // see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html + "UTF8" + }); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1 + || cs instanceof UTF_8 || cs instanceof UTF_16BE + || cs instanceof UTF_16LE || cs instanceof UTF_16; + } + + public CharsetDecoder newDecoder () + { + return new Decoder (this); + } + + public CharsetEncoder newEncoder () + { + return new Encoder (this); + } + + private static final class Decoder extends CharsetDecoder + { + // Package-private to avoid a trampoline constructor. + Decoder (Charset cs) + { + super (cs, 1f, 1f); + } + + protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out) + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + int inPos = in.position(); + try + { + while (in.hasRemaining ()) + { + char c; + byte b1 = in.get (); + int highNibble = ((b1 & 0xFF) >> 4) & 0xF; + switch (highNibble) + { + case 0: case 1: case 2: case 3: + case 4: case 5: case 6: case 7: + if (out.remaining () < 1) + return CoderResult.OVERFLOW; + out.put ((char) b1); + inPos++; + break; + + case 0xC: case 0xD: + byte b2; + if (in.remaining () < 1) + return CoderResult.UNDERFLOW; + if (out.remaining () < 1) + return CoderResult.OVERFLOW; + if (!isContinuation (b2 = in.get ())) + return CoderResult.malformedForLength (1); + c = (char) (((b1 & 0x1F) << 6) | (b2 & 0x3F)); + // check that we had the shortest encoding + if (c <= 0x7F) + return CoderResult.malformedForLength (2); + out.put (c); + inPos += 2; + break; + + case 0xE: + byte b3; + if (in.remaining () < 2) + return CoderResult.UNDERFLOW; + if (out.remaining () < 1) + return CoderResult.OVERFLOW; + if (!isContinuation (b2 = in.get ())) + return CoderResult.malformedForLength (1); + if (!isContinuation (b3 = in.get ())) + return CoderResult.malformedForLength (1); + c = (char) (((b1 & 0x0F) << 12) + | ((b2 & 0x3F) << 6) + | (b3 & 0x3F)); + // check that we had the shortest encoding + if (c <= 0x7FF) + return CoderResult.malformedForLength (3); + out.put (c); + inPos += 3; + break; + + case 0xF: + byte b4; + if (in.remaining () < 3) + return CoderResult.UNDERFLOW; + if((b1&0x0F) > 4) + return CoderResult.malformedForLength (4); + if (out.remaining () < 2) + return CoderResult.OVERFLOW; + if (!isContinuation (b2 = in.get ())) + return CoderResult.malformedForLength (3); + if (!isContinuation (b3 = in.get ())) + return CoderResult.malformedForLength (2); + if (!isContinuation (b4 = in.get ())) + return CoderResult.malformedForLength (1); + int n = (((b1 & 0x3) << 18) + | ((b2 & 0x3F) << 12) + | ((b3 & 0x3F) << 6) + | (b4 & 0x3F)) - 0x10000; + char c1 = (char)(0xD800 | (n & 0xFFC00)>>10); + char c2 = (char)(0xDC00 | (n & 0x003FF)); + out.put (c1); + out.put (c2); + inPos += 4; + break; + + default: + return CoderResult.malformedForLength (1); + } + } + + return CoderResult.UNDERFLOW; + } + finally + { + // In case we did a get(), then encountered an error, reset the + // position to before the error. If there was no error, this + // will benignly reset the position to the value it already has. + in.position (inPos); + } + } + + private static boolean isContinuation (byte b) + { + return (b & 0xC0) == 0x80; + } + } + + private static final class Encoder extends CharsetEncoder + { + // Package-private to avoid a trampoline constructor. + Encoder (Charset cs) + { + // According to + // http://www-106.ibm.com/developerworks/unicode/library/utfencodingforms/index.html + // On average, English takes slightly over one unit per code point. + // Most Latin-script languages take about 1.1 bytes. Greek, Russian, + // Arabic and Hebrew take about 1.7 bytes, and most others (including + // Japanese, Chinese, Korean and Hindi) take about 3 bytes. + // We assume we will be dealing with latin scripts, and use 1.1 + // for averageBytesPerChar. + super (cs, 1.1f, 4.0f); + } + + protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out) + { + int inPos = in.position(); + try + { + // TODO: Optimize this in the case in.hasArray() / out.hasArray() + while (in.hasRemaining ()) + { + int remaining = out.remaining (); + char c = in.get (); + + // UCS-4 range (hex.) UTF-8 octet sequence (binary) + // 0000 0000-0000 007F 0xxxxxxx + // 0000 0080-0000 07FF 110xxxxx 10xxxxxx + // 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + + // Scalar Value UTF-16 byte 1 byte 2 byte 3 byte 4 + // 0000 0000 0xxx xxxx 0000 0000 0xxx xxxx 0xxx xxxx + // 0000 0yyy yyxx xxxx 0000 0yyy yyxx xxxx 110y yyyy 10xx xxxx + // zzzz yyyy yyxx xxxx zzzz yyyy yyxx xxxx 1110 zzzz 10yy yyyy 10xx xxxx + // u uuuu zzzz yyyy yyxx xxxx 1101 10ww wwzz zzyy 1111 0uuu 10uu zzzz 10yy yyyy 10xx xxxx + // + 1101 11yy yyxx xxxx + // Note: uuuuu = wwww + 1 + if (c <= 0x7F) + { + if (remaining < 1) + return CoderResult.OVERFLOW; + out.put ((byte) c); + inPos++; + } + else if (c <= 0x7FF) + { + if (remaining < 2) + return CoderResult.OVERFLOW; + out.put ((byte) (0xC0 | (c >> 6))); + out.put ((byte) (0x80 | (c & 0x3F))); + inPos++; + } + else if (0xD800 <= c && c <= 0xDFFF) + { + if (remaining < 4) + return CoderResult.OVERFLOW; + + // we got a low surrogate without a preciding high one + if (c > 0xDBFF) + return CoderResult.malformedForLength (1); + + // high surrogates + if (!in.hasRemaining ()) + return CoderResult.UNDERFLOW; + + char d = in.get (); + + // make sure d is a low surrogate + if (d < 0xDC00 || d > 0xDFFF) + return CoderResult.malformedForLength (1); + + // make the 32 bit value + // int value2 = (c - 0xD800) * 0x400 + (d - 0xDC00) + 0x10000; + int value = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000; + // assert value == value2; + out.put ((byte) (0xF0 | ((value >> 18) & 0x07))); + out.put ((byte) (0x80 | ((value >> 12) & 0x3F))); + out.put ((byte) (0x80 | ((value >> 6) & 0x3F))); + out.put ((byte) (0x80 | ((value ) & 0x3F))); + inPos += 2; + } + else + { + if (remaining < 3) + return CoderResult.OVERFLOW; + + out.put ((byte) (0xE0 | (c >> 12))); + out.put ((byte) (0x80 | ((c >> 6) & 0x3F))); + out.put ((byte) (0x80 | (c & 0x3F))); + inPos++; + } + } + + return CoderResult.UNDERFLOW; + } + finally + { + // In case we did a get(), then encountered an error, reset the + // position to before the error. If there was no error, this + // will benignly reset the position to the value it already has. + in.position (inPos); + } + } + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java b/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java new file mode 100644 index 0000000..d354e04 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java @@ -0,0 +1,74 @@ +/* UnicodeLittle.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.java.nio.charset; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; + +/** + * UTF-16 little endian with a byte-order mark + * Included for java.io completeness. + * ("UTF-16" is equal to UnicodeBig, and + * UTF-16BE/LE do not have a BOM + */ +final class UnicodeLittle extends Charset +{ + UnicodeLittle () + { + super ("UnicodeLittle", new String[] {}); + } + + public boolean contains (Charset cs) + { + return cs instanceof US_ASCII || cs instanceof ISO_8859_1 + || cs instanceof UTF_8 || cs instanceof UTF_16BE + || cs instanceof UTF_16LE || cs instanceof UTF_16; + } + + public CharsetDecoder newDecoder () + { + return new UTF_16Decoder (this, UTF_16Decoder.UNKNOWN_ENDIAN); + } + + public CharsetEncoder newEncoder () + { + return new UTF_16Encoder (this, UTF_16Encoder.LITTLE_ENDIAN, true); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1250.java b/libjava/classpath/gnu/java/nio/charset/Windows1250.java new file mode 100644 index 0000000..9d7ab8e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1250.java @@ -0,0 +1,103 @@ +/* Windows1250.java -- Charset for Windows-1250 Character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1250-Latin-1, + * aka cp1250 or Windows-1250 or whatever. + */ +public class Windows1250 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021, + 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0xFFFD, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 + }; + + public Windows1250() + { + super("windows-1250", new String[] { + "Windows1250", + "ibm-5346_P100-1998", + "ibm-5346", + "cp1250", + "cp-1250", + "cp_1250", + "windows1250", + "windows_1250" + }); + lookupTable = lookup; + } + +} // class Windows1250 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1251.java b/libjava/classpath/gnu/java/nio/charset/Windows1251.java new file mode 100644 index 0000000..bf3227e --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1251.java @@ -0,0 +1,101 @@ +/* Windows1251.java -- Charset for Windows-1251 Cyrillic character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1251 Cyrillic char set. + * aka cp1251 or Windows-1251 or whatever. + */ +public class Windows1251 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + NONE, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F + }; + + public Windows1251() + { + super("windows-1251", new String[] { + "Windows1251", + "cp1251", + "cp-1251", + "cp_1251", + "windows1251", + "windows_1251" + }); + lookupTable = lookup; + } + +} // class Windows1251 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1252.java b/libjava/classpath/gnu/java/nio/charset/Windows1252.java new file mode 100644 index 0000000..9391c87 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1252.java @@ -0,0 +1,100 @@ +/* Windows1252.java -- Charset for Windows-1252 Character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1252-Latin-1, + * aka cp1252 or Windows-1252 or whatever. + */ +public class Windows1252 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, NONE, 0x017D, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, NONE, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF + }; + + public Windows1252() + { + super("windows-1252", new String[] { + "Windows1252", + "ibm-5348_P100-1997", + "ibm-5348", + "windows-1252", + "cp1252", + "cp-1252" + }); + lookupTable = lookup; + } + +} // class Windows1252 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1253.java b/libjava/classpath/gnu/java/nio/charset/Windows1253.java new file mode 100644 index 0000000..02150b4 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1253.java @@ -0,0 +1,101 @@ +/* Windows1253.java -- Charset for Windows-1253 Greek character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1253 Greek char set. + * aka cp1253 or Windows-1253 or whatever. + */ +public class Windows1253 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + NONE, 0x2030, NONE, 0x2039, NONE, NONE, NONE, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + NONE, 0x2122, NONE, 0x203A, NONE, NONE, NONE, NONE, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, NONE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, NONE, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, NONE + }; + + public Windows1253() + { + super("windows-1253", new String[] { + "Windows1253", + "cp1253", + "cp-1253", + "cp_1253", + "windows1253", + "windows_1253" + }); + lookupTable = lookup; + } + +} // class Windows1253 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1254.java b/libjava/classpath/gnu/java/nio/charset/Windows1254.java new file mode 100644 index 0000000..7cdad3c --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1254.java @@ -0,0 +1,101 @@ +/* Windows1254.java -- Charset for Windows-1254 Turkish character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1254 Turkish char set. + * aka cp1254 or Windows-1254 or whatever. + */ +public class Windows1254 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, NONE, NONE, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, NONE, NONE, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF + }; + + public Windows1254() + { + super("windows-1254", new String[] { + "Windows1254", + "cp1254", + "cp-1254", + "cp_1254", + "windows1254", + "windows_1254" + }); + lookupTable = lookup; + } + +} // class Windows1254 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1255.java b/libjava/classpath/gnu/java/nio/charset/Windows1255.java new file mode 100644 index 0000000..b706d19 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1255.java @@ -0,0 +1,101 @@ +/* Windows1255.java -- Charset for Windows-1255 Character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1255 Hebrew char set. + * aka cp1255 or Windows-1255 or whatever. + */ +public class Windows1255 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, + 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, + 0x05B8, 0x05B9, 0xFFFD, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, + 0x05F4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD + }; + + public Windows1255() + { + super("windows-1255", new String[] { + "Windows1255", + "cp1255", + "cp-1255", + "cp_1255", + "windows1255", + "windows_1255" + }); + lookupTable = lookup; + } + +} // class Windows1255 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1256.java b/libjava/classpath/gnu/java/nio/charset/Windows1256.java new file mode 100644 index 0000000..6924420 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1256.java @@ -0,0 +1,101 @@ +/* Windows1256.java -- Charset for Windows-1256 Arabic character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1256 Arabic char set. + * aka cp1256 or Windows-1256 or whatever. + */ +public class Windows1256 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, + 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, + 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2 + }; + + public Windows1256() + { + super("windows-1256", new String[] { + "Windows1256", + "cp1256", + "cp-1256", + "cp_1256", + "windows1256", + "windows_1256" + }); + lookupTable = lookup; + } + +} // class Windows1256 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1257.java b/libjava/classpath/gnu/java/nio/charset/Windows1257.java new file mode 100644 index 0000000..2f95d64 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1257.java @@ -0,0 +1,101 @@ +/* Windows1257.java -- Charset for Windows-1257 Baltic character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1257 Baltic char set. + * aka cp1257 or Windows-1257 or whatever. + */ +public class Windows1257 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, 0x201A, NONE, 0x201E, 0x2026, 0x2020, 0x2021, + NONE, 0x2030, NONE, 0x2039, NONE, 0x00A8, 0x02C7, 0x00B8, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + NONE, 0x2122, NONE, 0x203A, NONE, 0x00AF, 0x02DB, NONE, + 0x00A0, NONE, 0x00A2, 0x00A3, 0x00A4, NONE, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9 + }; + + public Windows1257() + { + super("windows-1257", new String[] { + "Windows1257", + "cp1257", + "cp-1257", + "cp_1257", + "windows1257", + "windows_1257" + }); + lookupTable = lookup; + } + +} // class Windows1257 + diff --git a/libjava/classpath/gnu/java/nio/charset/Windows1258.java b/libjava/classpath/gnu/java/nio/charset/Windows1258.java new file mode 100644 index 0000000..7d653b4 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/Windows1258.java @@ -0,0 +1,101 @@ +/* Windows1258.java -- Charset for Windows-1258 Vietnamese character set. + 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.java.nio.charset; + +/** + * Encoding table for Windows-1258 Arabic char set. + * aka cp1258 or Windows-1258 or whatever. + */ +public class Windows1258 extends ByteCharset +{ + + /** + * This is the lookup table for this encoding + */ + private static final char[] lookup = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, + 0x20AC, NONE, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, NONE, 0x2039, 0x0152, NONE, NONE, NONE, + NONE, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, NONE, 0x203A, 0x0153, NONE, NONE, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF + }; + + public Windows1258() + { + super("windows-1258", new String[] { + "Windows1258", + "cp1258", + "cp-1258", + "cp_1258", + "windows1258", + "windows_1258" + }); + lookupTable = lookup; + } + +} // class Windows1258 + diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvCharset.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvCharset.java new file mode 100644 index 0000000..ffd2a10 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvCharset.java @@ -0,0 +1,85 @@ +/* IconvCharset.java -- Wrapper for iconv charsets. + 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.java.nio.charset.iconv; + +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; + +public final class IconvCharset extends Charset +{ + private IconvMetaData info; + + public IconvCharset(IconvMetaData info) + { + super(info.nioCanonical(), info.aliases()); + this.info = info; + if (newEncoder() == null || newDecoder() == null) + throw new IllegalArgumentException(); + } + + public boolean contains(Charset cs) + { + return false; + } + + public CharsetDecoder newDecoder() + { + try + { + return new IconvDecoder(this, info); + } + catch (IllegalArgumentException e) + { + return null; + } + } + + public CharsetEncoder newEncoder() + { + try + { + return new IconvEncoder(this, info); + } + catch (IllegalArgumentException e) + { + return null; + } + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java new file mode 100644 index 0000000..fa265a9 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvDecoder.java @@ -0,0 +1,113 @@ +/* IconvDecoder.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.java.nio.charset.iconv; + +import gnu.classpath.RawData; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +final class IconvDecoder extends CharsetDecoder +{ + IconvDecoder(Charset cs, IconvMetaData info) + { + super(cs, info.averageCharsPerByte(), info.maxCharsPerByte()); + openIconv(info.iconvName()); + } + + private RawData data; + private int inremaining; + private int outremaining; + + private native void openIconv(String name); + + private native int decode(byte[] in, char[] out, int posIn, int remIn, + int posOut, int remOut); + + private native void closeIconv(); + + protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) + { + int remIn = in.remaining(); + int inPos = in.position(); + int outPos = out.position(); + int remOut = out.remaining(); + byte[] inArr; + int ret; + + if (in.hasArray()) + inArr = in.array(); + else + { + inArr = new byte[remIn]; + in.get(inArr); + } + + if (out.hasArray()) + { + ret = decode(inArr, out.array(), inPos, remIn, outPos, remOut); + out.position(outPos + (remOut - outremaining)); + } + else + { + char[] outArr = new char[remOut]; + ret = decode(inArr, outArr, inPos, remIn, outPos, remOut); + out.put(outArr, 0, (remOut - outremaining)); + } + in.position(inPos + (remIn - inremaining)); + + if (ret == 1) + return CoderResult.malformedForLength(1); + + if (in.remaining() == 0) + return CoderResult.UNDERFLOW; + return CoderResult.OVERFLOW; + } + + protected void finalize() + { + closeIconv(); + } +} + + diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java new file mode 100644 index 0000000..bb10c9b --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvEncoder.java @@ -0,0 +1,111 @@ +/* IconvEncoder.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.java.nio.charset.iconv; + +import gnu.classpath.RawData; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; + +final class IconvEncoder extends CharsetEncoder +{ + private RawData data; + private int inremaining; + private int outremaining; + + private native void openIconv(String name); + + private native int encode(char[] in, byte[] out, int posIn, int remIn, + int posOut, int remOut); + + private native void closeIconv(); + + IconvEncoder(Charset cs, IconvMetaData info) + { + super(cs, info.averageBytesPerChar(), info.maxBytesPerChar()); + openIconv(info.iconvName()); + } + + protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) + { + int inPos = in.position(); + int outPos = out.position(); + int remIn = in.remaining(); + int remOut = out.remaining(); + char[] inArr; + int ret; + + if (in.hasArray()) + inArr = in.array(); + else + { + inArr = new char[remIn]; + in.get(inArr); + } + + if (out.hasArray()) + { + ret = encode(inArr, out.array(), inPos, remIn, outPos, remOut); + out.position(outPos + (remOut - outremaining)); + } + else + { + byte[] outArr = new byte[remOut]; + ret = encode(inArr, outArr, inPos, remIn, outPos, remOut); + out.put(outArr, 0, (remOut - outremaining)); + } + in.position(inPos + (remIn - inremaining)); + + if (ret == 1) + return CoderResult.malformedForLength(1); + + if (in.remaining() == 0) + return CoderResult.UNDERFLOW; + return CoderResult.OVERFLOW; + } + + protected void finalize() + { + closeIconv(); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvMetaData.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvMetaData.java new file mode 100644 index 0000000..c4686a2 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvMetaData.java @@ -0,0 +1,450 @@ +/* IconvMetaData.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.java.nio.charset.iconv; + +import java.util.HashMap; +import java.util.Vector; + +/** + * This is ugly glue. iconv doesn't have character metadata, + * so we include it here. + * + * TODO: Add more charsets which GNU iconv and the JDK support which aren't + * included here. + * + * @author Sven de Marothy + */ +final class IconvMetaData +{ + /** + * Map of names (and aliases) to metadata instances + */ + private static HashMap names; + + /** + * Vector of MetaData instances + */ + private static Vector charsets; + + /** + * Name to use with iconv (may differ from the nio canonical. + */ + private String iconvName; + + /** + * Average number of bytes per char. + */ + private float averageBperC; + + /** + * Maximum number of bytes per char. + */ + private float maxBperC; + + /** + * Average number of chars per byte. + */ + private float averageCperB; + + /** + * Maximum number of chars per byte. + */ + private float maxCperB; + + /** + * NIO canonical name. + */ + private String nioCanonical; + + /** + * Charset aliases. + */ + private String[] aliases; + + IconvMetaData(String nioCanonical, float averageBperC, float maxBperC, + float averageCperB, float maxCperB, String[] aliases, + String iconvName) + { + this.nioCanonical = nioCanonical; + this.iconvName = iconvName; + + this.averageBperC = averageBperC; + this.maxBperC = maxBperC; + this.averageCperB = averageCperB; + this.maxCperB = maxCperB; + this.aliases = aliases; + + names.put(nioCanonical, this); + names.put(iconvName, this); + for (int i = 0; i < aliases.length; i++) + names.put(aliases[i], this); + charsets.add(this); + } + + static Vector charsets() + { + return charsets; + } + + String[] aliases() + { + return aliases; + } + + String nioCanonical() + { + return nioCanonical; + } + + String iconvName() + { + return iconvName; + } + + float maxBytesPerChar() + { + return maxBperC; + } + + float maxCharsPerByte() + { + return maxCperB; + } + + float averageBytesPerChar() + { + return averageBperC; + } + + float averageCharsPerByte() + { + return averageCperB; + } + + static IconvMetaData get(String s) + { + return (IconvMetaData) names.get(s); + } + + static void setup() + { + names = new HashMap(); + charsets = new Vector(); + new IconvMetaData("Big5", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "big-5", "csBig5" }, "Big5"); + + new IconvMetaData("Big5-HKSCS", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "big5-hkscs", "Big5_HKSCS", "big5hkscs" }, + "Big5-HKSCS"); + + new IconvMetaData("EUC-CN", 2.0f, 2.0f, 0.5f, 1.0f, new String[] { }, + "EUC-CN"); + + new IconvMetaData("EUC-JP", 3.0f, 3.0f, 0.5f, 1.0f, + new String[] + { + "eucjis", "x-eucjp", "csEUCPkdFmtjapanese", "eucjp", + "Extended_UNIX_Code_Packed_Format_for_Japanese", + "x-euc-jp", "euc_jp" + }, "EUC-JP"); + + new IconvMetaData("EUC-KR", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] + { + "ksc5601", "5601", "ksc5601_1987", "ksc_5601", + "ksc5601-1987", "euc_kr", "ks_c_5601-1987", "euckr", + "csEUCKR" + }, "EUC-KR"); + + new IconvMetaData("EUC-TW", 4.0f, 4.0f, 2.0f, 2.0f, + new String[] { "cns11643", "euc_tw", "euctw", }, "EUC-TW"); + + new IconvMetaData("GB18030", 4.0f, 4.0f, 1.0f, 2.0f, + new String[] { "gb18030-2000", }, "GB18030"); + + new IconvMetaData("GBK", 2.0f, 2.0f, 0.5f, 1.0f, new String[] { "GBK" }, + "GBK"); + + new IconvMetaData("ISO-2022-CN-CNS", 4.0f, 4.0f, 2.0f, 2.0f, + new String[] { "ISO2022CN_CNS" }, "ISO-2022-CN"); // will this work? + + new IconvMetaData("ISO-2022-CN-GB", 4.0f, 4.0f, 2.0f, 2.0f, + new String[] { "ISO2022CN_GB" }, "ISO-2022-CN"); // same here? + + new IconvMetaData("ISO-2022-KR", 4.0f, 4.0f, 1.0f, 1.0f, + new String[] { "ISO2022KR", "csISO2022KR" }, + "ISO-2022-KR"); + + new IconvMetaData("ISO-8859-1", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "iso-ir-100", "ISO_8859-1", "latin1", "l1", "IBM819", + "CP819", "csISOLatin1", "8859_1", "ISO8859_1", + "ISO_8859_1", "ibm-819", "ISO_8859-1:1987", "819" + }, "ISO-8859-1"); + + new IconvMetaData("ISO-8859-13", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_13", "8859_13", "ibm-921_P100-1995", "ibm-921", + "iso_8859_13", "iso8859_13", "iso-8859-13", "8859_13", + "cp921", "921" + }, "ISO-8859-13"); + + new IconvMetaData("ISO-8859-15", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "8859_15", "csISOlatin9", "IBM923", "cp923", "923", + "LATIN0", "csISOlatin0", "ISO8859_15_FDIS", "L9", + "IBM-923", "ISO8859-15", "LATIN9", "ISO_8859-15", + "ISO-8859-15", + }, "ISO-8859-15"); + + new IconvMetaData("ISO-8859-2", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_2", "8859_2", "ibm-912_P100-1995", "ibm-912", + "iso_8859_2", "iso8859_2", "iso-8859-2", + "ISO_8859-2:1987", "latin2", "csISOLatin2", + "iso-ir-101", "l2", "cp912", "912", "windows-28592" + }, "ISO-8859-2"); + + new IconvMetaData("ISO-8859-3", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_3", "8859_3", "ibm-913_P100-2000", "ibm-913", + "iso_8859_3", "iso8859_3", "iso-8859-3", + "ISO_8859-3:1988", "latin3", "csISOLatin3", + "iso-ir-109", "l3", "cp913", "913", "windows-28593" + }, "ISO-8859-3"); + + new IconvMetaData("ISO-8859-4", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_4", "8859_4", "ibm-914_P100-1995", "ibm-914", + "iso_8859_4", "iso8859_4", "iso-8859-4", "latin4", + "csISOLatin4", "iso-ir-110", "ISO_8859-4:1988", "l4", + "cp914", "914", "windows-28594" + }, "ISO-8859-4"); + + new IconvMetaData("ISO-8859-5", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_5", "8859_5", "ibm-915_P100-1995", "ibm-915", + "iso_8859_5", "iso8859_5", "iso-8859-5", "cyrillic", + "csISOLatinCyrillic", "iso-ir-144", "ISO_8859-5:1988", + "cp915", "915", "windows-28595" + }, "ISO-8859-5"); + + new IconvMetaData("ISO-8859-6", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "8859_6", "ibm-1089_P100-1995", "ibm-1089", + "iso_8859_6", "iso8859_6", "iso-8859-6", "arabic", + "csISOLatinArabic", "iso-ir-127", "ISO_8859-6:1987", + "ECMA-114", "ASMO-708", "8859_6", "cp1089", "1089", + "windows-28596", "ISO-8859-6-I", "ISO-8859-6-E" + }, "ISO-8859-6"); + + new IconvMetaData("ISO-8859-7", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_7", "8859_7", "ibm-813_P100-1995", "ibm-813", + "iso_8859_7", "iso8859_7", "iso-8859-7", "greek", + "greek8", "ELOT_928", "ECMA-118", "csISOLatinGreek", + "iso-ir-126", "ISO_8859-7:1987", "cp813", "813", + "windows-28597" + }, "ISO-8859-7"); + + new IconvMetaData("ISO-8859-8", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_8", "8859_8", "ibm-916_P100-1995", "ibm-916", + "iso_8859_8", "iso8859_8", "iso-8859-8", "hebrew", + "csISOLatinHebrew", "iso-ir-138", "ISO_8859-8:1988", + "ISO-8859-8-I", "ISO-8859-8-E", "cp916", "916", + "windows-28598" + }, "ISO-8859-8"); + + new IconvMetaData("ISO-8859-9", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "ISO8859_9", "8859_9", "ibm-920_P100-1995", "ibm-920", + "iso8859_9", "iso-8859-9", "iso_8859_9", "latin5", + "csISOLatin5", "iso-ir-148", "ISO_8859-9:1989", "l5", + "cp920", "920", "windows-28599", "ECMA-128" + }, "ISO-8859-9"); + + new IconvMetaData("Johab", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "ms1361", "ksc5601_1992", "ksc5601-1992", }, + "Johab"); + + new IconvMetaData("KOI8-R", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "KOI8_R", "KOI8", "KOI-8", "KOI_8", "koi8-r", "koi8r", + "koi-8-r", "koi" + }, "KOI8-R"); + + new IconvMetaData("Shift_JIS", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] + { + "shift-jis", "x-sjis", "ms_kanji", "shift_jis", + "csShiftJIS", "sjis", "pck", + }, "Shift_JIS"); + + new IconvMetaData("TIS-620", 1.0f, 1.0f, 1.0f, 1.0f, new String[] { }, + "TIS-620"); + + new IconvMetaData("US-ASCII", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "IBM367", "ISO646-US", "ANSI_X3.4-1986", "cp367", + "ASCII", "iso_646.irv:1983", "646", "us", "iso-ir-6", + "csASCII", "ANSI_X3.4-1968", "ISO_646.irv:1991", + }, "US-ASCII"); + + new IconvMetaData("UTF-16", 2.0f, 4.0f, 0.5f, 1.0f, + new String[] + { + "UTF_16", "UTF16", "ISO-10646-UCS-2", "unicode", + "csUnicode", "ucs-2", "UnicodeBig" + }, "UTF-16"); + + new IconvMetaData("UTF-16BE", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] + { + "X-UTF-16BE", "UTF_16BE", "UTF16BE", "ISO-10646-UCS-2", + "x-utf-16be", "ibm-1200", "ibm-1201", "ibm-5297", + "ibm-13488", "ibm-17584", "windows-1201", "cp1200", + "cp1201", "UnicodeBigUnmarked" + }, "UTF-16BE"); + + new IconvMetaData("UTF-16LE", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] + { + "UTF_16LE", "UTF16LE", "X-UTF-16LE", "ibm-1202", + "ibm-13490", "ibm-17586", "UTF16_LittleEndian", + "UnicodeLittleUnmarked" + }, "UTF-16LE"); + + new IconvMetaData("UTF-8", 1.1f, 4.0f, 1.0f, 2.0f, + new String[] + { + "UTF8", "ibm-1208", "ibm-1209", "ibm-5304", "ibm-5305", + "windows-65001", "cp1208" + }, "UTF-8"); + + new IconvMetaData("windows-1250", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1250", "ibm-5346_P100-1998", "ibm-5346", + "cp1250", "cp-1250", "cp_1250", "windows1250", + "windows_1250" + }, "windows-1250"); + + new IconvMetaData("windows-1251", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1251", "cp1251", "cp-1251", "cp_1251", + "windows1251", "windows_1251" + }, "windows-1251"); + + new IconvMetaData("windows-1252", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1252", "ibm-5348_P100-1997", "ibm-5348", + "windows-1252", "cp1252", "cp-1252" + }, "windows-1252"); + + new IconvMetaData("windows-1253", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1253", "cp1253", "cp-1253", "cp_1253", + "windows1253", "windows_1253" + }, "windows-1253"); + + new IconvMetaData("windows-1254", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1254", "cp1254", "cp-1254", "cp_1254", + "windows1254", "windows_1254" + }, "windows-1254"); + + new IconvMetaData("windows-1255", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1255", "cp1255", "cp-1255", "cp_1255", + "windows1255", "windows_1255" + }, "windows-1255"); + + new IconvMetaData("windows-1256", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1255", "cp1256", "cp-1256", "cp_1256", + "windows1256", "windows_1256" + }, "windows-1256"); + + new IconvMetaData("windows-1257", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1255", "cp1257", "cp-1257", "cp_1257", + "windows1257", "windows_1257" + }, "windows-1257"); + + new IconvMetaData("windows-1258", 1.0f, 1.0f, 1.0f, 1.0f, + new String[] + { + "Windows1255", "cp1258", "cp-1258", "cp_1258", + "windows1258", "windows_1258" + }, "windows-1258"); + + new IconvMetaData("windows-936", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "cp936", "ms-936", "ms936", "ms_936" }, + "windows-936"); + + new IconvMetaData("windows-949", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "cp949", "ms-949", "ms_949", "ms949" }, + "cp949"); + + new IconvMetaData("windows-950", 2.0f, 2.0f, 0.5f, 1.0f, + new String[] { "cp950", "ms_950", "ms-950", "ms950", }, + "cp950"); + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java new file mode 100644 index 0000000..58eaa85 --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java @@ -0,0 +1,111 @@ +/* IconvProvider.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.java.nio.charset.iconv; + +import java.nio.charset.Charset; +import java.nio.charset.spi.CharsetProvider; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; + +/** + * Charset provider wrapping iconv. + * + * @author Sven de Marothy + */ +public final class IconvProvider extends CharsetProvider +{ + private static IconvProvider singleton; + + static + { + synchronized (IconvProvider.class) + { + singleton = null; + } + } + + private IconvProvider() + { + IconvMetaData.setup(); + } + + public Iterator charsets() + { + Vector names = IconvMetaData.charsets(); + Vector charsets = new Vector(); + for (int i = 0; i < names.size(); i++) + { + try + { + charsets.add(new IconvCharset((IconvMetaData) names.elementAt(i))); + } + catch (IllegalArgumentException e) + { + } + } + return charsets.iterator(); + } + + public Charset charsetForName(String charsetName) + { + try + { + IconvMetaData info = IconvMetaData.get(charsetName); + + // Try anyway if the set isn't found. + if (info == null) + info = new IconvMetaData(charsetName, 2.0f, 2.0f, 2.0f, 2.0f, + new String[] { }, charsetName); + return new IconvCharset(info); + } + catch (IllegalArgumentException e) + { + return null; + } + } + + public static synchronized IconvProvider provider() + { + if (singleton == null) + singleton = new IconvProvider(); + return singleton; + } +} diff --git a/libjava/classpath/gnu/java/nio/charset/package.html b/libjava/classpath/gnu/java/nio/charset/package.html new file mode 100644 index 0000000..002516d --- /dev/null +++ b/libjava/classpath/gnu/java/nio/charset/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.nio.charset package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.nio.charset</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/nio/package.html b/libjava/classpath/gnu/java/nio/package.html new file mode 100644 index 0000000..87f0d9b --- /dev/null +++ b/libjava/classpath/gnu/java/nio/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.nio package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.nio</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java new file mode 100644 index 0000000..1400693 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java @@ -0,0 +1,71 @@ +/* gnu.java.rmi.RMIMarshalledObjectInputStream + Copyright (C) 2002 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.java.rmi; + +import gnu.java.rmi.server.RMIObjectInputStream; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + +/** + * This class is only for java.rmi.MarshalledObject to deserialize object from + * objBytes and locBytes + */ + +public class RMIMarshalledObjectInputStream extends RMIObjectInputStream +{ + private ObjectInputStream locStream; + + public RMIMarshalledObjectInputStream(byte[] objBytes, byte[] locBytes) throws IOException + { + super(new ByteArrayInputStream(objBytes)); + if(locBytes != null) + locStream = new ObjectInputStream(new ByteArrayInputStream(locBytes)); + } + + //This method overrides RMIObjectInputStream's + protected Object getAnnotation() throws IOException, ClassNotFoundException + { + if(locStream == null) + return null; + return locStream.readObject(); + } + +} // End of RMIMarshalledObjectInputStream diff --git a/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java new file mode 100644 index 0000000..2bbbaac --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java @@ -0,0 +1,79 @@ +/* gnu.java.rmi.RMIMarshalledObjectOutputStream + 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.java.rmi; + +import gnu.java.rmi.server.RMIObjectOutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +/** + * This class is only for java.rmi.MarshalledObject to serialize object and + * got objBytes and locBytes + */ +public class RMIMarshalledObjectOutputStream extends RMIObjectOutputStream +{ + private ObjectOutputStream locStream; + private ByteArrayOutputStream locBytesStream; + + public RMIMarshalledObjectOutputStream(OutputStream objStream) throws IOException + { + super(objStream); + locBytesStream = new ByteArrayOutputStream(256); + locStream = new ObjectOutputStream(locBytesStream); + } + + //This method overrides RMIObjectOutputStream's. + protected void setAnnotation(String annotation) throws IOException{ + locStream.writeObject(annotation); + } + + public void flush() throws IOException { + super.flush(); + locStream.flush(); + } + + public byte[] getLocBytes(){ + return locBytesStream.toByteArray(); + } + +} // End of RMIMarshalledObjectOutputStream + diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java new file mode 100644 index 0000000..a32445c --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java @@ -0,0 +1,118 @@ +/* DGCImpl.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002, 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.java.rmi.dgc; + +import gnu.java.rmi.server.UnicastServerRef; + +import java.rmi.RemoteException; +import java.rmi.dgc.DGC; +import java.rmi.dgc.Lease; +import java.rmi.dgc.VMID; +import java.rmi.server.ObjID; +import java.rmi.server.RMISocketFactory; +import java.util.Hashtable; + +/** + * I let DGCImpl to extend UnicastServerRef, but not + * UnicastRemoteObject, because UnicastRemoteObject must + * exportObject automatically. + */ +public class DGCImpl + extends UnicastServerRef implements DGC { + + private static final long LEASE_VALUE = 600000L; + // leaseCache caches a LeaseRecord associated with a vmid + private Hashtable leaseCache = new Hashtable(); + +public DGCImpl() throws RemoteException { + super(new ObjID(ObjID.DGC_ID), 0, RMISocketFactory.getSocketFactory()); +} + +public Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) throws RemoteException { + VMID vmid = lease.getVMID(); + if (vmid == null) + vmid = new VMID(); + long leaseValue = LEASE_VALUE; + //long leaseValue = lease.getValue(); + lease = new Lease(vmid, leaseValue); + synchronized(leaseCache){ + LeaseRecord lr = (LeaseRecord)leaseCache.get(vmid); + if (lr != null) + lr.reset(leaseValue); + else{ + lr = new LeaseRecord(vmid, leaseValue); + leaseCache.put(vmid, lr); + } + } + + return (lease); +} + +public void clean(ObjID[] ids, long sequenceNum, VMID vmid, boolean strong) throws RemoteException { + // Not implemented +} + + /** + * LeaseRecord associates a vmid to expireTime. + */ + private static class LeaseRecord{ + private VMID vmid; + private long expireTime; + + LeaseRecord(VMID vmid, long leaseValue){ + this.vmid = vmid; + reset(leaseValue); + } + + // reset expireTime + void reset(long leaseValue){ + long l = System.currentTimeMillis(); + expireTime = l + leaseValue; + } + + boolean isExpired(){ + long l = System.currentTimeMillis(); + if ( l > expireTime) + return true; + return false; + } + + } //End of LeaseRecord + +} //End of DGCImpl diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java new file mode 100644 index 0000000..5f032e7 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java @@ -0,0 +1,144 @@ +/* DGCImpl_Skel.java + Copyright (C) 2002 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. */ + + +// Skel class generated by rmic - DO NOT EDIT! + +package gnu.java.rmi.dgc; + +public final class DGCImpl_Skel + implements java.rmi.server.Skeleton +{ + private static final long interfaceHash = -669196253586618813L; + + private static final java.rmi.server.Operation[] operations = { + new java.rmi.server.Operation("void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean"), + new java.rmi.server.Operation("java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease") + }; + + public java.rmi.server.Operation[] getOperations() { + return ((java.rmi.server.Operation[]) operations.clone()); + } + + public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception { + if (opnum < 0) { + if (hash == -5803803475088455571L) { + opnum = 0; + } + else if (hash == -8139341527526761862L) { + opnum = 1; + } + else { + throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + } + } + else if (hash != interfaceHash) { + throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + } + + gnu.java.rmi.dgc.DGCImpl server = (gnu.java.rmi.dgc.DGCImpl)obj; + switch (opnum) { + case 0: + { + java.rmi.server.ObjID[] $param_0; + long $param_1; + java.rmi.dgc.VMID $param_2; + boolean $param_3; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.rmi.server.ObjID[])in.readObject(); + $param_1 = (long)in.readLong(); + $param_2 = (java.rmi.dgc.VMID)in.readObject(); + $param_3 = (boolean)in.readBoolean(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + server.clean($param_0, $param_1, $param_2, $param_3); + try { + java.io.ObjectOutput out = call.getResultStream(true); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + case 1: + { + java.rmi.server.ObjID[] $param_0; + long $param_1; + java.rmi.dgc.Lease $param_2; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.rmi.server.ObjID[])in.readObject(); + $param_1 = (long)in.readLong(); + $param_2 = (java.rmi.dgc.Lease)in.readObject(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + java.rmi.dgc.Lease $result = server.dirty($param_0, $param_1, $param_2); + try { + java.io.ObjectOutput out = call.getResultStream(true); + out.writeObject($result); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + default: + throw new java.rmi.UnmarshalException("invalid method number"); + } + } +} diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java new file mode 100644 index 0000000..b1e086a --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java @@ -0,0 +1,158 @@ +/* DGCImpl_Stub.java + Copyright (C) 2002 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. */ + + +// Stub class generated by rmic - DO NOT EDIT! + +package gnu.java.rmi.dgc; + +public final class DGCImpl_Stub + extends java.rmi.server.RemoteStub + implements java.rmi.dgc.DGC +{ + private static final long serialVersionUID = 2L; + + private static final long interfaceHash = -669196253586618813L; + + private static boolean useNewInvoke; + + private static final java.rmi.server.Operation[] operations = { + new java.rmi.server.Operation("void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)"), + new java.rmi.server.Operation("java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)") + }; + + private static java.lang.reflect.Method $method_clean_0; + private static java.lang.reflect.Method $method_dirty_1; + + static { + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class }); + useNewInvoke = true; + $method_clean_0 = gnu.java.rmi.dgc.DGCImpl.class.getMethod("clean", new java.lang.Class[] {java.rmi.server.ObjID[].class, long.class, java.rmi.dgc.VMID.class, boolean.class}); + $method_dirty_1 = gnu.java.rmi.dgc.DGCImpl.class.getMethod("dirty", new java.lang.Class[] {java.rmi.server.ObjID[].class, long.class, java.rmi.dgc.Lease.class}); + + } + catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } + } + + public DGCImpl_Stub() { + super(); + } + public DGCImpl_Stub(java.rmi.server.RemoteRef ref) { + super(ref); + } + + public void clean(java.rmi.server.ObjID[] $param_0, long $param_1, java.rmi.dgc.VMID $param_2, boolean $param_3) throws java.rmi.RemoteException { + try { + if (useNewInvoke) { + ref.invoke(this, $method_clean_0, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2, new java.lang.Boolean($param_3)}, -5803803475088455571L); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 0, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + out.writeLong($param_1); + out.writeObject($param_2); + out.writeBoolean($param_3); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + try { + java.io.ObjectInput in = call.getInputStream(); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + + public java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[] $param_0, long $param_1, java.rmi.dgc.Lease $param_2) throws java.rmi.RemoteException { + try { + if (useNewInvoke) { + java.lang.Object $result = ref.invoke(this, $method_dirty_1, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2}, -8139341527526761862L); + return ((java.rmi.dgc.Lease)$result); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 1, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + out.writeLong($param_1); + out.writeObject($param_2); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.rmi.dgc.Lease $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.dgc.Lease)in.readObject(); + return ($result); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + +} diff --git a/libjava/classpath/gnu/java/rmi/dgc/package.html b/libjava/classpath/gnu/java/rmi/dgc/package.html new file mode 100644 index 0000000..3ed81cf --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/dgc/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.rmi.dgc package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.rmi.dgc</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/rmi/package.html b/libjava/classpath/gnu/java/rmi/package.html new file mode 100644 index 0000000..53b5f5e --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.rmi package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.rmi</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java new file mode 100644 index 0000000..0c94434 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java @@ -0,0 +1,154 @@ +/* RegistryImpl.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002, 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.java.rmi.registry; + +import gnu.java.rmi.server.UnicastServerRef; + +import java.rmi.AccessException; +import java.rmi.AlreadyBoundException; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.ObjID; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RMISocketFactory; +import java.rmi.server.UnicastRemoteObject; +import java.util.Enumeration; +import java.util.Hashtable; + +public class RegistryImpl + extends UnicastRemoteObject implements Registry { + +private Hashtable bindings = new Hashtable(); + +public RegistryImpl(int port) throws RemoteException { + this(port, RMISocketFactory.getSocketFactory(), RMISocketFactory.getSocketFactory()); +} + +public RegistryImpl(int port, RMIClientSocketFactory cf, RMIServerSocketFactory sf) throws RemoteException { + super(new UnicastServerRef(new ObjID(ObjID.REGISTRY_ID), port, sf)); + // The following is unnecessary, because UnicastRemoteObject export itself automatically. + //((UnicastServerRef)getRef()).exportObject(this); +} + +public Remote lookup(String name) throws RemoteException, NotBoundException, AccessException { + Object obj = bindings.get(name); + if (obj == null) { + throw new NotBoundException(name); + } + return ((Remote)obj); +} + +public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException, AccessException { + if (bindings.containsKey(name)) { + throw new AlreadyBoundException(name); + } + bindings.put(name, obj); +} + +public void unbind(String name) throws RemoteException, NotBoundException, AccessException { + Object obj = bindings.remove(name); + if (obj == null) { + throw new NotBoundException(name); + } +} + +public void rebind(String name, Remote obj) throws RemoteException, AccessException { + bindings.put(name, obj); +} + +public String[] list() throws RemoteException, AccessException { + int size = bindings.size(); + String[] strings = new String[size]; + Enumeration e = bindings.keys(); + for (int i = 0; i < size; i++) { + strings[i] = (String)e.nextElement(); + } + return (strings); +} + +public static void version() { + System.out.println("rmiregistry (" + + System.getProperty("java.vm.name") + + ") " + + System.getProperty("java.vm.version")); + System.out.println("Copyright 2005 Free Software Foundation, Inc."); + System.out.println("This is free software; see the source for copying conditions. There is NO"); + System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); + System.exit(0); +} + +public static void help() { + System.out.println( +"Usage: rmiregistry [OPTION | PORT]\n" + +"\n" + +" --help Print this help, then exit\n" + +" --version Print version number, then exit\n"); + System.exit(0); +} + +public static void main(String[] args) { + int port = Registry.REGISTRY_PORT; + if (args.length > 0) { + if (args[0].equals("--version")) { + version(); + } + else if (args[0].equals("--help")) { + help(); + } + try { + port = Integer.parseInt(args[0]); + } + catch (NumberFormatException _) { + System.err.println("Bad port number - using default"); + } + } + + try { + Registry impl = LocateRegistry.createRegistry(port); + } + catch (RemoteException _) { + System.err.println("Registry failed"); + } +} + +} diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java new file mode 100644 index 0000000..8cf14cc --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java @@ -0,0 +1,227 @@ +/* RegistryImpl_Skel.java + Copyright (C) 2002 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. */ + + +// Skel class generated by rmic - DO NOT EDIT! + +package gnu.java.rmi.registry; + +public final class RegistryImpl_Skel + implements java.rmi.server.Skeleton +{ + private static final long interfaceHash = 4905912898345647071L; + + private static final java.rmi.server.Operation[] operations = { + new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote"), + new java.rmi.server.Operation("java.lang.String[] list("), + new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String"), + new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote"), + new java.rmi.server.Operation("void unbind(java.lang.String") + }; + + public java.rmi.server.Operation[] getOperations() { + return ((java.rmi.server.Operation[]) operations.clone()); + } + + public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception { + if (opnum < 0) { + if (hash == 7583982177005850366L) { + opnum = 0; + } + else if (hash == 2571371476350237748L) { + opnum = 1; + } + else if (hash == -7538657168040752697L) { + opnum = 2; + } + else if (hash == -8381844669958460146L) { + opnum = 3; + } + else if (hash == 7305022919901907578L) { + opnum = 4; + } + else { + throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + } + } + else if (hash != interfaceHash) { + throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + } + + gnu.java.rmi.registry.RegistryImpl server = (gnu.java.rmi.registry.RegistryImpl)obj; + switch (opnum) { + case 0: + { + java.lang.String $param_0; + java.rmi.Remote $param_1; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.lang.String)in.readObject(); + $param_1 = (java.rmi.Remote)in.readObject(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + server.bind($param_0, $param_1); + try { + java.io.ObjectOutput out = call.getResultStream(true); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + case 1: + { + try { + java.io.ObjectInput in = call.getInputStream(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + java.lang.String[] $result = server.list(); + try { + java.io.ObjectOutput out = call.getResultStream(true); + out.writeObject($result); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + case 2: + { + java.lang.String $param_0; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.lang.String)in.readObject(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + java.rmi.Remote $result = server.lookup($param_0); + try { + java.io.ObjectOutput out = call.getResultStream(true); + out.writeObject($result); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + case 3: + { + java.lang.String $param_0; + java.rmi.Remote $param_1; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.lang.String)in.readObject(); + $param_1 = (java.rmi.Remote)in.readObject(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + server.rebind($param_0, $param_1); + try { + java.io.ObjectOutput out = call.getResultStream(true); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + case 4: + { + java.lang.String $param_0; + try { + java.io.ObjectInput in = call.getInputStream(); + $param_0 = (java.lang.String)in.readObject(); + + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + catch (java.lang.ClassCastException e) { + throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); + } + finally { + call.releaseInputStream(); + } + server.unbind($param_0); + try { + java.io.ObjectOutput out = call.getResultStream(true); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling return", e); + } + break; + } + + default: + throw new java.rmi.UnmarshalException("invalid method number"); + } + } +} diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java new file mode 100644 index 0000000..b289426 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java @@ -0,0 +1,293 @@ +/* RegistryImpl_Stub.java + Copyright (C) 2002 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. */ + + +// Stub class generated by rmic - DO NOT EDIT! + +package gnu.java.rmi.registry; + +public final class RegistryImpl_Stub + extends java.rmi.server.RemoteStub + implements java.rmi.registry.Registry +{ + private static final long serialVersionUID = 2L; + + private static final long interfaceHash = 4905912898345647071L; + + private static boolean useNewInvoke; + + private static final java.rmi.server.Operation[] operations = { + new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"), + new java.rmi.server.Operation("java.lang.String[] list()"), + new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"), + new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"), + new java.rmi.server.Operation("void unbind(java.lang.String)") + }; + + private static java.lang.reflect.Method $method_bind_0; + private static java.lang.reflect.Method $method_list_1; + private static java.lang.reflect.Method $method_lookup_2; + private static java.lang.reflect.Method $method_rebind_3; + private static java.lang.reflect.Method $method_unbind_4; + + static { + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class }); + useNewInvoke = false; + $method_bind_0 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("bind", new java.lang.Class[] {java.lang.String.class, java.rmi.Remote.class}); + $method_list_1 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("list", new java.lang.Class[] {}); + $method_lookup_2 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("lookup", new java.lang.Class[] {java.lang.String.class}); + $method_rebind_3 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("rebind", new java.lang.Class[] {java.lang.String.class, java.rmi.Remote.class}); + $method_unbind_4 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("unbind", new java.lang.Class[] {java.lang.String.class}); + + } + catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } + } + + public RegistryImpl_Stub() { + super(); + } + public RegistryImpl_Stub(java.rmi.server.RemoteRef ref) { + super(ref); + } + + public void bind(java.lang.String $param_0, java.rmi.Remote $param_1) throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException { + try { + if (useNewInvoke) { + ref.invoke(this, $method_bind_0, new java.lang.Object[] {$param_0, $param_1}, 7583982177005850366L); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 0, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + out.writeObject($param_1); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + try { + java.io.ObjectInput in = call.getInputStream(); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.AccessException e) { + throw e; + } + catch (java.rmi.AlreadyBoundException e) { + throw e; + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + + public java.lang.String[] list() throws java.rmi.AccessException, java.rmi.RemoteException { + try { + if (useNewInvoke) { + java.lang.Object $result = ref.invoke(this, $method_list_1, null, 2571371476350237748L); + return ((java.lang.String[])$result); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 1, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.lang.String[] $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String[])in.readObject(); + return ($result); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.AccessException e) { + throw e; + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + + public java.rmi.Remote lookup(java.lang.String $param_0) throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException { + try { + if (useNewInvoke) { + java.lang.Object $result = ref.invoke(this, $method_lookup_2, new java.lang.Object[] {$param_0}, -7538657168040752697L); + return ((java.rmi.Remote)$result); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 2, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.rmi.Remote $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.Remote)in.readObject(); + return ($result); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.AccessException e) { + throw e; + } + catch (java.rmi.NotBoundException e) { + throw e; + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + + public void rebind(java.lang.String $param_0, java.rmi.Remote $param_1) throws java.rmi.AccessException, java.rmi.RemoteException { + try { + if (useNewInvoke) { + ref.invoke(this, $method_rebind_3, new java.lang.Object[] {$param_0, $param_1}, -8381844669958460146L); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 3, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + out.writeObject($param_1); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + try { + java.io.ObjectInput in = call.getInputStream(); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.AccessException e) { + throw e; + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + + public void unbind(java.lang.String $param_0) throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException { + try { + if (useNewInvoke) { + ref.invoke(this, $method_unbind_4, new java.lang.Object[] {$param_0}, 7305022919901907578L); + } + else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 4, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_0); + } + catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + try { + java.io.ObjectInput in = call.getInputStream(); + } + catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } + finally { + ref.done(call); + } + } + } + catch (java.rmi.AccessException e) { + throw e; + } + catch (java.rmi.NotBoundException e) { + throw e; + } + catch (java.rmi.RemoteException e) { + throw e; + } + catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } + } + +} diff --git a/libjava/classpath/gnu/java/rmi/registry/package.html b/libjava/classpath/gnu/java/rmi/registry/package.html new file mode 100644 index 0000000..3750359 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/registry/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.rmi.registry package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.rmi.registry</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java b/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java new file mode 100644 index 0000000..9cc57b2 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java @@ -0,0 +1,156 @@ +/* gnu.java.rmi.server.ConnectionRunnerPool + Copyright (C) 2002, 2004, 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.java.rmi.server; + +import java.util.ArrayList; +import java.util.Arrays; + +//Should I generalize this class? + +class ConnectionRunnerPool +{ + + public static + class ConnectionRunner extends Thread{ + private UnicastConnection conn; + private volatile boolean exiting = false; + + public ConnectionRunner(ThreadGroup group, String id){ + super(group, id); + } + + public synchronized void run(){ + while(!exiting){ + if(conn == null) + try{ + wait(); + }catch(InterruptedException e){ + continue; + } + else{ + conn.run(); + conn = null; + synchronized(ConnectionRunnerPool.class){ + freelist.add(this); + if(freelist.size() == 1) + ConnectionRunnerPool.class.notifyAll(); + } + } + } + } + + public synchronized void dispatch(UnicastConnection conn){ + this.conn = conn; + notify(); + } + + void exit(){ + exiting = true; + if(conn != null) + try{ + join(500); + }catch(InterruptedException e){} + interrupt(); + } + + } + + // Should this value equal to number of CPU? + private static int size = 5; + private static int max_size = 10; + + // Package-private to avoid a trampoline. + static ArrayList freelist; + + private static ThreadGroup group = new ThreadGroup("pool"); + + static { + ConnectionRunner[] pools = new ConnectionRunner[size]; + for(int i = 0; i < pools.length; i++){ + pools[i] = new ConnectionRunner(group, new Integer(i).toString()); + pools[i].setContextClassLoader(Thread.currentThread().getContextClassLoader()); + pools[i].start(); + } + freelist = new ArrayList(Arrays.asList(pools)); + } + + public static void setSize(int size_){ + size = size_; + } + + public static void setMaxSize(int size){ + max_size = size; + } + + private static synchronized ConnectionRunner getConnectionRunner() + { + if(freelist.size() == 0){ + if(size < max_size){ + ++size; + ConnectionRunner a = new ConnectionRunner(group, new Integer(size).toString()); + a.start(); + freelist.add(a); + }else + while(freelist.size() == 0) + try{ + ConnectionRunnerPool.class.wait(); + }catch(InterruptedException e){} + } + + // always let the first in pool most busy or other scheduling plan?? + ConnectionRunner a = (ConnectionRunner)freelist.get(0); + freelist.remove(a); + return a; + } + + public static void dispatchConnection(UnicastConnection conn) + { + ConnectionRunner r = getConnectionRunner(); + r.dispatch(conn); + } + + public static void exit() + { + Thread[] list = new Thread[group.activeCount()]; + group.enumerate(list); + for(int i = 0; i < list.length; i++) + ((ConnectionRunner)list[i]).exit(); + } + +} diff --git a/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java b/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java new file mode 100644 index 0000000..30fb5e8 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java @@ -0,0 +1,62 @@ +/* ProtocolConstants.java -- + Copyright (c) 1996, 1997, 1998, 1999 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.java.rmi.server; + +public interface ProtocolConstants +{ + int PROTOCOL_HEADER = 0x4a524d49; // JRMI + int PROTOCOL_VERSION = 2; + + int STREAM_PROTOCOL = 0x4b; + int SINGLE_OP_PROTOCOL = 0x4c; + int MULTIPLEX_PROTOCOL = 0x4d; + + int PROTOCOL_ACK = 0x4e; + int PROTOCOL_NACK = 0x4f; + + int MESSAGE_CALL = 0x50; + int MESSAGE_CALL_ACK = 0x51; + int MESSAGE_PING = 0x52; + int MESSAGE_PING_ACK = 0x53; + int MESSAGE_DGCACK = 0x54; + + int RETURN_ACK = 0x01; + int RETURN_NACK = 0x02; + + int DEFAULT_PROTOCOL = STREAM_PROTOCOL; +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java b/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java new file mode 100644 index 0000000..628e1cc --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java @@ -0,0 +1,59 @@ +/* RMIDefaultSocketFactory.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.rmi.server.RMISocketFactory; + +public class RMIDefaultSocketFactory + extends RMISocketFactory { + +public RMIDefaultSocketFactory() { +} + +public Socket createSocket(String host, int port) throws IOException { + return (new Socket(host, port)); +} + +public ServerSocket createServerSocket(int port) throws IOException { + return (new ServerSocket(port)); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIHashes.java b/libjava/classpath/gnu/java/rmi/server/RMIHashes.java new file mode 100644 index 0000000..5a41440 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIHashes.java @@ -0,0 +1,98 @@ +/* RMIHashes.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import gnu.java.lang.reflect.TypeSignature; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Method; +import java.security.MessageDigest; + +public class RMIHashes +{ + //There're other places using DigestOutputStream to generate hash in classpath, but I think the way I used + //here is more efficient, anyway, you can switch to DigestOutputStream by doing like "//or:" comments say. + + //or:add this statement: private static final NullOutputStream nullOutputStream = new NullOutputStream (); + public static long getMethodHash(Method meth) + { + //Object Serialization Spec 8.3 + try + { + MessageDigest md = MessageDigest.getInstance ("SHA"); + //or:remove this statement: DigestOutputStream digest_out = new DigestOutputStream (nullOutputStream, md); + ByteArrayOutputStream digest_out = new ByteArrayOutputStream(); + DataOutputStream data_out = new DataOutputStream (digest_out); + + StringBuffer sbuf = new StringBuffer(); + sbuf.append(meth.getName()); + sbuf.append('('); + Class params[] = meth.getParameterTypes(); + for(int i = 0; i < params.length; i++) + sbuf.append(TypeSignature.getEncodingOfClass(params[i])); + sbuf.append(')'); + Class rcls = meth.getReturnType(); + if(rcls != Void.TYPE) + sbuf.append(TypeSignature.getEncodingOfClass(rcls)); + else + sbuf.append('V'); + + data_out.writeUTF (sbuf.toString()); + data_out.flush(); + data_out.close (); + + md.update(digest_out.toByteArray()); //or:remove this statement + byte[] sha = md.digest (); + long result = 0; + int len = sha.length < 8 ? sha.length : 8; + for (int i=0; i < len; i++) + result += (long)(sha[i] & 0xFF) << (8 * i); + return result; + }catch(Exception _){ + return -1L; + } + } + + public static long getInterfaceHash(Class clazz) + { + return clazz.hashCode (); + } +} + diff --git a/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java b/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java new file mode 100644 index 0000000..990d37b --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java @@ -0,0 +1,58 @@ +/* RMIIncomingThread.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002 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.java.rmi.server; + +public class RMIIncomingThread extends Thread { + + private String clientHost = null; + + public RMIIncomingThread(Runnable runnable, String s_clientHost) { + super(runnable); + clientHost = s_clientHost; + } + + public String toString() { + return "RMIIncoming from " + clientHost + " " + super.toString(); + } + + public String getClientHost() { + return clientHost; + } + + +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java new file mode 100644 index 0000000..888b30b --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java @@ -0,0 +1,126 @@ +/* RMIObjectInputStream.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.lang.reflect.Proxy; +import java.net.MalformedURLException; +import java.rmi.server.RMIClassLoader; + +public class RMIObjectInputStream + extends ObjectInputStream { + +public RMIObjectInputStream(InputStream strm) throws IOException { + super(strm); + enableResolveObject(true); +} + +protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { + String annotation = (String)getAnnotation(); + + try { + if(annotation == null) + return (RMIClassLoader.loadClass(desc.getName())); + else + return (RMIClassLoader.loadClass(annotation, desc.getName())); + } + catch (MalformedURLException _) { + throw new ClassNotFoundException(desc.getName()); + } +} + +//Separate it for override by MarshalledObject +protected Object getAnnotation() + throws IOException, ClassNotFoundException +{ + return readObject(); +} + +protected Class resolveProxyClass(String intfs[]) + throws IOException, ClassNotFoundException +{ + String annotation = (String)getAnnotation(); + + Class clss[] = new Class[intfs.length]; + if(annotation == null) + clss[0] = RMIClassLoader.loadClass(intfs[0]); + else + clss[0] = RMIClassLoader.loadClass(annotation, intfs[0]); + + //assume all interfaces can be loaded by the same classloader + ClassLoader loader = clss[0].getClassLoader(); + for (int i = 0; i < intfs.length; i++) + clss[i] = Class.forName(intfs[i], false, loader); + + try { + return Proxy.getProxyClass(loader, clss); + } catch (IllegalArgumentException e) { + throw new ClassNotFoundException(null, e); + } +} + +protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException { + if(valueClass.isPrimitive()){ + if(valueClass == Boolean.TYPE) + return new Boolean(readBoolean()); + if(valueClass == Byte.TYPE) + return new Byte(readByte()); + if(valueClass == Character.TYPE) + return new Character(readChar()); + if(valueClass == Short.TYPE) + return new Short(readShort()); + if(valueClass == Integer.TYPE) + return new Integer(readInt()); + if(valueClass == Long.TYPE) + return new Long(readLong()); + if(valueClass == Float.TYPE) + return new Float(readFloat()); + if(valueClass == Double.TYPE) + return new Double(readDouble()); + else + throw new Error("Unsupported primitive class: " + valueClass); + } else + return readObject(); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java b/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java new file mode 100644 index 0000000..d42908a --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java @@ -0,0 +1,114 @@ +/* RMIObjectOutputStream.java - + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.rmi.Remote; +import java.rmi.server.RMIClassLoader; +import java.rmi.server.RemoteStub; + +public class RMIObjectOutputStream + extends ObjectOutputStream { + +public RMIObjectOutputStream(OutputStream strm) throws IOException { + super(strm); + enableReplaceObject(true); +} + +//Separate it for override by MarshalledObject +protected void setAnnotation(String annotation) throws IOException{ + writeObject(annotation); +} + +protected void annotateClass(Class cls) throws IOException { + setAnnotation(RMIClassLoader.getClassAnnotation(cls)); +} + +protected void annotateProxyClass(Class cls) + throws IOException +{ + annotateClass(cls); +} + +protected Object replaceObject(Object obj) + throws IOException +{ + if((obj instanceof Remote) && !(obj instanceof RemoteStub)){ + UnicastServerRef ref = UnicastServer.getExportedRef((Remote)obj); + if (ref != null) + return ref.getStub(); + } + return obj; +} + +protected void writeValue(Object value, Class valueClass) throws IOException{ + if(valueClass.isPrimitive()){ + if(valueClass == Boolean.TYPE) + writeBoolean(((Boolean)value).booleanValue()); + else + if(valueClass == Byte.TYPE) + writeByte(((Byte)value).byteValue()); + else + if(valueClass == Character.TYPE) + writeChar(((Character)value).charValue()); + else + if(valueClass == Short.TYPE) + writeShort(((Short)value).shortValue()); + else + if(valueClass == Integer.TYPE) + writeInt(((Integer)value).intValue()); + else + if(valueClass == Long.TYPE) + writeLong(((Long)value).longValue()); + else + if(valueClass == Float.TYPE) + writeFloat(((Float)value).floatValue()); + else + if(valueClass == Double.TYPE) + writeDouble(((Double)value).doubleValue()); + else + throw new Error("Unsupported primitive class: " + valueClass); + } else + writeObject(value); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java b/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java new file mode 100644 index 0000000..8e5546d --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java @@ -0,0 +1,51 @@ +/* RMIVoidValue.java -- + Copyright (c) 2003 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.java.rmi.server; + +/** + * Package private class used to indicate a void return type. + * INSTANCE is the only object of this class ever made. + */ +final class RMIVoidValue +{ + static RMIVoidValue INSTANCE = new RMIVoidValue(); + + private RMIVoidValue() + { + } +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java b/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java new file mode 100644 index 0000000..216e453 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java @@ -0,0 +1,231 @@ +/* UnicastConnection.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.rmi.RemoteException; + +public class UnicastConnection + implements Runnable, ProtocolConstants { + +UnicastConnectionManager manager; +Socket sock; +DataInputStream din; +DataOutputStream dout; +ObjectInputStream oin; +ObjectOutputStream oout; + +// reviveTime and expireTime make UnicastConnection pool-able +long reviveTime = 0; +long expireTime = Long.MAX_VALUE; + +UnicastConnection(UnicastConnectionManager man, Socket sock) { + this.manager = man; + this.sock = sock; +} + +void acceptConnection() throws IOException { +//System.out.println("Accepting connection on " + sock); + //Use BufferedXXXStream would be more efficient + din = new DataInputStream(new BufferedInputStream(sock.getInputStream())); + dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); + + int sig = din.readInt(); + if (sig != PROTOCOL_HEADER) { + throw new IOException("bad protocol header"); + } + short ver = din.readShort(); + if (ver != PROTOCOL_VERSION) { + throw new IOException("bad protocol version"); + } + int protocol = din.readUnsignedByte(); + if (protocol != SINGLE_OP_PROTOCOL) { + // Send an ACK + dout.writeByte(PROTOCOL_ACK); + + // Send my hostname and port + dout.writeUTF(manager.serverName); + dout.writeInt(manager.serverPort); + dout.flush(); + + // Read their hostname and port + String rhost = din.readUTF(); + int rport = din.readInt(); + } + // Okay, ready to roll ... +} + +void makeConnection(int protocol) throws IOException { + //Use BufferedXXXStream would be more efficient + din = new DataInputStream(new BufferedInputStream(sock.getInputStream())); + + dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); + + // Send header + dout.writeInt(PROTOCOL_HEADER); + dout.writeShort(PROTOCOL_VERSION); + dout.writeByte(protocol); + dout.flush(); + + if (protocol != SINGLE_OP_PROTOCOL) { + // Get back ack. + int ack = din.readUnsignedByte(); + if (ack != PROTOCOL_ACK) { + throw new RemoteException("Unsupported protocol"); + } + + // Read in host and port + String dicard_rhost = din.readUTF(); + int discard_rport = din.readInt(); + + // Send them my endpoint + dout.writeUTF(manager.serverName); + dout.writeInt(manager.serverPort); + dout.flush(); + } + // Okay, ready to roll ... +} + +DataInputStream getDataInputStream() throws IOException { + return (din); +} + +DataOutputStream getDataOutputStream() throws IOException { + return (dout); +} + +/* +* +* get ObjectInputStream for reading more objects +* +*/ +ObjectInputStream getObjectInputStream() throws IOException { + if (oin == null) { + throw new IOException("no ObjectInputtream for reading more objects"); + } + return (oin); +} + +/** +* +* starts ObjectInputStream. +* +*/ +ObjectInputStream startObjectInputStream() throws IOException { + return (oin = new RMIObjectInputStream(din)); +} + +/** +* +* get ObjectOutputStream for sending more objects +* +*/ +ObjectOutputStream getObjectOutputStream() throws IOException { + if (oout == null) { + throw new IOException("no ObjectOutputStream for sending more objects"); + } + return (oout); +} + +/** +* +* starts ObjectOutputStream. +* +*/ +ObjectOutputStream startObjectOutputStream() throws IOException { + return (oout = new RMIObjectOutputStream(dout)); +} + +void disconnect() { + try { + if(oout != null) + oout.close(); + sock.close(); + } + catch (IOException _) { + } + + oin = null; + oout = null; + din = null; + dout = null; + sock = null; +} + +public static final long CONNECTION_TIMEOUT = 10000L; + +static boolean isExpired(UnicastConnection conn, long l){ + if (l <= conn.expireTime ) + return false; + return true; +} + +static void resetTime(UnicastConnection conn){ + long l = System.currentTimeMillis(); + conn.reviveTime = l; + conn.expireTime = l + CONNECTION_TIMEOUT; +} + +/** + * We run connects on the server. Dispatch it then discard it. + */ +public void run() { + do{ + try { + UnicastServer.dispatch(this); + //don't discardConnection explicitly, only when + // exception happens or the connection's expireTime + // comes + } catch (Exception e ){ + manager.discardConnection(this); + break; + } + }while(true); +} + + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java b/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java new file mode 100644 index 0000000..08f6a9b --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java @@ -0,0 +1,446 @@ +/* UnicastConnectionManager.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.rmi.RemoteException; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RMISocketFactory; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.Hashtable; +import java.util.Iterator; + +public class UnicastConnectionManager + implements Runnable, ProtocolConstants { + +private static String localhost; +// use different maps for server/client type UnicastConnectionManager +private static Hashtable servers = new Hashtable(); +// Package-private to avoid trampolines. +static Hashtable clients = new Hashtable(); +ArrayList connections; //client connection pool + +// make serverThread volatile for poll +private volatile Thread serverThread; +private ServerSocket ssock; +String serverName; +int serverPort; + +// Package-private to avoid a trampoline. +static Thread scavenger; + +// If client and server are in the same VM, serverobj represents server +Object serverobj; + +private static RMISocketFactory defaultSocketFactory = RMISocketFactory.getSocketFactory(); +private RMIServerSocketFactory serverFactory; +private RMIClientSocketFactory clientFactory; + +// The following is for debug +private static int ncsock = 0; //count of client socket +private static int nssock = 0; //count of server socket +private static int ncmanager = 0; //count of client manager +private static int nsmanager = 0; //count of server manager + +private static final boolean debug = false; + +private static final Object GLOBAL_LOCK = new Object(); + +static { + try { + //Use host address instead of host name to avoid name resolving issues + //localhost = InetAddress.getLocalHost().getHostName(); + localhost = InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException _) { + localhost = "localhost"; + } + + +} + +//Only one scavenger thread running globally +private static void startScavenger(){ + scavenger = new Thread(new Runnable(){ + public void run(){ + if (debug) System.out.println("************* start scavenger."); + boolean liveon = true; + while (liveon){ + // Sleep for the expire timeout + try{ + Thread.sleep(UnicastConnection.CONNECTION_TIMEOUT); + }catch(InterruptedException _ie){ + break; + } + liveon = false; + // Scavenge all clients' connections that're expired + Iterator iter = clients.values().iterator(); + long l = System.currentTimeMillis(); + try{ + while(iter.hasNext()){ + UnicastConnectionManager man = (UnicastConnectionManager)iter.next(); + ArrayList conns = man.connections; + synchronized(conns) { // is the lock a little coarser? + for (int last = conns.size() - 1; + last >= 0; + --last) + { + UnicastConnection conn = (UnicastConnection)conns.get(last); + if (UnicastConnection.isExpired(conn, l)){ + conns.remove(last); + conn.disconnect(); + conn = null; + }else + liveon = true; //there're still live connections + } + } + } + }catch(ConcurrentModificationException cme) { + // handle it lazily + liveon = true; + } + } + scavenger = null; + if (debug) System.out.println("************* exit scavenger."); + } + }); + // As it is used for client connection, we may put this thread + // in daemon state to prevent the VM from blocking when exiting. + scavenger.setDaemon(true); + scavenger.start(); +} + +/** + * Client UnicastConnectionManager constructor + */ +private UnicastConnectionManager(String host, int port, RMIClientSocketFactory csf) { + ssock = null; + serverName = host; + serverPort = port; + serverFactory = null; + clientFactory = csf; + connections = new ArrayList(); +} + +/** + * Server UnicastConnectionManager constructor + */ +private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) throws RemoteException { + + try { + ssock = ssf.createServerSocket(port); + serverPort = ssock.getLocalPort(); + } + catch (IOException ioex) { + ssock = null; + serverPort = 0; + throw new java.rmi.server.ExportException("can not create Server Socket on port " + port,ioex); + } + serverName = localhost; + serverFactory = ssf; + clientFactory = null; +} + +/** + * Return a client connection manager which will connect to the given + * host/port. + */ +public static synchronized UnicastConnectionManager getInstance(String host, int port, RMIClientSocketFactory csf) { +//System.out.println("getInstance: " + host + "," + port + "," + csf); + if (csf == null) { + csf = defaultSocketFactory; + } + // change host name to host address to avoid name resolving issues + try{ + host = InetAddress.getByName(host).getHostAddress(); + }catch(Exception _){} + + TripleKey key = new TripleKey(host, port, csf); + UnicastConnectionManager man = (UnicastConnectionManager)clients.get(key); + if (man == null) { + man = new UnicastConnectionManager(host, port, csf); + if (debug) { + ncmanager++; + System.out.println("\n\n ====== " + ncmanager + " client managers.\n\n"); + } + clients.put(key, man); + + // Detect if client and server are in the same VM, i.e., their keys are equal + UnicastConnectionManager svrman = (UnicastConnectionManager)servers.get(key); + if(svrman != null){ // server and client are in the same VM + man.serverobj = svrman.serverobj; + } + } + return (man); +} + +/** + * Return a server connection manager which will accept connection on the + * given port. + */ +public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) throws RemoteException { +//System.out.println("getInstance: " + port + "," + ssf); + if (ssf == null) { + ssf = defaultSocketFactory; + } + TripleKey key = new TripleKey(localhost, port, ssf); + UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key); + if (man == null) { + man = new UnicastConnectionManager(port, ssf); + if (debug) { + nsmanager++; + System.out.println("\n\n ****** " + nsmanager + " server managers.\n\n"); + } + // The provided port might not be the set port. + key.port = man.serverPort; + servers.put(key, man); + } + return (man); +} + +/** + * Get a connection from this manager. + */ +public UnicastConnection getConnection() throws IOException { + if (ssock == null) { + return (getClientConnection()); + } + else { + return (getServerConnection()); + } +} + +/** + * Accept a connection to this server. + */ +private UnicastConnection getServerConnection() throws IOException { + Socket sock = ssock.accept(); + sock.setTcpNoDelay(true); //?? + UnicastConnection conn = new UnicastConnection(this, sock); + conn.acceptConnection(); + if (debug){ + nssock++; + System.out.println("\n\n ****** " + nssock + " server socks.\n\n"); + } + //System.out.println("Server connection " + sock); + return (conn); +} + +/** + * Make a conection from this client to the server. + */ +private UnicastConnection getClientConnection() throws IOException { + ArrayList conns = connections; + UnicastConnection conn; + + synchronized(conns) { + int nconn = conns.size() - 1; + + // if there're free connections in connection pool + if(nconn >= 0) { + conn = (UnicastConnection)conns.get(nconn); + //Should we check if conn is alive using Ping?? + conns.remove(nconn); + + // Check if the connection is already expired + long l = System.currentTimeMillis(); + if (!UnicastConnection.isExpired(conn, l)){ + return conn; + }else { + conn.disconnect(); + conn = null; + } + } + } + + Socket sock = clientFactory.createSocket(serverName, serverPort); + conn = new UnicastConnection(this, sock); + conn.makeConnection(DEFAULT_PROTOCOL); + + if (debug) { + ncsock++; + System.out.println("\n\n ====== " + ncsock + " client socks.\n\n"); + } + + return (conn); +} + +/** + * Discard a connection when we're done with it - maybe it can be + * recycled. + */ +public void discardConnection(UnicastConnection conn) { +//System.out.println("Discarding connection " + conn); + //conn.disconnect(); + if (ssock != null) //server connection + conn.disconnect(); + else { + // To client connection, we'd like to return back to pool + UnicastConnection.resetTime(conn); + //Ensure there're only one scavenger globally + synchronized(GLOBAL_LOCK) { + connections.add(conn); //borrow this lock to garantee thread safety + if (scavenger == null) + startScavenger(); + } + } +} + +/** + * Start a server on this manager if it's a server socket and we've not + * already got one running. + */ +public void startServer() { + synchronized(this) { + if (ssock == null || serverThread != null) { + return; + } + serverThread = new Thread(this); + // The following is not necessary when java.lang.Thread's constructor do this. + // serverThread.setContextClassLoader(Thread.currentThread().getContextClassLoader()); + } + serverThread.start(); +} + +/** + * Stop a server on this manager + */ +public void stopServer() { + synchronized(this) { + if(serverThread != null){ + serverThread = null; + try{ + ssock.close(); + }catch(Exception _){} + } + } +} + +/** + * Server thread for connection manager. + */ +public void run() { + for (;serverThread != null;) { // if serverThread==null, then exit thread + try { +//System.out.println("Waiting for connection on " + serverPort); + UnicastConnection conn = getServerConnection(); + + // get address of remote host for the RMIIncomingThread object + String remoteHost = null; + if (conn.sock != null) { + remoteHost = conn.sock.getInetAddress().getHostAddress(); + } + + // use a thread pool to improve performance + //ConnectionRunnerPool.dispatchConnection(conn); + (new RMIIncomingThread(conn, remoteHost)).start(); +// (new Thread(conn)).start(); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + +/** + * Serialization routine. + */ +void write(ObjectOutput out) throws IOException { + out.writeUTF(serverName); + out.writeInt(serverPort); +} + +/** + * Serialization routine. + */ +static UnicastConnectionManager read(ObjectInput in) throws IOException { + String host = in.readUTF(); + int port = in.readInt(); + //RMIClientSocketFactory csf = ((RMIObjectInputStream)in).manager.clientFactory; + //return (getInstance(host, port, csf)); + return (getInstance(host, port, null)); +} + +} + +/** + * This is use as the hashkey for the client/server connections. + */ +class TripleKey { + +String host; +int port; +Object other; + +TripleKey(String host, int port, Object other) { + this.host = host; + this.port = port; + this.other = other; +} + +/** + * Hash code just include the host and other - we ignore the port since + * this has unusual matching behaviour. + */ +public int hashCode() { + return (host.hashCode() ^ other.hashCode()); +} + +public boolean equals(Object obj) { + if (obj instanceof TripleKey) { + TripleKey other = (TripleKey)obj; + if (this.host.equals(other.host) && + this.other == other.other && + (this.port == other.port /* || this.port == 0 || other.port == 0*/)) { + return (true); + } + } + return (false); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRef.java b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java new file mode 100644 index 0000000..c1b871f --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java @@ -0,0 +1,278 @@ +/* UnicastRef.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002, 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.java.rmi.server; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.server.ObjID; +import java.rmi.server.Operation; +import java.rmi.server.RMIClientSocketFactory; +import java.rmi.server.RemoteCall; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.rmi.server.UID; + +public class UnicastRef + implements RemoteRef, ProtocolConstants { + +public ObjID objid; +UnicastConnectionManager manager; + +/** + * Used by serialization, and let subclass capable of having default constructor + */ +// must be public otherwise java.rmi.RemoteObject cannot instantiate this class +// -- iP +public UnicastRef() { +} + +public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) { + this(objid); + manager = UnicastConnectionManager.getInstance(host, port, csf); +} + +public UnicastRef(ObjID objid) { + this.objid = objid; +} + +public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception { + // Check if client and server are in the same VM, then local call can be used to + // replace remote call, but it's somewhat violating remote semantic. + Object svrobj = manager.serverobj; + + // Make sure that the server object is compatible. It could be loaded from a different + // classloader --iP + if(svrobj != null && method.getDeclaringClass().isInstance(svrobj)){ + //local call + Object ret = null; + try{ + ret = method.invoke(svrobj, params); + }catch(InvocationTargetException e){ + throw (Exception)e.getTargetException(); + } + //System.out.println("\n\n ***** local call: " + method + "\nreturn: " + ret + "\n\n"); + return ret; + } + //System.out.println("***************** remote call:" + manager.serverPort); + return (invokeCommon(obj, method, params, -1, opnum)); +} + +private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception { + UnicastConnection conn; + try { + conn = manager.getConnection(); + } + catch (IOException e1) { + throw new RemoteException("connection failed to host: " + manager.serverName, e1); + } + + ObjectOutputStream out; + DataOutputStream dout; + try { + dout = conn.getDataOutputStream(); + dout.writeByte(MESSAGE_CALL); + + out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream + + objid.write(out); + out.writeInt(opnum); + out.writeLong(hash); + + // must handle primitive class and their wrapper classes + Class clss[] = method.getParameterTypes(); + for(int i = 0; i < clss.length; i++) + ((RMIObjectOutputStream)out).writeValue(params[i], clss[i]); + + out.flush(); + } + catch (IOException e2) { + throw new RemoteException("call failed: ", e2); + } + + int returncode; + Object returnval; + DataInputStream din; + ObjectInputStream in; + UID ack; + try { + din = conn.getDataInputStream(); + + if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK) { + conn.disconnect(); + throw new RemoteException("Call not acked:" + returncode); + } + + in = conn.startObjectInputStream(); // (re)start ObjectInputStream + returncode = in.readUnsignedByte(); + ack = UID.read(in); + + Class cls = method.getReturnType(); + + if (returncode == RETURN_NACK) { + returnval = in.readObject(); // get Exception + + } else if(cls == Void.TYPE) { + returnval = null; + // in.readObject() // not required! returntype 'void' means no field is returned. + } else { + returnval = ((RMIObjectInputStream)in).readValue(cls); // get returnvalue + } + } catch (IOException e3) { + //for debug: e3.printStackTrace(); + throw new RemoteException("call return failed: ", e3); + } + + /* if DGCAck is necessary?? + //According to RMI wire protocol, send a DGCAck + // to indicate receiving return value + dout.writeByte(MESSAGE_DGCACK); + ack.write(dout); + out.flush(); + */ + + manager.discardConnection(conn); + + if (returncode != RETURN_ACK && returnval != null) { + if (returncode == RETURN_NACK) throw (Exception)returnval; + else throw new RemoteException("unexpected returncode: " + returncode); + } + + return (returnval); +} + +/** + * @deprecated + */ +public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException { + UnicastConnection conn; + + try { + conn = manager.getConnection(); + } + catch (IOException e1) { + throw new RemoteException("connection failed to host: " + manager.serverName, e1); + } + + //obj: useless? + + return (new UnicastRemoteCall(conn, objid, opnum, hash)); +} + +/** + * @deprecated + */ +public void invoke(RemoteCall call) throws Exception { + UnicastRemoteCall c = (UnicastRemoteCall)call; + call.executeCall(); +} + +/** + * @deprecated + */ +public void done(RemoteCall call) throws RemoteException { + UnicastRemoteCall c = (UnicastRemoteCall)call; + try{ + c.done(); + } catch(IOException e){} + UnicastConnection conn = c.getConnection(); + manager.discardConnection(conn); +} + +public void writeExternal(ObjectOutput out) throws IOException { + if (manager == null) { + throw new IOException("no connection"); + } + manager.write(out); + objid.write(out); + // This byte is somewhat confusing when interoperating with JDK + out.writeByte(0); //RETURN_ACK); +} + +public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + manager = UnicastConnectionManager.read(in); + objid = ObjID.read(in); + byte ack = in.readByte(); + // This byte is somewhat confusing when interoperating with JDK + if (ack != RETURN_ACK && ack != 0/*jdk ack value*/) { + throw new IOException("no ack found"); + } +} + +public boolean remoteEquals(RemoteRef ref) { + throw new Error("Not implemented"); +} + +public int remoteHashCode() { + throw new Error("Not implemented"); +} + +public String getRefClass(ObjectOutput out) { + return ("UnicastRef"); +} + +public String remoteToString() { + throw new Error("Not implemented"); +} + +public void dump(UnicastConnection conn) { + try { + DataInputStream din = conn.getDataInputStream(); + for (;;) { + int b = din.readUnsignedByte(); + System.out.print(Integer.toHexString(b)); + if (b >= 32 && b < 128) { + System.out.print(": " + (char)b); + } + System.out.println(); + } + } + catch (IOException _) { + } +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java new file mode 100644 index 0000000..c5206e7 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java @@ -0,0 +1,525 @@ +/* UnicastRemoteCall.java + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 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.java.rmi.server; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.StreamCorruptedException; +import java.rmi.MarshalException; +import java.rmi.RemoteException; +import java.rmi.UnmarshalException; +import java.rmi.server.ObjID; +import java.rmi.server.RemoteCall; +import java.rmi.server.UID; +import java.util.Vector; + +public class UnicastRemoteCall + implements RemoteCall, ProtocolConstants +{ + + private UnicastConnection conn; + private Object result; + private Object object; + private int opnum; + private long hash; + // These are package-private due to inner class access. + Vector vec; + int ptr; + private ObjID objid; + + private ObjectOutput oout; + private ObjectInput oin; + + /** + * Incoming call. + */ + UnicastRemoteCall(UnicastConnection conn) + { + this.conn = conn; + } + + /** + * Outgoing call. + */ + UnicastRemoteCall(UnicastConnection conn, ObjID objid, int opnum, long hash) + throws RemoteException + { + this.conn = conn; + this.opnum = opnum; + this.hash = hash; + this.objid = objid; + } + + UnicastConnection getConnection() + { + return conn; + } + + public ObjectOutput getOutputStream() throws IOException + { + if (vec == null) + vec = new Vector(); + return (new DummyObjectOutputStream()); + } + + public void releaseOutputStream() throws IOException + { + if (vec != null) + { + oout = conn.getObjectOutputStream(); + + for (int i = 0; i < vec.size(); i += 2) + { + boolean primitive = ((Boolean)vec.elementAt(i)).booleanValue(); + Object data = vec.elementAt(i+1); + + // No type, this is + if (!primitive) + oout.writeObject(data); + else + { + if (data instanceof Boolean) + oout.writeBoolean(((Boolean)data).booleanValue()); + else if (data instanceof Character) + oout.writeChar(((Character)data).charValue()); + else if (data instanceof Byte) + oout.writeByte(((Byte)data).byteValue()); + else if (data instanceof Short) + oout.writeShort(((Short)data).shortValue()); + else if (data instanceof Integer) + oout.writeInt(((Integer)data).intValue()); + else if (data instanceof Long) + oout.writeLong(((Long)data).longValue()); + } + } + vec = null; + } + if(oout != null) + oout.flush(); + } + + /** + * + * (re)starts ObjectInputStream + * + */ + public ObjectInput startInputStream() throws IOException + { + if (conn != null) { + return (oin = conn.startObjectInputStream()); + } else { + return getInputStream(); // dummy Input Stream + } + + } + + public ObjectInput getInputStream() throws IOException + { + if (conn != null) + { + if(oin == null) + return (oin = conn.getObjectInputStream()); + else + return oin; + } + else + { + ptr = 0; + return (new DummyObjectInputStream()); + } + } + + public void releaseInputStream() throws IOException + { + // Does nothing. + } + + public ObjectOutput getResultStream(boolean success) + throws IOException, StreamCorruptedException + { + vec = new Vector(); + return new DummyObjectOutputStream(); + } + + public void executeCall() throws Exception + { + byte returncode; + ObjectInput oin; + + // signal the call when constructing + try + { + DataOutputStream dout = conn.getDataOutputStream(); + dout.write(MESSAGE_CALL); + + oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream + objid.write(oout); + oout.writeInt(opnum); + oout.writeLong(hash); + } + catch(IOException ex) + { + throw new MarshalException("Try to write header but failed.", ex); + } + + try + { + releaseOutputStream(); + DataInputStream din = conn.getDataInputStream(); + if (din.readByte() != MESSAGE_CALL_ACK) + throw new RemoteException("Call not acked"); + + oin = startInputStream(); + returncode = oin.readByte(); + UID.read(oin); + } + catch(IOException ex) + { + throw new UnmarshalException("Try to read header but failed:", ex); + } + + //check return code + switch(returncode) + { + case RETURN_ACK: //it's ok + return; + case RETURN_NACK: + Object returnobj; + try + { + returnobj = oin.readObject(); + } + catch(Exception ex2) + { + throw new UnmarshalException + ("Try to read exception object but failed", ex2); + } + + if(!(returnobj instanceof Exception)) + throw new UnmarshalException("Should be Exception type here: " + + returnobj); + throw (Exception)returnobj; + + default: + throw new UnmarshalException("Invalid return code"); + } + } + + public void done() throws IOException + { + // conn.disconnect(); + } + + boolean isReturnValue() + { + return vec.size() > 0; + } + + Object returnValue() + { + // This is not the first one (Boolean) but the second. + return vec.elementAt(1); + } + + Object[] getArguments() + { + return vec.toArray(); + } + + Object getObject() + { + return object; + } + + int getOpnum() + { + return opnum; + } + + long getHash() + { + return hash; + } + + void setReturnValue(Object obj) + { + vec.removeAllElements(); + vec.addElement(obj); + } + + /** + * Dummy object output class. + */ + private class DummyObjectOutputStream implements ObjectOutput + { + /** + * Non-private constructor to reduce bytecode emitted. + */ + DummyObjectOutputStream() + { + } + + public void writeBoolean(boolean v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(Boolean.valueOf(v)); + } + + public void writeByte(int v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Byte((byte) v)); + } + + public void writeChar(int v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Character((char) v)); + } + + public void writeDouble(double v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Double(v)); + } + + public void writeFloat(float v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Float(v)); + } + + public void writeInt(int v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Integer(v)); + } + + public void writeLong(long v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Long(v)); + } + + public void writeShort(int v) throws IOException + { + vec.addElement(Boolean.TRUE); + vec.addElement(new Short((short) v)); + } + + public void writeObject(Object obj) throws IOException + { + vec.addElement(Boolean.FALSE); + vec.addElement(obj); + } + + public void write(byte b[]) throws IOException + { + throw new IOException("not required"); + } + + public void write(byte b[], int off, int len) throws IOException + { + throw new IOException("not required"); + } + + public void write(int b) throws IOException + { + throw new IOException("not required"); + } + + public void writeBytes(String s) throws IOException + { + throw new IOException("not required"); + } + + public void writeChars(String s) throws IOException + { + throw new IOException("not required"); + } + + public void writeUTF(String str) throws IOException + { + throw new IOException("not required"); + } + + public void flush() throws IOException + { + } + + public void close() throws IOException + { + } + } // class DummyObjectOutputStream + + /** + * Dummy object input class. + */ + private class DummyObjectInputStream implements ObjectInput + { + /** + * Non-private constructor to reduce bytecode emitted. + */ + DummyObjectInputStream() + { + } + + public boolean readBoolean() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Boolean) obj).booleanValue(); + } + + public byte readByte() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Byte) obj).byteValue(); + } + + public char readChar() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Character) obj).charValue(); + } + + public double readDouble() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Double) obj).doubleValue(); + } + + public float readFloat() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Float) obj).floatValue(); + } + + public int readInt() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Integer) obj).intValue(); + } + + public long readLong() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Long) obj).longValue(); + } + + public short readShort() throws IOException + { + Object obj = vec.elementAt(ptr++); + return ((Short) obj).shortValue(); + } + + public Object readObject() throws IOException + { + return vec.elementAt(ptr++); + } + + public int read(byte b[]) throws IOException + { + throw new IOException("not required"); + } + + public int read(byte b[], int off, int len) throws IOException + { + throw new IOException("not required"); + } + + public int read() throws IOException + { + throw new IOException("not required"); + } + + public long skip(long n) throws IOException + { + throw new IOException("not required"); + } + + public int available() throws IOException + { + throw new IOException("not required"); + } + + public void readFully(byte b[]) throws IOException + { + throw new IOException("not required"); + } + + public void readFully(byte b[], int off, int len) throws IOException + { + throw new IOException("not required"); + } + + public String readLine() throws IOException + { + throw new IOException("not required"); + } + + public String readUTF() throws IOException + { + throw new IOException("not required"); + } + + public int readUnsignedByte() throws IOException + { + throw new IOException("not required"); + } + + public int readUnsignedShort() throws IOException + { + throw new IOException("not required"); + } + + public int skipBytes(int n) throws IOException + { + throw new IOException("not required"); + } + + public void close() throws IOException + { + } + } // class DummyObjectInputStream + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java new file mode 100644 index 0000000..87e932d --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java @@ -0,0 +1,50 @@ +/* UnicastRemoteStub.java -- + Copyright (c) 1996, 1997, 1998, 1999 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.java.rmi.server; + +import java.rmi.server.RemoteRef; +import java.rmi.server.RemoteStub; + +public class UnicastRemoteStub + extends RemoteStub { + +public static void setStubRef(RemoteStub stub, RemoteRef ref) { + setRef(stub, ref); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastServer.java b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java new file mode 100644 index 0000000..065ef8c --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java @@ -0,0 +1,167 @@ +/* UnicastServer.java -- + Copyright (c) 1996, 1997, 1998, 1999, 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.java.rmi.server; + +import gnu.java.rmi.dgc.DGCImpl; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.rmi.NoSuchObjectException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.ServerError; +import java.rmi.server.ObjID; +import java.rmi.server.UID; +import java.util.Hashtable; + +public class UnicastServer + implements ProtocolConstants { + +static private Hashtable objects = new Hashtable(); //mapping OBJID to server ref +static private Hashtable refcache = new Hashtable(); //mapping obj itself to server ref +static private DGCImpl dgc; + +public static void exportObject(UnicastServerRef obj) { + startDGC(); + objects.put(obj.objid, obj); + refcache.put(obj.myself, obj); + obj.manager.startServer(); +} + +// FIX ME: I haven't handle force parameter +public static boolean unexportObject(UnicastServerRef obj, boolean force) { + objects.remove(obj.objid); + refcache.remove(obj.myself); + obj.manager.stopServer(); + return true; +} + +public static UnicastServerRef getExportedRef(Remote remote){ + return (UnicastServerRef)refcache.get(remote); +} + +private static synchronized void startDGC() { + if (dgc == null) { + try { + dgc = new DGCImpl(); + // Changed DGCImpl to inherit UnicastServerRef directly + //((UnicastServerRef)dgc.getRef()).exportObject(dgc); + dgc.exportObject(dgc); + } + catch (RemoteException e) { + e.printStackTrace(); + } + } +} + +public static void dispatch(UnicastConnection conn) throws Exception { + switch (conn.getDataInputStream().readUnsignedByte()) { + case MESSAGE_CALL: + incomingMessageCall(conn); + break; + case MESSAGE_PING: + // jdk sends a ping before each method call -> answer it! + DataOutputStream out = conn.getDataOutputStream(); + out.writeByte(MESSAGE_PING_ACK); + out.flush(); + break; + default: + throw new Exception("bad method type"); + } +} + +private static void incomingMessageCall(UnicastConnection conn) throws IOException { + ObjectInputStream in = conn.startObjectInputStream(); // (re)start ObjectInputStream + + ObjID objid = ObjID.read(in); + int method = in.readInt(); + long hash = in.readLong(); + +//System.out.println("ObjID: " + objid + ", method: " + method + ", hash: " + hash); + + // Use the objid to locate the relevant UnicastServerRef + UnicastServerRef uref = (UnicastServerRef)objects.get(objid); + Object returnval; + int returncode = RETURN_ACK; + // returnval is from Method.invoke(), so we must check the return class to see + // if it's primitive type + Class returncls = null; + if (uref != null) { + try { + // Dispatch the call to it. + returnval = uref.incomingMessageCall(conn, method, hash); + returncls = uref.getMethodReturnType(method, hash); + } + catch (Exception e) { + returnval = e; + returncode = RETURN_NACK; + } + catch (Error e) { + returnval = new ServerError ("An Error is thrown while processing the invocation on the server", e); + returncode = RETURN_NACK; + } + } + else { + returnval = new NoSuchObjectException(""); + returncode = RETURN_NACK; + } + + conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK); + + ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream + + out.writeByte(returncode); + (new UID()).write(out); + + //System.out.println("returnval=" + returnval + " returncls=" + returncls); + + if(returnval != null && returncls != null) + ((RMIObjectOutputStream)out).writeValue(returnval, returncls); + + // 1.1/1.2 void return type detection: + else if (!(returnval instanceof RMIVoidValue || returncls == Void.TYPE)) + out.writeObject(returnval); + + out.flush(); +} + +} diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java b/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java new file mode 100644 index 0000000..1f6eede --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java @@ -0,0 +1,306 @@ +/* UnicastServerRef.java -- + Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 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.java.rmi.server; + +import java.io.ObjectInputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.server.ObjID; +import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RemoteRef; +import java.rmi.server.RemoteServer; +import java.rmi.server.RemoteStub; +import java.rmi.server.ServerNotActiveException; +import java.rmi.server.ServerRef; +import java.rmi.server.Skeleton; +import java.util.Hashtable; + +public class UnicastServerRef + extends UnicastRef + implements ServerRef{ //SHOULD implement ServerRef + +final static private Class[] stubprototype = new Class[] { RemoteRef.class }; + +Remote myself; //save the remote object itself +private Skeleton skel; +private RemoteStub stub; +private Hashtable methods = new Hashtable(); + +/** + * Used by serialization. + */ +UnicastServerRef() +{ +} + +public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) throws RemoteException { + super(id); + manager = UnicastConnectionManager.getInstance(port, ssf); +} + +public RemoteStub exportObject(Remote obj) throws RemoteException { + if (myself == null) { + myself = obj; + // Save it to server manager, to let client calls in the same VM to issue + // local call + manager.serverobj = obj; + + // Find and install the stub + Class cls = obj.getClass(); + Class expCls; + try { + // where ist the _Stub? (check superclasses also) + expCls = findStubSkelClass(cls); + } catch (Exception ex) { + throw new RemoteException("can not find stubs for class: " + cls, ex); + } + + stub = (RemoteStub)getHelperClass(expCls, "_Stub"); + if (stub == null) { + throw new RemoteException("failed to export: " + cls); + } + + // Find and install the skeleton (if there is one) + skel = (Skeleton)getHelperClass(expCls, "_Skel"); + + // Build hash of methods which may be called. + buildMethodHash(obj.getClass(), true); + + // Export it. + UnicastServer.exportObject(this); + } + + return (stub); +} + +public RemoteStub exportObject(Remote remote, Object obj) + throws RemoteException +{ + //FIX ME + return exportObject(remote); +} + +public RemoteStub getStub(){ + return stub; +} + + +public boolean unexportObject(Remote obj, boolean force) { + // Remove all hashes of methods which may be called. + buildMethodHash(obj.getClass(), false); + return UnicastServer.unexportObject(this, force); +} + +/** +* +* The Subs/Skels might not there for the actual class, but maybe +* for one of the superclasses. +* +*/ +private Class findStubSkelClass(Class startCls) throws Exception { + Class cls = startCls; + + while (true) { + try { + String stubClassname = cls.getName() + "_Stub"; + ClassLoader cl = cls.getClassLoader(); + Class scls = cl == null ? Class.forName(stubClassname) + : cl.loadClass(stubClassname); + return cls; // found it + } catch (ClassNotFoundException e) { + Class superCls = cls.getSuperclass(); + if (superCls == null + || superCls == java.rmi.server.UnicastRemoteObject.class) + { + throw new Exception("Neither " + startCls + + " nor one of their superclasses (like" + cls + ")" + + " has a _Stub"); + } + cls = superCls; + } + } +} + + + +private Object getHelperClass(Class cls, String type) { + try { + String classname = cls.getName(); + ClassLoader cl = cls.getClassLoader(); + Class scls = cl == null ? Class.forName(classname + type) + : cl.loadClass(classname + type); + if (type.equals("_Stub")) { + try { + // JDK 1.2 stubs + Constructor con = scls.getConstructor(stubprototype); + return (con.newInstance(new Object[]{this})); + } + catch (NoSuchMethodException e) { + } + catch (InstantiationException e) { + } + catch (IllegalAccessException e) { + } + catch (IllegalArgumentException e) { + } + catch (InvocationTargetException e) { + } + // JDK 1.1 stubs + RemoteStub stub = (RemoteStub)scls.newInstance(); + UnicastRemoteStub.setStubRef(stub, this); + return (stub); + } + else { + // JDK 1.1 skel + return (scls.newInstance()); + } + } + catch (ClassNotFoundException e) { + } + catch (InstantiationException e) { + } + catch (IllegalAccessException e) { + } + return (null); +} + + + +public String getClientHost() throws ServerNotActiveException { + return RemoteServer.getClientHost(); +} + +private void buildMethodHash(Class cls, boolean build) { + Method[] meths = cls.getMethods(); + for (int i = 0; i < meths.length; i++) { + /* Don't need to include any java.xxx related stuff */ + if (meths[i].getDeclaringClass().getName().startsWith("java.")) { + continue; + } + long hash = RMIHashes.getMethodHash(meths[i]); + if(build) + methods.put(new Long (hash), meths[i]); + else + methods.remove(new Long (hash)); +//System.out.println("meth = " + meths[i] + ", hash = " + hash); + } +} + +Class getMethodReturnType(int method, long hash) throws Exception +{ + if (method == -1) { + Method meth = (Method)methods.get(new Long (hash)); + return meth.getReturnType(); + }else + return null; +} + +public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throws Exception { +//System.out.println("method = " + method + ", hash = " + hash); + // If method is -1 then this is JDK 1.2 RMI - so use the hash + // to locate the method + if (method == -1) { + Method meth = (Method)methods.get(new Long (hash)); +//System.out.println("class = " + myself.getClass() + ", meth = " + meth); + if (meth == null) { + throw new NoSuchMethodException(); + } + + ObjectInputStream in = conn.getObjectInputStream(); + int nrargs = meth.getParameterTypes().length; + Object[] args = new Object[nrargs]; + for (int i = 0; i < nrargs; i++) { + /** + * For debugging purposes - we don't handle CodeBases + * quite right so we don't always find the stubs. This + * lets us know that. + */ + try { + // need to handle primitive types + args[i] = ((RMIObjectInputStream)in).readValue(meth.getParameterTypes()[i]); + + } + catch (Exception t) { + t.printStackTrace(); + throw t; + } + } + //We must reinterpret the exception thrown by meth.invoke() + //return (meth.invoke(myself, args)); + Object ret = null; + try{ + ret = meth.invoke(myself, args); + }catch(InvocationTargetException e){ + Throwable cause = e.getTargetException(); + if (cause instanceof Exception) { + throw (Exception)cause; + } + else if (cause instanceof Error) { + throw (Error)cause; + } + else { + throw new Error("The remote method threw a java.lang.Throwable that is neither java.lang.Exception nor java.lang.Error.", e); + } + } + return ret; + } + // Otherwise this is JDK 1.1 style RMI - we find the skeleton + // and invoke it using the method number. We wrap up our + // connection system in a UnicastRemoteCall so it appears in a + // way the Skeleton can handle. + else { + if (skel == null) { + throw new NoSuchMethodException(); + } + UnicastRemoteCall call = new UnicastRemoteCall(conn); + skel.dispatch(myself, call, method, hash); + if (!call.isReturnValue()) + return RMIVoidValue.INSTANCE; + else + return (call.returnValue()); + } +} + +} + + diff --git a/libjava/classpath/gnu/java/rmi/server/package.html b/libjava/classpath/gnu/java/rmi/server/package.html new file mode 100644 index 0000000..08c105b --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.rmi.server package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.rmi.server</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/Engine.java b/libjava/classpath/gnu/java/security/Engine.java new file mode 100644 index 0000000..b75de5c --- /dev/null +++ b/libjava/classpath/gnu/java/security/Engine.java @@ -0,0 +1,237 @@ +/* Engine -- generic getInstance method. + Copyright (C) 2003 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.java.security; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import java.security.NoSuchAlgorithmException; +import java.security.Provider; + +/** + * Generic implementation of the getInstance methods in the various + * engine classes in java.security. + * <p> + * These classes ({@link java.security.Signature} for example) can be + * thought of as the "chrome, upholstery, and steering wheel", and the SPI + * (service provider interface, e.g. {@link java.security.SignatureSpi}) + * classes can be thought of as the "engine" -- providing the actual + * functionality of whatever cryptographic algorithm the instance + * represents. + * + * @see Provider + * @author Casey Marshall + */ +public final class Engine +{ + + // Constants. + // ------------------------------------------------------------------------ + + /** Prefix for aliases. */ + private static final String ALG_ALIAS = "Alg.Alias."; + + /** Maximum number of aliases to try. */ + private static final int MAX_ALIASES = 5; + + /** Argument list for no-argument constructors. */ + private static final Object[] NO_ARGS = new Object[0]; + + // Constructor. + // ------------------------------------------------------------------------ + + /** This class cannot be instantiated. */ + private Engine() { } + + // Class method. + // ------------------------------------------------------------------------ + + /** + * Get the implementation for <i>algorithm</i> for service + * <i>service</i> from <i>provider</i>. The service is e.g. + * "Signature", and the algorithm "DSA". + * + * @param service The service name. + * @param algorithm The name of the algorithm to get. + * @param provider The provider to get the implementation from. + * @return The engine class for the specified algorithm; the object + * returned is typically a subclass of the SPI class for that + * service, but callers should check that this is so. + * @throws NoSuchAlgorithmException If the implementation cannot be + * found or cannot be instantiated. + * @throws InvocationTargetException If the SPI class's constructor + * throws an exception. + * @throws IllegalArgumentException If any of the three arguments are null. + */ + public static Object getInstance(String service, String algorithm, + Provider provider) + throws InvocationTargetException, NoSuchAlgorithmException + { + return getInstance(service, algorithm, provider, NO_ARGS); + } + + /** + * Get the implementation for <i>algorithm</i> for service + * <i>service</i> from <i>provider</i>, passing <i>initArgs</i> to the + * SPI class's constructor (which cannot be null; pass a zero-length + * array if the SPI takes no arguments). The service is e.g. + * "Signature", and the algorithm "DSA". + * + * @param service The service name. + * @param algorithm The name of the algorithm to get. + * @param provider The provider to get the implementation from. + * @param initArgs The arguments to pass to the SPI class's + * constructor (cannot be null). + * @return The engine class for the specified algorithm; the object + * returned is typically a subclass of the SPI class for that + * service, but callers should check that this is so. + * @throws NoSuchAlgorithmException If the implementation cannot be + * found or cannot be instantiated. + * @throws InvocationTargetException If the SPI class's constructor + * throws an exception. + * @throws IllegalArgumentException If any of the four arguments are null. + */ + public static Object getInstance(String service, String algorithm, + Provider provider, Object[] initArgs) + throws InvocationTargetException, NoSuchAlgorithmException + { + if (service == null || algorithm == null + || provider == null || initArgs == null) + throw new IllegalArgumentException(); + + // If there is no property "service.algorithm" + if (provider.getProperty(service + "." + algorithm) == null) + { + // Iterate through aliases, until we find the class name or resolve + // too many aliases. + String alias = null; + int count = 0; + while ((alias = provider.getProperty( + ALG_ALIAS + service + "." + algorithm)) != null) + { + if (algorithm.equals(alias)) // Refers to itself! + break; + algorithm = alias; + if (count++ > MAX_ALIASES) + throw new NoSuchAlgorithmException("too many aliases"); + } + if (provider.getProperty(service + "." + algorithm) == null) + throw new NoSuchAlgorithmException(algorithm); + } + + // Find and instantiate the implementation. + Class clazz = null; + ClassLoader loader = provider.getClass().getClassLoader(); + Constructor constructor = null; + String error = algorithm; + + try + { + if (loader != null) + clazz = loader.loadClass(provider.getProperty(service+"."+algorithm)); + else + clazz = Class.forName(provider.getProperty(service+"."+algorithm)); + constructor = getCompatibleConstructor(clazz, initArgs); + return constructor.newInstance(initArgs); + } + catch (ClassNotFoundException cnfe) + { + error = "class not found: " + algorithm; + } + catch (IllegalAccessException iae) + { + error = "illegal access: " + iae.getMessage(); + } + catch (InstantiationException ie) + { + error = "instantiation exception: " + ie.getMessage(); + } + catch (ExceptionInInitializerError eiie) + { + error = "exception in initializer: " + eiie.getMessage(); + } + catch (SecurityException se) + { + error = "security exception: " + se.getMessage(); + } + catch (NoSuchMethodException nsme) + { + error = "no appropriate constructor found"; + } + + throw new NoSuchAlgorithmException(error); + } + + // Own methods. + // ------------------------------------------------------------------------ + + /** + * Find a constructor in the given class that can take the specified + * argument list, allowing any of which to be null. + * + * @param clazz The class from which to get the constructor. + * @param initArgs The argument list to be passed to the constructor. + * @return The constructor. + * @throws NoSuchMethodException If no constructor of the given class + * can take the specified argument array. + */ + private static Constructor getCompatibleConstructor(Class clazz, + Object[] initArgs) + throws NoSuchMethodException + { + Constructor[] c = clazz.getConstructors(); + outer:for (int i = 0; i < c.length; i++) + { + Class[] argTypes = c[i].getParameterTypes(); + if (argTypes.length != initArgs.length) + continue; + for (int j = 0; j < argTypes.length; j++) + { + if (initArgs[j] != null && + !argTypes[j].isAssignableFrom(initArgs[j].getClass())) + continue outer; + } + // If we reach this point, we know this constructor (c[i]) has + // the same number of parameters as the target parameter list, + // and all our parameters are either (1) null, or (2) assignable + // to the target parameter type. + return c[i]; + } + throw new NoSuchMethodException(); + } +} diff --git a/libjava/classpath/gnu/java/security/OID.java b/libjava/classpath/gnu/java/security/OID.java new file mode 100644 index 0000000..8cda43e --- /dev/null +++ b/libjava/classpath/gnu/java/security/OID.java @@ -0,0 +1,509 @@ +/* OID.java -- numeric representation of an object identifier + Copyright (C) 2003, 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.java.security; + +import gnu.java.security.der.DEREncodingException; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.StringTokenizer; + +/** + * This immutable class represents an object identifier, or OID. + * + * <p>OIDs are represented as a series of hierarcical tokens, each of + * which is usually represented as a single, unsigned integer. The + * hierarchy works so that later tokens are considered within the group + * of earlier tokens. Thus, the OID for the Serpent block cipher, + * 1.3.6.1.4.1.11591.13.2, is maintained by the GNU project, whose OID + * is 1.3.6.1.4.1.11591 (which is, in turn, part of bigger, more general + * bodies; the topmost, 1, stands for the OIDs assigned by the + * International Standards Organization, ISO). + * + * <p>OIDs can be represented in a variety of ways, including the + * dotted-decimal form we use here. + * + * <p>OIDs may be relative, in which case the first two elements of the + * OID are omitted. + * + * @author Casey Marshall (csm@gnu.org) + */ +public class OID implements Cloneable, Comparable, java.io.Serializable +{ + + // Fields. + // ------------------------------------------------------------------------ + + /** + * The numeric ID structure. + */ + private int[] components; + + /** + * The string representation of this OID, in dotted-decimal format. + */ + private transient String strRep; + + /** + * The DER encoding of this OID. + */ + private transient byte[] der; + + /** + * Whether or not this OID is relative. + */ + private boolean relative; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a new OID from the given byte array. The argument (which can + * neither be null nor zero-length) is copied to prevent subsequent + * modification. + * + * @param components The numeric IDs. + * @throws IllegalArgumentException If <i>components</i> is null or empty. + */ + public OID(int[] components) + { + this(components, false); + } + + /** + * Create a new OID from the given byte array. The argument (which can + * neither be null nor zero-length) is copied to prevent subsequent + * modification. + * + * @param components The numeric IDs. + * @param relative The relative flag. + * @throws IllegalArgumentException If <i>components</i> is null or empty. + */ + public OID(int[] components, boolean relative) + { + if (components == null || components.length == 0) + throw new IllegalArgumentException(); + this.components = (int[]) components.clone(); + this.relative = relative; + } + + /** + * Create a new OID from the given dotted-decimal representation. + * + * @param strRep The string representation of the OID. + * @throws IllegalArgumentException If the string does not contain at + * least one integer. + * @throws NumberFormatException If the string does not contain only + * numbers and periods ('.'). + */ + public OID(String strRep) + { + this(strRep, false); + } + + /** + * Create a new OID from the given dotted-decimal representation. + * + * @param strRep The string representation of the OID. + * @param relative The relative flag. + * @throws IllegalArgumentException If the string does not contain at + * least one integer. + * @throws NumberFormatException If the string does not contain only + * numbers and periods ('.'). + */ + public OID(String strRep, boolean relative) + { + this.relative = relative; + this.strRep = strRep; + components = fromString(strRep); + } + + /** + * Construct a new OID from the DER bytes in an input stream. This method + * does not read the tag or the length field from the input stream, so + * the caller must supply the number of octets in this OID's encoded + * form. + * + * @param derIn The DER input stream. + * @param len The number of bytes in the encoded form. + * @throws IOException If an error occurs reading the OID. + */ + public OID(InputStream derIn, int len) throws IOException + { + this(derIn, len, false); + } + + /** + * Construct a new OID from the DER bytes in an input stream. This method + * does not read the tag or the length field from the input stream, so + * the caller must supply the number of octets in this OID's encoded + * form. + * + * @param derIn The DER input stream. + * @param len The number of bytes in the encoded form. + * @param relative The relative flag. + * @throws IOException If an error occurs reading the OID. + */ + public OID(InputStream derIn, int len, boolean relative) throws IOException + { + der = new byte[len]; + derIn.read(der); + this.relative = relative; + try + { + components = fromDER(der, relative); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + aioobe.printStackTrace(); + throw aioobe; + } + } + + /** + * Construct a new OID from the given DER bytes. + * + * @param encoded The DER encoded OID. + * @throws IOException If an error occurs reading the OID. + */ + public OID(byte[] encoded) throws IOException + { + this(encoded, false); + } + + /** + * Construct a new OID from the given DER bytes. + * + * @param root The root OID. + * @param encoded The encoded relative OID. + * @param relative The relative flag. + */ + public OID(byte[] encoded, boolean relative) throws IOException + { + der = (byte[]) encoded.clone(); + this.relative = relative; + try + { + components = fromDER(der, relative); + } + catch (ArrayIndexOutOfBoundsException aioobe) + { + aioobe.printStackTrace(); + throw aioobe; + } + } + + /** + * Our private constructor. + */ + private OID() + { + } + + // Instance methods. + // ------------------------------------------------------------------------ + + /** + * Return the numeric IDs of this OID. The value returned is copied to + * prevent modification. + * + * @return The IDs in a new integer array. + */ + public int[] getIDs() + { + return (int[]) components.clone(); + } + + /** + * Get the DER encoding of this OID, minus the tag and length fields. + * + * @return The DER bytes. + */ + public byte[] getDER() + { + if (der == null) + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + int i = 0; + if (!relative) + { + int b = components[i++] * 40 + (components.length > 1 + ? components[i++] : 0); + encodeSubID(bout, b); + } + for ( ; i < components.length; i++) + encodeSubID(bout, components[i]); + der = bout.toByteArray(); + } + return (byte[]) der.clone(); + } + + /** + * Get the parent OID of this OID. That is, if this OID is "1.2.3.4", + * then the parent OID will be "1.2.3". If this OID is a top-level + * OID, this method returns null. + * + * @return The parent OID, or null. + */ + public OID getParent() + { + if (components.length == 1) + return null; + int[] parent = new int[components.length - 1]; + System.arraycopy(components, 0, parent, 0, parent.length); + return new OID(parent); + } + + public OID getChild(int id) + { + int[] child = new int[components.length + 1]; + System.arraycopy(components, 0, child, 0, components.length); + child[child.length - 1] = id; + return new OID(child); + } + + /** + * Get the root OID of this OID. That is, the first two components. + * + * @return The root OID. + */ + public OID getRoot() + { + if (components.length <= 2) + return this; + int[] root = new int[2]; + root[0] = components[0]; + root[1] = components[1]; + return new OID(root); + } + + public boolean isRelative() + { + return relative; + } + + /** + * Returns a copy of this OID. + * + * @return The copy. + */ + public Object clone() + { + OID oid = new OID(); + oid.components = this.components; + oid.strRep = this.strRep; + return oid; + } + + /* Nice idea, but possibly too expensive for whatever benefit it + * provides. + + public String getShortName() + { + return OIDTable.getShortName(this); + } + + public String getLongName() + { + return OIDTable.getLongName(this); + } + + */ + + /** + * Returns the value of this OID in dotted-decimal format. + * + * @return The string representation. + */ + public String toString() + { + if (strRep != null) + return strRep; + else + { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < components.length; i++) + { + buf.append((long) components[i] & 0xFFFFFFFFL); + if (i < components.length - 1) + buf.append('.'); + } + return (strRep = buf.toString()); + } + } + + /** + * Computes a hash code for this OID. + * + * @return The hash code. + */ + public int hashCode() + { + int ret = 0; + for (int i = 0; i < components.length; i++) + ret += components[i] << (i & 31); + return ret; + } + + /** + * Tests whether or not this OID equals another. + * + * @return Whether or not this OID equals the other. + */ + public boolean equals(Object o) + { + if (!(o instanceof OID)) + return false; + return java.util.Arrays.equals(components, ((OID) o).components); + } + + /** + * Compares this OID to another. The comparison is essentially + * lexicographic, where the two OIDs are compared until their + * first difference, then that difference is returned. If one OID is + * shorter, but all elements equal between the two for the shorter + * length, then the shorter OID is lesser than the longer. + * + * @param o The object to compare. + * @return An integer less than, equal to, or greater than zero if + * this object is less than, equal to, or greater than the + * argument. + * @throws ClassCastException If <i>o</i> is not an OID. + */ + public int compareTo(Object o) + { + if (equals(o)) + return 0; + int[] components2 = ((OID) o).components; + int len = Math.min(components.length, components2.length); + for (int i = 0; i < len; i++) + { + if (components[i] != components2[i]) + return (components[i] < components2[i]) ? -1 : 1; + } + if (components.length == components2.length) + return 0; + return (components.length < components2.length) ? -1 : 1; + } + + // Own methods. + // ------------------------------------------------------------------------ + + private static int[] fromDER(byte[] der, boolean relative) + throws DEREncodingException + { + // cannot be longer than this. + int[] components = new int[der.length + 1]; + int count = 0; + int i = 0; + if (!relative && i < der.length) + { + // Non-relative OIDs have the first two arcs coded as: + // + // i = first_arc * 40 + second_arc; + // + int j = (der[i] & 0xFF); + components[count++] = j / 40; + components[count++] = j % 40; + i++; + } + while (i < der.length) + { + int j = 0; + do + { + j = der[i++] & 0xFF; + components[count] <<= 7; + components[count] |= j & 0x7F; + if (i >= der.length && (j & 0x80) != 0) + throw new DEREncodingException("malformed OID"); + } + while ((j & 0x80) != 0); + count++; + } + if (count == components.length) + return components; + int[] ret = new int[count]; + System.arraycopy(components, 0, ret, 0, count); + return ret; + } + + private static int[] fromString(String strRep) throws NumberFormatException + { + if (strRep.startsWith("OID.") || strRep.startsWith("oid.")) + strRep = strRep.substring(4); + StringTokenizer tok = new StringTokenizer(strRep, "."); + if (tok.countTokens() == 0) + throw new IllegalArgumentException(); + int[] components = new int[tok.countTokens()]; + int i = 0; + while (tok.hasMoreTokens()) + { + components[i++] = Integer.parseInt(tok.nextToken()); + } + return components; + } + + private static void encodeSubID(ByteArrayOutputStream out, int id) + { + if (id < 128) + { + out.write(id); + } + else if (id < 16384) + { + out.write((id >>> 7) | 0x80); + out.write(id & 0x7F); + } + else if (id < 2097152) + { + out.write((id >>> 14) | 0x80); + out.write(((id >>> 7) | 0x80) & 0xFF); + out.write(id & 0x7F); + } + else if (id < 268435456) + { + out.write( (id >>> 21) | 0x80); + out.write(((id >>> 14) | 0x80) & 0xFF); + out.write(((id >>> 7) | 0x80) & 0xFF); + out.write(id & 0x7F); + } + } +} diff --git a/libjava/classpath/gnu/java/security/PolicyFile.java b/libjava/classpath/gnu/java/security/PolicyFile.java new file mode 100644 index 0000000..dd3a4de --- /dev/null +++ b/libjava/classpath/gnu/java/security/PolicyFile.java @@ -0,0 +1,667 @@ +/* PolicyFile.java -- policy file reader + Copyright (C) 2004, 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.java.security; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StreamTokenizer; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.Principal; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.security.Security; +import java.security.UnresolvedPermission; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * An implementation of a {@link java.security.Policy} object whose + * permissions are specified by a <em>policy file</em>. + * + * <p>The approximate syntax of policy files is:</p> + * + * <pre> + * policyFile ::= keystoreOrGrantEntries ; + * + * keystoreOrGrantEntries ::= keystoreOrGrantEntry | + * keystoreOrGrantEntries keystoreOrGrantEntry | + * EMPTY ; + * + * keystoreOrGrantEntry ::= keystoreEntry | grantEntry ; + * + * keystoreEntry ::= "keystore" keystoreUrl ';' | + * "keystore" keystoreUrl ',' keystoreAlgorithm ';' ; + * + * keystoreUrl ::= URL ; + * keystoreAlgorithm ::= STRING ; + * + * grantEntry ::= "grant" domainParameters '{' permissions '}' ';' + * + * domainParameters ::= domainParameter | + * domainParameter ',' domainParameters ; + * + * domainParameter ::= "signedBy" signerNames | + * "codeBase" codeBaseUrl | + * "principal" principalClassName principalName | + * "principal" principalName ; + * + * signerNames ::= quotedString ; + * codeBaseUrl ::= URL ; + * principalClassName ::= STRING ; + * principalName ::= quotedString ; + * + * quotedString ::= quoteChar STRING quoteChar ; + * quoteChar ::= '"' | '\''; + * + * permissions ::= permission | permissions permission ; + * + * permission ::= "permission" permissionClassName permissionTarget permissionAction | + * "permission" permissionClassName permissionTarget | + * "permission" permissionClassName; + * </pre> + * + * <p>Comments are either form of Java comments. Keystore entries only + * affect subsequent grant entries, so if a grant entry preceeds a + * keystore entry, that grant entry is not affected by that keystore + * entry. Certian instances of <code>${property-name}</code> will be + * replaced with <code>System.getProperty("property-name")</code> in + * quoted strings.</p> + * + * <p>This class will load the following files when created or + * refreshed, in order:</p> + * + * <ol> + * <li>The file <code>${java.home}/lib/security/java.policy</code>.</li> + * <li>All URLs specified by security properties + * <code>"policy.file.<i>n</i>"</code>, for increasing <i>n</i> + * starting from 1. The sequence stops at the first undefined + * property, so you must set <code>"policy.file.1"</code> if you also + * set <code>"policy.file.2"</code>, and so on.</li> + * <li>The URL specified by the property + * <code>"java.security.policy"</code>.</li> + * </ol> + * + * @author Casey Marshall (csm@gnu.org) + * @see java.security.Policy + */ +public final class PolicyFile extends Policy +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = true; + // Package-private to avoid a trampoline. + static void debug(String msg) + { + System.err.print(">> PolicyFile: "); + System.err.println(msg); + } + + private static void debug(Throwable t) + { + System.err.println(">> PolicyFile"); + t.printStackTrace(System.err); + } + + private static final String DEFAULT_POLICY = System.getProperty("java.home") + + System.getProperty("file.separator") + "lib" + + System.getProperty("file.separator") + "security" + + System.getProperty("file.separator") + "java.policy"; + + private final Map cs2pc; + + // Constructors. + // ------------------------------------------------------------------------- + + public PolicyFile() + { + cs2pc = new HashMap(); + refresh(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public PermissionCollection getPermissions(CodeSource codeSource) + { + Permissions perms = new Permissions(); + for (Iterator it = cs2pc.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry e = (Map.Entry) it.next(); + CodeSource cs = (CodeSource) e.getKey(); + if (cs.implies(codeSource)) + { + if (DEBUG) debug(cs+" -> "+codeSource); + PermissionCollection pc = (PermissionCollection) e.getValue(); + for (Enumeration ee = pc.elements(); ee.hasMoreElements(); ) + { + perms.add((Permission) ee.nextElement()); + } + } + else + if (DEBUG) debug(cs+" !-> "+codeSource); + } + if (DEBUG) debug ("returning permissions " + perms + " for " + codeSource); + return perms; + } + + public void refresh() + { + cs2pc.clear(); + List policyFiles = new LinkedList(); + try + { + policyFiles.add(new File(DEFAULT_POLICY).toURL()); + if (DEBUG) debug ("defualt policy is " + DEFAULT_POLICY); + policyFiles.addAll((List) AccessController.doPrivileged( + new PrivilegedExceptionAction() + { + public Object run() throws Exception + { + LinkedList l = new LinkedList(); + for (int i = 1; ; i++) + { + String s = Security.getProperty("policy.file."+i); + if (DEBUG) debug("policy.file."+i+"="+s); + if (s == null) + break; + l.add(new URL(s)); + } + String s = System.getProperty("java.security.policy"); + if (DEBUG) debug("java.security.policy="+s); + if (s != null) + l.add(new URL(s)); + return l; + } + })); + } + catch (PrivilegedActionException pae) + { + if (DEBUG) debug(pae); + } + catch (MalformedURLException mue) + { + if (DEBUG) debug(mue); + } + for (Iterator it = policyFiles.iterator(); it.hasNext(); ) + { + try + { + URL url = (URL) it.next(); + parse(url); + } + catch (IOException ioe) + { + if (DEBUG) debug(ioe); + } + } + } + + public String toString() + { + return super.toString() + " [ " + cs2pc.toString() + " ]"; + } + + // Own methods. + // ------------------------------------------------------------------------- + + private static final int STATE_BEGIN = 0; + private static final int STATE_GRANT = 1; + private static final int STATE_PERMS = 2; + + /** + * Parse a policy file, incorporating the permission definitions + * described therein. + * + * @param url The URL of the policy file to read. + * @throws IOException if an I/O error occurs, or if the policy file + * cannot be parsed. + */ + private void parse(final URL url) throws IOException + { + if (DEBUG) debug ("reading policy file from " + url); + final StreamTokenizer in = new StreamTokenizer(new InputStreamReader(url.openStream())); + in.resetSyntax(); + in.slashSlashComments(true); + in.slashStarComments(true); + in.wordChars('A', 'Z'); + in.wordChars('a', 'z'); + in.wordChars('0', '9'); + in.wordChars('.', '.'); + in.wordChars('_', '_'); + in.wordChars('$', '$'); + in.whitespaceChars(' ', ' '); + in.whitespaceChars('\t', '\t'); + in.whitespaceChars('\f', '\f'); + in.whitespaceChars('\n', '\n'); + in.whitespaceChars('\r', '\r'); + in.quoteChar('\''); + in.quoteChar('"'); + + int tok; + int state = STATE_BEGIN; + List keystores = new LinkedList(); + URL currentBase = null; + List currentCerts = new LinkedList(); + Permissions currentPerms = new Permissions(); + while ((tok = in.nextToken()) != StreamTokenizer.TT_EOF) + { + switch (tok) + { + case '{': + if (state != STATE_GRANT) + error(url, in, "spurious '{'"); + state = STATE_PERMS; + tok = in.nextToken(); + break; + case '}': + if (state != STATE_PERMS) + error(url, in, "spurious '}'"); + state = STATE_BEGIN; + currentPerms.setReadOnly(); + Certificate[] c = null; + if (!currentCerts.isEmpty()) + c = (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]); + cs2pc.put(new CodeSource(currentBase, c), currentPerms); + currentCerts.clear(); + currentPerms = new Permissions(); + currentBase = null; + tok = in.nextToken(); + if (tok != ';') + in.pushBack(); + continue; + } + if (tok != StreamTokenizer.TT_WORD) + { + error(url, in, "expecting word token"); + } + + // keystore "<keystore-path>" [',' "<keystore-type>"] ';' + if (in.sval.equalsIgnoreCase("keystore")) + { + String alg = KeyStore.getDefaultType(); + tok = in.nextToken(); + if (tok != '"' && tok != '\'') + error(url, in, "expecting key store URL"); + String store = in.sval; + tok = in.nextToken(); + if (tok == ',') + { + tok = in.nextToken(); + if (tok != '"' && tok != '\'') + error(url, in, "expecting key store type"); + alg = in.sval; + tok = in.nextToken(); + } + if (tok != ';') + error(url, in, "expecting semicolon"); + try + { + KeyStore keystore = KeyStore.getInstance(alg); + keystore.load(new URL(url, store).openStream(), null); + keystores.add(keystore); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + } + else if (in.sval.equalsIgnoreCase("grant")) + { + if (state != STATE_BEGIN) + error(url, in, "extraneous grant keyword"); + state = STATE_GRANT; + } + else if (in.sval.equalsIgnoreCase("signedBy")) + { + if (state != STATE_GRANT && state != STATE_PERMS) + error(url, in, "spurious 'signedBy'"); + if (keystores.isEmpty()) + error(url, in, "'signedBy' with no keystores"); + tok = in.nextToken(); + if (tok != '"' && tok != '\'') + error(url, in, "expecting signedBy name"); + StringTokenizer st = new StringTokenizer(in.sval, ","); + while (st.hasMoreTokens()) + { + String alias = st.nextToken(); + for (Iterator it = keystores.iterator(); it.hasNext(); ) + { + KeyStore keystore = (KeyStore) it.next(); + try + { + if (keystore.isCertificateEntry(alias)) + currentCerts.add(keystore.getCertificate(alias)); + } + catch (KeyStoreException kse) + { + error(url, in, kse.toString()); + } + } + } + tok = in.nextToken(); + if (tok != ',') + { + if (state != STATE_GRANT) + error(url, in, "spurious ','"); + in.pushBack(); + } + } + else if (in.sval.equalsIgnoreCase("codeBase")) + { + if (state != STATE_GRANT) + error(url, in, "spurious 'codeBase'"); + tok = in.nextToken(); + if (tok != '"' && tok != '\'') + error(url, in, "expecting code base URL"); + String base = expand(in.sval); + if (File.separatorChar != '/') + base = base.replace(File.separatorChar, '/'); + try + { + currentBase = new URL(base); + } + catch (MalformedURLException mue) + { + error(url, in, mue.toString()); + } + tok = in.nextToken(); + if (tok != ',') + in.pushBack(); + } + else if (in.sval.equalsIgnoreCase("principal")) + { + if (state != STATE_GRANT) + error(url, in, "spurious 'principal'"); + tok = in.nextToken(); + if (tok == StreamTokenizer.TT_WORD) + { + tok = in.nextToken(); + if (tok != '"' && tok != '\'') + error(url, in, "expecting principal name"); + String name = in.sval; + Principal p = null; + try + { + Class pclass = Class.forName(in.sval); + Constructor c = + pclass.getConstructor(new Class[] { String.class }); + p = (Principal) c.newInstance(new Object[] { name }); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + for (Iterator it = keystores.iterator(); it.hasNext(); ) + { + KeyStore ks = (KeyStore) it.next(); + try + { + for (Enumeration e = ks.aliases(); e.hasMoreElements(); ) + { + String alias = (String) e.nextElement(); + if (ks.isCertificateEntry(alias)) + { + Certificate cert = ks.getCertificate(alias); + if (!(cert instanceof X509Certificate)) + continue; + if (p.equals(((X509Certificate) cert).getSubjectDN()) || + p.equals(((X509Certificate) cert).getSubjectX500Principal())) + currentCerts.add(cert); + } + } + } + catch (KeyStoreException kse) + { + error(url, in, kse.toString()); + } + } + } + else if (tok == '"' || tok == '\'') + { + String alias = in.sval; + for (Iterator it = keystores.iterator(); it.hasNext(); ) + { + KeyStore ks = (KeyStore) it.next(); + try + { + if (ks.isCertificateEntry(alias)) + currentCerts.add(ks.getCertificate(alias)); + } + catch (KeyStoreException kse) + { + error(url, in, kse.toString()); + } + } + } + else + error(url, in, "expecting principal"); + tok = in.nextToken(); + if (tok != ',') + in.pushBack(); + } + else if (in.sval.equalsIgnoreCase("permission")) + { + if (state != STATE_PERMS) + error(url, in, "spurious 'permission'"); + tok = in.nextToken(); + if (tok != StreamTokenizer.TT_WORD) + error(url, in, "expecting permission class name"); + String className = in.sval; + Class clazz = null; + try + { + clazz = Class.forName(className); + } + catch (ClassNotFoundException cnfe) + { + } + tok = in.nextToken(); + if (tok == ';') + { + if (clazz == null) + { + currentPerms.add(new UnresolvedPermission(className, + null, null, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + continue; + } + try + { + currentPerms.add((Permission) clazz.newInstance()); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + continue; + } + if (tok != '"' && tok != '\'') + error(url, in, "expecting permission target"); + String target = expand(in.sval); + tok = in.nextToken(); + if (tok == ';') + { + if (clazz == null) + { + currentPerms.add(new UnresolvedPermission(className, + target, null, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + continue; + } + try + { + Constructor c = + clazz.getConstructor(new Class[] { String.class }); + currentPerms.add((Permission) c.newInstance( + new Object[] { target })); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + continue; + } + if (tok != ',') + error(url, in, "expecting ','"); + tok = in.nextToken(); + if (tok == StreamTokenizer.TT_WORD) + { + if (!in.sval.equalsIgnoreCase("signedBy")) + error(url, in, "expecting 'signedBy'"); + try + { + Constructor c = + clazz.getConstructor(new Class[] { String.class }); + currentPerms.add((Permission) c.newInstance( + new Object[] { target })); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + in.pushBack(); + continue; + } + if (tok != '"' && tok != '\'') + error(url, in, "expecting permission action"); + String action = in.sval; + if (clazz == null) + { + currentPerms.add(new UnresolvedPermission(className, + target, action, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + continue; + } + else + { + try + { + Constructor c = clazz.getConstructor( + new Class[] { String.class, String.class }); + currentPerms.add((Permission) c.newInstance( + new Object[] { target, action })); + } + catch (Exception x) + { + error(url, in, x.toString()); + } + } + tok = in.nextToken(); + if (tok != ';' && tok != ',') + error(url, in, "expecting ';' or ','"); + } + } + } + + /** + * Expand all instances of <code>"${property-name}"</code> into + * <code>System.getProperty("property-name")</code>. + */ + private static String expand(final String s) + { + final StringBuffer result = new StringBuffer(); + final StringBuffer prop = new StringBuffer(); + int state = 0; + for (int i = 0; i < s.length(); i++) + { + switch (state) + { + case 0: + if (s.charAt(i) == '$') + state = 1; + else + result.append(s.charAt(i)); + break; + case 1: + if (s.charAt(i) == '{') + state = 2; + else + { + state = 0; + result.append('$').append(s.charAt(i)); + } + break; + case 2: + if (s.charAt(i) == '}') + { + String p = prop.toString(); + if (p.equals("/")) + p = "file.separator"; + p = System.getProperty(p); + if (p == null) + p = ""; + result.append(p); + prop.setLength(0); + state = 0; + } + else + prop.append(s.charAt(i)); + break; + } + } + if (state != 0) + result.append('$').append('{').append(prop); + return result.toString(); + } + + /** + * I miss macros. + */ + private static void error(URL base, StreamTokenizer in, String msg) + throws IOException + { + throw new IOException(base+":"+in.lineno()+": "+msg); + } +} diff --git a/libjava/classpath/gnu/java/security/action/GetPropertyAction.java b/libjava/classpath/gnu/java/security/action/GetPropertyAction.java new file mode 100644 index 0000000..2886deb --- /dev/null +++ b/libjava/classpath/gnu/java/security/action/GetPropertyAction.java @@ -0,0 +1,89 @@ +/* GetPropertyAction.java + Copyright (C) 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.java.security.action; + +import java.security.PrivilegedAction; + +/** + * PrivilegedAction implementation that calls System.getProperty() with + * the property name passed to its constructor. + * + * Example of use: + * <code> + * GetPropertyAction action = new GetPropertyAction("http.proxyPort"); + * String port = AccessController.doPrivileged(action); + * </code> + */ +public class GetPropertyAction implements PrivilegedAction +{ + String name; + String value = null; + + public GetPropertyAction() + { + } + + public GetPropertyAction(String propName) + { + setParameters(propName); + } + + public GetPropertyAction(String propName, String defaultValue) + { + setParameters(propName, defaultValue); + } + + public Object run() + { + return System.getProperty(name, value); + } + + public GetPropertyAction setParameters(String propName) + { + this.name = propName; + this.value = null; + return this; + } + + public GetPropertyAction setParameters(String propName, String defaultValue) + { + this.name = propName; + this.value = defaultValue; + return this; + } +} diff --git a/libjava/classpath/gnu/java/security/action/GetSecurityPropertyAction.java b/libjava/classpath/gnu/java/security/action/GetSecurityPropertyAction.java new file mode 100644 index 0000000..97fa15d --- /dev/null +++ b/libjava/classpath/gnu/java/security/action/GetSecurityPropertyAction.java @@ -0,0 +1,93 @@ +/* GetSecurityPropertyAction.java + Copyright (C) 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.java.security.action; + +import java.security.PrivilegedAction; +import java.security.Security; + +/** + * PrivilegedAction implementation that calls Security.getProperty() + * with the property name passed to its constructor. + * + * Example of use: + * <code> + * GetSecurityPropertyAction action = new GetSecurityPropertyAction("javax.net.ssl.trustStorePassword"); + * String passwd = AccessController.doPrivileged(action); + * </code> + */ +public class GetSecurityPropertyAction implements PrivilegedAction +{ + private String name; + private String value; + + public GetSecurityPropertyAction() + { + } + + public GetSecurityPropertyAction(String propName) + { + setParameters(propName); + } + + public GetSecurityPropertyAction(String propName, String defaultValue) + { + setParameters(propName, defaultValue); + } + + public GetSecurityPropertyAction setParameters(String propName) + { + this.name = propName; + this.value = null; + return this; + } + + public GetSecurityPropertyAction setParameters(String propName, String defaultValue) + { + this.name = propName; + this.value = defaultValue; + return this; + } + + public Object run() + { + String val = Security.getProperty(name); + if (val == null) + val = value; + return val; + } +} diff --git a/libjava/classpath/gnu/java/security/action/SetAccessibleAction.java b/libjava/classpath/gnu/java/security/action/SetAccessibleAction.java new file mode 100644 index 0000000..77e5fc9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/action/SetAccessibleAction.java @@ -0,0 +1,77 @@ +/* SetAccessibleAction.java + Copyright (C) 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.java.security.action; + +import java.lang.reflect.AccessibleObject; +import java.security.PrivilegedAction; + +/** + * PrivilegedAction implementation that calls setAccessible(true) on the + * AccessibleObject passed to its constructor. + * + * Example of use: + * <code> + * Field dataField = cl.getDeclaredField("data"); + * AccessController.doPrivileged(new SetAccessibleAction(dataField)); + * </code> + */ +public class SetAccessibleAction implements PrivilegedAction +{ + AccessibleObject member; + + public SetAccessibleAction() + { + } + + public SetAccessibleAction(AccessibleObject member) + { + this.member = member; + } + + public Object run() + { + member.setAccessible(true); + return null; + } + + public SetAccessibleAction setMember(AccessibleObject member) + { + this.member = member; + return this; + } +} diff --git a/libjava/classpath/gnu/java/security/action/package.html b/libjava/classpath/gnu/java/security/action/package.html new file mode 100644 index 0000000..fc3dfa2 --- /dev/null +++ b/libjava/classpath/gnu/java/security/action/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.action package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.action</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/ber/BER.java b/libjava/classpath/gnu/java/security/ber/BER.java new file mode 100644 index 0000000..7efb1bf --- /dev/null +++ b/libjava/classpath/gnu/java/security/ber/BER.java @@ -0,0 +1,46 @@ +/* BER.java -- basic encoding rules (BER) constants. + Copyright (C) 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.java.security.ber; + +import gnu.java.security.der.DER; + +public interface BER extends DER +{ + BERValue END_OF_SEQUENCE = new BERValue(0, null); +} diff --git a/libjava/classpath/gnu/java/security/ber/BEREncodingException.java b/libjava/classpath/gnu/java/security/ber/BEREncodingException.java new file mode 100644 index 0000000..aad1093 --- /dev/null +++ b/libjava/classpath/gnu/java/security/ber/BEREncodingException.java @@ -0,0 +1,54 @@ +/* BEREncodingException.java --- BER Encoding Exception + Copyright (C) 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.java.security.ber; + +import gnu.java.security.der.DEREncodingException; + +public class BEREncodingException extends DEREncodingException +{ + public BEREncodingException() + { + super (); + } + + public BEREncodingException (String msg) + { + super (msg); + } +} diff --git a/libjava/classpath/gnu/java/security/ber/BERReader.java b/libjava/classpath/gnu/java/security/ber/BERReader.java new file mode 100644 index 0000000..53a3f3e --- /dev/null +++ b/libjava/classpath/gnu/java/security/ber/BERReader.java @@ -0,0 +1,103 @@ +/* BERReader.java -- basic encoding rules (BER) reader. + Copyright (C) 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.java.security.ber; + +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +public class BERReader extends DERReader implements BER +{ + + /** + * Create a new DER reader from a byte array. + * + * @param in The encoded bytes. + */ + public BERReader(byte[] in) + { + super(in); + } + + public BERReader (byte[] in, int off, int len) + { + super(in, off, len); + } + + /** + * Create a new DER readed from an input stream. + * + * @param in The encoded bytes. + */ + public BERReader(InputStream in) + { + super(in); + } + + public DERValue read() throws IOException + { + in.mark(2); + int tag = in.read(); + if (tag == -1) + throw new EOFException(); + int length = in.read(); + if (length == 0) + { + if (tag == 0) + return END_OF_SEQUENCE; + return new BERValue(tag, CONSTRUCTED_VALUE, new byte[] { (byte) tag, 0 }); + } + else + { + in.reset(); + return super.read(); + } + } + + public int peek() throws IOException + { + in.mark(1); + int ret = in.read(); + in.reset(); + return ret; + } +} diff --git a/libjava/classpath/gnu/java/security/ber/BERValue.java b/libjava/classpath/gnu/java/security/ber/BERValue.java new file mode 100644 index 0000000..aeaef39 --- /dev/null +++ b/libjava/classpath/gnu/java/security/ber/BERValue.java @@ -0,0 +1,82 @@ +/* BERReader.java -- basic encoding rules (BER) value. + Copyright (C) 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.java.security.ber; + +import gnu.java.security.der.DERValue; + +public class BERValue extends DERValue +{ + + private boolean indefinite; + + public BERValue(int tag, Object value, byte[] encoded) + { + super(tag, 0, value, encoded); + indefinite = true; + } + + public BERValue(int tag, int length, Object value, byte[] encoded) + { + super(tag, length, value, encoded); + } + + public BERValue(int tag, Object value) + { + super(tag, 0, value, null); + } + + public static boolean isIndefinite(DERValue value) + { + if (value instanceof BERValue) + return ((BERValue) value).getIndefinite(); + return false; + } + + public boolean getIndefinite() + { + return indefinite; + } + + public int getLength() + { + if (indefinite) + return 0; + return super.getLength(); + } +} diff --git a/libjava/classpath/gnu/java/security/ber/package.html b/libjava/classpath/gnu/java/security/ber/package.html new file mode 100644 index 0000000..348a83c --- /dev/null +++ b/libjava/classpath/gnu/java/security/ber/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.ber package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.ber</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/der/BitString.java b/libjava/classpath/gnu/java/security/der/BitString.java new file mode 100644 index 0000000..b88b145 --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/BitString.java @@ -0,0 +1,317 @@ +/* BitString.java -- Java representation of the BIT STRING type. + Copyright (C) 2003 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.java.security.der; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Immutable representation of a bit string, which is equivalent to a + * byte array except some number of the rightmost bits are ignored. For + * example, this could be the bit string: + * + * <pre> 00010101 11101101 11010xxx</pre> + * + * <p>Where the "xxx" represents three bits that should be ignored, and + * can have any value. + * + * @author Casey Marshall (csm@gnu.org) + */ +public class BitString implements Cloneable, Comparable +{ + + // Fields. + // ------------------------------------------------------------------------ + + /** The bits themselves. */ + private final byte[] bytes; + + /** + * The exportable byte array. This array has the ignored bits + * removed. + */ + private transient byte[] externBytes; + + /** The number of bits ignored at the end of the byte array. */ + private final int ignoredBits; + + /** This bit string as a boolean array. */ + private transient boolean[] boolVal; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a new bit string, shifting the given byte array if needed. + * + * @param bytes The byte array holding the bit string. + * @param ignoredBits The number of bits to ignore. + * @param doShift Pass true in this parameter if the byte array has + * not yet been shifted left by <i>ignoredBits</i>. + * @throws IllegalArgumentException If <i>ignoredBits</i> is negative + * or greater than 7. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes, int ignoredBits, boolean doShift) + { + this(bytes, 0, bytes.length, ignoredBits, doShift); + } + + /** + * Create a new bit string, shifting the given byte array if needed. + * + * @param bytes The byte array holding the bit string. + * @param offset The offset where the meaningful bytes begin. + * @param length The number of meaningful bytes. + * @param ignoredBits The number of bits to ignore. + * @param doShift Pass true in this parameter if the byte array has + * not yet been shifted left by <i>ignoredBits</i>. + * @throws IllegalArgumentException If <i>ignoredBits</i> is negative + * or greater than 7. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes, int offset, int length, + int ignoredBits, boolean doShift) + { + if (ignoredBits < 0 || ignoredBits > 7) + throw new IllegalArgumentException(); + if (bytes == null) + throw new NullPointerException(); + if (doShift && ignoredBits > 0) + { + this.externBytes = new byte[length]; + System.arraycopy(bytes, offset, externBytes, 0, length); + this.bytes = new BigInteger(externBytes).shiftLeft(ignoredBits) + .toByteArray(); + } + else + { + this.bytes = new byte[length]; + System.arraycopy(bytes, offset, this.bytes, 0, length); + } + this.ignoredBits = ignoredBits; + } + + /** + * Create a new bit string. + * + * @param bytes The byte array holding the bit string. + * @param offset The offset where the meaningful bytes begin. + * @param length The number of meaningful bytes. + * @param ignoredBits The number of bits to ignore. + * @throws IllegalArgumentException If <i>ignoredBits</i> is negative + * or greater than 7. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes, int offset, int length, int ignoredBits) + { + this(bytes, offset, length, ignoredBits, false); + } + + /** + * Create a new bit string. + * + * @param bytes The byte array holding the bit string. + * @param ignoredBits The number of bits to ignore. + * @throws IllegalArgumentException If <i>ignoredBits</i> is negative + * or greater than 7. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes, int ignoredBits) + { + this(bytes, 0, bytes.length, ignoredBits, false); + } + + /** + * Create a new bit string. + * + * @param bytes The byte array holding the bit string. + * @param offset The offset where the meaningful bytes begin. + * @param length The number of meaningful bytes. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes, int offset, int length) + { + this(bytes, offset, length, 0, false); + } + + /** + * Create a new bit string. + * + * @param bytes The byte array holding the bit string. + * @throws NullPointerException If <i>bytes</i> is null. + */ + public BitString(byte[] bytes) + { + this(bytes, 0, bytes.length, 0, false); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + /** + * Return this bit string as a byte array, with the ignored bits + * trimmed off. The byte array is cloned every time this method is + * called to prevent modification. + * + * @return The trimmed byte array. + */ + public byte[] toByteArray() + { + if (ignoredBits == 0) + return (byte[]) bytes.clone(); + if (externBytes == null) + externBytes = new BigInteger(bytes).shiftRight(ignoredBits).toByteArray(); + return (byte[]) externBytes.clone(); + } + + /** + * Returns this bit string as a byte array, with the ignored bits + * present. The byte array is cloned every time this method is + * called to prevent modification. + * + * @return The byte array. + */ + public byte[] getShiftedByteArray() + { + return (byte[]) bytes.clone(); + } + + /** + * Returns the number of ignored bits. + * + * @return The number of ignored bits. + */ + public int getIgnoredBits() + { + return ignoredBits; + } + + /** + * Returns the size, in bits, of this bit string. + * + * @return The size of this bit string. + */ + public int size() + { + return (bytes.length << 3) - ignoredBits; + } + + /** + * Return this bit string as a boolean array. The value returned is of + * size {@link #size()}, and each <code>true</code> value + * corresponding to each "1" in this bit string. The boolean array is + * cloned before it is returned. + * + * @return The boolean array. + */ + public boolean[] toBooleanArray() + { + if (boolVal == null) + { + boolVal = new boolean[size()]; + for (int i = 0, j = 7, k = 0; i < boolVal.length; i++) + { + boolVal[i] = (bytes[k] & 1 << j--) != 0; + if (j < 0) + { + j = 7; + k++; + } + } + } + return (boolean[]) boolVal.clone(); + } + + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException cce) + { + throw new InternalError(cce.getMessage()); + } + } + + public int compareTo(Object o) + { + BitString that = (BitString) o; + if (this.equals(that)) + return 0; + if (this.bytes.length != that.bytes.length) + return (this.bytes.length < that.bytes.length) ? -1 : 1; + if (this.ignoredBits != that.ignoredBits) + return (this.ignoredBits < that.ignoredBits) ? -1 : 1; + for (int i = 0; i < this.bytes.length; i++) + if (this.bytes[i] != that.bytes[i]) + return (this.bytes[i] < that.bytes[i]) ? -1 : 1; + return 0; // not reached. + } + + public boolean equals(Object o) + { + if (!(o instanceof BitString)) + return false; + BitString that = (BitString) o; + // True for cloned instances. + if (this.bytes == that.bytes && this.ignoredBits == that.ignoredBits) + return true; + if (this.ignoredBits == that.ignoredBits) + return Arrays.equals(this.bytes, that.bytes); + return false; + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + for (int i = 0, j = 7, k = 0; i < size(); i++) + { + sb.append((bytes[k] & 1 << j) != 0 ? "1" : "0"); + j--; + if (j < 0) + { + j = 7; + k++; + } + } + return sb.toString(); + } +} diff --git a/libjava/classpath/gnu/java/security/der/DER.java b/libjava/classpath/gnu/java/security/der/DER.java new file mode 100644 index 0000000..a7eb4a6 --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/DER.java @@ -0,0 +1,86 @@ +/* DER.java -- Basic constants in DER sequences. + Copyright (C) 2003 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.java.security.der; + +/** + * The set of tags for DER types. + * + * @author Casey Marshall (csm@gnu.org) + */ +public interface DER +{ + int UNIVERSAL = 0x00; + int APPLICATION = 0x40; + int CONTEXT = 0x80; + int PRIVATE = 0xC0; + + int CONSTRUCTED = 0x20; + + int ANY = 0x00; + int BOOLEAN = 0x01; + int INTEGER = 0x02; + int BIT_STRING = 0x03; + int OCTET_STRING = 0x04; + int NULL = 0x05; + int OBJECT_IDENTIFIER = 0x06; + int REAL = 0x09; + int ENUMERATED = 0x0a; + int RELATIVE_OID = 0x0d; + + int SEQUENCE = 0x10; + int SET = 0x11; + + Object CONSTRUCTED_VALUE = new Object(); + + int NUMERIC_STRING = 0x12; + int PRINTABLE_STRING = 0x13; + int T61_STRING = 0x14; + int VIDEOTEX_STRING = 0x15; + int IA5_STRING = 0x16; + int GRAPHIC_STRING = 0x19; + int ISO646_STRING = 0x1A; + int GENERAL_STRING = 0x1B; + + int UTF8_STRING = 0x0C; + int UNIVERSAL_STRING = 0x1C; + int BMP_STRING = 0x1E; + + int UTC_TIME = 0x17; + int GENERALIZED_TIME = 0x18; +} diff --git a/libjava/classpath/gnu/java/security/der/DEREncodingException.java b/libjava/classpath/gnu/java/security/der/DEREncodingException.java new file mode 100644 index 0000000..90042a3 --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/DEREncodingException.java @@ -0,0 +1,54 @@ +/* DEREncodingException.java --- DER Encoding Exception + Copyright (C) 1999,2003 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.java.security.der; + +import java.io.IOException; + +public class DEREncodingException extends IOException +{ + public DEREncodingException() + { + super (); + } + + public DEREncodingException (String msg) + { + super (msg); + } +} diff --git a/libjava/classpath/gnu/java/security/der/DERReader.java b/libjava/classpath/gnu/java/security/der/DERReader.java new file mode 100644 index 0000000..cb07f14 --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/DERReader.java @@ -0,0 +1,437 @@ +/* DERReader.java -- parses ASN.1 DER sequences + Copyright (C) 2003 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.java.security.der; + +import gnu.java.security.OID; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +/** + * This class decodes DER sequences into Java objects. The methods of + * this class do not have knowledge of higher-levels of structure in the + * DER stream -- such as ASN.1 constructions -- and it is therefore up + * to the calling application to determine if the data are structured + * properly by inspecting the {@link DERValue} that is returned. + * + * @author Casey Marshall (csm@gnu.org) + */ +public class DERReader implements DER +{ + + // Fields. + // ------------------------------------------------------------------------ + + protected InputStream in; + + protected final ByteArrayOutputStream encBuf; + + // Constructor. + // ------------------------------------------------------------------------ + + /** + * Create a new DER reader from a byte array. + * + * @param in The encoded bytes. + */ + public DERReader(byte[] in) + { + this(new ByteArrayInputStream(in)); + } + + public DERReader (byte[] in, int off, int len) + { + this (new ByteArrayInputStream (in, off, len)); + } + + /** + * Create a new DER readed from an input stream. + * + * @param in The encoded bytes. + */ + public DERReader(InputStream in) + { + if (!in.markSupported()) + this.in = new BufferedInputStream(in, 16384); + else + this.in = in; + encBuf = new ByteArrayOutputStream(2048); + } + + // Class methods. + // ------------------------------------------------------------------------ + + /** + * Convenience method for reading a single primitive value from the + * given byte array. + * + * @param encoded The encoded bytes. + * @throws IOException If the bytes do not represent an encoded + * object. + */ + public static DERValue read(byte[] encoded) throws IOException + { + return new DERReader(encoded).read(); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public void skip (int bytes) throws IOException + { + in.skip (bytes); + } + + /** + * Decode a single value from the input stream, returning it in a new + * {@link DERValue}. By "single value" we mean any single type in its + * entirety -- including constructed types such as SEQUENCE and all + * the values they contain. Usually it is sufficient to call this + * method once to parse and return the top-level structure, then to + * inspect the returned value for the proper contents. + * + * @return The parsed DER structure. + * @throws IOException If an error occurs reading from the input + * stream. + * @throws DEREncodingException If the input does not represent a + * valid DER stream. + */ + public DERValue read() throws IOException + { + int tag = in.read(); + if (tag == -1) + throw new EOFException(); + encBuf.write(tag); + int len = readLength(); + DERValue value = null; + if ((tag & CONSTRUCTED) == CONSTRUCTED) + { + in.mark(2048); + byte[] encoded = new byte[len]; + in.read(encoded); + encBuf.write(encoded); + value = new DERValue(tag, len, CONSTRUCTED_VALUE, encBuf.toByteArray()); + in.reset(); + encBuf.reset(); + return value; + } + switch (tag & 0xC0) + { + case UNIVERSAL: + value = new DERValue(tag, len, readUniversal(tag, len), + encBuf.toByteArray()); + encBuf.reset(); + break; + case CONTEXT: + byte[] encoded = new byte[len]; + in.read(encoded); + encBuf.write(encoded); + value = new DERValue(tag, len, encoded, encBuf.toByteArray()); + encBuf.reset(); + break; + case APPLICATION: + // This should not be reached, since (I think) APPLICATION is + // always constructed. + throw new DEREncodingException("non-constructed APPLICATION data"); + default: + throw new DEREncodingException("PRIVATE class not supported"); + } + return value; + } + + protected int readLength() throws IOException + { + int i = in.read(); + if (i == -1) + throw new EOFException(); + encBuf.write(i); + if ((i & ~0x7F) == 0) + { + return i; + } + else if (i < 0xFF) + { + byte[] octets = new byte[i & 0x7F]; + in.read(octets); + encBuf.write(octets); + return new BigInteger(1, octets).intValue(); + } + throw new DEREncodingException(); + } + + // Own methods. + // ------------------------------------------------------------------------ + + private Object readUniversal(int tag, int len) throws IOException + { + byte[] value = new byte[len]; + in.read(value); + encBuf.write(value); + switch (tag & 0x1F) + { + case BOOLEAN: + if (value.length != 1) + throw new DEREncodingException(); + return Boolean.valueOf(value[0] != 0); + case NULL: + if (len != 0) + throw new DEREncodingException(); + return null; + case INTEGER: + case ENUMERATED: + return new BigInteger(value); + case BIT_STRING: + byte[] bits = new byte[len - 1]; + System.arraycopy(value, 1, bits, 0, bits.length); + return new BitString(bits, value[0] & 0xFF); + case OCTET_STRING: + return value; + case NUMERIC_STRING: + case PRINTABLE_STRING: + case T61_STRING: + case VIDEOTEX_STRING: + case IA5_STRING: + case GRAPHIC_STRING: + case ISO646_STRING: + case GENERAL_STRING: + case UNIVERSAL_STRING: + case BMP_STRING: + case UTF8_STRING: + return makeString(tag, value); + case UTC_TIME: + case GENERALIZED_TIME: + return makeTime(tag, value); + case OBJECT_IDENTIFIER: + return new OID(value); + case RELATIVE_OID: + return new OID(value, true); + default: + throw new DEREncodingException("unknown tag " + tag); + } + } + + private static String makeString(int tag, byte[] value) + throws IOException + { + switch (tag & 0x1F) + { + case NUMERIC_STRING: + case PRINTABLE_STRING: + case T61_STRING: + case VIDEOTEX_STRING: + case IA5_STRING: + case GRAPHIC_STRING: + case ISO646_STRING: + case GENERAL_STRING: + return fromIso88591(value); + + case UNIVERSAL_STRING: + // XXX The docs say UniversalString is encoded in four bytes + // per character, but Java has no support (yet) for UTF-32. + //return new String(buf, "UTF-32"); + case BMP_STRING: + return fromUtf16Be(value); + + case UTF8_STRING: + return fromUtf8(value); + + default: + throw new DEREncodingException("unknown string tag"); + } + } + + private static String fromIso88591(byte[] bytes) + { + StringBuffer str = new StringBuffer(bytes.length); + for (int i = 0; i < bytes.length; i++) + str.append((char) (bytes[i] & 0xFF)); + return str.toString(); + } + + private static String fromUtf16Be(byte[] bytes) throws IOException + { + if ((bytes.length & 0x01) != 0) + throw new IOException("UTF-16 bytes are odd in length"); + StringBuffer str = new StringBuffer(bytes.length / 2); + for (int i = 0; i < bytes.length; i += 2) + { + char c = (char) ((bytes[i] << 8) & 0xFF); + c |= (char) (bytes[i+1] & 0xFF); + str.append(c); + } + return str.toString(); + } + + private static String fromUtf8(byte[] bytes) throws IOException + { + StringBuffer str = new StringBuffer((int)(bytes.length / 1.5)); + for (int i = 0; i < bytes.length; ) + { + char c = 0; + if ((bytes[i] & 0xE0) == 0xE0) + { + if ((i + 2) >= bytes.length) + throw new IOException("short UTF-8 input"); + c = (char) ((bytes[i++] & 0x0F) << 12); + if ((bytes[i] & 0x80) != 0x80) + throw new IOException("malformed UTF-8 input"); + c |= (char) ((bytes[i++] & 0x3F) << 6); + if ((bytes[i] & 0x80) != 0x80) + throw new IOException("malformed UTF-8 input"); + c |= (char) (bytes[i++] & 0x3F); + } + else if ((bytes[i] & 0xC0) == 0xC0) + { + if ((i + 1) >= bytes.length) + throw new IOException("short input"); + c = (char) ((bytes[i++] & 0x1F) << 6); + if ((bytes[i] & 0x80) != 0x80) + throw new IOException("malformed UTF-8 input"); + c |= (char) (bytes[i++] & 0x3F); + } + else if ((bytes[i] & 0xFF) < 0x80) + { + c = (char) (bytes[i++] & 0xFF); + } + else + throw new IOException("badly formed UTF-8 sequence"); + str.append(c); + } + return str.toString(); + } + + private Date makeTime(int tag, byte[] value) throws IOException + { + Calendar calendar = Calendar.getInstance(); + String str = makeString(PRINTABLE_STRING, value); + + // Classpath's SimpleDateFormat does not work for parsing these + // types of times, so we do this by hand. + String date = str; + String tz = ""; + if (str.indexOf("+") > 0) + { + date = str.substring(0, str.indexOf("+")); + tz = str.substring(str.indexOf("+")); + } + else if (str.indexOf("-") > 0) + { + date = str.substring(0, str.indexOf("-")); + tz = str.substring(str.indexOf("-")); + } + else if (str.endsWith("Z")) + { + date = str.substring(0, str.length()-2); + tz = "Z"; + } + if (!tz.equals("Z") && tz.length() > 0) + calendar.setTimeZone(TimeZone.getTimeZone(tz)); + else + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + if ((tag & 0x1F) == UTC_TIME) + { + if (date.length() < 10) // must be at least 10 chars long + throw new DEREncodingException("cannot parse date"); + // UTCTime is of the form "yyMMddHHmm[ss](Z|(+|-)hhmm)" + try + { + int year = Integer.parseInt(str.substring(0, 2)); + if (year < 50) + year += 2000; + else + year += 1900; + calendar.set(year, + Integer.parseInt(str.substring( 2, 4))-1, // month + Integer.parseInt(str.substring( 4, 6)), // day + Integer.parseInt(str.substring( 6, 8)), // hour + Integer.parseInt(str.substring( 8, 10))); // minute + if (date.length() == 12); + calendar.set(Calendar.SECOND, + Integer.parseInt(str.substring(10, 12))); + } + catch (NumberFormatException nfe) + { + throw new DEREncodingException("cannot parse date"); + } + } + else + { + if (date.length() < 10) // must be at least 10 chars long + throw new DEREncodingException("cannot parse date"); + // GeneralTime is of the form "yyyyMMddHH[mm[ss[(.|,)SSSS]]]" + // followed by "Z" or "(+|-)hh[mm]" + try + { + calendar.set( + Integer.parseInt(date.substring(0, 4)), // year + Integer.parseInt(date.substring(4, 6))-1, // month + Integer.parseInt(date.substring(6, 8)), // day + Integer.parseInt(date.substring(8, 10)), 0); // hour, min + switch (date.length()) + { + case 19: + case 18: + case 17: + case 16: + calendar.set(Calendar.MILLISECOND, + Integer.parseInt(date.substring(15))); + case 14: + calendar.set(Calendar.SECOND, + Integer.parseInt(date.substring(12, 14))); + case 12: + calendar.set(Calendar.MINUTE, + Integer.parseInt(date.substring(10, 12))); + } + } + catch (NumberFormatException nfe) + { + throw new DEREncodingException("cannot parse date"); + } + } + return calendar.getTime(); + } +} diff --git a/libjava/classpath/gnu/java/security/der/DERValue.java b/libjava/classpath/gnu/java/security/der/DERValue.java new file mode 100644 index 0000000..9a597d7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/DERValue.java @@ -0,0 +1,170 @@ +/* DERValue.java -- a value read or written to a DER encoding. + Copyright (C) 2003 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.java.security.der; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class DERValue implements DER +{ + + // Fields. + // ------------------------------------------------------------------------ + + private final int tagClass; + private final boolean constructed; + private final int tag; + private int length; + private final Object value; + private byte[] encoded; + + // Constructor. + // ------------------------------------------------------------------------ + + public DERValue(int tag, int length, Object value, byte[] encoded) + { + tagClass = tag & 0xC0; + this.tag = tag & 0x1F; + constructed = (tag & CONSTRUCTED) == CONSTRUCTED; + this.length = length; + this.value = value; + if (encoded != null) + this.encoded = (byte[]) encoded.clone(); + } + + public DERValue(int tag, Object value) + { + this(tag, 0, value, null); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public int getExternalTag() + { + return tagClass | tag | (constructed ? 0x20 : 0x00); + } + + public int getTag() + { + return tag; + } + + public int getTagClass() + { + return tagClass; + } + + public boolean isConstructed() + { + return constructed; + } + + public int getLength() + { + if (encoded == null) + { + try + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + length = DERWriter.write(out, this); + encoded = out.toByteArray(); + } + catch (IOException ioe) + { + encoded = new byte[0]; + } + } + return length; + } + + public Object getValue() + { + return value; + } + + public Object getValueAs (final int derType) throws IOException + { + byte[] encoded = getEncoded (); + encoded[0] = (byte) derType; + return DERReader.read (encoded).getValue (); + } + + public byte[] getEncoded() + { + if (encoded == null) + { + try + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + length = DERWriter.write(out, this); + encoded = out.toByteArray(); + } + catch (IOException ioe) + { + encoded = new byte[0]; + } + } + return (byte[]) encoded.clone(); + } + + public int getEncodedLength() + { + if (encoded == null) + { + try + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + length = DERWriter.write(out, this); + encoded = out.toByteArray(); + } + catch (IOException ioe) + { + encoded = new byte[0]; + } + } + return encoded.length; + } + + public String toString() + { + return "DERValue [ tag=" + tag + ", class=" + tagClass + ", constructed=" + + constructed + ", value=" + value + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/der/DERWriter.java b/libjava/classpath/gnu/java/security/der/DERWriter.java new file mode 100644 index 0000000..78524fc --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/DERWriter.java @@ -0,0 +1,349 @@ +/* DERWriter.java -- write Java types in DER format. + Copyright (C) 2003, 2004, 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.java.security.der; + +import gnu.java.security.OID; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.math.BigInteger; + +import java.text.SimpleDateFormat; + +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; + +/** + * Methods that allow various Java types to be written as a DER + * (Distinguished Encoding Rules) stream to the specified output stream. + * DER is used to encode ASN.1 constructions, but this class provides no + * methods for interacting with ASN.1. Rather, callers should construct + * their output objects properly for whatever ASN.1 construct is being + * output. + * + * <p>This class only defines static methods; there are no instance + * variables needed. + * + * @author Casey Marshall (csm@gnu.org) + */ +public class DERWriter implements DER +{ + + // Constructors. + // ------------------------------------------------------------------------ + + /** This class only has static methods. */ + private DERWriter() + { + } + + // Class methods. + // ------------------------------------------------------------------------ + + public static int write(OutputStream out, DERValue object) + throws IOException + { + out.write(object.getExternalTag()); + Object value = object.getValue(); + if (value == null) + { + writeLength(out, 0); + return 0; + } + if (value instanceof Boolean) + return writeBoolean(out, (Boolean) value); + else if (value instanceof BigInteger) + return writeInteger(out, (BigInteger) value); + else if (value instanceof Date) + return writeDate(out, object.getExternalTag(), (Date) value); + else if (value instanceof String) + return writeString(out, object.getExternalTag(), (String) value); + else if (value instanceof List) + return writeSequence(out, (List) value); + else if (value instanceof Set) + return writeSet(out, (Set) value); + else if (value instanceof BitString) + return writeBitString(out, (BitString) value); + else if (value instanceof OID) + return writeOID(out, (OID) value); + else if (value instanceof byte[]) + { + writeLength(out, ((byte[]) value).length); + out.write((byte[]) value); + return ((byte[]) value).length; + } + else if (value instanceof DERValue) + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + write(bout, (DERValue) value); + byte[] buf = bout.toByteArray(); + writeLength(out, buf.length); + out.write(buf); + return buf.length; + } + else + throw new DEREncodingException("cannot encode " + value.getClass().getName()); + } + + public static int definiteEncodingSize(int length) + { + if (length < 128) + return 1; + else if (length < 256) + return 2; + else if (length < 65536) + return 3; + else if (length < 16777216) + return 4; + else + return 5; + } + + // Own methods. + // ------------------------------------------------------------------------ + + /** + * Write a BOOLEAN type to the given output stream. + * + * @param out The sink output stream. + * @param b The boolean value to write. + */ + private static int writeBoolean(OutputStream out, Boolean b) + throws IOException + { + writeLength(out, 1); + if (b.booleanValue()) + out.write(0xFF); + else + out.write(0); + return 1; + } + + /** + * Write an INTEGER type to the given output stream. + * + * @param out The sink output stream. + * @param integer The integer to write. + */ + private static int writeInteger(OutputStream out, BigInteger integer) + throws IOException + { + byte[] bytes = integer.toByteArray(); + writeLength(out, bytes.length); + out.write(bytes); + return bytes.length; + } + + private static int writeSequence(OutputStream out, List sequence) + throws IOException + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + for (Iterator i = sequence.iterator(); i.hasNext(); ) + { + write(bout, (DERValue) i.next()); + } + byte[] buf = bout.toByteArray(); + writeLength(out, buf.length); + out.write(buf); + return buf.length; + } + + private static int writeSet(OutputStream out, Set set) + throws IOException + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + for (Iterator i = set.iterator(); i.hasNext(); ) + { + write(bout, (DERValue) i.next()); + } + byte[] buf = bout.toByteArray(); + writeLength(out, buf.length); + out.write(buf); + return buf.length; + } + + private static int writeOID(OutputStream out, OID oid) + throws IOException + { + byte[] der = oid.getDER(); + writeLength(out, der.length); + out.write(der); + return der.length; + } + + private static int writeBitString(OutputStream out, BitString bs) + throws IOException + { + byte[] buf = bs.getShiftedByteArray(); + out.write(buf.length + 1); + out.write(bs.getIgnoredBits()); + out.write(buf); + return buf.length; + } + + private static int writeString(OutputStream out, int tag, String str) + throws IOException + { + byte[] b = null; + switch (tag & 0x1F) + { + case NUMERIC_STRING: + case PRINTABLE_STRING: + case T61_STRING: + case VIDEOTEX_STRING: + case IA5_STRING: + case GRAPHIC_STRING: + case ISO646_STRING: + case GENERAL_STRING: + b = toIso88591(str); + break; + + case UNIVERSAL_STRING: + case BMP_STRING: + b = toUtf16Be(str); + break; + + case UTF8_STRING: + default: + b = toUtf8(str); + break; + } + writeLength(out, b.length); + out.write(b); + return b.length; + } + + private static byte[] toIso88591(String string) + { + byte[] result = new byte[string.length()]; + for (int i = 0; i < string.length(); i++) + result[i] = (byte) string.charAt(i); + return result; + } + + private static byte[] toUtf16Be(String string) + { + byte[] result = new byte[string.length() * 2]; + for (int i = 0; i < string.length(); i++) + { + result[i*2 ] = (byte) ((string.charAt(i) >>> 8) & 0xFF); + result[i*2+1] = (byte) (string.charAt(i) & 0xFF); + } + return result; + } + + private static byte[] toUtf8(String string) + { + ByteArrayOutputStream buf = + new ByteArrayOutputStream((int)(string.length() * 1.5)); + for (int i = 0; i < string.length(); i++) + { + char c = string.charAt(i); + if (c < 0x0080) + buf.write(c & 0xFF); + else if (c < 0x0800) + { + buf.write(0xC0 | ((c >>> 6) & 0x3F)); + buf.write(0x80 | (c & 0x3F)); + } + else + { + buf.write(0xE0 | ((c >>> 12) & 0x0F)); + buf.write(0x80 | ((c >>> 6) & 0x3F)); + buf.write(0x80 | (c & 0x3F)); + } + } + return buf.toByteArray(); + } + + private static int writeDate(OutputStream out, int tag, Date date) + throws IOException + { + SimpleDateFormat sdf = null; + if ((tag & 0x1F) == UTC_TIME) + sdf = new SimpleDateFormat("yyMMddHHmmss'Z'"); + else + sdf = new SimpleDateFormat("yyyyMMddHHmmss'.'SSS'Z'"); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + byte[] b = sdf.format(date).getBytes("ISO-8859-1"); + writeLength(out, b.length); + out.write(b); + return b.length; + } + + // Package method. + // ------------------------------------------------------------------------ + + static void writeLength(OutputStream out, int len) throws IOException + { + if (len < 128) + out.write(len); + else if (len < 256) + { + out.write(0x81); + out.write(len); + } + else if (len < 65536) + { + out.write(0x82); + out.write(len >> 8); + out.write(len); + } + else if (len < 16777216) + { + out.write(0x83); + out.write(len >> 16); + out.write(len >> 8); + out.write(len); + } + else + { + out.write(0x84); + out.write(len >> 24); + out.write(len >> 16); + out.write(len >> 8); + out.write(len); + } + } +} diff --git a/libjava/classpath/gnu/java/security/der/package.html b/libjava/classpath/gnu/java/security/der/package.html new file mode 100644 index 0000000..e74b0db --- /dev/null +++ b/libjava/classpath/gnu/java/security/der/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.der package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.der</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/package.html b/libjava/classpath/gnu/java/security/package.html new file mode 100644 index 0000000..bb6e91d --- /dev/null +++ b/libjava/classpath/gnu/java/security/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/pkcs/PKCS7SignedData.java b/libjava/classpath/gnu/java/security/pkcs/PKCS7SignedData.java new file mode 100644 index 0000000..ba5efc7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/pkcs/PKCS7SignedData.java @@ -0,0 +1,364 @@ +/* PKCS7SignedData.java -- reader for PKCS#7 signedData objects + Copyright (C) 2004, 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.java.security.pkcs; + +import gnu.java.security.OID; +import gnu.java.security.ber.BER; +import gnu.java.security.ber.BEREncodingException; +import gnu.java.security.ber.BERReader; +import gnu.java.security.ber.BERValue; +import gnu.java.security.der.DERValue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.math.BigInteger; + +import java.security.cert.CRL; +import java.security.cert.CRLException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + * The SignedData object in PKCS #7. This is a read-only implementation of + * this format, and is used to provide signed Jar file support. + * + * @author Casey Marshall (csm@gnu.org) + */ +public class PKCS7SignedData +{ + + public static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1"); + public static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2"); + + private BigInteger version; + private Set digestAlgorithms; + private OID contentType; + private byte[] content; + private Certificate[] certificates; + private CRL[] crls; + private Set signerInfos; + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + System.err.print("PKCS7SignedData >> "); + System.err.println(msg); + } + + public PKCS7SignedData(InputStream in) + throws CRLException, CertificateException, IOException + { + this(new BERReader(in)); + } + + /** + * Parse an encoded PKCS#7 SignedData object. The ASN.1 format of this + * object is: + * + * <pre> + * SignedData ::= SEQUENCE { + * version Version, + * digestAlgorithms DigestAlgorithmIdentifiers, + * contentInfo ContentInfo, + * certificates + * [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, + * crls + * [1] IMPLICIT CertificateRevocationLists OPTIONAL, + * signerInfos SignerInfos } + * + * Version ::= INTEGER + * + * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * ContentInfo ::= SEQUENCE { + * contentType ContentType, + * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } + * + * ContentType ::= OBJECT IDENTIFIER + * + * ExtendedCertificatesAndCertificates ::= + * SET OF ExtendedCertificatesAndCertificate + * + * ExtendedCertificatesAndCertificate ::= CHOICE { + * certificate Certificate, -- from X.509 + * extendedCertificate [0] IMPLICIT ExtendedCertificate } + * + * CertificateRevocationLists ::= SET OF CertificateRevocationList + * -- from X.509 + * + * SignerInfos ::= SET OF SignerInfo + * + * SignerInfo ::= SEQUENCE { + * version Version, + * issuerAndSerialNumber IssuerAndSerialNumber, + * digestAlgorithm DigestAlgorithmIdentifier, + * authenticatedAttributes + * [0] IMPLICIT Attributes OPTIONAL, + * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, + * encryptedDigest EncryptedDigest, + * unauthenticatedAttributes + * [1] IMPLICIT Attributes OPTIONAL } + * + * EncryptedDigest ::= OCTET STRING + * </pre> + * + * <p>(Readers who are confused as to why it takes 40 levels of indirection + * to specify "data with a signature", rest assured that the present author + * is as confused as you are).</p> + */ + public PKCS7SignedData(BERReader ber) + throws CRLException, CertificateException, IOException + { + CertificateFactory x509 = CertificateFactory.getInstance("X509"); + DERValue val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed ContentInfo"); + + val = ber.read(); + if (val.getTag() != BER.OBJECT_IDENTIFIER) + throw new BEREncodingException("malformed ContentType"); + + if (!PKCS7_SIGNED_DATA.equals(val.getValue())) + throw new BEREncodingException("content is not SignedData"); + + val = ber.read(); + if (val.getTag() != 0) + throw new BEREncodingException("malformed Content"); + + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed SignedData"); + + if (DEBUG) + debug("SignedData: " + val); + + val = ber.read(); + if (val.getTag() != BER.INTEGER) + throw new BEREncodingException("expecting Version"); + version = (BigInteger) val.getValue(); + + if (DEBUG) + debug(" Version: " + version); + + digestAlgorithms = new HashSet(); + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed DigestAlgorithmIdentifiers"); + if (DEBUG) + debug(" DigestAlgorithmIdentifiers: " + val); + int count = 0; + DERValue val2 = ber.read(); + while (val2 != BER.END_OF_SEQUENCE && + (val.getLength() > 0 && val.getLength() > count)) + { + if (!val2.isConstructed()) + throw new BEREncodingException("malformed AlgorithmIdentifier"); + if (DEBUG) + debug(" AlgorithmIdentifier: " + val2); + count += val2.getEncodedLength(); + val2 = ber.read(); + if (val2.getTag() != BER.OBJECT_IDENTIFIER) + throw new BEREncodingException("malformed AlgorithmIdentifier"); + if (DEBUG) + debug(" ID: " + val2.getValue()); + List algId = new ArrayList(2); + algId.add(val2.getValue()); + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + { + count += val2.getEncodedLength(); + if (val2.getTag() == BER.NULL) + algId.add(null); + else + algId.add(val2.getEncoded()); + if (DEBUG) + debug(" params: " + new BigInteger(1, val2.getEncoded()).toString(16)); + if (val2.isConstructed()) + ber.skip(val2.getLength()); + if (BERValue.isIndefinite(val)) + val2 = ber.read(); + } + else + algId.add(null); + digestAlgorithms.add(algId); + } + + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed ContentInfo"); + if (DEBUG) + debug(" ContentInfo: " + val); + val2 = ber.read(); + if (val2.getTag() != BER.OBJECT_IDENTIFIER) + throw new BEREncodingException("malformed ContentType"); + contentType = (OID) val2.getValue(); + if (DEBUG) + debug(" ContentType: " + contentType); + if (BERValue.isIndefinite(val) + || (val.getLength() > 0 && val.getLength() > val2.getEncodedLength())) + { + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + { + content = val2.getEncoded(); + if (BERValue.isIndefinite(val)) + val2 = ber.read(); + if (DEBUG) + debug(" Content: " + new BigInteger(1, content).toString(16)); + } + } + + val = ber.read(); + if (val.getTag() == 0) + { + if (!val.isConstructed()) + throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates"); + if (DEBUG) + debug(" ExtendedCertificatesAndCertificates: " + val); + count = 0; + val2 = ber.read(); + List certs = new LinkedList(); + while (val2 != BER.END_OF_SEQUENCE && + (val.getLength() > 0 && val.getLength() > count)) + { + Certificate cert = + x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded())); + if (DEBUG) + debug(" Certificate: " + cert); + certs.add(cert); + count += val2.getEncodedLength(); + ber.skip(val2.getLength()); + if (BERValue.isIndefinite(val) || val.getLength() > count) + val2 = ber.read(); + } + certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]); + val = ber.read(); + } + + if (val.getTag() == 1) + { + if (!val.isConstructed()) + throw new BEREncodingException("malformed CertificateRevocationLists"); + if (DEBUG) + debug(" CertificateRevocationLists: " + val); + count = 0; + val2 = ber.read(); + List crls = new LinkedList(); + while (val2 != BER.END_OF_SEQUENCE && + (val.getLength() > 0 && val.getLength() > count)) + { + CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded())); + if (DEBUG) + debug (" CRL: " + crl); + crls.add(crl); + count += val2.getEncodedLength(); + ber.skip(val2.getLength()); + if (BERValue.isIndefinite(val) || val.getLength() > count) + val2 = ber.read(); + } + this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]); + val = ber.read(); + } + + signerInfos = new HashSet(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed SignerInfos"); + + if (DEBUG) + debug(" SignerInfos: " + val); + + // FIXME read this more carefully. + // Since we are just reading a file (probably) we just read until we + // reach the end. + while (true) + { + int i = ber.peek(); + if (i == 0 || i == -1) + break; + signerInfos.add(new SignerInfo(ber)); + } + } + + public BigInteger getVersion() + { + return version; + } + + public Certificate[] getCertificates() + { + return (certificates != null ? (Certificate[]) certificates.clone() + : null); + } + + public OID getContentType() + { + return contentType; + } + + public byte[] getContent() + { + return (content != null ? (byte[]) content.clone() : null); + } + + public Set getDigestAlgorithms() + { + // FIXME copy contents too, they are mutable!!! + return Collections.unmodifiableSet(digestAlgorithms); + } + + public Set getSignerInfos() + { + Set copy = new HashSet(); + for (Iterator it = signerInfos.iterator(); it.hasNext(); ) + copy.add(it.next()); + return Collections.unmodifiableSet(copy); + } +} diff --git a/libjava/classpath/gnu/java/security/pkcs/SignerInfo.java b/libjava/classpath/gnu/java/security/pkcs/SignerInfo.java new file mode 100644 index 0000000..c976799 --- /dev/null +++ b/libjava/classpath/gnu/java/security/pkcs/SignerInfo.java @@ -0,0 +1,279 @@ +/* SignerInfo.java -- a SignerInfo object, from PKCS #7 + Copyright (C) 2004, 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.java.security.pkcs; + +import gnu.java.security.OID; +import gnu.java.security.ber.BER; +import gnu.java.security.ber.BEREncodingException; +import gnu.java.security.ber.BERReader; +import gnu.java.security.ber.BERValue; +import gnu.java.security.der.DERValue; + +import java.io.IOException; + +import java.math.BigInteger; + +import javax.security.auth.x500.X500Principal; + +public class SignerInfo +{ + private final BigInteger version; + private final BigInteger serialNumber; + private final X500Principal issuer; + private final OID digestAlgorithmId; + private final byte[] digestAlgorithmParams; + private final byte[] authenticatedAttributes; + private final OID digestEncryptionAlgorithmId; + private final byte[] digestEncryptionAlgorithmParams; + private final byte[] encryptedDigest; + private final byte[] unauthenticatedAttributes; + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + System.err.print("SignerInfo >> "); + System.err.println(msg); + } + + /** + * Parse a SignerInfo object. + */ + public SignerInfo(BERReader ber) throws IOException + { + DERValue val = ber.read(); + if (DEBUG) + debug("SignerInfo: " + val); + if (!val.isConstructed()) + throw new BEREncodingException("malformed SignerInfo"); + + val = ber.read(); + if (val.getTag() != BER.INTEGER) + throw new BEREncodingException("malformed Version"); + version = (BigInteger) val.getValue(); + + if (DEBUG) + debug(" Version: " + version); + + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed IssuerAndSerialNumber"); + + if (DEBUG) + debug(" IssuerAndSerialNumber: " + val); + + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed Issuer"); + issuer = new X500Principal(val.getEncoded()); + ber.skip(val.getLength()); + if (DEBUG) + debug(" Issuer: " + issuer); + + val = ber.read(); + if (val.getTag() != BER.INTEGER) + throw new BEREncodingException("malformed SerialNumber"); + serialNumber = (BigInteger) val.getValue(); + if (DEBUG) + debug(" SerialNumber: " + serialNumber); + + val = ber.read(); + if (!val.isConstructed()) + throw new BEREncodingException("malformed DigestAlgorithmIdentifier"); + if (DEBUG) + debug(" DigestAlgorithmIdentifier: " + val); + + int count = 0; + DERValue val2 = ber.read(); + if (val2.getTag() != BER.OBJECT_IDENTIFIER) + throw new BEREncodingException("malformed AlgorithmIdentifier"); + digestAlgorithmId = (OID) val2.getValue(); + if (DEBUG) + debug(" OID: " + digestAlgorithmId); + + if (BERValue.isIndefinite(val)) + { + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + { + digestAlgorithmParams = val2.getEncoded(); + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + throw new BEREncodingException("expecting BER end-of-sequence"); + } + else + digestAlgorithmParams = null; + } + else if (val2.getEncodedLength() < val.getLength()) + { + val2 = ber.read(); + digestAlgorithmParams = val2.getEncoded(); + if (val2.isConstructed()) + ber.skip(val2.getLength()); + } + else + digestAlgorithmParams = null; + if(DEBUG) + debug(" params: " + (digestAlgorithmParams == null ? null + : new BigInteger(digestAlgorithmParams).toString(16))); + + val = ber.read(); + if (val.getTag() == 0) + { + authenticatedAttributes = val.getEncoded(); + val = ber.read(); + if (val.isConstructed()) + ber.skip(val.getLength()); + if (DEBUG) + debug(" AuthenticatedAttributes: " + val); + val = ber.read(); + } + else + authenticatedAttributes = null; + + if (!val.isConstructed()) + throw new BEREncodingException("malformed DigestEncryptionAlgorithmIdentifier"); + if (DEBUG) + debug(" DigestEncryptionAlgorithmIdentifier: " + val); + count = 0; + val2 = ber.read(); + if (val2.getTag() != BER.OBJECT_IDENTIFIER) + throw new BEREncodingException("malformed AlgorithmIdentifier"); + digestEncryptionAlgorithmId = (OID) val2.getValue(); + if (DEBUG) + debug(" OID: " + digestEncryptionAlgorithmId); + + if (BERValue.isIndefinite(val)) + { + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + { + digestEncryptionAlgorithmParams = val2.getEncoded(); + val2 = ber.read(); + if (val2 != BER.END_OF_SEQUENCE) + throw new BEREncodingException("expecting BER end-of-sequence"); + } + else + digestEncryptionAlgorithmParams = null; + } + else if (val2.getEncodedLength() < val.getLength()) + { + val2 = ber.read(); + digestEncryptionAlgorithmParams = val2.getEncoded(); + if (val2.isConstructed()) + ber.skip(val2.getLength()); + } + else + digestEncryptionAlgorithmParams = null; + if(DEBUG) + debug(" params: " + (digestEncryptionAlgorithmParams == null ? null + : new BigInteger(digestEncryptionAlgorithmParams).toString(16))); + + val = ber.read(); + if (val.getTag() != BER.OCTET_STRING) + throw new BEREncodingException("malformed EncryptedDigest"); + encryptedDigest = (byte[]) val.getValue(); + if (DEBUG) + debug(" EncryptedDigest: " + new BigInteger(1, encryptedDigest).toString(16)); + + if (ber.peek() == 1) + unauthenticatedAttributes = ber.read().getEncoded(); + else + unauthenticatedAttributes = null; + + if (ber.peek() == 0) + ber.read(); + } + + public BigInteger getVersion() + { + return version; + } + + public BigInteger getSerialNumber() + { + return serialNumber; + } + + public X500Principal getIssuer() + { + return issuer; + } + + public OID getDigestAlgorithmId() + { + return digestAlgorithmId; + } + + public byte[] getDigestAlgorithmParams() + { + return (digestAlgorithmParams != null + ? (byte[]) digestAlgorithmParams.clone() + : null); + } + + public byte[] getAuthenticatedAttributes() + { + return (authenticatedAttributes != null + ? (byte[]) authenticatedAttributes.clone() + : null); + } + + public OID getDigestEncryptionAlgorithmId() + { + return digestEncryptionAlgorithmId; + } + + public byte[] getDigestEncryptionAlgorithmParams() + { + return (digestEncryptionAlgorithmParams != null + ? (byte[]) digestEncryptionAlgorithmParams.clone() + : null); + } + + public byte[] getEncryptedDigest() + { + return (encryptedDigest != null ? (byte[]) encryptedDigest.clone() : null); + } + + public byte[] getUnauthenticatedAttributes() + { + return (unauthenticatedAttributes != null + ? (byte[]) unauthenticatedAttributes.clone() + : null); + } +} diff --git a/libjava/classpath/gnu/java/security/pkcs/package.html b/libjava/classpath/gnu/java/security/pkcs/package.html new file mode 100644 index 0000000..60d658f --- /dev/null +++ b/libjava/classpath/gnu/java/security/pkcs/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.pkcs package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.pkcs</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java b/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java new file mode 100644 index 0000000..4bf3d54 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/CollectionCertStoreImpl.java @@ -0,0 +1,102 @@ +/* CollectionCertStore.java -- Collection-based cert store. + Copyright (C) 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.java.security.provider; + +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.CertSelector; +import java.security.cert.CertStoreException; +import java.security.cert.CertStoreParameters; +import java.security.cert.CertStoreSpi; +import java.security.cert.Certificate; +import java.security.cert.CollectionCertStoreParameters; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +public final class CollectionCertStoreImpl extends CertStoreSpi +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final Collection store; + + // Constructors. + // ------------------------------------------------------------------------- + + public CollectionCertStoreImpl(CertStoreParameters params) + throws InvalidAlgorithmParameterException + { + super(params); + if (! (params instanceof CollectionCertStoreParameters)) + throw new InvalidAlgorithmParameterException("not a CollectionCertStoreParameters object"); + store = ((CollectionCertStoreParameters) params).getCollection(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Collection engineGetCertificates(CertSelector selector) + throws CertStoreException + { + LinkedList result = new LinkedList(); + for (Iterator it = store.iterator(); it.hasNext(); ) + { + Object o = it.next(); + if ((o instanceof Certificate) && selector.match((Certificate) o)) + result.add(o); + } + return result; + } + + public Collection engineGetCRLs(CRLSelector selector) + throws CertStoreException + { + LinkedList result = new LinkedList(); + for (Iterator it = store.iterator(); it.hasNext(); ) + { + Object o = it.next(); + if ((o instanceof CRL) && selector.match((CRL) o)) + result.add(o); + } + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java new file mode 100644 index 0000000..7e154e2 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java @@ -0,0 +1,134 @@ +/* DSAKeyFactory.java -- DSA key factory. + Copyright (C) 2003 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.java.security.provider; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; + +/** + * DSA key factory. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class DSAKeyFactory extends KeyFactorySpi +{ + + // Constructor. + // ------------------------------------------------------------------------ + + public DSAKeyFactory() + { + super(); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + if (!(keySpec instanceof DSAPrivateKeySpec)) + throw new InvalidKeySpecException(); + return new GnuDSAPrivateKey( + ((DSAPrivateKeySpec) keySpec).getX(), + ((DSAPrivateKeySpec) keySpec).getP(), + ((DSAPrivateKeySpec) keySpec).getQ(), + ((DSAPrivateKeySpec) keySpec).getG()); + } + + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + if (!(keySpec instanceof DSAPublicKeySpec)) + throw new InvalidKeySpecException(); + return new GnuDSAPublicKey( + ((DSAPublicKeySpec) keySpec).getY(), + ((DSAPublicKeySpec) keySpec).getP(), + ((DSAPublicKeySpec) keySpec).getQ(), + ((DSAPublicKeySpec) keySpec).getG()); + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if ((key instanceof DSAPublicKey) && + keySpec.isAssignableFrom(DSAPublicKeySpec.class)) + { + return new DSAPublicKeySpec(((DSAPublicKey) key).getY(), + ((DSAPublicKey) key).getParams().getP(), + ((DSAPublicKey) key).getParams().getQ(), + ((DSAPublicKey) key).getParams().getG()); + } + if ((key instanceof DSAPrivateKey) && + keySpec.isAssignableFrom(DSAPrivateKeySpec.class)) + { + return new DSAPrivateKeySpec(((DSAPrivateKey) key).getX(), + ((DSAPrivateKey) key).getParams().getP(), + ((DSAPrivateKey) key).getParams().getQ(), + ((DSAPrivateKey) key).getParams().getG()); + } + throw new InvalidKeySpecException(); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + if ((key instanceof GnuDSAPublicKey) || (key instanceof GnuDSAPrivateKey)) + return key; + if (key instanceof DSAPublicKey) + return new GnuDSAPublicKey(((DSAPublicKey) key).getY(), + ((DSAPublicKey) key).getParams().getP(), + ((DSAPublicKey) key).getParams().getQ(), + ((DSAPublicKey) key).getParams().getG()); + if (key instanceof DSAPrivateKey) + return new GnuDSAPrivateKey(((DSAPrivateKey) key).getX(), + ((DSAPrivateKey) key).getParams().getP(), + ((DSAPrivateKey) key).getParams().getQ(), + ((DSAPrivateKey) key).getParams().getG()); + throw new InvalidKeyException(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java new file mode 100644 index 0000000..2c643d5 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java @@ -0,0 +1,171 @@ +/* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator + Copyright (C) 1999 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.java.security.provider; + +import java.math.BigInteger; +import java.security.AlgorithmParameterGenerator; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidParameterException; +import java.security.KeyPair; +import java.security.KeyPairGeneratorSpi; +import java.security.SecureRandom; +import java.security.interfaces.DSAParams; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.util.Random; + +public class DSAKeyPairGenerator extends KeyPairGeneratorSpi + implements java.security.interfaces.DSAKeyPairGenerator +{ +int keysize; +SecureRandom random; +private BigInteger q = null; // the small prime +private BigInteger p = null; // the big prime +private BigInteger g = null; + +DSAKeyPairGenerator() +{ + keysize = 1024; +} + +public void initialize(int keysize, SecureRandom random) +{ + //if( ((keysize % 64) != 0) || (keysize < 512) || (keysize > 1024) ) + // throw new InvalidAlgorithmParameterException("Invalid key size"); + + this.keysize = keysize; + this.random = random; +} + +public void initialize(AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException +{ + if( !( params instanceof DSAParameterSpec ) ) + throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec"); + + DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params; + p = dsaparameterspec.getP(); + q = dsaparameterspec.getQ(); + g = dsaparameterspec.getG(); + this.random = random; +} + +public void initialize(DSAParams params, SecureRandom random) + throws InvalidParameterException +{ + if(params.getP() != null) + p = params.getP(); + else + throw new InvalidParameterException(); + + if(params.getQ() != null) + q = params.getQ(); + else + throw new InvalidParameterException(); + + if(params.getG() != null) + g = params.getG(); + else + throw new InvalidParameterException(); + + this.random = random; +} + +public void initialize(int modlen, boolean genParams, SecureRandom random) + throws InvalidParameterException +{ + if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) ) + throw new InvalidParameterException(); + + if( (genParams == false) && (modlen != 512) && (modlen != 768) && (modlen != 1024) ) + throw new InvalidParameterException(); + this.keysize = modlen; + this.random = random; + p = null; + q = null; + g = null; +} + +public KeyPair generateKeyPair() +{ + if( getDefaults() == false) { + try { + AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA"); + AlgorithmParameters apDSA = apgDSA.generateParameters(); + DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class ); + p = dsaparameterspec.getP(); + q = dsaparameterspec.getQ(); + g = dsaparameterspec.getG(); + } catch ( Exception e ) { + return null; + } + } + + BigInteger x = new BigInteger( 159, new Random() ); + + BigInteger y = g.modPow( x, p ); + + return new KeyPair( new GnuDSAPublicKey(y,p,q,g), new GnuDSAPrivateKey(x,p,q,g)); + //return new KeyPair( public, private ); +} + +//These constants are Sun's Constants copied from the +//Cryptography Specification +private boolean getDefaults() +{ + if( keysize == 512) { + p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16); + q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16); + g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16); + return true; + } else if( keysize == 768) { + p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16); + q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16); + g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16); + } else if( keysize == 512) { + p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16); + q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16); + g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16); + } + return false; +} + +} diff --git a/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java new file mode 100644 index 0000000..ccec113 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DSAParameterGenerator.java @@ -0,0 +1,128 @@ +/* DSAParameterGenerator.java --- DSA Parameter Generator Implementation + Copyright (C) 1999 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.java.security.provider; + +import gnu.java.security.util.Prime; + +import java.math.BigInteger; +import java.security.AlgorithmParameterGeneratorSpi; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.util.Random; + +public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi +{ + private int size; + private SecureRandom random = null; + + public DSAParameterGenerator() + { + size = 1024; + } + + public void engineInit(int size, SecureRandom random) + { + if( (size < 512) || (size > 1024) || ( (size % 64) != 0) ) + //throw new InvalidAlgorithmParameterException("Invalid Size"); + return; + this.size = size; + this.random = random; + } + + public void engineInit(AlgorithmParameterSpec genParamSpec, SecureRandom random) + throws InvalidAlgorithmParameterException + { + if( !( genParamSpec instanceof DSAParameterSpec ) ) + throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec"); + + DSAParameterSpec dsaparameterspec = (DSAParameterSpec)genParamSpec; + int tmp = dsaparameterspec.getP().bitLength(); + + if( (tmp < 512) || (tmp > 1024) || ( (tmp % 64) != 0) ) + throw new InvalidAlgorithmParameterException("Invalid Size"); + + this.random = random; + } + + //For more information see IEEE P1363 A.16.1 (10/05/98 Draft) + public AlgorithmParameters engineGenerateParameters() + { + DSAParameterSpec dsaparameterspec; + + int L = size; + BigInteger r, p, k, h, g; + + //q 2^159 < q < 2^160 + r = Prime.generateRandomPrime( 159, 160, BigInteger.valueOf(1)); + + // 2^(L-1) < p < 2^L + p = Prime.generateRandomPrime( r, BigInteger.valueOf(1), L - 1, L, BigInteger.valueOf(1)); + + k = p.subtract( BigInteger.valueOf(1) ); + k = k.divide( r ); + + Random rand = new Random(); + h = BigInteger.valueOf(1); + + for(;;) { + h = h.add(BigInteger.valueOf( 1 ) ); + + g = h.modPow(k, p); + + if( g.compareTo( BigInteger.valueOf(1) ) != 1 ) + break; + } + + try { + dsaparameterspec = new DSAParameterSpec(p, r, g); + AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA"); + ap.init( dsaparameterspec ); + return ap; + } catch ( NoSuchAlgorithmException nsae ) { + return null; + } catch ( InvalidParameterSpecException ipse) { + return null; + } + } +} diff --git a/libjava/classpath/gnu/java/security/provider/DSAParameters.java b/libjava/classpath/gnu/java/security/provider/DSAParameters.java new file mode 100644 index 0000000..77d6489 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DSAParameters.java @@ -0,0 +1,150 @@ +/* DSAParameters.java --- DSA Parameters Implementation + Copyright (C) 1999, 2003, 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.java.security.provider; + +import gnu.java.io.ASN1ParsingException; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.AlgorithmParametersSpi; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.util.ArrayList; + +/* + ASN.1 Encoding for DSA from rfc2459 + + id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) + x9cm(4) 1 } + + Dss-Parms ::= SEQUENCE { + p INTEGER, + q INTEGER, + g INTEGER } + +*/ +public class DSAParameters extends AlgorithmParametersSpi +{ +private BigInteger q; // the small prime +private BigInteger p; // the big prime +private BigInteger g; + + +public void engineInit(AlgorithmParameterSpec paramSpec) + throws InvalidParameterSpecException +{ + if( paramSpec instanceof DSAParameterSpec ) { + DSAParameterSpec dsaParamSpec = (DSAParameterSpec)paramSpec; + p = dsaParamSpec.getP(); + q = dsaParamSpec.getQ(); + g = dsaParamSpec.getG(); + } + else + throw new InvalidParameterSpecException("Only accepts DSAParameterSpec"); +} + +public void engineInit(byte[] params) + throws IOException +{ + DERReader in = new DERReader(params); + DERValue val = in.read(); + if (val.getValue() != DER.CONSTRUCTED_VALUE) + throw new ASN1ParsingException("badly formed parameters"); + try + { + p = (BigInteger) in.read().getValue(); + q = (BigInteger) in.read().getValue(); + g = (BigInteger) in.read().getValue(); + } + catch (Exception x) + { + throw new ASN1ParsingException("badly formed parameters"); + } +} + +public void engineInit(byte[] params, String format) + throws IOException +{ + if( !format.equals("ASN.1") ) + throw new IOException("Invalid Format: Only accepts ASN.1"); + engineInit( params ); +} + +public AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) + throws InvalidParameterSpecException +{ + if( paramSpec.isAssignableFrom(DSAParameterSpec.class) ) + return new DSAParameterSpec(p, q, g); + else + throw new InvalidParameterSpecException("Only accepts DSAParameterSpec"); +} + +public byte[] engineGetEncoded() + throws IOException +{ + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ArrayList seq = new ArrayList(3); + seq.add(new DERValue(DER.INTEGER, p)); + seq.add(new DERValue(DER.INTEGER, q)); + seq.add(new DERValue(DER.INTEGER, g)); + DERWriter.write(bout, new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, seq)); + return bout.toByteArray(); +} + + +public byte[] engineGetEncoded(String format) + throws IOException +{ + if( !format.equals("ASN.1") ) + throw new IOException("Invalid Format: Only accepts ASN.1"); + return engineGetEncoded(); +} + +public String engineToString() +{ + return ("q: " + q + " p: " + p + " g: " + g); +} + +} diff --git a/libjava/classpath/gnu/java/security/provider/DSASignature.java b/libjava/classpath/gnu/java/security/provider/DSASignature.java new file mode 100644 index 0000000..1d3875d --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DSASignature.java @@ -0,0 +1,251 @@ +/* DSASignature.java -- + Copyright (C) 1999, 2003, 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.java.security.provider; + +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.AlgorithmParameterSpec; +import java.util.ArrayList; +import java.util.Random; + +public class DSASignature extends SignatureSpi +{ + private DSAPublicKey publicKey; + private DSAPrivateKey privateKey; + private final MessageDigest digest; + private final SecureRandom random; + + public DSASignature() throws NoSuchAlgorithmException + { + random = new SecureRandom(); + digest = MessageDigest.getInstance ("SHA1"); + } + + private void init() + { + digest.reset(); + } + + public void engineInitVerify (PublicKey publicKey) + throws InvalidKeyException + { + if (publicKey instanceof DSAPublicKey) + this.publicKey = (DSAPublicKey) publicKey; + else + throw new InvalidKeyException(); + init(); + } + + public void engineInitSign (PrivateKey privateKey) + throws InvalidKeyException + { + if (privateKey instanceof DSAPrivateKey) + this.privateKey = (DSAPrivateKey) privateKey; + else + throw new InvalidKeyException ("not a DSA private key"); + + init(); + } + + public void engineInitSign (PrivateKey privateKey, + SecureRandom random) + throws InvalidKeyException + { + if (privateKey instanceof DSAPrivateKey) + this.privateKey = (DSAPrivateKey) privateKey; + else + throw new InvalidKeyException ("not a DSA private key"); + + appRandom = random; + init(); + } + + public void engineUpdate(byte b) + throws SignatureException + { + digest.update (b); + } + + public void engineUpdate (byte[] b, int off, int len) + throws SignatureException + { + digest.update (b, off, len); + } + + public byte[] engineSign() throws SignatureException + { + if (privateKey == null) + throw new SignatureException ("not initialized for signing"); + + try + { + BigInteger g = privateKey.getParams().getG(); + BigInteger p = privateKey.getParams().getP(); + BigInteger q = privateKey.getParams().getQ(); + + BigInteger x = privateKey.getX(); + + BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random); + + BigInteger r = g.modPow(k, p); + r = r.mod(q); + + byte bytes[] = digest.digest(); + BigInteger sha = new BigInteger (1, bytes); + + BigInteger s = sha.add (x.multiply (r)); + s = s.multiply (k.modInverse(q)).mod (q); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ArrayList seq = new ArrayList (2); + seq.add(0, new DERValue (DER.INTEGER, r)); + seq.add(1, new DERValue (DER.INTEGER, s)); + DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq)); + return bout.toByteArray(); + } + catch (IOException ioe) + { + SignatureException se = new SignatureException(); + se.initCause (ioe); + throw se; + } + catch (ArithmeticException ae) + { + SignatureException se = new SignatureException(); + se.initCause (ae); + throw se; + } + } + + public int engineSign (byte[] outbuf, int offset, int len) + throws SignatureException + { + byte tmp[] = engineSign(); + if (tmp.length > len) + throw new SignatureException ("output buffer too short"); + System.arraycopy (tmp, 0, outbuf, offset, tmp.length); + return tmp.length; + } + + public boolean engineVerify (byte[] sigBytes) + throws SignatureException + { + // Decode sigBytes from ASN.1 DER encoding + try + { + DERReader in = new DERReader (sigBytes); + DERValue val = in.read(); + if (!val.isConstructed()) + throw new SignatureException ("badly formed signature"); + BigInteger r = (BigInteger) in.read().getValue(); + BigInteger s = (BigInteger) in.read().getValue(); + + BigInteger g = publicKey.getParams().getG(); + BigInteger p = publicKey.getParams().getP(); + BigInteger q = publicKey.getParams().getQ(); + + BigInteger y = publicKey.getY(); + + BigInteger w = s.modInverse (q); + + byte bytes[] = digest.digest(); + BigInteger sha = new BigInteger (1, bytes); + + BigInteger u1 = w.multiply (sha).mod ( q ); + + BigInteger u2 = r.multiply (w).mod(q); + + BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q); + + if (v.equals (r)) + return true; + else + return false; + } + catch (IOException ioe) + { + SignatureException se = new SignatureException ("badly formed signature"); + se.initCause (ioe); + throw se; + } + } + + public void engineSetParameter (String param, + Object value) + throws InvalidParameterException + { + throw new InvalidParameterException(); + } + + public void engineSetParameter (AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException + { + throw new InvalidParameterException(); + + } + + public Object engineGetParameter (String param) + throws InvalidParameterException + { + throw new InvalidParameterException(); + } + + public Object clone() throws CloneNotSupportedException + { + return super.clone(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java b/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java new file mode 100644 index 0000000..d42be6c --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DefaultPolicy.java @@ -0,0 +1,68 @@ +/* DefaultPolicy.java -- + Copyright (C) 2001, 2002 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.java.security.provider; + +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; + +/** + * This is just a stub policy implementation which grants all permissions + * to any code source. FIXME: This should be replaced with a real + * implementation that reads the policy configuration from a file, like + * $JAVA_HOME/jre/lib/security/java.security. + */ +public class DefaultPolicy extends Policy +{ + static Permission allPermission = new AllPermission(); + + public PermissionCollection getPermissions(CodeSource codesource) + { + Permissions perms = new Permissions(); + perms.add(allPermission); + return perms; + } + + public void refresh() + { + // Nothing. + } +} diff --git a/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java b/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java new file mode 100644 index 0000000..2bf0fff --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java @@ -0,0 +1,303 @@ +/* EncodedKeyFactory.java -- encoded key factory. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.InvalidParameterSpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.spec.DHParameterSpec; + +/** + * A factory for keys encoded in either the X.509 format (for public + * keys) or the PKCS#8 format (for private keys). + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class EncodedKeyFactory extends KeyFactorySpi +{ + + // Constants. + // ------------------------------------------------------------------------ + + private static final OID ID_DSA = new OID("1.2.840.10040.4.1"); + private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1"); + private static final OID ID_DH = new OID("1.2.840.10046.2.1"); + + // Instance methods. + // ------------------------------------------------------------------------ + + public PublicKey engineGeneratePublic(KeySpec spec) + throws InvalidKeySpecException + { + if (!(spec instanceof X509EncodedKeySpec)) + throw new InvalidKeySpecException("only supports X.509 key specs"); + DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded()); + try + { + DERValue spki = der.read(); + if (!spki.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue alg = der.read(); + if (!alg.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue val = der.read(); + if (!(val.getValue() instanceof OID)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + OID algId = (OID) val.getValue(); + byte[] algParams = null; + if (alg.getLength() > val.getEncodedLength()) + { + val = der.read(); + algParams = val.getEncoded(); + if (val.isConstructed()) + der.skip(val.getLength()); + } + val = der.read(); + if (!(val.getValue() instanceof BitString)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + byte[] publicKey = ((BitString) val.getValue()).toByteArray(); + if (algId.equals(ID_DSA)) + { + BigInteger p = null, g = null, q = null, Y; + if (algParams != null) + { + DERReader dsaParams = new DERReader(algParams); + val = dsaParams.read(); + if (!val.isConstructed()) + throw new InvalidKeySpecException("malformed DSA parameters"); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + p = (BigInteger) val.getValue(); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + q = (BigInteger) val.getValue(); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + g = (BigInteger) val.getValue(); + } + DERReader dsaPub = new DERReader(publicKey); + val = dsaPub.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + Y = (BigInteger) val.getValue(); + return new GnuDSAPublicKey(Y, p, q, g); + } + else if (algId.equals(ID_RSA)) + { + DERReader rsaParams = new DERReader(publicKey); + if (!rsaParams.read().isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + return new GnuRSAPublicKey(new RSAPublicKeySpec( + (BigInteger) rsaParams.read().getValue(), + (BigInteger) rsaParams.read().getValue())); + } + else if (algId.equals(ID_DH)) + { + if (algParams == null) + throw new InvalidKeySpecException("missing DH parameters"); + DERReader dhParams = new DERReader(algParams); + val = dhParams.read(); + BigInteger p, g, q, Y; + if (!val.isConstructed()) + throw new InvalidKeySpecException("malformed DH parameters"); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + p = (BigInteger) val.getValue(); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + g = (BigInteger) val.getValue(); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + q = (BigInteger) val.getValue(); + DERReader dhPub = new DERReader(publicKey); + val = dhPub.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + Y = (BigInteger) val.getValue(); + return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q); + } + else + throw new InvalidKeySpecException("unknown algorithm: " + algId); + } + catch (IOException ioe) + { + throw new InvalidKeySpecException(ioe.getMessage()); + } + } + + public PrivateKey engineGeneratePrivate(KeySpec spec) + throws InvalidKeySpecException + { + if (!(spec instanceof PKCS8EncodedKeySpec)) + { + throw new InvalidKeySpecException("only supports PKCS8 key specs"); + } + DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded()); + try + { + DERValue pki = der.read(); + if (!pki.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue val = der.read(); + if (!(val.getValue() instanceof BigInteger)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue alg = der.read(); + if (!alg.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + val = der.read(); + if (!(val.getValue() instanceof OID)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + OID algId = (OID) val.getValue(); + byte[] algParams = null; + if (alg.getLength() > val.getEncodedLength()) + { + val = der.read(); + algParams = val.getEncoded(); + if (val.isConstructed()) + der.skip(val.getLength()); + } + byte[] privateKey = (byte[]) der.read().getValue(); + if (algId.equals(ID_DSA)) + { + if (algParams == null) + { + throw new InvalidKeySpecException("missing DSA parameters"); + } + AlgorithmParameters params = AlgorithmParameters.getInstance("DSA"); + params.init(algParams); + DSAParameterSpec dsaSpec = (DSAParameterSpec) + params.getParameterSpec(DSAParameterSpec.class); + DERReader dsaPriv = new DERReader(privateKey); + return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(), + dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()); + } + else if (algId.equals(ID_RSA)) + { + DERReader rsaParams = new DERReader(privateKey); + if (!rsaParams.read().isConstructed()) + throw new InvalidKeySpecException("malformed encoded key"); + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + (BigInteger) rsaParams.read().getValue(), // n + (BigInteger) rsaParams.read().getValue(), // e + (BigInteger) rsaParams.read().getValue(), // d + (BigInteger) rsaParams.read().getValue(), // p + (BigInteger) rsaParams.read().getValue(), // q + (BigInteger) rsaParams.read().getValue(), // d mod (p - 1) + (BigInteger) rsaParams.read().getValue(), // d mod (q - 1) + (BigInteger) rsaParams.read().getValue())); // (inv q) mod p + } + else + throw new InvalidKeySpecException("unknown algorithm: " + algId); + } + catch (InvalidParameterSpecException iapse) + { + throw new InvalidKeySpecException(iapse.getMessage()); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InvalidKeySpecException(nsae.getMessage()); + } + catch (IOException ioe) + { + throw new InvalidKeySpecException(ioe.getMessage()); + } + } + + public KeySpec engineGetKeySpec(Key key, Class speClass) + throws InvalidKeySpecException + { + if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8") + && speClass.isAssignableFrom(PKCS8EncodedKeySpec.class)) + return new PKCS8EncodedKeySpec(key.getEncoded()); + else if ((key instanceof PublicKey) && key.getFormat().equals("X.509") + && speClass.isAssignableFrom(X509EncodedKeySpec.class)) + return new X509EncodedKeySpec(key.getEncoded()); + else + throw new InvalidKeySpecException(); + } + + public Key engineTranslateKey(Key key) throws InvalidKeyException + { + throw new InvalidKeyException("translating keys not supported"); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/Gnu.java b/libjava/classpath/gnu/java/security/provider/Gnu.java new file mode 100644 index 0000000..849f63c --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/Gnu.java @@ -0,0 +1,168 @@ +/* Gnu.java --- Gnu provider main class + Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.security.provider; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.Provider; + +public final class Gnu extends Provider +{ + public Gnu() + { + super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores"); + + AccessController.doPrivileged (new PrivilegedAction() + { + public Object run() + { + // Note that all implementation class names are referenced by using + // Class.getName(). That way when we staticly link the Gnu provider + // we automatically get all the implementation classes. + + // Signature + put("Signature.SHA1withDSA", + gnu.java.security.provider.DSASignature.class.getName()); + + put("Alg.Alias.Signature.DSS", "SHA1withDSA"); + put("Alg.Alias.Signature.DSA", "SHA1withDSA"); + put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA"); + put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA"); + put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA"); + put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA"); + put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA"); + put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA"); + put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA"); + put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); + put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA"); + put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA"); + + put("Signature.MD2withRSA", MD2withRSA.class.getName()); + put("Signature.MD2withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.md2WithRSAEncryption", "MD2withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA"); + + put("Signature.MD4withRSA", MD4withRSA.class.getName()); + put("Signature.MD4withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.md4WithRSAEncryption", "MD4withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.3", "MD4withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.3", "MD4withRSA"); + + put("Signature.MD5withRSA", MD5withRSA.class.getName()); + put("Signature.MD5withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); + + put("Signature.SHA1withRSA", SHA1withRSA.class.getName()); + put("Signature.SHA1withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA1withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); + + // Key Pair Generator + put("KeyPairGenerator.DSA", + gnu.java.security.provider.DSAKeyPairGenerator.class.getName()); + + put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA"); + put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA"); + put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA"); + + // Key Factory + put("KeyFactory.DSA", + gnu.java.security.provider.DSAKeyFactory.class.getName()); + + put("KeyFactory.Encoded", EncodedKeyFactory.class.getName()); + put("KeyFactory.Encoded ImplementedIn", "Software"); + put("Alg.Alias.KeyFactory.X.509", "Encoded"); + put("Alg.Alias.KeyFactory.X509", "Encoded"); + put("Alg.Alias.KeyFactory.PKCS#8", "Encoded"); + put("Alg.Alias.KeyFactory.PKCS8", "Encoded"); + + put("KeyFactory.RSA", RSAKeyFactory.class.getName()); + + put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA"); + put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); + put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); + + // Message Digests + put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName()); + put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName()); + + // Format "Alias", "Actual Name" + put("Alg.Alias.MessageDigest.SHA1", "SHA"); + put("Alg.Alias.MessageDigest.SHA-1", "SHA"); + put("Alg.Alias.MessageDigest.SHA-160", "SHA"); + + // Algorithm Parameters + put("AlgorithmParameters.DSA", + gnu.java.security.provider.DSAParameters.class.getName()); + + put("Alg.Alias.AlgorithmParameters.DSS", "DSA"); + put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA"); + put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA"); + put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA"); + + // Algorithm Parameter Generator + put("AlgorithmParameterGenerator.DSA", + gnu.java.security.provider.DSAParameterGenerator.class.getName()); + + // SecureRandom + put("SecureRandom.SHA1PRNG", + gnu.java.security.provider.SHA1PRNG.class.getName()); + + // CertificateFactory + put("CertificateFactory.X509", X509CertificateFactory.class.getName()); + + put("CertificateFactory.X509 ImplementedIn", "Software"); + put("Alg.Alias.CertificateFactory.X.509", "X509"); + + // CertPathValidator + put("CertPathValidator.PKIX", PKIXCertPathValidatorImpl.class.getName()); + put("CertPathValidator.PKIX ImplementedIn", "Software"); + + // CertStore + put("CertStore.Collection", CollectionCertStoreImpl.class.getName()); + + return null; + } + }); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java new file mode 100644 index 0000000..6e13f6b --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java @@ -0,0 +1,115 @@ +/* GnuDHPublicKey.java -- A Diffie-Hellman public key. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; + +import java.math.BigInteger; +import java.util.ArrayList; + +import javax.crypto.interfaces.DHPublicKey; +import javax.crypto.spec.DHParameterSpec; + +public class GnuDHPublicKey implements DHPublicKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private byte[] encoded; + private final DHParameterSpec params; + private final BigInteger Y; + private final BigInteger q; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q) + { + this.params = params; + this.Y = Y; + this.q = q; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getY() + { + return Y; + } + + public DHParameterSpec getParams() + { + return params; + } + + public String getAlgorithm() + { + return "DH"; + } + + public String getFormat() + { + return "X.509"; + } + + public byte[] getEncoded() + { + if (encoded != null) + return (byte[]) encoded.clone(); + ArrayList spki = new ArrayList(2); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1"))); + ArrayList param = new ArrayList(3); + param.add(new DERValue(DER.INTEGER, params.getP())); + param.add(new DERValue(DER.INTEGER, params.getG())); + param.add(new DERValue(DER.INTEGER, q)); + alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param)); + spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); + spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray()))); + encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded(); + if (encoded != null) + return (byte[]) encoded.clone(); + return null; + } +} diff --git a/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java new file mode 100644 index 0000000..aac2faa --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java @@ -0,0 +1,147 @@ +/* GnuDSAPrivateKey.java --- Gnu DSA Private Key + Copyright (C) 1999,2003,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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPrivateKey; +import java.security.spec.DSAParameterSpec; +import java.util.ArrayList; + +public class GnuDSAPrivateKey implements DSAPrivateKey +{ + private byte[] encodedKey; + BigInteger x; + BigInteger p; + BigInteger q; + BigInteger g; + + public GnuDSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g ) + { + this.x = x; + this.p = p; + this.q = q; + this.g = g; + } + + public String getAlgorithm() + { + return "DSA"; + } + + public String getFormat() + { + return "PKCS#8"; + } + + /** + * Encodes this key as a <code>PrivateKeyInfo</code>, as described in + * PKCS #8. The ASN.1 specification for this structure is: + * + * <blockquote><pre> + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * Version ::= INTEGER + * + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * + * PrivateKey ::= OCTET STRING + * + * Attributes ::= SET OF Attribute + * </pre></blockquote> + * + * <p>DSA private keys (in Classpath at least) have no attributes. + */ + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + try + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ArrayList pki = new ArrayList(3); + pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); + ArrayList algId = new ArrayList(2); + algId.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.10040.4.1"))); + ArrayList algParams = new ArrayList(3); + algParams.add(new DERValue(DER.INTEGER, p)); + algParams.add(new DERValue(DER.INTEGER, q)); + algParams.add(new DERValue(DER.INTEGER, g)); + algId.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algParams)); + pki.add(new DERValue(DER.OCTET_STRING, x.toByteArray())); + DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pki)); + return (byte[]) (encodedKey = out.toByteArray()).clone(); + } + catch (IOException ioe) + { + return null; + } + } + + public DSAParams getParams() + { + return (DSAParams)(new DSAParameterSpec(p,q,g)); + } + + public BigInteger getX() + { + return x; + } + + public String toString() + { + return "GnuDSAPrivateKey: x=" + + (x != null ? x.toString(16) : "null") + " p=" + + (p != null ? p.toString(16) : "null") + " q=" + + (q != null ? q.toString(16) : "null") + " g=" + + (g != null ? g.toString(16) : "null"); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java new file mode 100644 index 0000000..41195fa --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java @@ -0,0 +1,137 @@ +/* GnuDSAPublicKey.java --- Gnu DSA Public Key + Copyright (C) 1999,2003,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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAParameterSpec; +import java.util.ArrayList; + +public class GnuDSAPublicKey implements DSAPublicKey +{ + private byte[] encodedKey; + BigInteger y; + BigInteger p; + BigInteger q; + BigInteger g; + + public GnuDSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g ) + { + this.y = y; + this.p = p; + this.q = q; + this.g = g; + } + + public String getAlgorithm() + { + return "DSA"; + } + + public String getFormat() + { + return "X.509"; + } + + /** + * The encoded form of DSA public keys is: + * + * <blockquote><pre> + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + * </pre></blockquote> + */ + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + try + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ArrayList spki = new ArrayList(2); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.113549.1.1.1"))); + ArrayList params = new ArrayList(3); + params.add(new DERValue(DER.INTEGER, p)); + params.add(new DERValue(DER.INTEGER, q)); + params.add(new DERValue(DER.INTEGER, g)); + alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, params)); + spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); + spki.add(new DERValue(DER.BIT_STRING, new BitString(y.toByteArray()))); + DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki)); + return (byte[]) (encodedKey = out.toByteArray()).clone(); + } + catch (IOException ioe) + { + return null; + } + } + + public DSAParams getParams() + { + if (p == null || q == null || g == null) + return null; + return (DSAParams)(new DSAParameterSpec(p,q,g)); + } + + public BigInteger getY() + { + return y; + } + + public String toString() + { + return + "GnuDSAPublicKey: y=" + (y != null ? y.toString(16) : "(null)") + + " p=" + (p != null ? p.toString(16) : "(null)") + + " q=" + (q != null ? q.toString(16) : "(null)") + + " g=" + (g != null ? g.toString(16) : "(null)"); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java new file mode 100644 index 0000000..b09fc88 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java @@ -0,0 +1,164 @@ +/* GnuRSAPrivateKey.java -- GNU RSA private key. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; + +import java.math.BigInteger; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.util.ArrayList; + +class GnuRSAPrivateKey implements RSAPrivateCrtKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final RSAPrivateCrtKeySpec spec; + private byte[] encodedKey; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec) + { + this.spec = spec; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getModulus() + { + return spec.getModulus(); + } + + public BigInteger getPrivateExponent() + { + return spec.getPrivateExponent(); + } + + public BigInteger getCrtCoefficient() + { + return spec.getCrtCoefficient(); + } + + public BigInteger getPrimeExponentP() + { + return spec.getPrimeExponentP(); + } + + public BigInteger getPrimeExponentQ() + { + return spec.getPrimeExponentQ(); + } + + public BigInteger getPrimeP() + { + return spec.getPrimeP(); + } + + public BigInteger getPrimeQ() + { + return spec.getPrimeQ(); + } + + public BigInteger getPublicExponent() + { + return spec.getPublicExponent(); + } + + public String getAlgorithm() + { + return "RSA"; + } + + public String getFormat() + { + return "PKCS#8"; + } + + /** + * The encoded form is: + * + * <pre> + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER -- (inverse of q) mod p } + * </pre> + * + * <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8. + */ + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + ArrayList key = new ArrayList(9); + key.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); + key.add(new DERValue(DER.INTEGER, getModulus())); + key.add(new DERValue(DER.INTEGER, getPublicExponent())); + key.add(new DERValue(DER.INTEGER, getPrivateExponent())); + key.add(new DERValue(DER.INTEGER, getPrimeP())); + key.add(new DERValue(DER.INTEGER, getPrimeQ())); + key.add(new DERValue(DER.INTEGER, getPrimeExponentP())); + key.add(new DERValue(DER.INTEGER, getPrimeExponentQ())); + key.add(new DERValue(DER.INTEGER, getCrtCoefficient())); + DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); + ArrayList pki = new ArrayList(3); + pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.113549.1.1.1"))); + alg.add(new DERValue(DER.NULL, null)); + pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); + pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded())); + encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded(); + return (byte[]) encodedKey.clone(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java new file mode 100644 index 0000000..a35e761 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java @@ -0,0 +1,109 @@ +/* GnuRSAPublicKey.java -- GNU RSA public key. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; + +import java.math.BigInteger; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.util.ArrayList; + +class GnuRSAPublicKey implements RSAPublicKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final RSAPublicKeySpec spec; + private byte[] encodedKey; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuRSAPublicKey(RSAPublicKeySpec spec) + { + this.spec = spec; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getModulus() + { + return spec.getModulus(); + } + + public BigInteger getPublicExponent() + { + return spec.getPublicExponent(); + } + + public String getAlgorithm() + { + return "RSA"; + } + + public String getFormat() + { + return "X.509"; + } + + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + ArrayList key = new ArrayList(2); + key.add(new DERValue(DER.INTEGER, getModulus())); + key.add(new DERValue(DER.INTEGER, getPublicExponent())); + DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.113549.1.1.1"))); + alg.add(new DERValue(DER.NULL, null)); + ArrayList spki = new ArrayList(2); + spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg)); + spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded()))); + encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded(); + return (byte[]) encodedKey.clone(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/MD2withRSA.java b/libjava/classpath/gnu/java/security/provider/MD2withRSA.java new file mode 100644 index 0000000..a72ae55 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/MD2withRSA.java @@ -0,0 +1,54 @@ +/* MD2withRSA.java -- MD2 with RSA encryption signatures. + Copyright (C) 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.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD2withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD2withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2)); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/MD4withRSA.java b/libjava/classpath/gnu/java/security/provider/MD4withRSA.java new file mode 100644 index 0000000..76a6a1a --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/MD4withRSA.java @@ -0,0 +1,54 @@ +/* MD4withRSA.java -- MD4 with RSA encryption signatures. + Copyright (C) 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.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD4withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD4withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4)); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/MD5.java b/libjava/classpath/gnu/java/security/provider/MD5.java new file mode 100644 index 0000000..1534eb9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/MD5.java @@ -0,0 +1,338 @@ +/* MD5.java -- Class implementing the MD5 algorithm as specified in RFC1321. + Copyright (C) 1999, 2002 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.java.security.provider; +import java.security.MessageDigest; + +/** + This class implements the MD5 algorithm as described in RFC1321. + + @see java.security.MessageDigest +*/ +public class MD5 extends MessageDigest implements Cloneable +{ + private final int W[] = new int[16]; + private long bytecount; + private int A; + private int B; + private int C; + private int D; + + public MD5() + { + super("MD5"); + engineReset (); + } + + public Object clone() + { + return new MD5 (this); + } + + private MD5 (MD5 copy) + { + this (); + bytecount = copy.bytecount; + A = copy.A; + B = copy.B; + C = copy.C; + D = copy.D; + System.arraycopy (copy.W, 0, W, 0, 16); + } + + public int engineGetDigestLength() + { + return 16; + } + + // Intialize the A,B,C,D needed for the hash + public void engineReset() + { + bytecount = 0; + A = 0x67452301; + B = 0xefcdab89; + C = 0x98badcfe; + D = 0x10325476; + for(int i = 0; i < 16; i++) + W[i] = 0; + } + + public void engineUpdate (byte b) + { + int i = (int)bytecount % 64; + int shift = (3 - i % 4) * 8; + int idx = i / 4; + + // if you could index ints, this would be: W[idx][shift/8] = b + W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift); + + // if we've filled up a block, then process it + if ((++ bytecount) % 64 == 0) + munch (); + } + + public void engineUpdate (byte bytes[], int off, int len) + { + if (len < 0) + throw new ArrayIndexOutOfBoundsException (); + + int end = off + len; + while (off < end) + engineUpdate (bytes[off++]); + } + + public byte[] engineDigest() + { + long bitcount = bytecount * 8; + engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding + + // add the rest of the padding to fill this block out, but leave 8 + // bytes to put in the original bytecount + while ((int)bytecount % 64 != 56) + engineUpdate ((byte)0); + + // add the length of the original, unpadded block to the end of + // the padding + W[14] = SWAP((int)(0xffffffff & bitcount)); + W[15] = SWAP((int)(0xffffffff & (bitcount >>> 32))); + bytecount += 8; + + // digest the fully padded block + munch (); + + A = SWAP(A); + B = SWAP(B); + C = SWAP(C); + D = SWAP(D); + byte[] result = new byte[] {(byte)(A >>> 24), (byte)(A >>> 16), + (byte)(A >>> 8), (byte)A, + (byte)(B >>> 24), (byte)(B >>> 16), + (byte)(B >>> 8), (byte)B, + (byte)(C >>> 24), (byte)(C >>> 16), + (byte)(C >>> 8), (byte)C, + (byte)(D >>> 24), (byte)(D >>> 16), + (byte)(D >>> 8), (byte)D}; + + engineReset (); + return result; + } + + private int F( int X, int Y, int Z) + { + return ((X & Y) | (~X & Z)); + } + + private int G( int X, int Y, int Z) + { + return ((X & Z) | (Y & ~Z)); + } + + private int H( int X, int Y, int Z) + { + return (X ^ Y ^ Z); + } + + private int I( int X, int Y, int Z) + { + return (Y ^ (X | ~Z)); + } + + private int rotateLeft( int i, int count) + { + //Taken from FIPS 180-1 + return ( (i << count) | (i >>> (32 - count)) ) ; + } + + /* Round 1. */ + private int FF( int a, int b, int c, int d, int k, int s, int i) + { + /* Let [abcd k s i] denote the operation */ + a += F(b,c,d) + k + i; + return b + rotateLeft(a, s); + } + /* Round 2. */ + private int GG( int a, int b, int c, int d, int k, int s, int i) + { + /* Let [abcd k s i] denote the operation */ + a += G(b,c,d) + k + i; + return b + rotateLeft(a, s); + } + /* Round 3. */ + private int HH( int a, int b, int c, int d, int k, int s, int i) + { + /* Let [abcd k s t] denote the operation */ + a += H(b,c,d) + k + i; + return b + rotateLeft(a, s); + } + + /* Round 4. */ + private int II( int a, int b, int c, int d, int k, int s, int i) + { + /* Let [abcd k s t] denote the operation */ + a += I(b,c,d) + k + i; + return b + rotateLeft(a, s); + } + + private int SWAP(int n) + { + //Copied from md5.c in FSF Gnu Privacy Guard 0.9.2 + return (( (0xff & n) << 24) | ((n & 0xff00) << 8) | ((n >>> 8) & 0xff00) | (n >>> 24)); + } + + private void munch() + { + int AA,BB,CC,DD, j; + int X[] = new int[16]; + + /* Copy block i into X. */ + for(j = 0; j < 16; j++) + X[j] = SWAP(W[j]); + + /* Save A as AA, B as BB, C as CC, and D as DD. */ + AA = A; + BB = B; + CC = C; + DD = D; + + /* The hex constants are from md5.c + in FSF Gnu Privacy Guard 0.9.2 */ + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + A = FF(A,B,C,D, X[0], 7, 0xd76aa478); + D = FF(D,A,B,C, X[1], 12, 0xe8c7b756); + C = FF(C,D,A,B, X[2], 17, 0x242070db); + B = FF(B,C,D,A, X[3], 22, 0xc1bdceee); + + A = FF(A,B,C,D, X[4], 7, 0xf57c0faf); + D = FF(D,A,B,C, X[5], 12, 0x4787c62a); + C = FF(C,D,A,B, X[6], 17, 0xa8304613); + B = FF(B,C,D,A, X[7], 22, 0xfd469501); + + A = FF(A,B,C,D, X[8], 7, 0x698098d8); + D = FF(D,A,B,C, X[9], 12, 0x8b44f7af); + C = FF(C,D,A,B, X[10], 17, 0xffff5bb1); + B = FF(B,C,D,A, X[11], 22, 0x895cd7be); + + A = FF(A,B,C,D, X[12], 7, 0x6b901122); + D = FF(D,A,B,C, X[13], 12, 0xfd987193); + C = FF(C,D,A,B, X[14], 17, 0xa679438e); + B = FF(B,C,D,A, X[15], 22, 0x49b40821); + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + A = GG(A,B,C,D, X[1], 5, 0xf61e2562); + D = GG(D,A,B,C, X[6], 9, 0xc040b340); + C = GG(C,D,A,B, X[11], 14, 0x265e5a51); + B = GG(B,C,D,A, X[0], 20, 0xe9b6c7aa); + + A = GG(A,B,C,D, X[5], 5, 0xd62f105d); + D = GG(D,A,B,C, X[10], 9, 0x02441453); + C = GG(C,D,A,B, X[15], 14, 0xd8a1e681); + B = GG(B,C,D,A, X[4], 20, 0xe7d3fbc8); + + A = GG(A,B,C,D, X[9], 5, 0x21e1cde6); + D = GG(D,A,B,C, X[14], 9, 0xc33707d6); + C = GG(C,D,A,B, X[3], 14, 0xf4d50d87); + B = GG(B,C,D,A, X[8], 20, 0x455a14ed); + + A = GG(A,B,C,D, X[13], 5, 0xa9e3e905); + D = GG(D,A,B,C, X[2], 9, 0xfcefa3f8); + C = GG(C,D,A,B, X[7], 14, 0x676f02d9); + B = GG(B,C,D,A, X[12], 20, 0x8d2a4c8a); + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + A = HH(A,B,C,D, X[5], 4, 0xfffa3942); + D = HH(D,A,B,C, X[8], 11, 0x8771f681); + C = HH(C,D,A,B, X[11], 16, 0x6d9d6122); + B = HH(B,C,D,A, X[14], 23, 0xfde5380c); + + A = HH(A,B,C,D, X[1], 4, 0xa4beea44); + D = HH(D,A,B,C, X[4], 11, 0x4bdecfa9); + C = HH(C,D,A,B, X[7], 16, 0xf6bb4b60); + B = HH(B,C,D,A, X[10], 23, 0xbebfbc70); + + A = HH(A,B,C,D, X[13], 4, 0x289b7ec6); + D = HH(D,A,B,C, X[0], 11, 0xeaa127fa); + C = HH(C,D,A,B, X[3], 16, 0xd4ef3085); + B = HH(B,C,D,A, X[6], 23, 0x04881d05); + + A = HH(A,B,C,D, X[9], 4, 0xd9d4d039); + D = HH(D,A,B,C, X[12], 11, 0xe6db99e5); + C = HH(C,D,A,B, X[15], 16, 0x1fa27cf8); + B = HH(B,C,D,A, X[2], 23, 0xc4ac5665); + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + /* Do the following 16 operations. */ + A = II(A,B,C,D, X[0], 6, 0xf4292244); + D = II(D,A,B,C, X[7], 10, 0x432aff97); + C = II(C,D,A,B, X[14], 15, 0xab9423a7); + B = II(B,C,D,A, X[5], 21, 0xfc93a039); + + A = II(A,B,C,D, X[12], 6, 0x655b59c3); + D = II(D,A,B,C, X[3], 10, 0x8f0ccc92); + C = II(C,D,A,B, X[10], 15, 0xffeff47d); + B = II(B,C,D,A, X[1], 21, 0x85845dd1); + + A = II(A,B,C,D, X[8], 6, 0x6fa87e4f); + D = II(D,A,B,C, X[15], 10, 0xfe2ce6e0); + C = II(C,D,A,B, X[6], 15, 0xa3014314); + B = II(B,C,D,A, X[13], 21, 0x4e0811a1); + + A = II(A,B,C,D, X[4], 6, 0xf7537e82); + D = II(D,A,B,C, X[11], 10, 0xbd3af235); + C = II(C,D,A,B, X[2], 15, 0x2ad7d2bb); + B = II(B,C,D,A, X[9], 21, 0xeb86d391); + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + A = A + AA; + B = B + BB; + C = C + CC; + D = D + DD; + } +} diff --git a/libjava/classpath/gnu/java/security/provider/MD5withRSA.java b/libjava/classpath/gnu/java/security/provider/MD5withRSA.java new file mode 100644 index 0000000..721d897 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/MD5withRSA.java @@ -0,0 +1,54 @@ +/* MD5withRSA.java -- MD5 with RSA encryption signatures. + Copyright (C) 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.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD5withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD5withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5)); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java new file mode 100644 index 0000000..1268b16 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java @@ -0,0 +1,701 @@ +/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.x509.GnuPKIExtension; +import gnu.java.security.x509.PolicyNodeImpl; +import gnu.java.security.x509.X509CRLSelectorImpl; +import gnu.java.security.x509.X509CertSelectorImpl; +import gnu.java.security.x509.ext.BasicConstraints; +import gnu.java.security.x509.ext.CertificatePolicies; +import gnu.java.security.x509.ext.Extension; +import gnu.java.security.x509.ext.KeyUsage; +import gnu.java.security.x509.ext.PolicyConstraint; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.cert.CRL; +import java.security.cert.CertPath; +import java.security.cert.CertPathParameters; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorResult; +import java.security.cert.CertPathValidatorSpi; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.CertificateException; +import java.security.cert.PKIXCertPathChecker; +import java.security.cert.PKIXCertPathValidatorResult; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CRL; +import java.security.cert.X509Certificate; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + * An implementation of the Public Key Infrastructure's X.509 + * certificate path validation algorithm. + * + * <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: + * Internet X.509 Public Key Infrastructure Certificate and + * Certificate Revocation List (CRL) Profile</a>. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi +{ + + // Constants. + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = false; + private static void debug (String msg) + { + System.err.print (">> PKIXCertPathValidatorImpl: "); + System.err.println (msg); + } + + public static final String ANY_POLICY = "2.5.29.32.0"; + + // Constructor. + // ------------------------------------------------------------------------- + + public PKIXCertPathValidatorImpl() + { + super(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public CertPathValidatorResult engineValidate(CertPath path, + CertPathParameters params) + throws CertPathValidatorException, InvalidAlgorithmParameterException + { + if (!(params instanceof PKIXParameters)) + throw new InvalidAlgorithmParameterException("not a PKIXParameters object"); + + // First check if the certificate path is valid. + // + // This means that: + // + // (a) for all x in {1, ..., n-1}, the subject of certificate x is + // the issuer of certificate x+1; + // + // (b) for all x in {1, ..., n}, the certificate was valid at the + // time in question. + // + // Because this is the X.509 algorithm, we also check if all + // cerificates are of type X509Certificate. + + PolicyNodeImpl rootNode = new PolicyNodeImpl(); + Set initPolicies = ((PKIXParameters) params).getInitialPolicies(); + rootNode.setValidPolicy(ANY_POLICY); + rootNode.setCritical(false); + rootNode.setDepth(0); + if (initPolicies != null) + rootNode.addAllExpectedPolicies(initPolicies); + else + rootNode.addExpectedPolicy(ANY_POLICY); + List checks = ((PKIXParameters) params).getCertPathCheckers(); + List l = path.getCertificates(); + if (l == null || l.size() == 0) + throw new CertPathValidatorException(); + X509Certificate[] p = null; + try + { + p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]); + } + catch (ClassCastException cce) + { + throw new CertPathValidatorException("invalid certificate path"); + } + + String sigProvider = ((PKIXParameters) params).getSigProvider(); + PublicKey prevKey = null; + Date now = ((PKIXParameters) params).getDate(); + if (now == null) + now = new Date(); + LinkedList policyConstraints = new LinkedList(); + for (int i = p.length - 1; i >= 0; i--) + { + try + { + p[i].checkValidity(now); + } + catch (CertificateException ce) + { + throw new CertPathValidatorException(ce.toString()); + } + Set uce = getCritExts(p[i]); + for (Iterator check = checks.iterator(); check.hasNext(); ) + { + try + { + ((PKIXCertPathChecker) check.next()).check(p[i], uce); + } + catch (Exception x) + { + } + } + + PolicyConstraint constr = null; + if (p[i] instanceof GnuPKIExtension) + { + Extension pcx = + ((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID); + if (pcx != null) + constr = (PolicyConstraint) pcx.getValue(); + } + else + { + byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString()); + if (pcx != null) + { + try + { + constr = new PolicyConstraint (pcx); + } + catch (Exception x) + { + } + } + } + if (constr != null && constr.getRequireExplicitPolicy() >= 0) + { + policyConstraints.add (new int[] + { p.length-i, constr.getRequireExplicitPolicy() }); + } + + updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params, + checkExplicitPolicy (p.length-i, policyConstraints)); + + // The rest of the tests involve this cert's relationship with the + // next in the path. If this cert is the end entity, we can stop. + if (i == 0) + break; + + basicSanity(p, i); + PublicKey pubKey = null; + try + { + pubKey = p[i].getPublicKey(); + if (pubKey instanceof DSAPublicKey) + { + DSAParams dsa = ((DSAPublicKey) pubKey).getParams(); + // If the DSA public key is missing its parameters, use those + // from the previous cert's key. + if (dsa == null || dsa.getP() == null || dsa.getG() == null + || dsa.getQ() == null) + { + if (prevKey == null) + throw new InvalidKeyException("DSA keys not chainable"); + if (!(prevKey instanceof DSAPublicKey)) + throw new InvalidKeyException("DSA keys not chainable"); + dsa = ((DSAPublicKey) prevKey).getParams(); + pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(), + dsa.getP(), dsa.getQ(), dsa.getG()); + } + } + if (sigProvider == null) + p[i-1].verify(pubKey); + else + p[i-1].verify(pubKey, sigProvider); + prevKey = pubKey; + } + catch (Exception e) + { + throw new CertPathValidatorException(e.toString()); + } + if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN())) + throw new CertPathValidatorException("issuer DN mismatch"); + boolean[] issuerUid = p[i-1].getIssuerUniqueID(); + boolean[] subjectUid = p[i].getSubjectUniqueID(); + if (issuerUid != null && subjectUid != null) + if (!Arrays.equals(issuerUid, subjectUid)) + throw new CertPathValidatorException("UID mismatch"); + + // Check the certificate against the revocation lists. + if (((PKIXParameters) params).isRevocationEnabled()) + { + X509CRLSelectorImpl selector = new X509CRLSelectorImpl(); + try + { + selector.addIssuerName(p[i].getSubjectDN()); + } + catch (IOException ioe) + { + throw new CertPathValidatorException("error selecting CRLs"); + } + List certStores = ((PKIXParameters) params).getCertStores(); + List crls = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + Collection c = cs.getCRLs(selector); + crls.addAll(c); + } + catch (CertStoreException cse) + { + } + } + if (crls.isEmpty()) + throw new CertPathValidatorException("no CRLs for issuer"); + boolean certOk = false; + for (Iterator it = crls.iterator(); it.hasNext(); ) + { + CRL crl = (CRL) it.next(); + if (!(crl instanceof X509CRL)) + continue; + X509CRL xcrl = (X509CRL) crl; + if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores)) + continue; + if (xcrl.isRevoked(p[i-1])) + throw new CertPathValidatorException("certificate is revoked"); + else + certOk = true; + } + if (!certOk) + throw new CertPathValidatorException("certificate's validity could not be determined"); + } + } + rootNode.setReadOnly(); + + // Now ensure that the first certificate in the chain was issued + // by a trust anchor. + Exception cause = null; + Set anchors = ((PKIXParameters) params).getTrustAnchors(); + for (Iterator i = anchors.iterator(); i.hasNext(); ) + { + TrustAnchor anchor = (TrustAnchor) i.next(); + X509Certificate anchorCert = null; + PublicKey anchorKey = null; + if (anchor.getTrustedCert() != null) + { + anchorCert = anchor.getTrustedCert(); + anchorKey = anchorCert.getPublicKey(); + } + else + anchorKey = anchor.getCAPublicKey(); + if (anchorKey == null) + continue; + try + { + if (anchorCert == null) + anchorCert.checkValidity(now); + p[p.length-1].verify(anchorKey); + if (anchorCert != null && anchorCert.getBasicConstraints() >= 0 + && anchorCert.getBasicConstraints() < p.length) + continue; + + if (((PKIXParameters) params).isRevocationEnabled()) + { + X509CRLSelectorImpl selector = new X509CRLSelectorImpl(); + if (anchorCert != null) + try + { + selector.addIssuerName(anchorCert.getSubjectDN()); + } + catch (IOException ioe) + { + } + else + selector.addIssuerName(anchor.getCAName()); + List certStores = ((PKIXParameters) params).getCertStores(); + List crls = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + Collection c = cs.getCRLs(selector); + crls.addAll(c); + } + catch (CertStoreException cse) + { + } + } + if (crls.isEmpty()) + continue; + for (Iterator it = crls.iterator(); it.hasNext(); ) + { + CRL crl = (CRL) it.next(); + if (!(crl instanceof X509CRL)) + continue; + X509CRL xcrl = (X509CRL) crl; + try + { + xcrl.verify(anchorKey); + } + catch (Exception x) + { + continue; + } + Date nextUpdate = xcrl.getNextUpdate(); + if (nextUpdate != null && nextUpdate.compareTo(now) < 0) + continue; + if (xcrl.isRevoked(p[p.length-1])) + throw new CertPathValidatorException("certificate is revoked"); + } + } + + // The chain is valid; return the result. + return new PKIXCertPathValidatorResult(anchor, rootNode, + p[0].getPublicKey()); + } + catch (Exception ignored) + { + cause = ignored; + continue; + } + } + + // The path is not valid. + CertPathValidatorException cpve = + new CertPathValidatorException("path validation failed"); + if (cause != null) + cpve.initCause (cause); + throw cpve; + } + + // Own methods. + // ------------------------------------------------------------------------- + + /** + * Check if a given CRL is acceptable for checking the revocation status + * of certificates in the path being checked. + * + * <p>The CRL is accepted iff:</p> + * + * <ol> + * <li>The <i>nextUpdate</i> field (if present) is in the future.</li> + * <li>The CRL does not contain any unsupported critical extensions.</li> + * <li>The CRL is signed by one of the certificates in the path, or,</li> + * <li>The CRL is signed by the given public key and was issued by the + * public key's subject, or,</li> + * <li>The CRL is signed by a certificate in the given cert stores, and + * that cert is signed by one of the certificates in the path.</li> + * </ol> + * + * @param crl The CRL being checked. + * @param path The path this CRL is being checked against. + * @param now The value to use as 'now'. + * @param pubKeySubject The subject of the public key. + * @param pubKey The public key to check. + * @return True if the CRL is acceptable. + */ + private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now, + X509Certificate pubKeyCert, PublicKey pubKey, + List certStores) + { + Date nextUpdate = crl.getNextUpdate(); + if (nextUpdate != null && nextUpdate.compareTo(now) < 0) + return false; + if (crl.hasUnsupportedCriticalExtension()) + return false; + for (int i = 0; i < path.length; i++) + { + if (!path[i].getSubjectDN().equals(crl.getIssuerDN())) + continue; + boolean[] keyUsage = path[i].getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + continue; + } + try + { + crl.verify(path[i].getPublicKey()); + return true; + } + catch (Exception x) + { + } + } + if (crl.getIssuerDN().equals(pubKeyCert.getSubjectDN())) + { + try + { + boolean[] keyUsage = pubKeyCert.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + throw new Exception(); + } + crl.verify(pubKey); + return true; + } + catch (Exception x) + { + } + } + try + { + X509CertSelectorImpl select = new X509CertSelectorImpl(); + select.addSubjectName(crl.getIssuerDN()); + List certs = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + certs.addAll(cs.getCertificates(select)); + } + catch (CertStoreException cse) + { + } + } + for (Iterator it = certs.iterator(); it.hasNext(); ) + { + X509Certificate c = (X509Certificate) it.next(); + for (int i = 0; i < path.length; i++) + { + if (!c.getIssuerDN().equals(path[i].getSubjectDN())) + continue; + boolean[] keyUsage = c.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + continue; + } + try + { + c.verify(path[i].getPublicKey()); + crl.verify(c.getPublicKey()); + return true; + } + catch (Exception x) + { + } + } + if (c.getIssuerDN().equals(pubKeyCert.getSubjectDN())) + { + c.verify(pubKey); + crl.verify(c.getPublicKey()); + } + } + } + catch (Exception x) + { + } + return false; + } + + private static Set getCritExts(X509Certificate cert) + { + HashSet s = new HashSet(); + if (cert instanceof GnuPKIExtension) + { + Collection exts = ((GnuPKIExtension) cert).getExtensions(); + for (Iterator it = exts.iterator(); it.hasNext(); ) + { + Extension ext = (Extension) it.next(); + if (ext.isCritical() && !ext.isSupported()) + s.add(ext.getOid().toString()); + } + } + else + s.addAll(cert.getCriticalExtensionOIDs()); + return s; + } + + /** + * Perform a basic sanity check on the CA certificate at <code>index</code>. + */ + private static void basicSanity(X509Certificate[] path, int index) + throws CertPathValidatorException + { + X509Certificate cert = path[index]; + int pathLen = 0; + for (int i = index - 1; i > 0; i--) + { + if (!path[i].getIssuerDN().equals(path[i].getSubjectDN())) + pathLen++; + } + Extension e = null; + if (cert instanceof GnuPKIExtension) + { + e = ((GnuPKIExtension) cert).getExtension(BasicConstraints.ID); + } + else + { + try + { + e = new Extension(cert.getExtensionValue(BasicConstraints.ID.toString())); + } + catch (Exception x) + { + } + } + if (e == null) + throw new CertPathValidatorException("no basicConstraints"); + BasicConstraints bc = (BasicConstraints) e.getValue(); + if (!bc.isCA()) + throw new CertPathValidatorException("certificate cannot be used to verify signatures"); + if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen) + throw new CertPathValidatorException("path is too long"); + + boolean[] keyUsage = cert.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.KEY_CERT_SIGN]) + throw new CertPathValidatorException("certificate cannot be used to sign certificates"); + } + } + + private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root, + int depth, PKIXParameters params, + boolean explicitPolicy) + throws CertPathValidatorException + { + if (DEBUG) debug("updatePolicyTree depth == " + depth); + Set nodes = new HashSet(); + LinkedList stack = new LinkedList(); + Iterator current = null; + stack.addLast(Collections.singleton(root).iterator()); + do + { + current = (Iterator) stack.removeLast(); + while (current.hasNext()) + { + PolicyNodeImpl p = (PolicyNodeImpl) current.next(); + if (DEBUG) debug("visiting node == " + p); + if (p.getDepth() == depth - 1) + { + if (DEBUG) debug("added node"); + nodes.add(p); + } + else + { + if (DEBUG) debug("skipped node"); + stack.addLast(current); + current = p.getChildren(); + } + } + } + while (!stack.isEmpty()); + + Extension e = null; + CertificatePolicies policies = null; + List qualifierInfos = null; + if (cert instanceof GnuPKIExtension) + { + e = ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID); + if (e != null) + policies = (CertificatePolicies) e.getValue(); + } + + List cp = null; + if (policies != null) + cp = policies.getPolicies(); + else + cp = Collections.EMPTY_LIST; + boolean match = false; + if (DEBUG) debug("nodes are == " + nodes); + if (DEBUG) debug("cert policies are == " + cp); + for (Iterator it = nodes.iterator(); it.hasNext(); ) + { + PolicyNodeImpl parent = (PolicyNodeImpl) it.next(); + if (DEBUG) debug("adding policies to " + parent); + for (Iterator it2 = cp.iterator(); it2.hasNext(); ) + { + OID policy = (OID) it2.next(); + if (DEBUG) debug("trying to add policy == " + policy); + if (policy.toString().equals(ANY_POLICY) && + params.isAnyPolicyInhibited()) + continue; + PolicyNodeImpl child = new PolicyNodeImpl(); + child.setValidPolicy(policy.toString()); + child.addExpectedPolicy(policy.toString()); + if (parent.getExpectedPolicies().contains(policy.toString())) + { + parent.addChild(child); + match = true; + } + else if (parent.getExpectedPolicies().contains(ANY_POLICY)) + { + parent.addChild(child); + match = true; + } + else if (ANY_POLICY.equals (policy.toString())) + { + parent.addChild (child); + match = true; + } + if (match && policies != null) + { + List qualifiers = policies.getPolicyQualifierInfos (policy); + if (qualifiers != null) + child.addAllPolicyQualifiers (qualifiers); + } + } + } + if (!match && (params.isExplicitPolicyRequired() || explicitPolicy)) + throw new CertPathValidatorException("policy tree building failed"); + } + + private boolean checkExplicitPolicy (int depth, List explicitPolicies) + { + if (DEBUG) debug ("checkExplicitPolicy depth=" + depth); + for (Iterator it = explicitPolicies.iterator(); it.hasNext(); ) + { + int[] i = (int[]) it.next(); + int caDepth = i[0]; + int limit = i[1]; + if (DEBUG) debug (" caDepth=" + caDepth + " limit=" + limit); + if (depth - caDepth >= limit) + return true; + } + return false; + } +} diff --git a/libjava/classpath/gnu/java/security/provider/RSA.java b/libjava/classpath/gnu/java/security/provider/RSA.java new file mode 100644 index 0000000..c3cfbbf --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/RSA.java @@ -0,0 +1,311 @@ +/* RSA.java -- RSA PKCS#1 signatures. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; + +public abstract class RSA extends SignatureSpi implements Cloneable +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + /** + * digestAlgorithm OBJECT IDENTIFIER ::= + * { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) } + */ + protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2"); + + protected final OID digestAlgorithm; + protected final MessageDigest md; + protected RSAPrivateKey signerKey; + protected RSAPublicKey verifierKey; + + // Constructor. + // ------------------------------------------------------------------------- + + protected RSA(MessageDigest md, OID digestAlgorithm) + { + super(); + this.md = md; + this.digestAlgorithm = digestAlgorithm; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Object clone() throws CloneNotSupportedException + { + return super.clone(); + } + + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("deprecated"); + } + + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("deprecated"); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (!(privateKey instanceof RSAPrivateKey)) + throw new InvalidKeyException(); + verifierKey = null; + signerKey = (RSAPrivateKey) privateKey; + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + // This class does not need random bytes. + engineInitSign(privateKey); + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (!(publicKey instanceof RSAPublicKey)) + throw new InvalidKeyException(); + signerKey = null; + verifierKey = (RSAPublicKey) publicKey; + } + + protected void engineUpdate(byte b) throws SignatureException + { + if (signerKey == null && verifierKey == null) + throw new SignatureException("not initialized"); + md.update(b); + } + + protected void engineUpdate(byte[] buf, int off, int len) + throws SignatureException + { + if (signerKey == null && verifierKey == null) + throw new SignatureException("not initialized"); + md.update(buf, off, len); + } + + protected byte[] engineSign() throws SignatureException + { + if (signerKey == null) + throw new SignatureException("not initialized for signing"); + // + // The signature will be the RSA encrypted BER representation of + // the following: + // + // DigestInfo ::= SEQUENCE { + // digestAlgorithm DigestAlgorithmIdentifier, + // digest Digest } + // + // DigestAlgorithmIdentifier ::= AlgorithmIdentifier + // + // Digest ::= OCTET STRING + // + ArrayList digestAlg = new ArrayList(2); + digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm)); + digestAlg.add(new DERValue(DER.NULL, null)); + ArrayList digestInfo = new ArrayList(2); + digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg)); + digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest())); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try + { + DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo)); + } + catch (IOException ioe) + { + throw new SignatureException(ioe.toString()); + } + byte[] buf = out.toByteArray(); + md.reset(); + + // k = octect length of the modulus. + int k = signerKey.getModulus().bitLength(); + k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); + if (buf.length < k - 3) + { + throw new SignatureException("RSA modulus too small"); + } + byte[] d = new byte[k]; + + // Padding type 1: + // 00 | 01 | FF | ... | FF | 00 | D + d[1] = 0x01; + for (int i = 2; i < k - buf.length - 1; i++) + d[i] = (byte) 0xFF; + System.arraycopy(buf, 0, d, k - buf.length, buf.length); + + BigInteger eb = new BigInteger(d); + + byte[] ed = eb.modPow(signerKey.getPrivateExponent(), + signerKey.getModulus()).toByteArray(); + + // Ensure output is k octets long. + if (ed.length < k) + { + byte[] b = new byte[k]; + System.arraycopy(eb, 0, b, k - ed.length, ed.length); + ed = b; + } + else if (ed.length > k) + { + if (ed.length != k + 1) + { + throw new SignatureException("modPow result is larger than the modulus"); + } + // Maybe an extra 00 octect. + byte[] b = new byte[k]; + System.arraycopy(ed, 1, b, 0, k); + ed = b; + } + + return ed; + } + + protected int engineSign(byte[] out, int off, int len) + throws SignatureException + { + if (out == null || off < 0 || len < 0 || off+len > out.length) + throw new SignatureException("illegal output argument"); + byte[] result = engineSign(); + if (result.length > len) + throw new SignatureException("not enough space for signature"); + System.arraycopy(result, 0, out, off, result.length); + return result.length; + } + + protected boolean engineVerify(byte[] sig) throws SignatureException + { + if (verifierKey == null) + throw new SignatureException("not initialized for verifying"); + if (sig == null) + throw new SignatureException("no signature specified"); + int k = verifierKey.getModulus().bitLength(); + k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); + if (sig.length != k) + throw new SignatureException("signature is the wrong size (expecting " + + k + " bytes, got " + sig.length + ")"); + BigInteger ed = new BigInteger(1, sig); + byte[] eb = ed.modPow(verifierKey.getPublicExponent(), + verifierKey.getModulus()).toByteArray(); + + int i = 0; + if (eb[0] == 0x00) + { + for (i = 1; i < eb.length && eb[i] == 0x00; i++); + if (i == 1) + throw new SignatureException("wrong RSA padding"); + i--; + } + else if (eb[0] == 0x01) + { + for (i = 1; i < eb.length && eb[i] != 0x00; i++) + if (eb[i] != (byte) 0xFF) + throw new IllegalArgumentException("wrong RSA padding"); + } + else + throw new SignatureException("wrong RSA padding type"); + + byte[] d = new byte[eb.length-i-1]; + System.arraycopy(eb, i+1, d, 0, eb.length-i-1); + + DERReader der = new DERReader(d); + try + { + DERValue val = der.read(); + if (val.getTag() != DER.SEQUENCE) + throw new SignatureException("failed to parse DigestInfo"); + val = der.read(); + if (val.getTag() != DER.SEQUENCE) + throw new SignatureException("failed to parse DigestAlgorithmIdentifier"); + boolean sequenceIsBer = val.getLength() == 0; + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new SignatureException("failed to parse object identifier"); + if (!val.getValue().equals(digestAlgorithm)) + throw new SignatureException("digest algorithms do not match"); + val = der.read(); + // We should never see parameters here, since they are never used. + if (val.getTag() != DER.NULL) + throw new SignatureException("cannot handle digest parameters"); + if (sequenceIsBer) + der.skip(1); // end-of-sequence byte. + val = der.read(); + if (val.getTag() != DER.OCTET_STRING) + throw new SignatureException("failed to parse Digest"); + return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue()); + } + catch (IOException ioe) + { + throw new SignatureException(ioe.toString()); + } + } + + protected boolean engineVerify(byte[] sig, int off, int len) + throws SignatureException + { + if (sig == null || off < 0 || len < 0 || off+len > sig.length) + throw new SignatureException("illegal parameter"); + byte[] buf = new byte[len]; + System.arraycopy(sig, off, buf, 0, len); + return engineVerify(buf); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java new file mode 100644 index 0000000..d13cbe5 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java @@ -0,0 +1,181 @@ +/* RSAKeyFactory.java -- RSA key factory. + Copyright (C) 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.java.security.provider; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; + +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class RSAKeyFactory extends KeyFactorySpi +{ + + // Default constructor. + // ------------------------------------------------------------------------- + + // Instance methods. + // ------------------------------------------------------------------------- + + protected PrivateKey engineGeneratePrivate(KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof RSAPrivateCrtKeySpec) + { + return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec); + } + if (spec instanceof RSAPrivateKeySpec) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateKeySpec) spec).getModulus(), null, + ((RSAPrivateKeySpec) spec).getPrivateExponent(), null, + null, null, null, null)); + } + if (spec instanceof PKCS8EncodedKeySpec) + { + EncodedKeyFactory ekf = new EncodedKeyFactory(); + PrivateKey pk = ekf.engineGeneratePrivate(spec); + if (pk instanceof RSAPrivateKey) + return pk; + } + throw new InvalidKeySpecException(); + } + + protected PublicKey engineGeneratePublic(KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof RSAPublicKeySpec) + { + return new GnuRSAPublicKey((RSAPublicKeySpec) spec); + } + if (spec instanceof X509EncodedKeySpec) + { + EncodedKeyFactory ekf = new EncodedKeyFactory(); + PublicKey pk = ekf.engineGeneratePublic(spec); + if (pk instanceof RSAPublicKey) + return pk; + } + throw new InvalidKeySpecException(); + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class) + && (key instanceof RSAPrivateCrtKey)) + { + return new RSAPrivateCrtKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent(), + ((RSAPrivateCrtKey) key).getPrivateExponent(), + ((RSAPrivateCrtKey) key).getPrimeP(), + ((RSAPrivateCrtKey) key).getPrimeQ(), + ((RSAPrivateCrtKey) key).getPrimeExponentP(), + ((RSAPrivateCrtKey) key).getPrimeExponentQ(), + ((RSAPrivateCrtKey) key).getCrtCoefficient()); + } + if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class) + && (key instanceof RSAPrivateKey)) + { + return new RSAPrivateKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPrivateExponent()); + } + if (keySpec.isAssignableFrom(RSAPublicKeySpec.class) + && (key instanceof RSAPublicKey)) + { + return new RSAPublicKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent()); + } + if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class) + && key.getFormat().equalsIgnoreCase("PKCS#8")) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + if (keySpec.isAssignableFrom(X509EncodedKeySpec.class) + && key.getFormat().equalsIgnoreCase("X.509")) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + throw new InvalidKeySpecException(); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + if (key instanceof RSAPrivateCrtKey) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent(), + ((RSAPrivateCrtKey) key).getPrivateExponent(), + ((RSAPrivateCrtKey) key).getPrimeP(), + ((RSAPrivateCrtKey) key).getPrimeQ(), + ((RSAPrivateCrtKey) key).getPrimeExponentP(), + ((RSAPrivateCrtKey) key).getPrimeExponentQ(), + ((RSAPrivateCrtKey) key).getCrtCoefficient())); + } + if (key instanceof RSAPrivateKey) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateKey) key).getModulus(), null, + ((RSAPrivateKey) key).getPrivateExponent(), null, + null, null, null, null)); + } + if (key instanceof RSAPublicKey) + { + return new GnuRSAPublicKey(new RSAPublicKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent())); + } + throw new InvalidKeyException(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/SHA.java b/libjava/classpath/gnu/java/security/provider/SHA.java new file mode 100644 index 0000000..e3b09bc --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/SHA.java @@ -0,0 +1,242 @@ +/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1]. + Copyright (C) 1999, 2000, 2002 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.java.security.provider; + +import java.security.MessageDigest; + +/** + This class implements the SHA-1 algorithm as described in [1]. + + [1] Federal Information Processing Standards Publication 180-1. + Specifications for the Secure Hash Standard. April 17, 1995. + + @see java.security.MessageDigest +*/ +public class SHA extends MessageDigest implements Cloneable +{ + public SHA () + { + super("SHA"); + engineReset (); + } + + public int engineGetDigestLength() + { + return 20; + } + + public void engineUpdate (byte b) + { + int i = ((int)bytecount) & 0x3f; //wgs + int shift = (3 - i % 4) << 3; + int idx = i / 4; + + i = (int)b; + W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift); + + // if we've filled up a block, then process it + if (((++bytecount) & 0x3f) == 0) + munch (); + } + + // This could be optimized. + public void engineUpdate (byte bytes[], int off, int len) + { + if (len < 0) + throw new ArrayIndexOutOfBoundsException (); + + int end = off + len; + while (off < end) + engineUpdate (bytes[off++]); + } + + public void engineReset () + { + bytecount = 0; + // magic numbers from [1] p. 10. + H0 = 0x67452301; + H1 = 0xefcdab89; + H2 = 0x98badcfe; + H3 = 0x10325476; + H4 = 0xc3d2e1f0; + } + + public byte[] engineDigest () + { + long bitcount = bytecount << 3; + engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding + + // add the rest of the padding to fill this block out, but leave 8 + // bytes to put in the original bytecount + while ((bytecount & 0x3f) != 56) + engineUpdate ((byte)0); + + // add the length of the original, unpadded block to the end of + // the padding + W[14] = (int)(bitcount >>> 32); + W[15] = (int)bitcount; + bytecount += 8; + + // digest the fully padded block + munch (); + + byte[] result + = new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16), + (byte)(H0 >>> 8), (byte)H0, + (byte)(H1 >>> 24), (byte)(H1 >>> 16), + (byte)(H1 >>> 8), (byte)H1, + (byte)(H2 >>> 24), (byte)(H2 >>> 16), + (byte)(H2 >>> 8), (byte)H2, + (byte)(H3 >>> 24), (byte)(H3 >>> 16), + (byte)(H3 >>> 8), (byte)H3, + (byte)(H4 >>> 24), (byte)(H4 >>> 16), + (byte)(H4 >>> 8), (byte)H4}; + + engineReset (); + return result; + } + + // Process a single block. This is pretty much copied verbatim from + // [1] pp. 9, 10. + private void munch () + { + for (int t = 16; t < 80; ++ t) + { + int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; + W[t] = Wt << 1 | Wt >>> 31; + } + + int A = H0; + int B = H1; + int C = H2; + int D = H3; + int E = H4; + + for (int t = 0; t < 20; ++ t) + { + int TEMP = (A << 5 | A >>> 27) // S^5(A) + + ((B & C) | (~B & D)) // f_t(B,C,D) + + E + W[t] + + 0x5a827999; // K_t + + E = D; + D = C; + C = B << 30 | B >>> 2; // S^30(B) + B = A; + A = TEMP; + } + + for (int t = 20; t < 40; ++ t) + { + int TEMP = (A << 5 | A >>> 27) // S^5(A) + + (B ^ C ^ D) // f_t(B,C,D) + + E + W[t] + + 0x6ed9eba1; // K_t + + E = D; + D = C; + C = B << 30 | B >>> 2; // S^30(B) + B = A; + A = TEMP; + } + + for (int t = 40; t < 60; ++ t) + { + int TEMP = (A << 5 | A >>> 27) // S^5(A) + + (B & C | B & D | C & D) // f_t(B,C,D) + + E + W[t] + + 0x8f1bbcdc; // K_t + + E = D; + D = C; + C = B << 30 | B >>> 2; // S^30(B) + B = A; + A = TEMP; + } + + for (int t = 60; t < 80; ++ t) + { + int TEMP = (A << 5 | A >>> 27) // S^5(A) + + (B ^ C ^ D) // f_t(B,C,D) + + E + W[t] + + 0xca62c1d6; // K_t + + E = D; + D = C; + C = B << 30 | B >>> 2; // S^30(B) + B = A; + A = TEMP; + } + + H0 += A; + H1 += B; + H2 += C; + H3 += D; + H4 += E; + + // Reset W by clearing it. + for (int t = 0; t < 80; ++ t) + W[t] = 0; + } + + public Object clone () + { + return new SHA (this); + } + + private SHA (SHA copy) + { + this (); + bytecount = copy.bytecount; + H0 = copy.H0; + H1 = copy.H1; + H2 = copy.H2; + H3 = copy.H3; + H4 = copy.H4; + System.arraycopy (copy.W, 0, W, 0, 80); + } + + private final int W[] = new int[80]; + private long bytecount; + private int H0; + private int H1; + private int H2; + private int H3; + private int H4; +} diff --git a/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java b/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java new file mode 100644 index 0000000..e4058e3 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java @@ -0,0 +1,137 @@ +/* SHA1PRNG.java --- Secure Random SPI SHA1PRNG + Copyright (C) 1999, 2001, 2003, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 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.java.security.provider; + +import java.io.Serializable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandomSpi; +import java.util.Random; + +public class SHA1PRNG extends SecureRandomSpi implements Serializable +{ + MessageDigest digest; + byte seed[]; + byte data[]; + int seedpos; + int datapos; + private boolean seeded = false; // set to true when we seed this + /** + * The size of seed. + */ + private static final int SEED_SIZE = 20; + /** + * The size of data. + */ + private static final int DATA_SIZE = 40; + + /** + * Create a new SHA-1 pseudo-random number generator. + */ + public SHA1PRNG() + { + try { + digest = MessageDigest.getInstance("SHA"); + } catch ( NoSuchAlgorithmException nsae) { +// System.out.println("Failed to find SHA Message Digest: " + nsae); +// nsae.printStackTrace(); + throw new InternalError ("no SHA implementation found"); + } + + seed = new byte[SEED_SIZE]; + seedpos = 0; + data = new byte[DATA_SIZE]; + datapos = SEED_SIZE; // try to force hashing a first block + } + + public void engineSetSeed(byte[] seed) + { + for(int i = 0; i < seed.length; i++) + this.seed[seedpos++ % SEED_SIZE] ^= seed[i]; + seedpos %= SEED_SIZE; + + } + + public void engineNextBytes(byte[] bytes) + { + ensureIsSeeded (); + int loc = 0; + while (loc < bytes.length) + { + int copy = Math.min (bytes.length - loc, SEED_SIZE - datapos); + + if (copy > 0) + { + System.arraycopy (data, datapos, bytes, loc, copy); + datapos += copy; + loc += copy; + } + else + { + // No data ready for copying, so refill our buffer. + System.arraycopy( seed, 0, data, SEED_SIZE, SEED_SIZE); + byte[] digestdata = digest.digest( data ); + System.arraycopy( digestdata, 0, data, 0, SEED_SIZE); + datapos = 0; + } + } + } + + public byte[] engineGenerateSeed(int numBytes) + { + byte tmp[] = new byte[numBytes]; + + engineNextBytes( tmp ); + return tmp; + } + + private void ensureIsSeeded() + { + if (!seeded) + { + new Random(0L).nextBytes(seed); + + byte[] digestdata = digest.digest(data); + System.arraycopy(digestdata, 0, data, 0, SEED_SIZE); + + seeded = true; + } + } + +} diff --git a/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java b/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java new file mode 100644 index 0000000..0e63fde --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java @@ -0,0 +1,61 @@ +/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures. + Copyright (C) 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.java.security.provider; + +import gnu.java.security.OID; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class SHA1withRSA extends RSA +{ + + // Constant. + // ------------------------------------------------------------------------- + + private static final OID SHA1 = new OID("1.3.14.3.2.26"); + + // Constructor. + // ------------------------------------------------------------------------- + + public SHA1withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("SHA-160"), SHA1); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java b/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java new file mode 100644 index 0000000..1a415ea --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/X509CertificateFactory.java @@ -0,0 +1,305 @@ +/* X509CertificateFactory.java -- generates X.509 certificates. + Copyright (C) 2003 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.java.security.provider; + +import gnu.java.io.Base64InputStream; +import gnu.java.security.x509.X509CRL; +import gnu.java.security.x509.X509CertPath; +import gnu.java.security.x509.X509Certificate; + +import java.io.BufferedInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.security.cert.CRL; +import java.security.cert.CRLException; +import java.security.cert.CertPath; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactorySpi; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class X509CertificateFactory extends CertificateFactorySpi +{ + + // Constants. + // ------------------------------------------------------------------------ + + public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----"; + public static final String END_CERTIFICATE = "-----END CERTIFICATE-----"; + public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----"; + public static final String END_X509_CRL = "-----END X509 CRL-----"; + + // Constructors. + // ------------------------------------------------------------------------ + + public X509CertificateFactory() + { + super(); + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public Certificate engineGenerateCertificate(InputStream inStream) + throws CertificateException + { + try + { + return generateCert(inStream); + } + catch (IOException ioe) + { + CertificateException ce = new CertificateException(ioe.getMessage()); + ce.initCause (ioe); + throw ce; + } + } + + public Collection engineGenerateCertificates(InputStream inStream) + throws CertificateException + { + LinkedList certs = new LinkedList(); + while (true) + { + try + { + certs.add(generateCert(inStream)); + } + catch (EOFException eof) + { + break; + } + catch (IOException ioe) + { + CertificateException ce = new CertificateException(ioe.getMessage()); + ce.initCause (ioe); + throw ce; + } + } + return certs; + } + + public CRL engineGenerateCRL(InputStream inStream) throws CRLException + { + try + { + return generateCRL(inStream); + } + catch (IOException ioe) + { + CRLException crle = new CRLException(ioe.getMessage()); + crle.initCause (ioe); + throw crle; + } + } + + public Collection engineGenerateCRLs(InputStream inStream) + throws CRLException + { + LinkedList crls = new LinkedList(); + while (true) + { + try + { + crls.add(generateCRL(inStream)); + } + catch (EOFException eof) + { + break; + } + catch (IOException ioe) + { + CRLException crle = new CRLException(ioe.getMessage()); + crle.initCause (ioe); + throw crle; + } + } + return crls; + } + + public CertPath engineGenerateCertPath(List certs) + { + return new X509CertPath(certs); + } + + public CertPath engineGenerateCertPath(InputStream in) + throws CertificateEncodingException + { + return new X509CertPath(in); + } + + public CertPath engineGenerateCertPath(InputStream in, String encoding) + throws CertificateEncodingException + { + return new X509CertPath(in, encoding); + } + + public Iterator engineGetCertPathEncodings() + { + return X509CertPath.ENCODINGS.iterator(); + } + + // Own methods. + // ------------------------------------------------------------------------ + + private X509Certificate generateCert(InputStream inStream) + throws IOException, CertificateException + { + if (inStream == null) + throw new CertificateException("missing input stream"); + if (!inStream.markSupported()) + inStream = new BufferedInputStream(inStream, 8192); + inStream.mark(20); + int i = inStream.read(); + if (i == -1) + throw new EOFException(); + + // If the input is in binary DER format, the first byte MUST be + // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the + // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set. + // + // So if we do not see 0x30 here we will assume it is in Base-64. + if (i != 0x30) + { + inStream.reset(); + StringBuffer line = new StringBuffer(80); + do + { + line.setLength(0); + do + { + i = inStream.read(); + if (i == -1) + throw new EOFException(); + if (i != '\n' && i != '\r') + line.append((char) i); + } + while (i != '\n' && i != '\r'); + } + while (!line.toString().equals(BEGIN_CERTIFICATE)); + X509Certificate ret = new X509Certificate( + new BufferedInputStream(new Base64InputStream(inStream), 8192)); + line.setLength(0); + line.append('-'); // Base64InputStream will eat this. + do + { + i = inStream.read(); + if (i == -1) + throw new EOFException(); + if (i != '\n' && i != '\r') + line.append((char) i); + } + while (i != '\n' && i != '\r'); + // XXX ??? + if (!line.toString().equals(END_CERTIFICATE)) + throw new CertificateException("no end-of-certificate marker"); + return ret; + } + else + { + inStream.reset(); + return new X509Certificate(inStream); + } + } + + private X509CRL generateCRL(InputStream inStream) + throws IOException, CRLException + { + if (inStream == null) + throw new CRLException("missing input stream"); + if (!inStream.markSupported()) + inStream = new BufferedInputStream(inStream, 8192); + inStream.mark(20); + int i = inStream.read(); + if (i == -1) + throw new EOFException(); + + // If the input is in binary DER format, the first byte MUST be + // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the + // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set. + // + // So if we do not see 0x30 here we will assume it is in Base-64. + if (i != 0x30) + { + inStream.reset(); + StringBuffer line = new StringBuffer(80); + do + { + line.setLength(0); + do + { + i = inStream.read(); + if (i == -1) + throw new EOFException(); + if (i != '\n' && i != '\r') + line.append((char) i); + } + while (i != '\n' && i != '\r'); + } + while (!line.toString().startsWith(BEGIN_X509_CRL)); + X509CRL ret = new X509CRL( + new BufferedInputStream(new Base64InputStream(inStream), 8192)); + line.setLength(0); + line.append('-'); // Base64InputStream will eat this. + do + { + i = inStream.read(); + if (i == -1) + throw new EOFException(); + if (i != '\n' && i != '\r') + line.append((char) i); + } + while (i != '\n' && i != '\r'); + // XXX ??? + if (!line.toString().startsWith(END_X509_CRL)) + throw new CRLException("no end-of-CRL marker"); + return ret; + } + else + { + inStream.reset(); + return new X509CRL(inStream); + } + } +} diff --git a/libjava/classpath/gnu/java/security/provider/package.html b/libjava/classpath/gnu/java/security/provider/package.html new file mode 100644 index 0000000..641a22a --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.provider package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.provider</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/util/Prime.java b/libjava/classpath/gnu/java/security/util/Prime.java new file mode 100644 index 0000000..e493ce6 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/Prime.java @@ -0,0 +1,164 @@ +/* Prime.java --- Prime number generation utilities + Copyright (C) 1999, 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.java.security.util; +import java.math.BigInteger; +import java.util.Random; +//import java.security.SecureRandom; + +public final class Prime +{ + + /* + See IEEE P1363 A.15.4 (10/05/98 Draft) + */ + public static BigInteger generateRandomPrime( int pmin, int pmax, BigInteger f ) + { + BigInteger d; + + //Step 1 - generate prime + BigInteger p = new BigInteger( (pmax + pmin)/2, new Random() ); + if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmin ) ) <= 0 ) + { + p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin ).subtract( p ) ); + } + + //Step 2 - test for even + if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0) + p = p.add( BigInteger.valueOf( 1 ) ); + + for(;;) + { + //Step 3 + if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmax)) > 0) + { + //Step 3.1 + p = p.subtract( BigInteger.valueOf( 1 ).shiftLeft( pmax) ); + p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin) ); + p = p.subtract( BigInteger.valueOf( 1 ) ); + + //Step 3.2 + // put step 2 code here so looping code is cleaner + //Step 2 - test for even + if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0) + p = p.add( BigInteger.valueOf( 1 ) ); + continue; + } + + //Step 4 - compute GCD + d = p.subtract( BigInteger.valueOf(1) ); + d = d.gcd( f ); + + //Step 5 - test d + if( d.compareTo( BigInteger.valueOf( 1 ) ) == 0) + { + //Step 5.1 - test primality + if( p.isProbablePrime( 1 ) == true ) + { + //Step 5.2; + return p; + } + } + //Step 6 + p = p.add( BigInteger.valueOf( 2 ) ); + + //Step 7 + } + } + + + /* + See IEEE P1363 A.15.5 (10/05/98 Draft) + */ + public static BigInteger generateRandomPrime( BigInteger r, BigInteger a, int pmin, int pmax, BigInteger f ) + { + BigInteger d, w; + + //Step 1 - generate prime + BigInteger p = new BigInteger( (pmax + pmin)/2, new Random() ); + + steptwo:{ //Step 2 + w = p.mod( r.multiply( BigInteger.valueOf(2) )); + + //Step 3 + p = p.add( r.multiply( BigInteger.valueOf(2) ) ); + p = p.subtract( w ); + p = p.add(a); + + //Step 4 - test for even + if( p.mod( BigInteger.valueOf(2) ).compareTo( BigInteger.valueOf( 0 )) == 0) + p = p.add( r ); + + for(;;) + { + //Step 5 + if( p.compareTo( BigInteger.valueOf( 1 ).shiftLeft( pmax)) > 0) + { + //Step 5.1 + p = p.subtract( BigInteger.valueOf( 1 ).shiftLeft( pmax) ); + p = p.add( BigInteger.valueOf( 1 ).shiftLeft( pmin) ); + p = p.subtract( BigInteger.valueOf( 1 ) ); + + //Step 5.2 - goto to Step 2 + break steptwo; + } + + //Step 6 + d = p.subtract( BigInteger.valueOf(1) ); + d = d.gcd( f ); + + //Step 7 - test d + if( d.compareTo( BigInteger.valueOf( 1 ) ) == 0) + { + //Step 7.1 - test primality + if( p.isProbablePrime( 1 ) == true ) + { + //Step 7.2; + return p; + } + } + //Step 8 + p = p.add( r.multiply( BigInteger.valueOf(2) ) ); + + //Step 9 + } + } + //Should never reach here but makes the compiler happy + return BigInteger.valueOf(0); + } +} diff --git a/libjava/classpath/gnu/java/security/util/package.html b/libjava/classpath/gnu/java/security/util/package.html new file mode 100644 index 0000000..36dd33b --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.util package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.util</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/x509/GnuPKIExtension.java b/libjava/classpath/gnu/java/security/x509/GnuPKIExtension.java new file mode 100644 index 0000000..8e74b8b --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/GnuPKIExtension.java @@ -0,0 +1,59 @@ +/* GnuPKIExtension.java -- interface for GNU PKI extensions. + Copyright (C) 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.java.security.x509; + +import gnu.java.security.OID; +import gnu.java.security.x509.ext.Extension; + +import java.security.cert.X509Extension; +import java.util.Collection; + +public interface GnuPKIExtension extends X509Extension +{ + + /** + * Returns the extension object for the given object identifier. + * + * @param oid The OID of the extension to get. + * @return The extension, or null if there is no such extension. + */ + Extension getExtension(OID oid); + + Collection getExtensions(); +} diff --git a/libjava/classpath/gnu/java/security/x509/PolicyNodeImpl.java b/libjava/classpath/gnu/java/security/x509/PolicyNodeImpl.java new file mode 100644 index 0000000..72cb4a9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/PolicyNodeImpl.java @@ -0,0 +1,214 @@ +/* PolicyNodeImpl.java -- An implementation of a policy tree node. + Copyright (C) 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.java.security.x509; + +import java.security.cert.PolicyNode; +import java.security.cert.PolicyQualifierInfo; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public final class PolicyNodeImpl implements PolicyNode +{ + + // Fields. + // ------------------------------------------------------------------------- + + private String policy; + private final Set expectedPolicies; + private final Set qualifiers; + private final Set children; + private PolicyNodeImpl parent; + private int depth; + private boolean critical; + private boolean readOnly; + + // Constructors. + // ------------------------------------------------------------------------- + + public PolicyNodeImpl() + { + expectedPolicies = new HashSet(); + qualifiers = new HashSet(); + children = new HashSet(); + readOnly = false; + critical = false; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addChild(PolicyNodeImpl node) + { + if (readOnly) + throw new IllegalStateException("read only"); + if (node.getParent() != null) + throw new IllegalStateException("already a child node"); + node.parent = this; + node.setDepth(depth + 1); + children.add(node); + } + + public Iterator getChildren() + { + return Collections.unmodifiableSet(children).iterator(); + } + + public int getDepth() + { + return depth; + } + + public void setDepth(int depth) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.depth = depth; + } + + public void addAllExpectedPolicies(Set policies) + { + if (readOnly) + throw new IllegalStateException("read only"); + expectedPolicies.addAll(policies); + } + + public void addExpectedPolicy(String policy) + { + if (readOnly) + throw new IllegalStateException("read only"); + expectedPolicies.add(policy); + } + + public Set getExpectedPolicies() + { + return Collections.unmodifiableSet(expectedPolicies); + } + + public PolicyNode getParent() + { + return parent; + } + + public void addAllPolicyQualifiers (Collection qualifiers) + { + for (Iterator it = qualifiers.iterator(); it.hasNext(); ) + { + if (!(it.next() instanceof PolicyQualifierInfo)) + throw new IllegalArgumentException ("can only add PolicyQualifierInfos"); + } + qualifiers.addAll (qualifiers); + } + + public void addPolicyQualifier (PolicyQualifierInfo qualifier) + { + if (readOnly) + throw new IllegalStateException("read only"); + qualifiers.add(qualifier); + } + + public Set getPolicyQualifiers() + { + return Collections.unmodifiableSet(qualifiers); + } + + public String getValidPolicy() + { + return policy; + } + + public void setValidPolicy(String policy) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.policy = policy; + } + + public boolean isCritical() + { + return critical; + } + + public void setCritical(boolean critical) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.critical = critical; + } + + public void setReadOnly() + { + if (readOnly) + return; + readOnly = true; + for (Iterator it = getChildren(); it.hasNext(); ) + ((PolicyNodeImpl) it.next()).setReadOnly(); + } + + public String toString() + { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < depth; i++) + buf.append(" "); + buf.append("("); + buf.append(PolicyNodeImpl.class.getName()); + buf.append(" (oid "); + buf.append(policy); + buf.append(") (depth "); + buf.append(depth); + buf.append(") (qualifiers "); + buf.append(qualifiers); + buf.append(") (critical "); + buf.append(critical); + buf.append(") (expectedPolicies "); + buf.append(expectedPolicies); + buf.append(") (children ("); + final String nl = System.getProperty("line.separator"); + for (Iterator it = getChildren(); it.hasNext(); ) + { + buf.append(nl); + buf.append(it.next().toString()); + } + buf.append(")))"); + return buf.toString(); + } +} diff --git a/libjava/classpath/gnu/java/security/x509/Util.java b/libjava/classpath/gnu/java/security/x509/Util.java new file mode 100644 index 0000000..d273920 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/Util.java @@ -0,0 +1,202 @@ +/* Util.java -- Miscellaneous utility methods. + Copyright (C) 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.java.security.x509; + +/** + * A collection of useful class methods. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public final class Util +{ + + // Constants. + // ------------------------------------------------------------------------- + + public static final String HEX = "0123456789abcdef"; + + // Class methods. + // ------------------------------------------------------------------------- + + /** + * Convert a byte array to a hexadecimal string, as though it were a + * big-endian arbitrarily-sized integer. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to format. + * @return A hexadecimal representation of the specified bytes. + */ + public static String toHexString(byte[] buf, int off, int len) + { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < len; i++) + { + str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F)); + str.append(HEX.charAt(buf[i+off] & 0x0F)); + } + return str.toString(); + } + + /** + * See {@link #toHexString(byte[],int,int)}. + */ + public static String toHexString(byte[] buf) + { + return Util.toHexString(buf, 0, buf.length); + } + + /** + * Convert a byte array to a hexadecimal string, separating octets + * with the given character. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to format. + * @param sep The character to insert between octets. + * @return A hexadecimal representation of the specified bytes. + */ + public static String toHexString(byte[] buf, int off, int len, char sep) + { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < len; i++) + { + str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F)); + str.append(HEX.charAt(buf[i+off] & 0x0F)); + if (i < len - 1) + str.append(sep); + } + return str.toString(); + } + + /** + * See {@link #toHexString(byte[],int,int,char)}. + */ + public static String toHexString(byte[] buf, char sep) + { + return Util.toHexString(buf, 0, buf.length, sep); + } + + /** + * Create a representation of the given byte array similar to the + * output of `hexdump -C', which is + * + * <p><pre>OFFSET SIXTEEN-BYTES-IN-HEX PRINTABLE-BYTES</pre> + * + * <p>The printable bytes show up as-is if they are printable and + * not a newline character, otherwise showing as '.'. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to encode. + * @return The formatted string. + */ + public static String hexDump(byte[] buf, int off, int len, String prefix) + { + String nl = System.getProperty("line.separator"); + StringBuffer str = new StringBuffer(); + int i = 0; + while (i < len) + { + str.append(prefix); + str.append(Util.formatInt(i+off, 16, 8)); + str.append(" "); + String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' '); + str.append(s); + for (int j = 56 - (56 - s.length()); j < 56; j++) + str.append(" "); + for (int j = 0; j < Math.min(16, len - i); j++) + { + if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E) + str.append('.'); + else + str.append((char) (buf[i+off+j] & 0xFF)); + } + str.append(nl); + i += 16; + } + return str.toString(); + } + + /** + * See {@link #hexDump(byte[],int,int)}. + */ + public static String hexDump(byte[] buf, String prefix) + { + return hexDump(buf, 0, buf.length, prefix); + } + + /** + * Format an integer into the specified radix, zero-filled. + * + * @param i The integer to format. + * @param radix The radix to encode to. + * @param len The target length of the string. The string is + * zero-padded to this length, but may be longer. + * @return The formatted integer. + */ + public static String formatInt(int i, int radix, int len) + { + String s = Integer.toString(i, radix); + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < len - s.length(); j++) + buf.append("0"); + buf.append(s); + return buf.toString(); + } + + /** + * Convert a hexadecimal string into its byte representation. + * + * @param hex The hexadecimal string. + * @return The converted bytes. + */ + public static byte[] toByteArray(String hex) + { + hex = hex.toLowerCase(); + byte[] buf = new byte[hex.length() / 2]; + int j = 0; + for (int i = 0; i < buf.length; i++) + { + buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) | + Character.digit(hex.charAt(j++), 16)); + } + return buf; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X500DistinguishedName.java b/libjava/classpath/gnu/java/security/x509/X500DistinguishedName.java new file mode 100644 index 0000000..daf746f --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X500DistinguishedName.java @@ -0,0 +1,548 @@ +/* X500DistinguishedName.java -- X.500 distinguished name. + Copyright (C) 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.java.security.x509; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class X500DistinguishedName implements Principal +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID CN = new OID("2.5.4.3"); + public static final OID C = new OID("2.5.4.6"); + public static final OID L = new OID("2.5.4.7"); + public static final OID ST = new OID("2.5.4.8"); + public static final OID STREET = new OID("2.5.4.9"); + public static final OID O = new OID("2.5.4.10"); + public static final OID OU = new OID("2.5.4.11"); + public static final OID T = new OID("2.5.4.12"); + public static final OID DNQ = new OID("2.5.4.46"); + public static final OID NAME = new OID("2.5.4.41"); + public static final OID GIVENNAME = new OID("2.5.4.42"); + public static final OID INITIALS = new OID("2.5.4.43"); + public static final OID GENERATION = new OID("2.5.4.44"); + public static final OID EMAIL = new OID("1.2.840.113549.1.9.1"); + public static final OID DC = new OID("0.9.2342.19200300.100.1.25"); + public static final OID UID = new OID("0.9.2342.19200300.100.1.1"); + + private List components; + private Map currentRdn; + private boolean fixed; + private String stringRep; + private byte[] encoded; + + // Constructors. + // ------------------------------------------------------------------------- + + public X500DistinguishedName() + { + components = new LinkedList(); + currentRdn = new LinkedHashMap(); + components.add(currentRdn); + } + + public X500DistinguishedName(String name) + { + this(); + try + { + parseString(name); + } + catch (IOException ioe) + { + throw new IllegalArgumentException(ioe.toString()); + } + } + + public X500DistinguishedName(byte[] encoded) throws IOException + { + this(); + parseDer(new DERReader(encoded)); + } + + public X500DistinguishedName(InputStream encoded) throws IOException + { + this(); + parseDer(new DERReader(encoded)); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public String getName() + { + return toString(); + } + + public void newRelativeDistinguishedName() + { + if (fixed || currentRdn.isEmpty()) return; + currentRdn = new LinkedHashMap(); + components.add(currentRdn); + } + + public int size() + { + return components.size(); + } + + public int countComponents() + { + int count = 0; + for (Iterator it = components.iterator(); it.hasNext(); ) + { + count += ((Map) it.next()).size(); + } + return count; + } + + public boolean containsComponent(OID oid, String value) + { + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map rdn = (Map) it.next(); + String s = (String) rdn.get(oid); + if (s == null) + continue; + if (compressWS(value).equalsIgnoreCase(compressWS(s))) + return true; + } + return false; + } + + public String getComponent(OID oid) + { + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map rdn = (Map) it.next(); + if (rdn.containsKey(oid)) + return (String) rdn.get(oid); + } + return null; + } + + public String getComponent(OID oid, int rdn) + { + if (rdn >= size()) + return null; + return (String) ((Map) components.get(rdn)).get(oid); + } + + public void putComponent(OID oid, String value) + { + currentRdn.put(oid, value); + } + + public void putComponent(String name, String value) + { + name = name.trim().toLowerCase(); + if (name.equals("cn")) + putComponent(CN, value); + else if (name.equals("c")) + putComponent(C, value); + else if (name.equals("l")) + putComponent(L, value); + else if (name.equals("street")) + putComponent(STREET, value); + else if (name.equals("st")) + putComponent(ST, value); + else if (name.equals("t")) + putComponent(T, value); + else if (name.equals("dnq")) + putComponent(DNQ, value); + else if (name.equals("name")) + putComponent(NAME, value); + else if (name.equals("givenname")) + putComponent(GIVENNAME, value); + else if (name.equals("initials")) + putComponent(INITIALS, value); + else if (name.equals("generation")) + putComponent(GENERATION, value); + else if (name.equals("email")) + putComponent(EMAIL, value); + else if (name.equals("dc")) + putComponent(DC, value); + else if (name.equals("uid")) + putComponent(UID, value); + else + putComponent(new OID(name), value); + } + + public void setUnmodifiable() + { + if (fixed) return; + fixed = true; + List newComps = new ArrayList(components.size()); + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map rdn = (Map) it.next(); + rdn = Collections.unmodifiableMap(rdn); + newComps.add(rdn); + } + components = Collections.unmodifiableList(newComps); + currentRdn = Collections.EMPTY_MAP; + } + + public int hashCode() + { + int sum = 0; + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map m = (Map) it.next(); + for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); ) + { + Map.Entry e = (Map.Entry) it2.next(); + sum += e.getKey().hashCode(); + sum += e.getValue().hashCode(); + } + } + return sum; + } + + public boolean equals(Object o) + { + if (!(o instanceof X500DistinguishedName)) + return false; + if (size() != ((X500DistinguishedName) o).size()) + return false; + for (int i = 0; i < size(); i++) + { + Map m = (Map) components.get(i); + for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); ) + { + Map.Entry e = (Map.Entry) it2.next(); + OID oid = (OID) e.getKey(); + String v1 = (String) e.getValue(); + String v2 = ((X500DistinguishedName) o).getComponent(oid, i); + if (!compressWS(v1).equalsIgnoreCase(compressWS(v2))) + return false; + } + } + return true; + } + + public String toString() + { + if (fixed && stringRep != null) + return stringRep; + StringBuffer str = new StringBuffer(); + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map m = (Map) it.next(); + for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it2.next(); + OID oid = (OID) entry.getKey(); + String value = (String) entry.getValue(); + if (oid.equals(CN)) + str.append("CN"); + else if (oid.equals(C)) + str.append("C"); + else if (oid.equals(L)) + str.append("L"); + else if (oid.equals(ST)) + str.append("ST"); + else if (oid.equals(STREET)) + str.append("STREET"); + else if (oid.equals(O)) + str.append("O"); + else if (oid.equals(OU)) + str.append("OU"); + else if (oid.equals(T)) + str.append("T"); + else if (oid.equals(DNQ)) + str.append("DNQ"); + else if (oid.equals(NAME)) + str.append("NAME"); + else + str.append(oid.toString()); + str.append('='); + str.append(value); + if (it2.hasNext()) + str.append("+"); + } + if (it.hasNext()) + str.append(','); + } + return (stringRep = str.toString()); + } + + public byte[] getDer() + { + if (fixed && encoded != null) + return (byte[]) encoded.clone(); + ArrayList name = new ArrayList(components.size()); + for (Iterator it = components.iterator(); it.hasNext(); ) + { + Map m = (Map) it.next(); + if (m.isEmpty()) + continue; + Set rdn = new HashSet(); + for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); ) + { + Map.Entry e = (Map.Entry) it.next(); + ArrayList atav = new ArrayList(2); + atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey())); + atav.add(new DERValue(DER.UTF8_STRING, e.getValue())); + rdn.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, atav)); + } + name.add(new DERValue(DER.SET|DER.CONSTRUCTED, rdn)); + } + DERValue val = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, name); + return (byte[]) (encoded = val.getEncoded()).clone(); + } + + // Own methods. + // ------------------------------------------------------------------------- + + private int sep; + + private void parseString(String str) throws IOException + { + Reader in = new StringReader(str); + while (true) + { + String key = readAttributeType(in); + if (key == null) + break; + String value = readAttributeValue(in); + putComponent(key, value); + if (sep == ',') + newRelativeDistinguishedName(); + } + setUnmodifiable(); + } + + private String readAttributeType(Reader in) throws IOException + { + StringBuffer buf = new StringBuffer(); + int ch; + while ((ch = in.read()) != '=') + { + if (ch == -1) + { + if (buf.length() > 0) + throw new EOFException(); + return null; + } + if (ch > 127) + throw new IOException("Invalid char: " + (char) ch); + if (Character.isLetterOrDigit((char) ch) || ch == '-' || ch == '.') + buf.append((char) ch); + else + throw new IOException("Invalid char: " + (char) ch); + } + return buf.toString(); + } + + private String readAttributeValue(Reader in) throws IOException + { + StringBuffer buf = new StringBuffer(); + int ch = in.read(); + if (ch == '#') + { + while (true) + { + ch = in.read(); + if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') + || Character.isDigit((char) ch)) + buf.append((char) ch); + else if (ch == '+' || ch == ',') + { + sep = ch; + String hex = buf.toString(); + return new String(Util.toByteArray(hex)); + } + else + throw new IOException("illegal character: " + (char) ch); + } + } + else if (ch == '"') + { + while (true) + { + ch = in.read(); + if (ch == '"') + break; + else if (ch == '\\') + { + ch = in.read(); + if (ch == -1) + throw new EOFException(); + if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') + || Character.isDigit((char) ch)) + { + int i = Character.digit((char) ch, 16) << 4; + ch = in.read(); + if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') + || Character.isDigit((char) ch))) + throw new IOException("illegal hex char"); + i |= Character.digit((char) ch, 16); + buf.append((char) i); + } + else + buf.append((char) ch); + } + else + buf.append((char) ch); + } + sep = in.read(); + if (sep != '+' || sep != ',') + throw new IOException("illegal character: " + (char) ch); + return buf.toString(); + } + else + { + while (true) + { + switch (ch) + { + case '+': + case ',': + sep = ch; + return buf.toString(); + case '\\': + ch = in.read(); + if (ch == -1) + throw new EOFException(); + if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') + || Character.isDigit((char) ch)) + { + int i = Character.digit((char) ch, 16) << 4; + ch = in.read(); + if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') + || Character.isDigit((char) ch))) + throw new IOException("illegal hex char"); + i |= Character.digit((char) ch, 16); + buf.append((char) i); + } + else + buf.append((char) ch); + break; + case '=': + case '<': + case '>': + case '#': + case ';': + throw new IOException("illegal character: " + (char) ch); + case -1: + throw new EOFException(); + default: + buf.append((char) ch); + } + } + } + } + + private void parseDer(DERReader der) throws IOException + { + DERValue name = der.read(); + if (!name.isConstructed()) + throw new IOException("malformed Name"); + encoded = name.getEncoded(); + int len = 0; + while (len < name.getLength()) + { + DERValue rdn = der.read(); + if (!rdn.isConstructed()) + throw new IOException("badly formed RDNSequence"); + int len2 = 0; + while (len2 < rdn.getLength()) + { + DERValue atav = der.read(); + if (!atav.isConstructed()) + throw new IOException("badly formed AttributeTypeAndValue"); + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("badly formed AttributeTypeAndValue"); + OID oid = (OID) val.getValue(); + val = der.read(); + if (!(val.getValue() instanceof String)) + throw new IOException("badly formed AttributeTypeAndValue"); + String value = (String) val.getValue(); + putComponent(oid, value); + len2 += atav.getEncodedLength(); + } + len += rdn.getEncodedLength(); + if (len < name.getLength()) + newRelativeDistinguishedName(); + } + setUnmodifiable(); + } + + private static String compressWS(String str) + { + StringBuffer buf = new StringBuffer(); + char lastChar = 0; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (Character.isWhitespace(c)) + { + if (!Character.isWhitespace(lastChar)) + buf.append(' '); + } + else + buf.append(c); + lastChar = c; + } + return buf.toString().trim(); + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X509CRL.java b/libjava/classpath/gnu/java/security/x509/X509CRL.java new file mode 100644 index 0000000..5b2d3b1 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509CRL.java @@ -0,0 +1,476 @@ +/* X509CRL.java -- X.509 certificate revocation list. + Copyright (C) 2003, 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.java.security.x509; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.ext.Extension; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.CRLException; +import java.security.cert.Certificate; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +/** + * X.509 certificate revocation lists. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class X509CRL extends java.security.cert.X509CRL + implements GnuPKIExtension +{ + + // Constants and fields. + // ------------------------------------------------------------------------ + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + if (DEBUG) + { + System.err.print(">> X509CRL: "); + System.err.println(msg); + } + } + + private static final OID ID_DSA = new OID("1.2.840.10040.4.1"); + private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3"); + private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1"); + private static final OID ID_RSA_WITH_MD2 = new OID("1.2.840.113549.1.1.2"); + private static final OID ID_RSA_WITH_MD5 = new OID("1.2.840.113549.1.1.4"); + private static final OID ID_RSA_WITH_SHA1 = new OID("1.2.840.113549.1.1.5"); + + private byte[] encoded; + + private byte[] tbsCRLBytes; + private int version; + private OID algId; + private byte[] algParams; + private Date thisUpdate; + private Date nextUpdate; + private X500DistinguishedName issuerDN; + private HashMap revokedCerts; + private HashMap extensions; + + private OID sigAlg; + private byte[] sigAlgParams; + private byte[] rawSig; + private byte[] signature; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a new X.509 CRL. + * + * @param encoded The DER encoded CRL. + * @throws CRLException If the input bytes are incorrect. + * @throws IOException If the input bytes cannot be read. + */ + public X509CRL(InputStream encoded) throws CRLException, IOException + { + super(); + revokedCerts = new HashMap(); + extensions = new HashMap(); + try + { + parse(encoded); + } + catch (IOException ioe) + { + ioe.printStackTrace(); + throw ioe; + } + catch (Exception x) + { + x.printStackTrace(); + throw new CRLException(x.toString()); + } + } + + // X509CRL methods. + // ------------------------------------------------------------------------ + + public boolean equals(Object o) + { + if (!(o instanceof X509CRL)) + return false; + return ((X509CRL) o).getRevokedCertificates().equals(revokedCerts.values()); + } + + public int hashCode() + { + return revokedCerts.hashCode(); + } + + public byte[] getEncoded() throws CRLException + { + return (byte[]) encoded.clone(); + } + + public void verify(PublicKey key) + throws CRLException, NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, SignatureException + { + Signature sig = Signature.getInstance(sigAlg.toString()); + doVerify(sig, key); + } + + public void verify(PublicKey key, String provider) + throws CRLException, NoSuchAlgorithmException, InvalidKeyException, + NoSuchProviderException, SignatureException + { + Signature sig = Signature.getInstance(sigAlg.toString(), provider); + doVerify(sig, key); + } + + public int getVersion() + { + return version; + } + + public Principal getIssuerDN() + { + return issuerDN; + } + + public X500Principal getIssuerX500Principal() + { + return new X500Principal(issuerDN.getDer()); + } + + public Date getThisUpdate() + { + return (Date) thisUpdate.clone(); + } + + public Date getNextUpdate() + { + if (nextUpdate != null) + return (Date) nextUpdate.clone(); + return null; + } + + public java.security.cert.X509CRLEntry getRevokedCertificate(BigInteger serialNo) + { + return (java.security.cert.X509CRLEntry) revokedCerts.get(serialNo); + } + + public Set getRevokedCertificates() + { + return Collections.unmodifiableSet(new HashSet(revokedCerts.values())); + } + + public byte[] getTBSCertList() throws CRLException + { + return (byte[]) tbsCRLBytes.clone(); + } + + public byte[] getSignature() + { + return (byte[]) rawSig.clone(); + } + + public String getSigAlgName() + { + if (sigAlg.equals(ID_DSA_WITH_SHA1)) + return "SHA1withDSA"; + if (sigAlg.equals(ID_RSA_WITH_MD2)) + return "MD2withRSA"; + if (sigAlg.equals(ID_RSA_WITH_MD5)) + return "MD5withRSA"; + if (sigAlg.equals(ID_RSA_WITH_SHA1)) + return "SHA1withRSA"; + return "unknown"; + } + + public String getSigAlgOID() + { + return sigAlg.toString(); + } + + public byte[] getSigAlgParams() + { + if (sigAlgParams != null) + return (byte[]) sigAlgParams.clone(); + return null; + } + + // X509Extension methods. + // ------------------------------------------------------------------------ + + public boolean hasUnsupportedCriticalExtension() + { + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical() && !e.isSupported()) + return true; + } + return false; + } + + public Set getCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public Set getNonCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (!e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public byte[] getExtensionValue(String oid) + { + Extension e = getExtension(new OID(oid)); + if (e != null) + { + return e.getValue().getEncoded(); + } + return null; + } + + // GnuPKIExtension method. + // ------------------------------------------------------------------------- + + public Extension getExtension(OID oid) + { + return (Extension) extensions.get(oid); + } + + public Collection getExtensions() + { + return extensions.values(); + } + + // CRL methods. + // ------------------------------------------------------------------------- + + public String toString() + { + return X509CRL.class.getName(); + } + + public boolean isRevoked(Certificate cert) + { + if (!(cert instanceof java.security.cert.X509Certificate)) + throw new IllegalArgumentException("not a X.509 certificate"); + BigInteger certSerial = + ((java.security.cert.X509Certificate) cert).getSerialNumber(); + X509CRLEntry ent = (X509CRLEntry) revokedCerts.get(certSerial); + if (ent == null) + return false; + return ent.getRevocationDate().compareTo(new Date()) < 0; + } + + // Own methods. + // ------------------------------------------------------------------------ + + private void doVerify(Signature sig, PublicKey key) + throws CRLException, InvalidKeyException, SignatureException + { + sig.initVerify(key); + sig.update(tbsCRLBytes); + if (!sig.verify(signature)) + throw new CRLException("signature not verified"); + } + + private void parse(InputStream in) throws Exception + { + // CertificateList ::= SEQUENCE { + DERReader der = new DERReader(in); + DERValue val = der.read(); + debug("start CertificateList len == " + val.getLength()); + if (!val.isConstructed()) + throw new IOException("malformed CertificateList"); + encoded = val.getEncoded(); + + // tbsCertList ::= SEQUENCE { -- TBSCertList + val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed TBSCertList"); + debug("start tbsCertList len == " + val.getLength()); + tbsCRLBytes = val.getEncoded(); + + // version Version OPTIONAL, + // -- If present must be v2 + val = der.read(); + if (val.getValue() instanceof BigInteger) + { + version = ((BigInteger) val.getValue()).intValue() + 1; + val = der.read(); + } + else + version = 1; + debug("read version == " + version); + + // signature AlgorithmIdentifier, + debug("start AlgorithmIdentifier len == " + val.getLength()); + if (!val.isConstructed()) + throw new IOException("malformed AlgorithmIdentifier"); + DERValue algIdVal = der.read(); + algId = (OID) algIdVal.getValue(); + debug("read object identifier == " + algId); + if (val.getLength() > algIdVal.getEncodedLength()) + { + val = der.read(); + debug("read parameters len == " + val.getEncodedLength()); + algParams = val.getEncoded(); + if (val.isConstructed()) + in.skip(val.getLength()); + } + + // issuer Name, + val = der.read(); + issuerDN = new X500DistinguishedName(val.getEncoded()); + der.skip(val.getLength()); + debug("read issuer == " + issuerDN); + + // thisUpdate Time, + thisUpdate = (Date) der.read().getValue(); + debug("read thisUpdate == " + thisUpdate); + + // nextUpdate Time OPTIONAL, + val = der.read(); + if (val.getValue() instanceof Date) + { + nextUpdate = (Date) val.getValue(); + debug("read nextUpdate == " + nextUpdate); + val = der.read(); + } + + // revokedCertificates SEQUENCE OF SEQUENCE { + // -- X509CRLEntry objects... + // } OPTIONAL, + if (val.getTag() != 0) + { + int len = 0; + while (len < val.getLength()) + { + X509CRLEntry entry = new X509CRLEntry(version, der); + revokedCerts.put(entry.getSerialNumber(), entry); + len += entry.getEncoded().length; + } + val = der.read(); + } + + // crlExtensions [0] EXPLICIT Extensions OPTIONAL + // -- if present MUST be v2 + if (val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0) + { + if (version < 2) + throw new IOException("extra data in CRL"); + DERValue exts = der.read(); + if (!exts.isConstructed()) + throw new IOException("malformed Extensions"); + debug("start Extensions len == " + exts.getLength()); + int len = 0; + while (len < exts.getLength()) + { + DERValue ext = der.read(); + if (!ext.isConstructed()) + throw new IOException("malformed Extension"); + Extension e = new Extension(ext.getEncoded()); + extensions.put(e.getOid(), e); + der.skip(ext.getLength()); + len += ext.getEncodedLength(); + debug("current count == " + len); + } + val = der.read(); + } + + debug("read tag == " + val.getTag()); + if (!val.isConstructed()) + throw new IOException("malformed AlgorithmIdentifier"); + debug("start AlgorithmIdentifier len == " + val.getLength()); + DERValue sigAlgVal = der.read(); + debug("read tag == " + sigAlgVal.getTag()); + if (sigAlgVal.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed AlgorithmIdentifier"); + sigAlg = (OID) sigAlgVal.getValue(); + debug("signature id == " + sigAlg); + debug("sigAlgVal length == " + sigAlgVal.getEncodedLength()); + if (val.getLength() > sigAlgVal.getEncodedLength()) + { + val = der.read(); + debug("sig params tag = " + val.getTag() + " len == " + val.getEncodedLength()); + sigAlgParams = (byte[]) val.getEncoded(); + if (val.isConstructed()) + in.skip(val.getLength()); + } + val = der.read(); + debug("read tag = " + val.getTag()); + rawSig = val.getEncoded(); + signature = ((BitString) val.getValue()).toByteArray(); + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X509CRLEntry.java b/libjava/classpath/gnu/java/security/x509/X509CRLEntry.java new file mode 100644 index 0000000..a3bcfde --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509CRLEntry.java @@ -0,0 +1,278 @@ +/* X509CRLEntry.java -- an entry in a X.509 CRL. + Copyright (C) 2003, 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.java.security.x509; + +import gnu.java.security.OID; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.ext.Extension; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.CRLException; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * A single entry in a X.509 certificate revocation list. + * + * @see X509CRL + * @author Casey Marshall + */ +class X509CRLEntry extends java.security.cert.X509CRLEntry + implements GnuPKIExtension +{ + + // Constants and fields. + // ------------------------------------------------------------------------ + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + if (DEBUG) + { + System.err.print(">> X509CRLEntry: "); + System.err.println(msg); + } + } + + /** The DER encoded form of this CRL entry. */ + private byte[] encoded; + + /** The revoked certificate's serial number. */ + private BigInteger serialNo; + + /** The date the certificate was revoked. */ + private Date revocationDate; + + /** The CRL entry extensions. */ + private HashMap extensions; + + // Constructor. + // ------------------------------------------------------------------------ + + /** + * Create a new X.509 certificate revocation list entry from the given + * input stream and CRL version number. + * + * @param version The CRL version. + * @param encoded The stream of DER bytes. + * @throws CRLException If the ASN.1 structure is invalid. + * @throws IOException If the bytes cannot be read. + */ + X509CRLEntry(int version, DERReader encoded) + throws CRLException, IOException + { + super(); + extensions = new HashMap(); + try + { + parse(version, encoded); + } + catch (IOException ioe) + { + throw ioe; + } + catch (Exception x) + { + throw new CRLException(x.toString()); + } + } + + // X509CRLEntry methods. + // ------------------------------------------------------------------------ + + public boolean equals(Object o) + { + if (!(o instanceof X509CRLEntry)) + return false; + return ((X509CRLEntry) o).getSerialNumber().equals(serialNo) && + ((X509CRLEntry) o).getRevocationDate().equals(revocationDate); + } + + public int hashCode() + { + return serialNo.hashCode(); + } + + public byte[] getEncoded() throws CRLException + { + return (byte[]) encoded.clone(); + } + + public BigInteger getSerialNumber() + { + return serialNo; + } + + public Date getRevocationDate() + { + return (Date) revocationDate.clone(); + } + + public boolean hasExtensions() + { + return ! extensions.isEmpty(); + } + + public String toString() + { + return "X509CRLEntry serial=" + serialNo + " revocation date=" + + revocationDate + " ext=" + extensions; + } + + // X509Extension methods. + // ------------------------------------------------------------------------- + + public boolean hasUnsupportedCriticalExtension() + { + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical() && !e.isSupported()) + return true; + } + return false; + } + + public Set getCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public Set getNonCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (!e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public byte[] getExtensionValue(String oid) + { + Extension e = getExtension(new OID(oid)); + if (e != null) + { + return e.getValue().getEncoded(); + } + return null; + } + + // GnuPKIExtension method. + // ------------------------------------------------------------------------- + + public Extension getExtension(OID oid) + { + return (Extension) extensions.get(oid); + } + + public Collection getExtensions() + { + return extensions.values(); + } + + // Own methods. + // ------------------------------------------------------------------------- + + private void parse(int version, DERReader der) throws Exception + { + // RevokedCertificate ::= SEQUENCE { + DERValue entry = der.read(); + debug("start CRL entry len == " + entry.getLength()); + if (!entry.isConstructed()) + throw new IOException("malformed revokedCertificate"); + encoded = entry.getEncoded(); + int len = 0; + + debug("encoded entry:\n" + Util.hexDump(encoded, ">>>> ")); + + // userCertificate CertificateSerialNumber, + DERValue val = der.read(); + serialNo = (BigInteger) val.getValue(); + len += val.getEncodedLength(); + debug("userCertificate == " + serialNo + " current count == " + len); + + // revocationDate Time, + val = der.read(); + revocationDate = (Date) val.getValue(); + len += val.getEncodedLength(); + debug("revocationDate == " + revocationDate + " current count == " + len); + + // crlEntryExtensions Extensions OPTIONAL + // -- if present MUST be v2 + if (len < entry.getLength()) + { + if (version < 2) + throw new IOException("extra data in CRL entry"); + DERValue exts = der.read(); + if (!exts.isConstructed()) + throw new IOException("malformed Extensions"); + debug("start Extensions len == " + exts.getLength()); + len = 0; + while (len < exts.getLength()) + { + val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed Extension"); + debug("start Extension len == " + val.getLength()); + Extension e = new Extension(val.getEncoded()); + extensions.put(e.getOid(), e); + der.skip(val.getLength()); + len += val.getEncodedLength(); + debug("current count == " + len); + } + } + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X509CRLSelectorImpl.java b/libjava/classpath/gnu/java/security/x509/X509CRLSelectorImpl.java new file mode 100644 index 0000000..0ada550 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509CRLSelectorImpl.java @@ -0,0 +1,138 @@ +/* X509CRLSelectorImpl.java -- implementation of an X509CRLSelector. + Copyright (C) 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.java.security.x509; + +import java.io.IOException; + +import java.security.Principal; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.X509CRL; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +/** + * Sun's implementation of X509CRLSelector sucks. This one tries to work + * better. + */ +public class X509CRLSelectorImpl implements CRLSelector +{ + + // Fields. + // ------------------------------------------------------------------------- + + private Set issuerNames; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CRLSelectorImpl() + { + issuerNames = new HashSet(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addIssuerName(byte[] issuerName) throws IOException + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(String issuerName) + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(Principal issuerName) throws IOException + { + if (issuerName instanceof X500DistinguishedName) + issuerNames.add(issuerName); + else if (issuerName instanceof X500Principal) + issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded())); + else + issuerNames.add(new X500DistinguishedName(issuerName.getName())); + } + + public Collection getIssuerNames() + { + return Collections.unmodifiableSet(issuerNames); + } + + public Object clone() + { + X509CRLSelectorImpl copy = new X509CRLSelectorImpl(); + copy.issuerNames.addAll(issuerNames); + return copy; + } + + public boolean match(CRL crl) + { + if (!(crl instanceof X509CRL)) + return false; + try + { + Principal p = ((X509CRL) crl).getIssuerDN(); + X500DistinguishedName thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + for (Iterator it = issuerNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + return true; + } + } + catch (Exception x) + { + } + return false; + } +} + diff --git a/libjava/classpath/gnu/java/security/x509/X509CertPath.java b/libjava/classpath/gnu/java/security/x509/X509CertPath.java new file mode 100644 index 0000000..e8ed6bf --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509CertPath.java @@ -0,0 +1,303 @@ +/* X509CertPath.java -- an X.509 certificate path. + Copyright (C) 2004 Free Software Fonudation, 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.java.security.x509; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DEREncodingException; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.security.cert.CertPath; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * A certificate path (or certificate chain) of X509Certificates. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class X509CertPath extends CertPath +{ + + // Fields. + // ------------------------------------------------------------------------- + + public static final List ENCODINGS = Collections.unmodifiableList( + Arrays.asList(new String[] { "PkiPath", "PKCS7" })); + + private static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2"); + private static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1"); + + /** The certificate path. */ + private List path; + + /** The cached PKCS #7 encoded bytes. */ + private byte[] pkcs_encoded; + + /** The cached PkiPath encoded bytes. */ + private byte[] pki_encoded; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CertPath(List path) + { + super("X.509"); + this.path = Collections.unmodifiableList(path); + } + + public X509CertPath(InputStream in) throws CertificateEncodingException + { + this(in, (String) ENCODINGS.get(0)); + } + + public X509CertPath(InputStream in, String encoding) + throws CertificateEncodingException + { + super("X.509"); + try + { + parse(in, encoding); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getCertificates() + { + return path; // already unmodifiable + } + + public byte[] getEncoded() throws CertificateEncodingException + { + return getEncoded((String) ENCODINGS.get(0)); + } + + public byte[] getEncoded(String encoding) throws CertificateEncodingException + { + if (encoding.equalsIgnoreCase("PkiPath")) + { + if (pki_encoded == null) + { + try + { + pki_encoded = encodePki(); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + return (byte[]) pki_encoded.clone(); + } + else if (encoding.equalsIgnoreCase("PKCS7")) + { + if (pkcs_encoded == null) + { + try + { + pkcs_encoded = encodePKCS(); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + return (byte[]) pkcs_encoded.clone(); + } + else + throw new CertificateEncodingException("unknown encoding: " + encoding); + } + + public Iterator getEncodings() + { + return ENCODINGS.iterator(); // already unmodifiable + } + + // Own methods. + // ------------------------------------------------------------------------- + + private void parse(InputStream in, String encoding) + throws CertificateEncodingException, IOException + { + DERReader der = new DERReader(in); + DERValue path = null; + if (encoding.equalsIgnoreCase("PkiPath")) + { + // PKI encoding is just a SEQUENCE of X.509 certificates. + path = der.read(); + if (!path.isConstructed()) + throw new DEREncodingException("malformed PkiPath"); + } + else if (encoding.equalsIgnoreCase("PKCS7")) + { + // PKCS #7 encoding means that the certificates are contained in a + // SignedData PKCS #7 type. + // + // ContentInfo ::= SEQUENCE { + // contentType ::= ContentType, + // content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } + // + // ContentType ::= OBJECT IDENTIFIER + // + // SignedData ::= SEQUENCE { + // version Version, + // digestAlgorithms DigestAlgorithmIdentifiers, + // contentInfo ContentInfo, + // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates + // OPTIONAL, + // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, + // signerInfos SignerInfos } + // + // Version ::= INTEGER + // + DERValue value = der.read(); + if (!value.isConstructed()) + throw new DEREncodingException("malformed ContentInfo"); + value = der.read(); + if (!(value.getValue() instanceof OID) || + ((OID) value.getValue()).equals(PKCS7_SIGNED_DATA)) + throw new DEREncodingException("not a SignedData"); + value = der.read(); + if (!value.isConstructed() || value.getTag() != 0) + throw new DEREncodingException("malformed content"); + value = der.read(); + if (value.getTag() != DER.INTEGER) + throw new DEREncodingException("malformed Version"); + value = der.read(); + if (!value.isConstructed() || value.getTag() != DER.SET) + throw new DEREncodingException("malformed DigestAlgorithmIdentifiers"); + der.skip(value.getLength()); + value = der.read(); + if (!value.isConstructed()) + throw new DEREncodingException("malformed ContentInfo"); + der.skip(value.getLength()); + path = der.read(); + if (!path.isConstructed() || path.getTag() != 0) + throw new DEREncodingException("no certificates"); + } + else + throw new CertificateEncodingException("unknown encoding: " + encoding); + + LinkedList certs = new LinkedList(); + int len = 0; + while (len < path.getLength()) + { + DERValue cert = der.read(); + try + { + certs.add(new X509Certificate(new ByteArrayInputStream(cert.getEncoded()))); + } + catch (CertificateException ce) + { + throw new CertificateEncodingException(ce.getMessage()); + } + len += cert.getEncodedLength(); + der.skip(cert.getLength()); + } + + this.path = Collections.unmodifiableList(certs); + } + + private byte[] encodePki() + throws CertificateEncodingException, IOException + { + synchronized (path) + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + for (Iterator i = path.iterator(); i.hasNext(); ) + { + out.write(((Certificate) i.next()).getEncoded()); + } + byte[] b = out.toByteArray(); + DERValue val = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + b.length, b, null); + return val.getEncoded(); + } + } + + private byte[] encodePKCS() + throws CertificateEncodingException, IOException + { + synchronized (path) + { + ArrayList signedData = new ArrayList(5); + signedData.add(new DERValue(DER.INTEGER, BigInteger.ONE)); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.SET, + Collections.EMPTY_SET)); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + Collections.singletonList( + new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_DATA)))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + for (Iterator i = path.iterator(); i.hasNext(); ) + { + out.write(((Certificate) i.next()).getEncoded()); + } + byte[] b = out.toByteArray(); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, + b.length, b, null)); + DERValue sdValue = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + signedData); + + ArrayList contentInfo = new ArrayList(2); + contentInfo.add(new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_SIGNED_DATA)); + contentInfo.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, sdValue)); + return new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + contentInfo).getEncoded(); + } + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X509CertSelectorImpl.java b/libjava/classpath/gnu/java/security/x509/X509CertSelectorImpl.java new file mode 100644 index 0000000..36187ad --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509CertSelectorImpl.java @@ -0,0 +1,197 @@ +/* X509CertSelectorImpl.java -- implementation of an X509CertSelector. + Copyright (C) 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.java.security.x509; + +import java.io.IOException; +import java.security.Principal; +import java.security.cert.CertSelector; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +/** + * Sun's implementation of X509CertSelector sucks. This one tries to work + * better. + */ +public class X509CertSelectorImpl implements CertSelector +{ + + // Fields. + // ------------------------------------------------------------------------- + + private Set issuerNames; + private Set subjectNames; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CertSelectorImpl() + { + issuerNames = new HashSet(); + subjectNames = new HashSet(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addIssuerName(byte[] issuerName) throws IOException + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(String issuerName) + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(Principal issuerName) throws IOException + { + if (issuerName instanceof X500DistinguishedName) + issuerNames.add(issuerName); + else if (issuerName instanceof X500Principal) + issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded())); + else + issuerNames.add(new X500DistinguishedName(issuerName.getName())); + } + + public Collection getIssuerNames() + { + return Collections.unmodifiableSet(issuerNames); + } + + public void addSubjectName(byte[] subjectName) throws IOException + { + subjectNames.add(new X500DistinguishedName(subjectName)); + } + + public void addSubjectName(String subjectName) throws IOException + { + subjectNames.add(new X500DistinguishedName(subjectName)); + } + + public void addSubjectName(Principal subjectName) throws IOException + { + if (subjectName instanceof X500DistinguishedName) + subjectNames.add(subjectName); + else if (subjectName instanceof X500Principal) + subjectNames.add(new X500DistinguishedName(((X500Principal) subjectName).getEncoded())); + else + subjectNames.add(new X500DistinguishedName(subjectName.getName())); + } + + public Collection getSubjectNames() + { + return Collections.unmodifiableSet(subjectNames); + } + + public Object clone() + { + X509CertSelectorImpl copy = new X509CertSelectorImpl(); + copy.issuerNames.addAll(issuerNames); + copy.subjectNames.addAll(subjectNames); + return copy; + } + + public boolean match(Certificate cert) + { + if (!(cert instanceof X509Certificate)) + return false; + boolean matchIssuer = false; + boolean matchSubject = false; + try + { + Principal p = ((X509Certificate) cert).getIssuerDN(); + X500DistinguishedName thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + if (issuerNames.isEmpty()) + matchIssuer = true; + else + { + for (Iterator it = issuerNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + { + matchIssuer = true; + break; + } + } + } + + p = ((X509Certificate) cert).getSubjectDN(); + thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + if (subjectNames.isEmpty()) + matchSubject = true; + else + { + for (Iterator it = subjectNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + { + matchSubject = true; + break; + } + } + } + } + catch (Exception x) + { + } + return matchIssuer && matchSubject; + } +} + diff --git a/libjava/classpath/gnu/java/security/x509/X509Certificate.java b/libjava/classpath/gnu/java/security/x509/X509Certificate.java new file mode 100644 index 0000000..14ac43a --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/X509Certificate.java @@ -0,0 +1,745 @@ +/* X509Certificate.java -- X.509 certificate. + Copyright (C) 2003, 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.java.security.x509; + +import gnu.classpath.debug.Component; +import gnu.classpath.debug.SystemLogger; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.ext.BasicConstraints; +import gnu.java.security.x509.ext.ExtendedKeyUsage; +import gnu.java.security.x509.ext.Extension; +import gnu.java.security.x509.ext.IssuerAlternativeNames; +import gnu.java.security.x509.ext.KeyUsage; +import gnu.java.security.x509.ext.SubjectAlternativeNames; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.StringWriter; +import java.math.BigInteger; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.CertificateParsingException; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAParameterSpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.security.auth.x500.X500Principal; + +/** + * An implementation of X.509 certificates. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class X509Certificate extends java.security.cert.X509Certificate + implements Serializable, GnuPKIExtension +{ + + // Constants and fields. + // ------------------------------------------------------------------------ + + private static final Logger logger = SystemLogger.SYSTEM; + + protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1"); + protected static final OID ID_DSA_WITH_SHA1 = new OID ("1.2.840.10040.4.3"); + protected static final OID ID_RSA = new OID ("1.2.840.113549.1.1.1"); + protected static final OID ID_RSA_WITH_MD2 = new OID ("1.2.840.113549.1.1.2"); + protected static final OID ID_RSA_WITH_MD5 = new OID ("1.2.840.113549.1.1.4"); + protected static final OID ID_RSA_WITH_SHA1 = new OID ("1.2.840.113549.1.1.5"); + protected static final OID ID_ECDSA_WITH_SHA1 = new OID ("1.2.840.10045.4.1"); + + // This object SHOULD be serialized with an instance of + // java.security.cert.Certificate.CertificateRep, thus all fields are + // transient. + + // The encoded certificate. + protected transient byte[] encoded; + + // TBSCertificate part. + protected transient byte[] tbsCertBytes; + protected transient int version; + protected transient BigInteger serialNo; + protected transient OID algId; + protected transient byte[] algVal; + protected transient X500DistinguishedName issuer; + protected transient Date notBefore; + protected transient Date notAfter; + protected transient X500DistinguishedName subject; + protected transient PublicKey subjectKey; + protected transient BitString issuerUniqueId; + protected transient BitString subjectUniqueId; + protected transient Map extensions; + + // Signature. + protected transient OID sigAlgId; + protected transient byte[] sigAlgVal; + protected transient byte[] signature; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a new X.509 certificate from the encoded data. The input + * data are expected to be the ASN.1 DER encoding of the certificate. + * + * @param encoded The encoded certificate data. + * @throws IOException If the certificate cannot be read, possibly + * from a formatting error. + * @throws CertificateException If the data read is not an X.509 + * certificate. + */ + public X509Certificate(InputStream encoded) + throws CertificateException, IOException + { + super(); + extensions = new HashMap(); + try + { + parse(encoded); + } + catch (IOException ioe) + { + logger.log (Component.X509, "", ioe); + throw ioe; + } + catch (Exception e) + { + logger.log (Component.X509, "", e); + CertificateException ce = new CertificateException(e.getMessage()); + ce.initCause (e); + throw ce; + } + } + + protected X509Certificate() + { + extensions = new HashMap(); + } + + // X509Certificate methods. + // ------------------------------------------------------------------------ + + public void checkValidity() + throws CertificateExpiredException, CertificateNotYetValidException + { + checkValidity(new Date()); + } + + public void checkValidity(Date date) + throws CertificateExpiredException, CertificateNotYetValidException + { + if (date.compareTo(notBefore) < 0) + { + throw new CertificateNotYetValidException(); + } + if (date.compareTo(notAfter) > 0) + { + throw new CertificateExpiredException(); + } + } + + public int getVersion() + { + return version; + } + + public BigInteger getSerialNumber() + { + return serialNo; + } + + public Principal getIssuerDN() + { + return issuer; + } + + public X500Principal getIssuerX500Principal() + { + return new X500Principal(issuer.getDer()); + } + + public Principal getSubjectDN() + { + return subject; + } + + public X500Principal getSubjectX500Principal() + { + return new X500Principal(subject.getDer()); + } + + public Date getNotBefore() + { + return (Date) notBefore.clone(); + } + + public Date getNotAfter() + { + return (Date) notAfter.clone(); + } + + public byte[] getTBSCertificate() throws CertificateEncodingException + { + return (byte[]) tbsCertBytes.clone(); + } + + public byte[] getSignature() + { + return (byte[]) signature.clone(); + } + + public String getSigAlgName() + { + if (sigAlgId.equals(ID_DSA_WITH_SHA1)) + { + return "SHA1withDSA"; + } + if (sigAlgId.equals(ID_RSA_WITH_MD2)) + { + return "MD2withRSA"; + } + if (sigAlgId.equals(ID_RSA_WITH_MD5)) + { + return "MD5withRSA"; + } + if (sigAlgId.equals(ID_RSA_WITH_SHA1)) + { + return "SHA1withRSA"; + } + return "unknown"; + } + + public String getSigAlgOID() + { + return sigAlgId.toString(); + } + + public byte[] getSigAlgParams() + { + return (byte[]) sigAlgVal.clone(); + } + + public boolean[] getIssuerUniqueID() + { + if (issuerUniqueId != null) + { + return issuerUniqueId.toBooleanArray(); + } + return null; + } + + public boolean[] getSubjectUniqueID() + { + if (subjectUniqueId != null) + { + return subjectUniqueId.toBooleanArray(); + } + return null; + } + + public boolean[] getKeyUsage() + { + Extension e = getExtension(KeyUsage.ID); + if (e != null) + { + KeyUsage ku = (KeyUsage) e.getValue(); + boolean[] result = new boolean[9]; + boolean[] b = ku.getKeyUsage().toBooleanArray(); + System.arraycopy(b, 0, result, 0, b.length); + return result; + } + return null; + } + + public List getExtendedKeyUsage() throws CertificateParsingException + { + Extension e = getExtension(ExtendedKeyUsage.ID); + if (e != null) + { + List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds(); + List b = new ArrayList(a.size()); + for (Iterator it = a.iterator(); it.hasNext(); ) + { + b.add(it.next().toString()); + } + return Collections.unmodifiableList(b); + } + return null; + } + + public int getBasicConstraints() + { + Extension e = getExtension(BasicConstraints.ID); + if (e != null) + { + return ((BasicConstraints) e.getValue()).getPathLengthConstraint(); + } + return -1; + } + + public Collection getSubjectAlternativeNames() + throws CertificateParsingException + { + Extension e = getExtension(SubjectAlternativeNames.ID); + if (e != null) + { + return ((SubjectAlternativeNames) e.getValue()).getNames(); + } + return null; + } + + public Collection getIssuerAlternativeNames() + throws CertificateParsingException + { + Extension e = getExtension(IssuerAlternativeNames.ID); + if (e != null) + { + return ((IssuerAlternativeNames) e.getValue()).getNames(); + } + return null; + } + +// X509Extension methods. + // ------------------------------------------------------------------------ + + public boolean hasUnsupportedCriticalExtension() + { + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical() && !e.isSupported()) + return true; + } + return false; + } + + public Set getCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public Set getNonCriticalExtensionOIDs() + { + HashSet s = new HashSet(); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + Extension e = (Extension) it.next(); + if (!e.isCritical()) + s.add(e.getOid().toString()); + } + return Collections.unmodifiableSet(s); + } + + public byte[] getExtensionValue(String oid) + { + Extension e = getExtension(new OID(oid)); + if (e != null) + { + return e.getValue().getEncoded(); + } + return null; + } + + // GnuPKIExtension method. + // ------------------------------------------------------------------------- + + public Extension getExtension(OID oid) + { + return (Extension) extensions.get(oid); + } + + public Collection getExtensions() + { + return extensions.values(); + } + + // Certificate methods. + // ------------------------------------------------------------------------- + + public byte[] getEncoded() throws CertificateEncodingException + { + return (byte[]) encoded.clone(); + } + + public void verify(PublicKey key) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException + { + Signature sig = Signature.getInstance(sigAlgId.toString()); + doVerify(sig, key); + } + + public void verify(PublicKey key, String provider) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException + { + Signature sig = Signature.getInstance(sigAlgId.toString(), provider); + doVerify(sig, key); + } + + public String toString() + { + StringWriter str = new StringWriter(); + PrintWriter out = new PrintWriter(str); + out.println(X509Certificate.class.getName() + " {"); + out.println(" TBSCertificate {"); + out.println(" version = " + version + ";"); + out.println(" serialNo = " + serialNo + ";"); + out.println(" signature = {"); + out.println(" algorithm = " + getSigAlgName() + ";"); + out.print(" parameters ="); + if (sigAlgVal != null) + { + out.println(); + out.print(Util.hexDump(sigAlgVal, " ")); + } + else + { + out.println(" null;"); + } + out.println(" }"); + out.println(" issuer = " + issuer.getName() + ";"); + out.println(" validity = {"); + out.println(" notBefore = " + notBefore + ";"); + out.println(" notAfter = " + notAfter + ";"); + out.println(" }"); + out.println(" subject = " + subject.getName() + ";"); + out.println(" subjectPublicKeyInfo = {"); + out.println(" algorithm = " + subjectKey.getAlgorithm()); + out.println(" key ="); + out.print(Util.hexDump(subjectKey.getEncoded(), " ")); + out.println(" };"); + out.println(" issuerUniqueId = " + issuerUniqueId + ";"); + out.println(" subjectUniqueId = " + subjectUniqueId + ";"); + out.println(" extensions = {"); + for (Iterator it = extensions.values().iterator(); it.hasNext(); ) + { + out.println(" " + it.next()); + } + out.println(" }"); + out.println(" }"); + out.println(" signatureAlgorithm = " + getSigAlgName() + ";"); + out.println(" signatureValue ="); + out.print(Util.hexDump(signature, " ")); + out.println("}"); + return str.toString(); + } + + public PublicKey getPublicKey() + { + return subjectKey; + } + + public boolean equals(Object other) + { + if (!(other instanceof X509Certificate)) + return false; + try + { + if (other instanceof X509Certificate) + return Arrays.equals(encoded, ((X509Certificate) other).encoded); + byte[] enc = ((X509Certificate) other).getEncoded(); + if (enc == null) + return false; + return Arrays.equals(encoded, enc); + } + catch (CertificateEncodingException cee) + { + return false; + } + } + + // Own methods. + // ------------------------------------------------------------------------ + + /** + * Verify this certificate's signature. + */ + private void doVerify(Signature sig, PublicKey key) + throws CertificateException, InvalidKeyException, SignatureException + { + logger.log (Component.X509, "verifying sig={0} key={1}", + new Object[] { sig, key }); + sig.initVerify(key); + sig.update(tbsCertBytes); + if (!sig.verify(signature)) + { + throw new CertificateException("signature not validated"); + } + } + + /** + * Parse a DER stream into an X.509 certificate. + * + * @param encoded The encoded bytes. + */ + private void parse(InputStream encoded) throws Exception + { + DERReader der = new DERReader(encoded); + + // Certificate ::= SEQUENCE { + DERValue cert = der.read(); + logger.log (Component.X509, "start Certificate len == {0}", + new Integer (cert.getLength())); + + this.encoded = cert.getEncoded(); + if (!cert.isConstructed()) + { + throw new IOException("malformed Certificate"); + } + + // TBSCertificate ::= SEQUENCE { + DERValue tbsCert = der.read(); + if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE) + { + throw new IOException("malformed TBSCertificate"); + } + tbsCertBytes = tbsCert.getEncoded(); + logger.log (Component.X509, "start TBSCertificate len == {0}", + new Integer (tbsCert.getLength())); + + // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) } + DERValue val = der.read(); + if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0) + { + version = ((BigInteger) der.read().getValue()).intValue() + 1; + val = der.read(); + } + else + { + version = 1; + } + logger.log (Component.X509, "read version == {0}", + new Integer (version)); + + // SerialNumber ::= INTEGER + serialNo = (BigInteger) val.getValue(); + logger.log (Component.X509, "read serial number == {0}", serialNo); + + // AlgorithmIdentifier ::= SEQUENCE { + val = der.read(); + if (!val.isConstructed()) + { + throw new IOException("malformed AlgorithmIdentifier"); + } + int certAlgLen = val.getLength(); + logger.log (Component.X509, "start AlgorithmIdentifier len == {0}", + new Integer (certAlgLen)); + val = der.read(); + + // algorithm OBJECT IDENTIFIER, + algId = (OID) val.getValue(); + logger.log (Component.X509, "read algorithm ID == {0}", algId); + + // parameters ANY DEFINED BY algorithm OPTIONAL } + if (certAlgLen > val.getEncodedLength()) + { + val = der.read(); + if (val == null) + { + algVal = null; + } + else + { + algVal = val.getEncoded(); + + if (val.isConstructed()) + encoded.skip(val.getLength()); + } + logger.log (Component.X509, "read algorithm parameters == {0}", algVal); + } + + // issuer Name, + val = der.read(); + issuer = new X500DistinguishedName(val.getEncoded()); + der.skip(val.getLength()); + logger.log (Component.X509, "read issuer == {0}", issuer); + + // Validity ::= SEQUENCE { + // notBefore Time, + // notAfter Time } + if (!der.read().isConstructed()) + { + throw new IOException("malformed Validity"); + } + notBefore = (Date) der.read().getValue(); + logger.log (Component.X509, "read notBefore == {0}", notBefore); + notAfter = (Date) der.read().getValue(); + logger.log (Component.X509, "read notAfter == {0}", notAfter); + + // subject Name, + val = der.read(); + subject = new X500DistinguishedName(val.getEncoded()); + der.skip(val.getLength()); + logger.log (Component.X509, "read subject == {0}", subject); + + // SubjectPublicKeyInfo ::= SEQUENCE { + // algorithm AlgorithmIdentifier, + // subjectPublicKey BIT STRING } + DERValue spki = der.read(); + if (!spki.isConstructed()) + { + throw new IOException("malformed SubjectPublicKeyInfo"); + } + KeyFactory spkFac = KeyFactory.getInstance("X.509"); + subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded())); + der.skip(spki.getLength()); + logger.log (Component.X509, "read subjectPublicKey == {0}", subjectKey); + + if (version > 1) + { + val = der.read(); + } + if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1) + { + byte[] b = (byte[]) val.getValue(); + issuerUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF); + logger.log (Component.X509, "read issuerUniqueId == {0}", issuerUniqueId); + val = der.read(); + } + if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2) + { + byte[] b = (byte[]) val.getValue(); + subjectUniqueId = new BitString(b, 1, b.length-1, b[0] & 0xFF); + logger.log (Component.X509, "read subjectUniqueId == {0}", subjectUniqueId); + val = der.read(); + } + if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3) + { + val = der.read(); + logger.log (Component.X509, "start Extensions len == {0}", + new Integer (val.getLength())); + int len = 0; + while (len < val.getLength()) + { + DERValue ext = der.read(); + logger.log (Component.X509, "start extension len == {0}", + new Integer (ext.getLength())); + Extension e = new Extension(ext.getEncoded()); + extensions.put(e.getOid(), e); + der.skip(ext.getLength()); + len += ext.getEncodedLength(); + logger.log (Component.X509, "read extension {0} == {1}", + new Object[] { e.getOid (), e }); + logger.log (Component.X509, "count == {0}", new Integer (len)); + } + + val = der.read (); + } + + logger.log (Component.X509, "read value {0}", val); + if (!val.isConstructed()) + { + throw new CertificateException ("malformed AlgorithmIdentifier"); + } + int sigAlgLen = val.getLength(); + logger.log (Component.X509, "start AlgorithmIdentifier len == {0}", + new Integer (sigAlgLen)); + val = der.read(); + sigAlgId = (OID) val.getValue(); + logger.log (Component.X509, "read algorithm id == {0}", sigAlgId); + if (sigAlgLen > val.getEncodedLength()) + { + val = der.read(); + if (val.getValue() == null) + { + if (subjectKey instanceof DSAPublicKey) + { + AlgorithmParameters params = + AlgorithmParameters.getInstance("DSA"); + DSAParams dsap = ((DSAPublicKey) subjectKey).getParams(); + DSAParameterSpec spec = + new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG()); + params.init(spec); + sigAlgVal = params.getEncoded(); + } + } + else + { + sigAlgVal = (byte[]) val.getEncoded(); + } + if (val.isConstructed()) + { + encoded.skip(val.getLength()); + } + logger.log (Component.X509, "read parameters == {0}", sigAlgVal); + } + signature = ((BitString) der.read().getValue()).toByteArray(); + logger.log (Component.X509, "read signature ==\n{0}", Util.hexDump(signature, ">>>> ")); + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java b/libjava/classpath/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java new file mode 100644 index 0000000..a94b76f --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java @@ -0,0 +1,133 @@ +/* AuthorityKeyIdentifier.java -- Authority key identifier extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +import java.io.IOException; +import java.math.BigInteger; + +public class AuthorityKeyIdentifier extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.35"); + + private final byte[] keyIdentifier; + private final GeneralNames authorityCertIssuer; + private final BigInteger authorityCertSerialNumber; + + // Contstructor. + // ------------------------------------------------------------------------- + + public AuthorityKeyIdentifier(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + + // AuthorityKeyIdentifier ::= SEQUENCE { + DERValue val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed AuthorityKeyIdentifier"); + if (val.getLength() > 0) + val = der.read(); + + // keyIdentifier [0] KeyIdentifier OPTIONAL, + // KeyIdentifier ::= OCTET STRING + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 0) + { + keyIdentifier = (byte[]) val.getValue(); + val = der.read(); + } + else + keyIdentifier = null; + + // authorityCertIssuer [1] GeneralNames OPTIONAL, + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 1) + { + byte[] b = val.getEncoded(); + b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); + authorityCertIssuer = new GeneralNames(b); + der.skip(val.getLength()); + val = der.read(); + } + else + authorityCertIssuer = null; + + // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 2) + { + authorityCertSerialNumber = new BigInteger((byte[]) val.getValue()); + } + else + authorityCertSerialNumber = null; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public byte[] getKeyIdentifier() + { + return keyIdentifier != null ? (byte[]) keyIdentifier.clone() : null; + } + + public GeneralNames getAuthorityCertIssuer() + { + return authorityCertIssuer; + } + + public BigInteger getAuthorityCertSerialNumber() + { + return authorityCertSerialNumber; + } + + public String toString() + { + return AuthorityKeyIdentifier.class.getName() + " [ keyId=" + + (keyIdentifier != null ? Util.toHexString (keyIdentifier, ':') : "nil") + + " authorityCertIssuer=" + authorityCertIssuer + + " authorityCertSerialNumbe=" + authorityCertSerialNumber + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java b/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java new file mode 100644 index 0000000..00f7a6e --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java @@ -0,0 +1,129 @@ +/* BasicConstraints.java -- the basic constraints extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public class BasicConstraints extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.19"); + + private final boolean ca; + private final int pathLenConstraint; + + // Constructor. + // ------------------------------------------------------------------------- + + public BasicConstraints(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue bc = der.read(); + if (!bc.isConstructed()) + throw new IOException("malformed BasicConstraints"); + DERValue val = bc; + if (bc.getLength() > 0) + val = der.read(); + if (val.getTag() == DER.BOOLEAN) + { + ca = ((Boolean) val.getValue()).booleanValue(); + if (val.getEncodedLength() < bc.getLength()) + val = der.read(); + } + else + ca = false; + if (val.getTag() == DER.INTEGER) + { + pathLenConstraint = ((BigInteger) val.getValue()).intValue(); + } + else + pathLenConstraint = -1; + } + + public BasicConstraints (final boolean ca, final int pathLenConstraint) + { + this.ca = ca; + this.pathLenConstraint = pathLenConstraint; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public boolean isCA() + { + return ca; + } + + public int getPathLengthConstraint() + { + return pathLenConstraint; + } + + public byte[] getEncoded() + { + if (encoded == null) + { + List bc = new ArrayList (2); + bc.add (new DERValue (DER.BOOLEAN, new Boolean (ca))); + if (pathLenConstraint >= 0) + bc.add (new DERValue (DER.INTEGER, + BigInteger.valueOf ((long) pathLenConstraint))); + encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, bc).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return BasicConstraints.class.getName() + " [ isCA=" + ca + + " pathLen=" + pathLenConstraint + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/CRLNumber.java b/libjava/classpath/gnu/java/security/x509/ext/CRLNumber.java new file mode 100644 index 0000000..36b1c7b --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/CRLNumber.java @@ -0,0 +1,97 @@ +/* CRLNumber.java -- CRL number extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.math.BigInteger; + +public class CRLNumber extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.20"); + + private final BigInteger number; + + // Constructor. + // ------------------------------------------------------------------------- + + public CRLNumber(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.INTEGER) + throw new IOException("malformed CRLNumber"); + number = (BigInteger) val.getValue(); + } + + public CRLNumber (final BigInteger number) + { + this.number = number; + } + + // Instance method. + // ------------------------------------------------------------------------- + + public BigInteger getNumber() + { + return number; + } + + public byte[] getEncoded() + { + if (encoded == null) + { + encoded = new DERValue (DER.INTEGER, number).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return CRLNumber.class.getName() + " [ " + number + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java b/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java new file mode 100644 index 0000000..50bc6d3 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java @@ -0,0 +1,189 @@ +/* CertificatePolicies.java -- certificate policy extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.security.cert.PolicyQualifierInfo; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class CertificatePolicies extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.32"); + + private final List policies; + private final Map policyQualifierInfos; + + // Constructor. + // ------------------------------------------------------------------------- + + public CertificatePolicies(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue pol = der.read(); + if (!pol.isConstructed()) + throw new IOException("malformed CertificatePolicies"); + + int len = 0; + LinkedList policyList = new LinkedList(); + HashMap qualifierMap = new HashMap(); + while (len < pol.getLength()) + { + DERValue policyInfo = der.read(); + if (!policyInfo.isConstructed()) + throw new IOException("malformed PolicyInformation"); + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed CertPolicyId"); + OID policyId = (OID) val.getValue(); + policyList.add(policyId); + if (val.getEncodedLength() < policyInfo.getLength()) + { + DERValue qual = der.read(); + int len2 = 0; + LinkedList quals = new LinkedList(); + while (len2 < qual.getLength()) + { + val = der.read(); + quals.add(new PolicyQualifierInfo(val.getEncoded())); + der.skip(val.getLength()); + len2 += val.getEncodedLength(); + } + qualifierMap.put(policyId, quals); + } + len += policyInfo.getEncodedLength(); + } + + policies = Collections.unmodifiableList(policyList); + policyQualifierInfos = Collections.unmodifiableMap(qualifierMap); + } + + public CertificatePolicies (final List policies, + final Map policyQualifierInfos) + { + for (Iterator it = policies.iterator(); it.hasNext(); ) + if (!(it.next() instanceof OID)) + throw new IllegalArgumentException ("policies must be OIDs"); + for (Iterator it = policyQualifierInfos.entrySet().iterator(); it.hasNext();) + { + Map.Entry e = (Map.Entry) it.next(); + if (!(e.getKey() instanceof OID) || !policies.contains (e.getKey())) + throw new IllegalArgumentException + ("policyQualifierInfos keys must be OIDs"); + if (!(e.getValue() instanceof List)) + throw new IllegalArgumentException + ("policyQualifierInfos values must be Lists of PolicyQualifierInfos"); + for (Iterator it2 = ((List) e.getValue()).iterator(); it.hasNext(); ) + if (!(it2.next() instanceof PolicyQualifierInfo)) + throw new IllegalArgumentException + ("policyQualifierInfos values must be Lists of PolicyQualifierInfos"); + } + this.policies = Collections.unmodifiableList (new ArrayList (policies)); + this.policyQualifierInfos = Collections.unmodifiableMap + (new HashMap (policyQualifierInfos)); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getPolicies() + { + return policies; + } + + public List getPolicyQualifierInfos(OID oid) + { + return (List) policyQualifierInfos.get(oid); + } + + public byte[] getEncoded() + { + if (encoded == null) + { + List pol = new ArrayList (policies.size()); + for (Iterator it = policies.iterator(); it.hasNext(); ) + { + OID policy = (OID) it.next(); + List qualifiers = getPolicyQualifierInfos (policy); + List l = new ArrayList (qualifiers == null ? 1 : 2); + l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy)); + if (qualifiers != null) + { + List ll = new ArrayList (qualifiers.size()); + for (Iterator it2 = qualifiers.iterator(); it.hasNext(); ) + { + PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next(); + try + { + ll.add (DERReader.read (info.getEncoded())); + } + catch (IOException ioe) + { + } + } + l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll)); + } + pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l)); + } + encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return CertificatePolicies.class.getName() + " [ policies=" + policies + + " policyQualifierInfos=" + policyQualifierInfos + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java b/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java new file mode 100644 index 0000000..37b08ac --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java @@ -0,0 +1,95 @@ +/* ExtendedKeyUsage.java -- the extended key usage extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class ExtendedKeyUsage extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.37"); + + private final List purposeIds; + + // Constructor. + // ------------------------------------------------------------------------- + + public ExtendedKeyUsage(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue usageList = der.read(); + if (!usageList.isConstructed()) + throw new IOException("malformed ExtKeyUsageSyntax"); + int len = 0; + purposeIds = new LinkedList(); + while (len < usageList.getLength()) + { + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed KeyPurposeId"); + purposeIds.add(val.getValue()); + len += val.getEncodedLength(); + } + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getPurposeIds() + { + return Collections.unmodifiableList(purposeIds); + } + + public String toString() + { + return ExtendedKeyUsage.class.getName() + " [ " + purposeIds + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/Extension.java b/libjava/classpath/gnu/java/security/x509/ext/Extension.java new file mode 100644 index 0000000..5ca9ac3 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/Extension.java @@ -0,0 +1,289 @@ +/* Extension.java -- an X.509 certificate or CRL extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Extension +{ + + // Fields. + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + System.err.print(">> Extension: "); + System.err.println(msg); + } + + /** + * This extension's object identifier. + */ + protected final OID oid; + + /** + * The criticality flag. + */ + protected final boolean critical; + + /** + * Whether or not this extension is locally supported. + */ + protected boolean isSupported; + + /** + * The extension value. + */ + protected final Value value; + + /** + * The DER encoded form. + */ + protected byte[] encoded; + + // Constructors. + // ------------------------------------------------------------------------- + + public Extension(byte[] encoded) throws IOException + { + this.encoded = (byte[]) encoded.clone(); + DERReader der = new DERReader(encoded); + + // Extension ::= SEQUENCE { + DERValue val = der.read(); + if (DEBUG) debug("read val tag == " + val.getTag() + " len == " + val.getLength()); + if (!val.isConstructed()) + throw new IOException("malformed Extension"); + + // extnID OBJECT IDENTIFIER, + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("expecting OBJECT IDENTIFIER"); + oid = (OID) val.getValue(); + if (DEBUG) debug("read oid == " + oid); + + // critical BOOLEAN DEFAULT FALSE, + val = der.read(); + if (val.getTag() == DER.BOOLEAN) + { + critical = ((Boolean) val.getValue()).booleanValue(); + val = der.read(); + } + else + critical = false; + if (DEBUG) debug("is critical == " + critical); + + // extnValue OCTET STRING } + if (val.getTag() != DER.OCTET_STRING) + throw new IOException("expecting OCTET STRING"); + byte[] encval = (byte[]) val.getValue(); + isSupported = true; + if (oid.equals(AuthorityKeyIdentifier.ID)) + { + value = new AuthorityKeyIdentifier(encval); + } + else if (oid.equals(SubjectKeyIdentifier.ID)) + { + value = new SubjectKeyIdentifier(encval); + } + else if (oid.equals(KeyUsage.ID)) + { + value = new KeyUsage(encval); + } + else if (oid.equals(PrivateKeyUsagePeriod.ID)) + { + value = new PrivateKeyUsagePeriod(encval); + } + else if (oid.equals(CertificatePolicies.ID)) + { + value = new CertificatePolicies(encval); + } + else if (oid.equals (PolicyConstraint.ID)) + { + value = new PolicyConstraint (encval); + } + else if (oid.equals(PolicyMappings.ID)) + { + value = new PolicyMappings(encval); + } + else if (oid.equals(SubjectAlternativeNames.ID)) + { + value = new SubjectAlternativeNames(encval); + } + else if (oid.equals(IssuerAlternativeNames.ID)) + { + value = new IssuerAlternativeNames(encval); + } + else if (oid.equals(BasicConstraints.ID)) + { + value = new BasicConstraints(encval); + } + else if (oid.equals(ExtendedKeyUsage.ID)) + { + value = new ExtendedKeyUsage(encval); + } + else if (oid.equals(CRLNumber.ID)) + { + value = new CRLNumber(encval); + } + else if (oid.equals(ReasonCode.ID)) + { + value = new ReasonCode(encval); + } + else + { + value = new Value(encval); + isSupported = false; + } + if (DEBUG) debug("read value == " + value); + } + + public Extension (final OID oid, final Value value, final boolean critical) + { + this.oid = oid; + this.value = value; + this.critical = critical; + isSupported = true; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public OID getOid() + { + return oid; + } + + public boolean isCritical() + { + return critical; + } + + public boolean isSupported() + { + return isSupported; + } + + public Value getValue() + { + return value; + } + + public byte[] getEncoded() + { + if (encoded == null) + encode(); + return (byte[]) encoded.clone(); + } + + public String toString() + { + return Extension.class.getName() + " [ id=" + oid + " critical=" + + critical + " value=" + value + " ]"; + } + + public DERValue getDerValue() + { + List ext = new ArrayList (3); + ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid)); + ext.add (new DERValue (DER.BOOLEAN, new Boolean (critical))); + ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded())); + return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext); + } + + // Own methods. + // ------------------------------------------------------------------------- + + private void encode() + { + encoded = getDerValue().getEncoded(); + } + + // Inner class. + // ------------------------------------------------------------------------- + + public static class Value + { + + // Fields. + // ----------------------------------------------------------------------- + + protected byte[] encoded; + + // Constructor. + // ----------------------------------------------------------------------- + + public Value(byte[] encoded) + { + this.encoded = (byte[]) encoded.clone(); + } + + protected Value() { } + + // Instance methods. + // ----------------------------------------------------------------------- + + public byte[] getEncoded() + { + return (byte[]) encoded; + } + + public boolean equals(Object o) + { + if (!(o instanceof Value)) + return false; + return Arrays.equals(encoded, ((Value) o).encoded); + } + + public String toString() + { + return Util.toHexString(encoded, ':'); + } + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java new file mode 100644 index 0000000..e92aeda --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java @@ -0,0 +1,155 @@ +/* GeneralNames.java -- the GeneralNames object + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.X500DistinguishedName; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class GeneralNames +{ + + // Instance methods. + // ------------------------------------------------------------------------- + + public static final int OTHER_NAME = 0; + public static final int RFC822_NAME = 1; + public static final int DNS_NAME = 2; + public static final int X400_ADDRESS = 3; + public static final int DIRECTORY_NAME = 4; + public static final int EDI_PARTY_NAME = 5; + public static final int URI = 6; + public static final int IP_ADDRESS = 7; + public static final int REGISTERED_ID = 8; + + private List names; + + // Constructor. + // ------------------------------------------------------------------------- + + public GeneralNames(final byte[] encoded) throws IOException + { + names = new LinkedList(); + DERReader der = new DERReader(encoded); + DERValue nameList = der.read(); + if (!nameList.isConstructed()) + throw new IOException("malformed GeneralNames"); + int len = 0; + while (len < nameList.getLength()) + { + DERValue name = der.read(); + List namePair = new ArrayList(2); + if (name.getTagClass() != DER.APPLICATION) + throw new IOException("malformed GeneralName"); + namePair.add(new Integer(name.getTag())); + DERValue val = null; + switch (name.getTag()) + { + case RFC822_NAME: + case DNS_NAME: + case X400_ADDRESS: + case URI: + namePair.add(new String((byte[]) name.getValue())); + break; + + case OTHER_NAME: + case EDI_PARTY_NAME: + namePair.add(name.getValue()); + break; + + case DIRECTORY_NAME: + byte[] b = name.getEncoded(); + b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); + namePair.add(new X500DistinguishedName(b).toString()); + break; + + case IP_ADDRESS: + namePair.add(InetAddress.getByAddress((byte[]) name.getValue()) + .getHostAddress()); + break; + + case REGISTERED_ID: + byte[] bb = name.getEncoded(); + bb[0] = (byte) DER.OBJECT_IDENTIFIER; + namePair.add(new OID(bb).toString()); + break; + + default: + throw new IOException("unknown tag " + name.getTag()); + } + names.add(namePair); + len += name.getEncodedLength(); + } + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getNames() + { + List l = new ArrayList(names.size()); + for (Iterator it = names.iterator(); it.hasNext(); ) + { + List ll = (List) it.next(); + List pair = new ArrayList(2); + pair.add(ll.get(0)); + if (ll.get(1) instanceof byte[]) + pair.add(((byte[]) ll.get(1)).clone()); + else + pair.add(ll.get(1)); + l.add(Collections.unmodifiableList(pair)); + } + return Collections.unmodifiableList(l); + } + + public String toString() + { + return GeneralNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java b/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java new file mode 100644 index 0000000..8b017dc --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java @@ -0,0 +1,77 @@ +/* IssuerAlternatuveNames.java -- issuer alternative names extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; + +import java.io.IOException; +import java.util.List; + +public class IssuerAlternativeNames extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.18"); + + private final GeneralNames names; + + // Constructor. + // ------------------------------------------------------------------------- + + public IssuerAlternativeNames(final byte[] encoded) throws IOException + { + super(encoded); + names = new GeneralNames(encoded); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getNames() + { + return names.getNames(); + } + + public String toString() + { + return IssuerAlternativeNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/KeyUsage.java b/libjava/classpath/gnu/java/security/x509/ext/KeyUsage.java new file mode 100644 index 0000000..dcd9818 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/KeyUsage.java @@ -0,0 +1,92 @@ +/* KeyUsage.java -- the key usage extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; + +public class KeyUsage extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.15"); + public static final int DIGITAL_SIGNATURE = 0; + public static final int NON_REPUDIATION = 1; + public static final int KEY_ENCIPHERMENT = 2; + public static final int DATA_ENCIPHERMENT = 3; + public static final int KEY_AGREEMENT = 4; + public static final int KEY_CERT_SIGN = 5; + public static final int CRL_SIGN = 6; + public static final int ENCIPHER_ONLY = 7; + public static final int DECIPHER_ONLY = 8; + + private final BitString keyUsage; + + // Constructor. + // ------------------------------------------------------------------------- + + public KeyUsage(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.BIT_STRING) + throw new IOException("malformed KeyUsage"); + keyUsage = (BitString) val.getValue(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BitString getKeyUsage() + { + return keyUsage; + } + + public String toString() + { + return KeyUsage.class.getName() + " [ " + keyUsage + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/PolicyConstraint.java b/libjava/classpath/gnu/java/security/x509/ext/PolicyConstraint.java new file mode 100644 index 0000000..20cf552 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/PolicyConstraint.java @@ -0,0 +1,107 @@ +/* PolicyConstraint.java -- policyConstraint extension + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.math.BigInteger; + +public class PolicyConstraint extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID ("2.5.29.36"); + + private final int requireExplicitPolicy; + private final int inhibitPolicyMapping; + + // Constructors. + // ------------------------------------------------------------------------- + + public PolicyConstraint (final byte[] encoded) throws IOException + { + super (encoded); + int rpc = -1, ipm = -1; + DERReader der = new DERReader(encoded); + DERValue pc = der.read(); + if (!pc.isConstructed()) + throw new IOException("malformed PolicyConstraints"); + DERValue val; + int len = pc.getLength(); + while (len > 0) + { + val = der.read(); + if (val.getTag() == 0) + rpc = new BigInteger ((byte[]) val.getValue()).intValue(); + else if (val.getTag() == 1) + ipm = new BigInteger ((byte[]) val.getValue()).intValue(); + else + throw new IOException ("invalid policy constraint"); + len -= val.getEncodedLength(); + } + + requireExplicitPolicy = rpc; + inhibitPolicyMapping = ipm; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public int getRequireExplicitPolicy() + { + return requireExplicitPolicy; + } + + public int getInhibitPolicyMapping() + { + return inhibitPolicyMapping; + } + + public String toString() + { + return PolicyConstraint.class.getName() + " [ requireExplicitPolicy=" + + requireExplicitPolicy + " inhibitPolicyMapping=" + inhibitPolicyMapping + + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/PolicyMappings.java b/libjava/classpath/gnu/java/security/x509/ext/PolicyMappings.java new file mode 100644 index 0000000..0493ed8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/PolicyMappings.java @@ -0,0 +1,104 @@ +/* PolicyMappings.java -- policy mappings extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class PolicyMappings extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.33"); + + private final Map mappings; + + // Constructor. + // ------------------------------------------------------------------------- + + public PolicyMappings(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue maps = der.read(); + if (!maps.isConstructed()) + throw new IOException("malformed PolicyMappings"); + int len = 0; + HashMap _mappings = new HashMap(); + while (len < maps.getLength()) + { + DERValue map = der.read(); + if (!map.isConstructed()) + throw new IOException("malformed PolicyMapping"); + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed PolicyMapping"); + OID issuerPolicy = (OID) val.getValue(); + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed PolicyMapping"); + OID subjectPolicy = (OID) val.getValue(); + _mappings.put(issuerPolicy, subjectPolicy); + len += map.getEncodedLength(); + } + mappings = Collections.unmodifiableMap(_mappings); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public OID getSubjectDomainPolicy(OID issuerDomainPolicy) + { + return (OID) mappings.get(issuerDomainPolicy); + } + + public String toString() + { + return PolicyMappings.class.getName() + " [ " + mappings + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java b/libjava/classpath/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java new file mode 100644 index 0000000..3b531c0 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java @@ -0,0 +1,105 @@ +/* PrivateKeyUsagePeriod.java -- private key usage period extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.util.Date; + +public class PrivateKeyUsagePeriod extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.16"); + + private final Date notBefore; + private final Date notAfter; + + // Constructor. + // ------------------------------------------------------------------------- + + public PrivateKeyUsagePeriod(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed PrivateKeyUsagePeriod"); + if (val.getLength() > 0) + val = der.read(); + if (val.getTagClass() == DER.APPLICATION || val.getTag() == 0) + { + notBefore = (Date) val.getValueAs (DER.GENERALIZED_TIME); + val = der.read(); + } + else + notBefore = null; + if (val.getTagClass() == DER.APPLICATION || val.getTag() == 1) + { + notAfter = (Date) val.getValueAs (DER.GENERALIZED_TIME); + } + else + notAfter = null; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Date getNotBefore() + { + return notBefore != null ? (Date) notBefore.clone() : null; + } + + public Date getNotAfter() + { + return notAfter != null ? (Date) notAfter.clone() : null; + } + + public String toString() + { + return PrivateKeyUsagePeriod.class.getName() + " [ notBefore=" + notBefore + + " notAfter=" + notAfter + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/ReasonCode.java b/libjava/classpath/gnu/java/security/x509/ext/ReasonCode.java new file mode 100644 index 0000000..a6d59e4 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/ReasonCode.java @@ -0,0 +1,85 @@ +/* ReasonCode.java -- a reason code for a certificate revocation. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +import java.io.IOException; +import java.math.BigInteger; + +public class ReasonCode extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.21"); + + public final int reason; + + // Constructor. + // ------------------------------------------------------------------------- + + public ReasonCode(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.ENUMERATED) + throw new IOException("malformed CRLReason"); + reason = ((BigInteger) val.getValue()).intValue(); + if (reason < 0 || reason == 7 || reason > 10) + throw new IOException("illegal reason: " + reason); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public int getReasonCode() + { + return reason; + } + + public String toString() + { + return ReasonCode.class.getName() + " [ " + reason + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java b/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java new file mode 100644 index 0000000..f88e854 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java @@ -0,0 +1,77 @@ +/* SubjectAlternatuveNames.java -- subject alternative names extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; + +import java.io.IOException; +import java.util.List; + +public class SubjectAlternativeNames extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.17"); + + private final GeneralNames names; + + // Constructor. + // ------------------------------------------------------------------------- + + public SubjectAlternativeNames(final byte[] encoded) throws IOException + { + super(encoded); + names = new GeneralNames(encoded); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getNames() + { + return names.getNames(); + } + + public String toString() + { + return SubjectAlternativeNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/SubjectKeyIdentifier.java b/libjava/classpath/gnu/java/security/x509/ext/SubjectKeyIdentifier.java new file mode 100644 index 0000000..fc65abe --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/SubjectKeyIdentifier.java @@ -0,0 +1,84 @@ +/* SubjectKeyIdentifier.java -- subject key identifier extension. + Copyright (C) 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.java.security.x509.ext; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +import java.io.IOException; + +public class SubjectKeyIdentifier extends Extension.Value +{ + + // Constant. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.14"); + + private final byte[] keyIdentifier; + + // Constructor. + // ------------------------------------------------------------------------- + + public SubjectKeyIdentifier(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.OCTET_STRING) + throw new IOException("malformed SubjectKeyIdentifier"); + keyIdentifier = (byte[]) val.getValue(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public byte[] getKeyIdentifier() + { + return (byte[]) keyIdentifier.clone(); + } + + public String toString() + { + return SubjectKeyIdentifier.class.getName() + " [ " + + Util.toHexString (keyIdentifier, ':') + " ]"; + } +} diff --git a/libjava/classpath/gnu/java/security/x509/ext/package.html b/libjava/classpath/gnu/java/security/x509/ext/package.html new file mode 100644 index 0000000..cc44e55c --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/ext/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.x509.ext package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.x509.ext</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/security/x509/package.html b/libjava/classpath/gnu/java/security/x509/package.html new file mode 100644 index 0000000..8b0ba00 --- /dev/null +++ b/libjava/classpath/gnu/java/security/x509/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.security.x509 package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.security.x509</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/text/AttributedFormatBuffer.java b/libjava/classpath/gnu/java/text/AttributedFormatBuffer.java new file mode 100644 index 0000000..8cfc8f5 --- /dev/null +++ b/libjava/classpath/gnu/java/text/AttributedFormatBuffer.java @@ -0,0 +1,247 @@ +/* AttributedFormatBuffer.java -- Implements an attributed FormatBuffer. + Copyright (C) 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.java.text; + +import java.text.AttributedCharacterIterator; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This class is an implementation of a FormatBuffer with attributes. + * + * @author Guilhem Lavaux <guilhem@kaffe.org> + * @date April 10, 2004 + */ +public class AttributedFormatBuffer implements FormatBuffer +{ + private StringBuffer buffer; + private ArrayList ranges; + private ArrayList attributes; + private int[] a_ranges; + private HashMap[] a_attributes; + private int startingRange; + AttributedCharacterIterator.Attribute defaultAttr; + + /** + * This constructor accepts a StringBuffer. If the buffer contains + * already some characters they will not be attributed. + */ + public AttributedFormatBuffer(StringBuffer buffer) + { + this.buffer = buffer; + this.ranges = new ArrayList(); + this.attributes = new ArrayList(); + this.defaultAttr = null; + if (buffer.length() != 0) + { + this.startingRange = buffer.length(); + addAttribute(buffer.length(), null); + } + else + this.startingRange = -1; + } + + public AttributedFormatBuffer(int prebuffer) + { + this(new StringBuffer(prebuffer)); + } + + public AttributedFormatBuffer() + { + this(10); + } + + /** + * This method is a helper function for formatters. Given a set of ranges + * and attributes it adds exactly one attribute for the range of characters + * comprised between the last entry in 'ranges' and the specified new range. + * + * @param new_range A new range to insert in the list. + * @param new_attribute A new attribute to insert in the list. + */ + private final void addAttribute(int new_range, AttributedCharacterIterator.Attribute attr) + { + HashMap map; + + if (attr != null) + { + map = new HashMap(); + map.put(attr, attr); + attributes.add(map); + } + else + attributes.add(null); + + ranges.add(new Integer(new_range)); + } + + public void append(String s) + { + if (startingRange < 0) + startingRange = 0; + buffer.append(s); + } + + public void append(String s, AttributedCharacterIterator.Attribute attr) + { + setDefaultAttribute(attr); + startingRange = buffer.length(); + append(s); + setDefaultAttribute(null); + } + + public void append(String s, int[] ranges, HashMap[] attrs) + { + int curPos = buffer.length(); + + setDefaultAttribute(null); + if (ranges != null) + { + for (int i = 0; i < ranges.length; i++) + { + this.ranges.add(new Integer(ranges[i] + curPos)); + this.attributes.add(attrs[i]); + } + } + startingRange = buffer.length(); + buffer.append(s); + } + + public void append(char c) + { + if (startingRange < 0) + startingRange = buffer.length(); + buffer.append(c); + } + + public void append(char c, AttributedCharacterIterator.Attribute attr) + { + setDefaultAttribute(attr); + buffer.append(c); + setDefaultAttribute(null); + } + + public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr) + { + if (attr == defaultAttr) + return; + + int currentPos = buffer.length(); + + if (startingRange != currentPos && startingRange >= 0) + { + addAttribute(currentPos, defaultAttr); + } + defaultAttr = attr; + startingRange = currentPos; + } + + public AttributedCharacterIterator.Attribute getDefaultAttribute() + { + return defaultAttr; + } + + public void cutTail(int length) + { + buffer.setLength(buffer.length()-length); + } + + public int length() + { + return buffer.length(); + } + + public void clear() + { + buffer.setLength(0); + ranges.clear(); + attributes.clear(); + defaultAttr = null; + startingRange = -1; + } + + /** + * This method synchronizes the state of the attribute array. + * After calling it you may call {@link #getDefaultAttribute()}. + */ + public void sync() + { + if (startingRange < 0 || startingRange == buffer.length()) + return; + + addAttribute(buffer.length(), defaultAttr); + + a_ranges = new int[ranges.size()]; + for (int i = 0; i < a_ranges.length; i++) + a_ranges[i] = ((Integer)(ranges.get (i))).intValue(); + + a_attributes = new HashMap[attributes.size()]; + System.arraycopy(attributes.toArray(), 0, a_attributes, 0, a_attributes.length); + } + + /** + * This method returns the internal StringBuffer describing + * the attributed string. + * + * @return An instance of StringBuffer which contains the string. + */ + public StringBuffer getBuffer() + { + return buffer; + } + + /** + * This method returns the ranges for the attributes. + * + * @return An array of int describing the ranges. + */ + public int[] getRanges() + { + return a_ranges; + } + + /** + * This method returns the array containing the map on the + * attributes. + * + * @return An array of {@link java.util.Map} containing the attributes. + */ + public HashMap[] getAttributes() + { + return a_attributes; + } +} diff --git a/libjava/classpath/gnu/java/text/BaseBreakIterator.java b/libjava/classpath/gnu/java/text/BaseBreakIterator.java new file mode 100644 index 0000000..c28a208 --- /dev/null +++ b/libjava/classpath/gnu/java/text/BaseBreakIterator.java @@ -0,0 +1,121 @@ +/* BaseBreakIterator.java -- Base class for default BreakIterators + Copyright (C) 1999, 2001, 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.java.text; + +import java.text.BreakIterator; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 22, 1999 + */ + +public abstract class BaseBreakIterator extends BreakIterator +{ + public BaseBreakIterator () + { + // It isn't documented, but break iterators are created in a + // working state; their methods won't throw exceptions before + // setText(). + iter = new StringCharacterIterator(""); + } + + public int current () + { + return iter.getIndex(); + } + + public int first () + { + iter.first(); + return iter.getBeginIndex(); + } + + public int following (int pos) + { + int save = iter.getIndex(); + iter.setIndex(pos); + int r = next (); + iter.setIndex(save); + return r; + } + + public CharacterIterator getText () + { + return iter; + } + + public int last () + { + iter.last(); + // Go past the last character. + iter.next(); + return iter.getEndIndex(); + } + + public int next (int n) + { + int r = iter.getIndex (); + if (n > 0) + { + while (n > 0 && r != DONE) + { + r = next (); + --n; + } + } + else if (n < 0) + { + while (n < 0 && r != DONE) + { + r = previous (); + ++n; + } + } + return r; + } + + public void setText (CharacterIterator newText) + { + iter = newText; + } + + protected CharacterIterator iter; +} diff --git a/libjava/classpath/gnu/java/text/CharacterBreakIterator.java b/libjava/classpath/gnu/java/text/CharacterBreakIterator.java new file mode 100644 index 0000000..5274543 --- /dev/null +++ b/libjava/classpath/gnu/java/text/CharacterBreakIterator.java @@ -0,0 +1,213 @@ +/* CharacterBreakIterator.java - Default character BreakIterator. + Copyright (C) 1999, 2001, 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.java.text; + +import java.text.CharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 19, 1999 + * Written using The Unicode Standard, Version 2.0. + */ + +public class CharacterBreakIterator extends BaseBreakIterator +{ + // Hangul Jamo constants from Unicode book. + private static final int LBase = 0x1100; + private static final int VBase = 0x1161; + private static final int TBase = 0x11a7; + private static final int LCount = 19; + private static final int VCount = 21; + private static final int TCount = 28; + + // Information about surrogates. + private static final int highSurrogateStart = 0xD800; + private static final int highSurrogateEnd = 0xDBFF; + private static final int lowSurrogateStart = 0xDC00; + private static final int lowSurrogateEnd = 0xDFFF; + + public Object clone () + { + return new CharacterBreakIterator (this); + } + + public CharacterBreakIterator () + { + } + + private CharacterBreakIterator (CharacterBreakIterator other) + { + iter = (CharacterIterator) other.iter.clone(); + } + + // Some methods to tell us different properties of characters. + private final boolean isL (char c) + { + return c >= LBase && c <= LBase + LCount; + } + private final boolean isV (char c) + { + return c >= VBase && c <= VBase + VCount; + } + private final boolean isT (char c) + { + return c >= TBase && c <= TBase + TCount; + } + private final boolean isLVT (char c) + { + return isL (c) || isV (c) || isT (c); + } + private final boolean isHighSurrogate (char c) + { + return c >= highSurrogateStart && c <= highSurrogateEnd; + } + private final boolean isLowSurrogate (char c) + { + return c >= lowSurrogateStart && c <= lowSurrogateEnd; + } + + public int next () + { + int end = iter.getEndIndex(); + if (iter.getIndex() == end) + return DONE; + + char c; + for (char prev = CharacterIterator.DONE; iter.getIndex() < end; prev = c) + { + c = iter.next(); + if (c == CharacterIterator.DONE) + break; + int type = Character.getType(c); + + // Break after paragraph separators. + if (type == Character.PARAGRAPH_SEPARATOR) + break; + + // Now we need some lookahead. + char ahead = iter.next(); + iter.previous(); + if (ahead == CharacterIterator.DONE) + break; + int aheadType = Character.getType(ahead); + + if (aheadType != Character.NON_SPACING_MARK + && ! isLowSurrogate (ahead) + && ! isLVT (ahead)) + break; + if (! isLVT (c) && isLVT (ahead)) + break; + if (isL (c) && ! isLVT (ahead) + && aheadType != Character.NON_SPACING_MARK) + break; + if (isV (c) && ! isV (ahead) && !isT (ahead) + && aheadType != Character.NON_SPACING_MARK) + break; + if (isT (c) && ! isT (ahead) + && aheadType != Character.NON_SPACING_MARK) + break; + + if (! isHighSurrogate (c) && isLowSurrogate (ahead)) + break; + if (isHighSurrogate (c) && ! isLowSurrogate (ahead)) + break; + if (! isHighSurrogate (prev) && isLowSurrogate (c)) + break; + } + + return iter.getIndex(); + } + + public int previous () + { + if (iter.getIndex() == iter.getBeginIndex()) + return DONE; + + while (iter.getIndex() >= iter.getBeginIndex()) + { + char c = iter.previous(); + if (c == CharacterIterator.DONE) + break; + int type = Character.getType(c); + + if (type != Character.NON_SPACING_MARK + && ! isLowSurrogate (c) + && ! isLVT (c)) + break; + + // Now we need some lookahead. + char ahead = iter.previous(); + if (ahead == CharacterIterator.DONE) + { + iter.next(); + break; + } + char ahead2 = iter.previous(); + iter.next(); + iter.next(); + if (ahead2 == CharacterIterator.DONE) + break; + int aheadType = Character.getType(ahead); + + if (aheadType == Character.PARAGRAPH_SEPARATOR) + break; + + if (isLVT (c) && ! isLVT (ahead)) + break; + if (! isLVT (c) && type != Character.NON_SPACING_MARK + && isL (ahead)) + break; + if (! isV (c) && ! isT (c) && type != Character.NON_SPACING_MARK + && isV (ahead)) + break; + if (! isT (c) && type != Character.NON_SPACING_MARK + && isT (ahead)) + break; + + if (isLowSurrogate (c) && ! isHighSurrogate (ahead)) + break; + if (! isLowSurrogate (c) && isHighSurrogate (ahead)) + break; + if (isLowSurrogate (ahead) && ! isHighSurrogate (ahead2)) + break; + } + + return iter.getIndex(); + } +} diff --git a/libjava/classpath/gnu/java/text/FormatBuffer.java b/libjava/classpath/gnu/java/text/FormatBuffer.java new file mode 100644 index 0000000..e6b6820 --- /dev/null +++ b/libjava/classpath/gnu/java/text/FormatBuffer.java @@ -0,0 +1,136 @@ +/* FormatBuffer.java -- General interface to build attributed strings. + Copyright (C) 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.java.text; + +import java.text.AttributedCharacterIterator; +import java.util.HashMap; + +/** + * This interface describes a modifiable buffer which contains attributed + * characters. The implementation may or may not implements attributes. It + * aims to greatly simplify and clarify the implementation of java.text + * formatters. The buffer may be appended or have its tail cut. It may also + * be completely cleant up. + * + * @author Guilhem Lavaux <guilhem@kaffe.org> + * @date April 10, 2004 + */ +public interface FormatBuffer +{ + /** + * This method appends a simple string to the buffer. This part of + * the buffer will be attributed using the default attribute. + * + * @param s The string to append to the buffer. + */ + public void append(String s); + + /** + * This method appends a simple string to the buffer. This part of + * the buffer will have the specified attribute (and only this one). + * The default attribute may be changed after calling this method. + * + * @param s The string to append to the buffer. + * @param attr Attribute to use for the string in the buffer. + */ + public void append(String s, AttributedCharacterIterator.Attribute attr); + + /** + * This method appends a simple string to the buffer. This part of + * the buffer will be attributed using the specified ranges and attributes. + * To have an example on how to specify ranges see {@link gnu.java.text.FormatCharacterIterator}. + * + * @param s The string to append to the buffer. + * @param ranges The ranges describing how the attributes should be applied + * to the string. + * @param attrs The attributes of the string in the buffer. + */ + public void append(String s, int[] ranges, HashMap[] attrs); + + /** + * This method appends a simple char to the buffer. This part of + * the buffer will be attributed using the default attribute. + * + * @param c The character to append to the buffer. + */ + public void append(char c); + + /** + * This method appends a simple character to the buffer. This part of + * the buffer will have the specified attribute (and only this one). + * The default attribute may be changed after calling this method. + * + * @param c The character to append to the buffer. + * @param attr Attribute to use for the character in the buffer. + */ + public void append(char c, AttributedCharacterIterator.Attribute attr); + + /** + * This method changes the current default attribute for the next string + * or character which will be appended to the buffer. + * + * @param attr The attribute which will be used by default. + */ + public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr); + + /** + * This method returns the current default attribute for the buffer. + * + * @return The default attribute for the buffer. + */ + public AttributedCharacterIterator.Attribute getDefaultAttribute(); + + /** + * This method cuts the last characters of the buffer. The number of + * characters to cut is given by "length". + * + * @param length Number of characters to cut at the end of the buffer. + */ + public void cutTail(int length); + + /** + * This method resets completely the buffer. + */ + public void clear(); + + /** + * This method returns the number of character in the buffer. + * + * @return The number of character in the buffer. + */ + public int length(); +} diff --git a/libjava/classpath/gnu/java/text/FormatCharacterIterator.java b/libjava/classpath/gnu/java/text/FormatCharacterIterator.java new file mode 100644 index 0000000..60773aa --- /dev/null +++ b/libjava/classpath/gnu/java/text/FormatCharacterIterator.java @@ -0,0 +1,533 @@ +/* FormatCharacter.java -- Implementation of AttributedCharacterIterator for + formatters. + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 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.java.text; + +import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +/** + * This class should not be put public and it is only intended to the + * classes of the java.text package. Its aim is to build a segmented + * character iterator by appending strings and adding attributes to + * portions of strings. The code intends to do some optimization + * concerning memory consumption and attribute access but at the + * end it is only an AttributedCharacterIterator. + * + * @author Guilhem Lavaux <guilhem@kaffe.org> + * @date November 22, 2003 + */ +public class FormatCharacterIterator implements AttributedCharacterIterator +{ + private String formattedString; + private int charIndex; + private int attributeIndex; + private int[] ranges; + private HashMap[] attributes; + private static final boolean DEBUG = false; + + /** + * This constructor builds an empty iterated strings. The attributes + * are empty and so is the string. However you may append strings + * and attributes to this iterator. + */ + public FormatCharacterIterator() + { + formattedString = ""; + ranges = new int[0]; + attributes = new HashMap[0]; + } + + /** + * This constructor take a string <code>s</code>, a set of ranges + * and the corresponding attributes. This is used to build an iterator. + * The array <code>ranges</code> should be formatted as follow: + * each element of <code>ranges</code> specifies the index in the string + * until which the corresponding map of attributes at the same position + * is applied. For example, if you have: + * <pre> + * s = "hello"; + * ranges = new int[] { 2, 6 }; + * attributes = new HashMap[2]; + * </pre> + * <code>"he"</code> will have the attributes <code>attributes[0]</code>, + * <code>"llo"</code> the <code>attributes[1]</code>. + */ + public FormatCharacterIterator (String s, int[] ranges, HashMap[] attributes) + { + formattedString = s; + this.ranges = ranges; + this.attributes = attributes; + } + + /* + * The following methods are inherited from AttributedCharacterIterator, + * and thus are already documented. + */ + + public Set getAllAttributeKeys() + { + if (attributes != null && attributes[attributeIndex] != null) + return attributes[attributeIndex].keySet(); + else + return new HashSet(); + } + + public Map getAttributes() + { + if (attributes != null && attributes[attributeIndex] != null) + return attributes[attributeIndex]; + else + return new HashMap(); + } + + public Object getAttribute (AttributedCharacterIterator.Attribute attrib) + { + if (attributes != null && attributes[attributeIndex] != null) + return attributes[attributeIndex].get (attrib); + else + return null; + } + + public int getRunLimit(Set reqAttrs) + { + if (attributes == null) + return formattedString.length(); + + int currentAttrIndex = attributeIndex; + Set newKeys; + + do + { + currentAttrIndex++; + if (currentAttrIndex == attributes.length) + return formattedString.length(); + if (attributes[currentAttrIndex] == null) + break; + newKeys = attributes[currentAttrIndex].keySet(); + } + while (newKeys.containsAll (reqAttrs)); + + return ranges[currentAttrIndex-1]; + } + + public int getRunLimit (AttributedCharacterIterator.Attribute attribute) + { + Set s = new HashSet(); + + s.add (attribute); + return getRunLimit (s); + } + + public int getRunLimit() + { + if (attributes == null) + return formattedString.length(); + if (attributes[attributeIndex] == null) + { + for (int i=attributeIndex+1;i<attributes.length;i++) + if (attributes[i] != null) + return ranges[i-1]; + return formattedString.length(); + } + + return getRunLimit (attributes[attributeIndex].keySet()); + } + + public int getRunStart (Set reqAttrs) + { + if (attributes == null) + return formattedString.length(); + + int currentAttrIndex = attributeIndex; + Set newKeys = null; + + do + { + if (currentAttrIndex == 0) + return 0; + + currentAttrIndex--; + if (attributes[currentAttrIndex] == null) + break; + newKeys = attributes[currentAttrIndex].keySet(); + } + while (newKeys.containsAll (reqAttrs)); + + return (currentAttrIndex > 0) ? ranges[currentAttrIndex-1] : 0; + } + + public int getRunStart() + { + if (attributes == null) + return 0; + + if (attributes[attributeIndex] == null) + { + for (int i=attributeIndex;i>0;i--) + if (attributes[i] != null) + return ranges[attributeIndex-1]; + return 0; + } + + return getRunStart (attributes[attributeIndex].keySet()); + } + + public int getRunStart (AttributedCharacterIterator.Attribute attribute) + { + Set s = new HashSet(); + + s.add (attribute); + return getRunStart (s); + } + + public Object clone() + { + return new FormatCharacterIterator (formattedString, ranges, attributes); + } + + /* + * The following methods are inherited from CharacterIterator and thus + * are already documented. + */ + + public char current() + { + return formattedString.charAt (charIndex); + } + + public char first() + { + charIndex = 0; + attributeIndex = 0; + return formattedString.charAt (0); + } + + public int getBeginIndex() + { + return 0; + } + + public int getEndIndex() + { + return formattedString.length(); + } + + public int getIndex() + { + return charIndex; + } + + public char last() + { + charIndex = formattedString.length()-1; + if (attributes != null) + attributeIndex = attributes.length-1; + return formattedString.charAt (charIndex); + } + + public char next() + { + charIndex++; + if (charIndex >= formattedString.length()) + { + charIndex = getEndIndex(); + return DONE; + } + if (attributes != null) + { + if (charIndex >= ranges[attributeIndex]) + attributeIndex++; + } + return formattedString.charAt (charIndex); + } + + public char previous() + { + charIndex--; + if (charIndex < 0) + { + charIndex = 0; + return DONE; + } + + if (attributes != null) + { + if (charIndex < ranges[attributeIndex]) + attributeIndex--; + } + return formattedString.charAt (charIndex); + } + + public char setIndex (int position) + { + if (position < 0 || position > formattedString.length()) + throw new IllegalArgumentException ("position is out of range"); + + charIndex = position; + if (attributes != null) + { + for (attributeIndex=0;attributeIndex<attributes.length; + attributeIndex++) + if (ranges[attributeIndex] > charIndex) + break; + attributeIndex--; + } + if (charIndex == formattedString.length()) + return DONE; + else + return formattedString.charAt (charIndex); + } + + /** + * This method merge the specified attributes and ranges with the + * internal tables. This method is in charge of the optimization + * of tables. Two following sets of attributes are never the same. + * + * @see #FormatCharacterIterator() + * + * @param attributes the new array attributes to apply to the string. + */ + public void mergeAttributes (HashMap[] attributes, int[] ranges) + { + Vector new_ranges = new Vector(); + Vector new_attributes = new Vector(); + int i = 0, j = 0; + + debug("merging " + attributes.length + " attrs"); + + while (i < this.ranges.length && j < ranges.length) + { + if (this.attributes[i] != null) + { + new_attributes.add (this.attributes[i]); + if (attributes[j] != null) + this.attributes[i].putAll (attributes[j]); + } + else + { + new_attributes.add (attributes[j]); + } + if (this.ranges[i] == ranges[j]) + { + new_ranges.add (new Integer (ranges[j])); + i++; + j++; + } + else if (this.ranges[i] < ranges[j]) + { + new_ranges.add (new Integer (this.ranges[i])); + i++; + } + else + { + new_ranges.add (new Integer (ranges[j])); + j++; + } + } + + if (i != this.ranges.length) + { + for (;i<this.ranges.length;i++) + { + new_attributes.add (this.attributes[i]); + new_ranges.add (new Integer (this.ranges[i])); + } + } + if (j != ranges.length) + { + for (;j<ranges.length;j++) + { + new_attributes.add (attributes[j]); + new_ranges.add (new Integer (ranges[j])); + } + } + + this.attributes = new HashMap[new_attributes.size()]; + this.ranges = new int[new_ranges.size()]; + System.arraycopy (new_attributes.toArray(), 0, this.attributes, + 0, this.attributes.length); + + for (i=0;i<new_ranges.size();i++) + { + this.ranges[i] = ((Integer)new_ranges.elementAt (i)).intValue(); + } + + dumpTable(); + } + + /** + * This method appends to the internal attributed string the attributed + * string contained in the specified iterator. + * + * @param iterator the iterator which contains the attributed string to + * append to this iterator. + */ + public void append (AttributedCharacterIterator iterator) + { + char c = iterator.first(); + Vector more_ranges = new Vector(); + Vector more_attributes = new Vector(); + + do + { + formattedString = formattedString + String.valueOf (c); + // TODO: Reduce the size of the output array. + more_attributes.add (iterator.getAttributes()); + more_ranges.add (new Integer (formattedString.length())); + // END TOOD + c = iterator.next(); + } + while (c != DONE); + + HashMap[] new_attributes = new HashMap[attributes.length + + more_attributes.size()]; + int[] new_ranges = new int[ranges.length + more_ranges.size()]; + + System.arraycopy (attributes, 0, new_attributes, 0, attributes.length); + System.arraycopy (more_attributes.toArray(), 0, new_attributes, + attributes.length, more_attributes.size()); + + System.arraycopy (ranges, 0, new_ranges, 0, ranges.length); + Object[] new_ranges_array = more_ranges.toArray(); + for (int i = 0; i < more_ranges.size();i++) + new_ranges[i+ranges.length] = ((Integer) new_ranges_array[i]).intValue(); + + attributes = new_attributes; + ranges = new_ranges; + } + + /** + * This method appends an attributed string which attributes are specified + * directly in the calling parameters. + * + * @param text The string to append. + * @param local_attributes The attributes to put on this string in the + * iterator. If it is <code>null</code> the string will simply have no + * attributes. + */ + public void append (String text, HashMap local_attributes) + { + int[] new_ranges = new int[ranges.length+1]; + HashMap[] new_attributes = new HashMap[attributes.length+1]; + + formattedString += text; + System.arraycopy (attributes, 0, new_attributes, 0, attributes.length); + System.arraycopy (ranges, 0, new_ranges, 0, ranges.length); + new_ranges[ranges.length] = formattedString.length(); + new_attributes[attributes.length] = local_attributes; + + ranges = new_ranges; + attributes = new_attributes; + } + + /** + * This method appends a string without attributes. It is completely + * equivalent to call {@link #append(String,HashMap)} with local_attributes + * equal to <code>null</code>. + * + * @param text The string to append to the iterator. + */ + public void append (String text) + { + append (text, null); + } + + /** + * This method adds a set of attributes to a range of character. The + * bounds are always inclusive. In the case many attributes have to + * be added it is advised to directly use {@link #mergeAttributes([Ljava.util.HashMap;[I} + * + * @param attributes Attributes to merge into the iterator. + * @param range_start Lower bound of the range of characters which will receive the + * attribute. + * @param range_end Upper bound of the range of characters which will receive the + * attribute. + * + * @throws IllegalArgumentException if ranges are out of bounds. + */ + public void addAttributes(HashMap attributes, int range_start, int range_end) + { + if (range_start == 0) + mergeAttributes(new HashMap[] { attributes }, new int[] { range_end }); + else + mergeAttributes(new HashMap[] { null, attributes }, new int[] { range_start, range_end }); + } + + private void debug(String s) + { + if (DEBUG) + System.out.println(s); + } + + private void dumpTable() + { + int start_range = 0; + + if (!DEBUG) + return; + + System.out.println("Dumping internal table:"); + for (int i = 0; i < ranges.length; i++) + { + System.out.print("\t" + start_range + " => " + ranges[i] + ":"); + if (attributes[i] == null) + System.out.println("null"); + else + { + Set keyset = attributes[i].keySet(); + if (keyset != null) + { + Iterator keys = keyset.iterator(); + + while (keys.hasNext()) + System.out.print(" " + keys.next()); + } + else + System.out.println("keySet null"); + System.out.println(); + } + } + System.out.println(); + System.out.flush(); + } +} diff --git a/libjava/classpath/gnu/java/text/LineBreakIterator.java b/libjava/classpath/gnu/java/text/LineBreakIterator.java new file mode 100644 index 0000000..ad07479 --- /dev/null +++ b/libjava/classpath/gnu/java/text/LineBreakIterator.java @@ -0,0 +1,194 @@ +/* LineBreakIterator.java - Default word BreakIterator. + Copyright (C) 1999, 2001, 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.java.text; + +import java.text.CharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 22, 1999 + * Written using The Unicode Standard, Version 2.0. + */ + +public class LineBreakIterator extends BaseBreakIterator +{ + public Object clone () + { + return new LineBreakIterator (this); + } + + public LineBreakIterator () + { + } + + private LineBreakIterator (LineBreakIterator other) + { + iter = (CharacterIterator) other.iter.clone(); + } + + // Some methods to tell us different properties of characters. + private final boolean isNb (char c) + { + return (c == 0x00a0 // NO-BREAK SPACE + || c == 0x2011 // NON-BREAKING HYPHEN + || c == 0xfeff); // ZERO WITH NO-BREAK SPACE + } + private final boolean isClose (int type) + { + return (type == Character.END_PUNCTUATION + // Unicode book says "comma, period, ...", which I take to + // mean "Po" class. + || type == Character.OTHER_PUNCTUATION); + } + private final boolean isIdeo (char c) + { + return (c >= 0x3040 && c <= 0x309f // Hiragana + || c >= 0x30a0 && c <= 0x30ff // Katakana + || c >= 0x4e00 && c <= 0x9fff // Han + || c >= 0x3100 && c <= 0x312f); // Bopomofo + } + + public int next () + { + int end = iter.getEndIndex(); + if (iter.getIndex() == end) + return DONE; + + while (iter.getIndex() < end) + { + char c = iter.current(); + int type = Character.getType(c); + + char n = iter.next(); + + if (n == CharacterIterator.DONE + || type == Character.PARAGRAPH_SEPARATOR + || type == Character.LINE_SEPARATOR) + break; + + // Handle two cases where we must scan for non-spacing marks. + int start = iter.getIndex(); + if (type == Character.SPACE_SEPARATOR + || type == Character.START_PUNCTUATION + || isIdeo (c)) + { + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.NON_SPACING_MARK) + n = iter.next(); + if (n == CharacterIterator.DONE) + break; + + if (type == Character.SPACE_SEPARATOR) + { + int nt = Character.getType(n); + if (nt != Character.NON_SPACING_MARK + && nt != Character.SPACE_SEPARATOR + && ! isNb (n)) + break; + } + else if (type == Character.START_PUNCTUATION) + { + if (isIdeo (n)) + { + // Open punctuation followed by non spacing marks + // and then ideograph does not have a break in + // it. So skip all this. + start = iter.getIndex(); + } + } + else + { + // Ideograph preceded this character. + if (isClose (Character.getType(n))) + break; + } + } + iter.setIndex(start); + } + + return iter.getIndex(); + } + + public int previous () + { + int start = iter.getBeginIndex(); + if (iter.getIndex() == start) + return DONE; + + while (iter.getIndex() >= start) + { + char c = iter.previous(); + if (c == CharacterIterator.DONE) + break; + int type = Character.getType(c); + + char n = iter.previous(); + if (n == CharacterIterator.DONE) + break; + iter.next(); + + int nt = Character.getType(n); + // Break after paragraph separators. + if (nt == Character.PARAGRAPH_SEPARATOR + || nt == Character.LINE_SEPARATOR) + break; + + // Skip non-spacing marks. + int init = iter.getIndex(); + while (n != CharacterIterator.DONE && nt == Character.NON_SPACING_MARK) + { + n = iter.previous(); + nt = Character.getType(n); + } + + if (nt == Character.SPACE_SEPARATOR + && type != Character.SPACE_SEPARATOR + && type != Character.NON_SPACING_MARK + && ! isNb (c)) + break; + if (! isClose (type) && isIdeo (n)) + break; + if (isIdeo (c) && nt != Character.START_PUNCTUATION) + break; + iter.setIndex(init); + } + + return iter.getIndex(); + } +} diff --git a/libjava/classpath/gnu/java/text/SentenceBreakIterator.java b/libjava/classpath/gnu/java/text/SentenceBreakIterator.java new file mode 100644 index 0000000..f91d269 --- /dev/null +++ b/libjava/classpath/gnu/java/text/SentenceBreakIterator.java @@ -0,0 +1,247 @@ +/* SentenceBreakIterator.java - Default sentence BreakIterator. + Copyright (C) 1999, 2001, 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.java.text; + +import java.text.CharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 23, 1999 + * Written using The Unicode Standard, Version 2.0. + */ + +public class SentenceBreakIterator extends BaseBreakIterator +{ + public Object clone () + { + return new SentenceBreakIterator (this); + } + + public SentenceBreakIterator () + { + } + + private SentenceBreakIterator (SentenceBreakIterator other) + { + iter = (CharacterIterator) other.iter.clone(); + } + + public int next () + { + int end = iter.getEndIndex(); + if (iter.getIndex() == end) + return DONE; + + while (iter.getIndex() < end) + { + char c = iter.current(); + if (c == CharacterIterator.DONE) + break; + int type = Character.getType(c); + + char n = iter.next(); + if (n == CharacterIterator.DONE) + break; + + // Always break after paragraph separator. + if (type == Character.PARAGRAPH_SEPARATOR) + break; + + if (c == '!' || c == '?') + { + // Skip close punctuation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.END_PUNCTUATION) + n = iter.next(); + // Skip (java) space, line and paragraph separators. + while (n != CharacterIterator.DONE && Character.isWhitespace(n)) + n = iter.next(); + + // There's always a break somewhere after `!' or `?'. + break; + } + + if (c == '.') + { + int save = iter.getIndex(); + // Skip close punctuation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.END_PUNCTUATION) + n = iter.next(); + // Skip (java) space, line and paragraph separators. + // We keep count because we need at least one for this period to + // represent a terminator. + int spcount = 0; + while (n != CharacterIterator.DONE && Character.isWhitespace(n)) + { + n = iter.next(); + ++spcount; + } + if (spcount > 0) + { + int save2 = iter.getIndex(); + // Skip over open puncutation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.START_PUNCTUATION) + n = iter.next(); + // Next character must not be lower case. + if (n == CharacterIterator.DONE + || ! Character.isLowerCase(n)) + { + iter.setIndex(save2); + break; + } + } + iter.setIndex(save); + } + } + + return iter.getIndex(); + } + + private final int previous_internal () + { + int start = iter.getBeginIndex(); + if (iter.getIndex() == start) + return DONE; + + while (iter.getIndex() >= start) + { + char c = iter.previous(); + if (c == CharacterIterator.DONE) + break; + + char n = iter.previous(); + if (n == CharacterIterator.DONE) + break; + iter.next(); + int nt = Character.getType(n); + + if (! Character.isLowerCase(c) + && (nt == Character.START_PUNCTUATION + || Character.isWhitespace(n))) + { + int save = iter.getIndex(); + int save_nt = nt; + char save_n = n; + // Skip open punctuation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.START_PUNCTUATION) + n = iter.previous(); + if (n == CharacterIterator.DONE) + break; + if (Character.isWhitespace(n)) + { + // Must have at least one (java) space after the `.'. + int save2 = iter.getIndex(); + while (n != CharacterIterator.DONE + && Character.isWhitespace(n)) + n = iter.previous(); + // Skip close punctuation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.END_PUNCTUATION) + n = iter.previous(); + if (n == CharacterIterator.DONE || n == '.') + { + // Communicate location of actual end. + period = iter.getIndex(); + iter.setIndex(save2); + break; + } + } + iter.setIndex(save); + nt = save_nt; + n = save_n; + } + + if (nt == Character.PARAGRAPH_SEPARATOR) + { + // Communicate location of actual end. + period = iter.getIndex(); + break; + } + else if (Character.isWhitespace(n) + || nt == Character.END_PUNCTUATION) + { + int save = iter.getIndex(); + // Skip (java) space, line and paragraph separators. + while (n != CharacterIterator.DONE + && Character.isWhitespace(n)) + n = iter.previous(); + // Skip close punctuation. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.END_PUNCTUATION) + n = iter.previous(); + int here = iter.getIndex(); + iter.setIndex(save); + if (n == CharacterIterator.DONE || n == '!' || n == '?') + { + // Communicate location of actual end. + period = here; + break; + } + } + else if (n == '!' || n == '?') + { + // Communicate location of actual end. + period = iter.getIndex(); + break; + } + } + + return iter.getIndex(); + } + + public int previous () + { + // We want to skip over the first sentence end to the second one. + // However, at the end of the string we want the first end. + int here = iter.getIndex(); + period = here; + int first = previous_internal (); + if (here == iter.getEndIndex() || first == DONE) + return first; + iter.setIndex(period); + return previous_internal (); + } + + // This is used for communication between previous and + // previous_internal. + private int period; +} diff --git a/libjava/classpath/gnu/java/text/StringFormatBuffer.java b/libjava/classpath/gnu/java/text/StringFormatBuffer.java new file mode 100644 index 0000000..5772186 --- /dev/null +++ b/libjava/classpath/gnu/java/text/StringFormatBuffer.java @@ -0,0 +1,121 @@ +/* StringFormatBuffer.java -- Implements FormatBuffer using StringBuffer. + Copyright (C) 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.java.text; + +import java.text.AttributedCharacterIterator; +import java.util.HashMap; + +/** + * This class is an implementation of a FormatBuffer without attributes. + * + * @author Guilhem Lavaux <guilhem@kaffe.org> + * @date April 10, 2004 + */ +public class StringFormatBuffer implements FormatBuffer +{ + private StringBuffer buffer; + private AttributedCharacterIterator.Attribute defaultAttr; + + public StringFormatBuffer(int prebuffer) + { + buffer = new StringBuffer(prebuffer); + } + + public StringFormatBuffer(StringBuffer buffer) + { + this.buffer = buffer; + } + + public void append(String s) + { + buffer.append(s); + } + + public void append(String s, AttributedCharacterIterator.Attribute attr) + { + buffer.append(s); + } + + public void append(String s, int[] ranges, HashMap[] attrs) + { + buffer.append(s); + } + + public void append(char c) + { + buffer.append(c); + } + + public void append(char c, AttributedCharacterIterator.Attribute attr) + { + buffer.append(c); + } + + public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr) + { + defaultAttr = attr; + } + + public AttributedCharacterIterator.Attribute getDefaultAttribute() + { + return defaultAttr; + } + + public void cutTail(int length) + { + buffer.setLength(buffer.length()-length); + } + + public int length() + { + return buffer.length(); + } + + public void clear() + { + buffer.setLength(0); + } + + /** + * This method returns the internal {@link java.lang.StringBuffer} which + * contains the string of character. + */ + public StringBuffer getBuffer() + { + return buffer; + } +} diff --git a/libjava/classpath/gnu/java/text/WordBreakIterator.java b/libjava/classpath/gnu/java/text/WordBreakIterator.java new file mode 100644 index 0000000..f140369 --- /dev/null +++ b/libjava/classpath/gnu/java/text/WordBreakIterator.java @@ -0,0 +1,250 @@ +/* WordBreakIterator.java - Default word BreakIterator. + Copyright (C) 1999, 2001, 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.java.text; + +import java.text.CharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 22, 1999 + * Written using The Unicode Standard, Version 2.0. + */ + +public class WordBreakIterator extends BaseBreakIterator +{ + public Object clone () + { + return new WordBreakIterator (this); + } + + public WordBreakIterator () + { + } + + private WordBreakIterator (WordBreakIterator other) + { + iter = (CharacterIterator) other.iter.clone(); + } + + // Some methods to tell us different properties of characters. + private final boolean isHira (char c) + { + return c >= 0x3040 && c <= 0x309f; + } + private final boolean isKata (char c) + { + return c >= 0x30a0 && c <= 0x30ff; + } + private final boolean isHan (char c) + { + return c >= 0x4e00 && c <= 0x9fff; + } + + public int next () + { + int end = iter.getEndIndex(); + if (iter.getIndex() == end) + return DONE; + + while (iter.getIndex() < end) + { + char c = iter.current(); + if (c == CharacterIterator.DONE) + break; + int type = Character.getType(c); + + char n = iter.next(); + if (n == CharacterIterator.DONE) + break; + + // Break after paragraph separators. + if (type == Character.PARAGRAPH_SEPARATOR + || type == Character.LINE_SEPARATOR) + break; + + // Break between letters and non-letters. + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + boolean is_letter = Character.isLetter(c); + if (c != '\'' && ! is_letter && type != Character.NON_SPACING_MARK + && Character.isLetter(n)) + break; + + // Always break after certain symbols, such as punctuation. + // This heuristic is derived from hints in the JCL book and is + // not part of Unicode. It seems to be right, however. + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + if (c != '\'' + && (type == Character.DASH_PUNCTUATION + || type == Character.START_PUNCTUATION + || type == Character.END_PUNCTUATION + || type == Character.CONNECTOR_PUNCTUATION + || type == Character.OTHER_PUNCTUATION + || type == Character.MATH_SYMBOL + || type == Character.CURRENCY_SYMBOL + || type == Character.MODIFIER_SYMBOL + || type == Character.OTHER_SYMBOL + || type == Character.FORMAT + || type == Character.CONTROL)) + break; + + boolean is_hira = isHira (c); + boolean is_kata = isKata (c); + boolean is_han = isHan (c); + + // Special case Japanese. + if (! is_hira && ! is_kata && ! is_han + && type != Character.NON_SPACING_MARK + && (isHira (n) || isKata (n) || isHan (n))) + break; + + if (is_hira || is_kata || is_han || is_letter) + { + // Now we need to do some lookahead. We might need to do + // quite a bit of lookahead, so we save our position and + // restore it later. + int save = iter.getIndex(); + // Skip string of non spacing marks. + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.NON_SPACING_MARK) + n = iter.next(); + if (n == CharacterIterator.DONE) + break; + if ((is_hira && ! isHira (n)) + || (is_kata && ! isHira (n) && ! isKata (n)) + || (is_han && ! isHira (n) && ! isHan (n)) + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + || (is_letter && ! Character.isLetter(n) && n != '\'')) + break; + iter.setIndex(save); + } + } + + return iter.getIndex(); + } + + public int previous () + { + int start = iter.getBeginIndex(); + if (iter.getIndex() == start) + return DONE; + + while (iter.getIndex() >= start) + { + char c = iter.previous(); + if (c == CharacterIterator.DONE) + break; + + boolean is_hira = isHira (c); + boolean is_kata = isKata (c); + boolean is_han = isHan (c); + boolean is_letter = Character.isLetter(c); + + char n = iter.previous(); + if (n == CharacterIterator.DONE) + break; + iter.next(); + int type = Character.getType(n); + // Break after paragraph separators. + if (type == Character.PARAGRAPH_SEPARATOR + || type == Character.LINE_SEPARATOR) + break; + + // Break between letters and non-letters. + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + if (n != '\'' && ! Character.isLetter(n) + && type != Character.NON_SPACING_MARK + && is_letter) + break; + + // Always break after certain symbols, such as punctuation. + // This heuristic is derived from hints in the JCL book and is + // not part of Unicode. It seems to be right, however. + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + if (n != '\'' + && (type == Character.DASH_PUNCTUATION + || type == Character.START_PUNCTUATION + || type == Character.END_PUNCTUATION + || type == Character.CONNECTOR_PUNCTUATION + || type == Character.OTHER_PUNCTUATION + || type == Character.MATH_SYMBOL + || type == Character.CURRENCY_SYMBOL + || type == Character.MODIFIER_SYMBOL + || type == Character.OTHER_SYMBOL + || type == Character.FORMAT + || type == Character.CONTROL)) + break; + + // Special case Japanese. + if ((is_hira || is_kata || is_han) + && ! isHira (n) && ! isKata (n) && ! isHan (n) + && type != Character.NON_SPACING_MARK) + break; + + // We might have to skip over non spacing marks to see what's + // on the other side. + if (! is_hira || (! is_letter && c != '\'')) + { + int save = iter.getIndex(); + while (n != CharacterIterator.DONE + && Character.getType(n) == Character.NON_SPACING_MARK) + n = iter.previous(); + iter.setIndex(save); + // This is a strange case: a bunch of non-spacing marks at + // the beginning. We treat the current location as a word + // break. + if (n == CharacterIterator.DONE) + break; + if ((isHira (n) && ! is_hira) + || (isKata (n) && ! is_hira && ! is_kata) + || (isHan (n) && ! is_hira && ! is_han) + // FIXME: we treat apostrophe as part of a word. This + // is an English-ism. + || (! is_letter && c != '\'' && Character.isLetter(n))) + break; + } + } + + return iter.getIndex(); + } +} diff --git a/libjava/classpath/gnu/java/text/package.html b/libjava/classpath/gnu/java/text/package.html new file mode 100644 index 0000000..a1025a8 --- /dev/null +++ b/libjava/classpath/gnu/java/text/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.text package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.text</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/util/DoubleEnumeration.java b/libjava/classpath/gnu/java/util/DoubleEnumeration.java new file mode 100644 index 0000000..1fc37f8 --- /dev/null +++ b/libjava/classpath/gnu/java/util/DoubleEnumeration.java @@ -0,0 +1,138 @@ +/* gnu.java.util.DoubleEnumeration + Copyright (C) 1998, 1999, 2001 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.java.util; + +import java.util.Enumeration; +import java.util.NoSuchElementException; + + +/** + * This is a helper class that combines two Enumerations. + * It returns the elements of the first Enumeration until it has + * no more elements and then returns the elements of the second + * Enumeration.<br> + * + * In the default case: + * <pre> + * doubleEnum = new DoubleEnumeration(enum1, enum2); + * while (doubleEnum.hasMoreElements()) { + * Object o = doubleEnum.nextElement(); + * do_something(o); + * } + * </pre> + * it calls hasMoreElements of the Enumerations as few times as + * possible. + * The references to the Enumerations are cleared as soon as they have no + * more elements to help garbage collecting. + * + * @author Jochen Hoenicke + * @author Mark Wielaard (mark@klomp.org) + */ +public class DoubleEnumeration implements Enumeration +{ + /** + * This is true as long as one of the enumerations has more + * elements. + * Only valid when hasChecked is true. + * Set in <code>hasMoreElements()</code> + */ + private boolean hasMore; + /** + * This is true, if it is sure that hasMore indicates wether there are + * more elements. + * Set to true in <code>hasMoreElements()</code>. + * Set to false in <code>getNextElement()</code>. + */ + private boolean hasChecked; + /** + * The first enumeration. + */ + private Enumeration e1; + /** + * The second enumeration. + */ + private Enumeration e2; + + /** + * Creates a new Enumeration combining the given two enumerations. + * The enumerations mustn't be accessed by other classes. + */ + public DoubleEnumeration(Enumeration e1, Enumeration e2) + { + this.e1 = e1; + this.e2 = e2; + hasChecked = false; + } + + /** + * Returns true, if at least one of the two enumerations has more + * elements. + */ + public boolean hasMoreElements() + { + if (hasChecked) + return hasMore; + + hasMore = (e1 != null && e1.hasMoreElements()); + + if (!hasMore) { + e1 = e2; + e2 = null; + hasMore = (e1 != null && e1.hasMoreElements()); + } + + hasChecked = true; + return hasMore; + } + + /** + * Returns the next element. This returns the next element of the + * first enumeration, if it has more elements, otherwise the next + * element of the second enumeration. If both enumeration don't have + * any elements it throws a <code>NoSuchElementException</code>. + */ + public Object nextElement() + { + if (!hasMoreElements()) + throw new NoSuchElementException(); + else { + hasChecked = false; + return e1.nextElement(); + } + } +} diff --git a/libjava/classpath/gnu/java/util/EmptyEnumeration.java b/libjava/classpath/gnu/java/util/EmptyEnumeration.java new file mode 100644 index 0000000..46a82d6 --- /dev/null +++ b/libjava/classpath/gnu/java/util/EmptyEnumeration.java @@ -0,0 +1,96 @@ +/* EmptyEnumeration.java -- a constant empty enumeration + Copyright (C) 2001, 2002 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.java.util; + +import java.io.Serializable; +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/** + * This is a helper class that produces an empty Enumerations. There is only + * one instance of this class that can be used whenever one needs a + * non-null but empty enumeration. Using this class prevents multiple + * small objects and inner classes. <code>getInstance()</code> returns + * the only instance of this class. It can be shared by multiple objects and + * threads. + * + * @author Mark Wielaard (mark@klomp.org) + */ +public final class EmptyEnumeration implements Enumeration, Serializable +{ + /** The only instance of this class */ + private static final EmptyEnumeration instance = new EmptyEnumeration(); + + /** + * Private constructor that creates a new empty Enumeration. + */ + private EmptyEnumeration() + { + } + + /** + * Returns the only instance of this class. + * It can be shared by multiple objects and threads. + * + * @return the common empty enumeration + */ + public static EmptyEnumeration getInstance() + { + return instance; + } + + /** + * Returns false, since there are no elements. + * + * @return false + */ + public boolean hasMoreElements() + { + return false; + } + + /** + * Always throws <code>NoSuchElementException</code>, since it is empty. + * + * @throws NoSuchElementException this is empty + */ + public Object nextElement() + { + throw new NoSuchElementException(); + } +} diff --git a/libjava/classpath/gnu/java/util/package.html b/libjava/classpath/gnu/java/util/package.html new file mode 100644 index 0000000..d90fa59 --- /dev/null +++ b/libjava/classpath/gnu/java/util/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.util package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.util</title></head> + +<body> +<p></p> + +</body> +</html> diff --git a/libjava/classpath/gnu/java/util/prefs/FileBasedFactory.java b/libjava/classpath/gnu/java/util/prefs/FileBasedFactory.java new file mode 100644 index 0000000..70f3558 --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/FileBasedFactory.java @@ -0,0 +1,57 @@ +/* FileBasedFactory - Default Classpath implementation of a PreferencesFactory + Copyright (C) 2001 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.java.util.prefs; + +import java.util.prefs.*; + +/** + * Default Classpath implementation of a PreferencesFactory. + * Returns system and user root Preferences nodes that are read from files. + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class FileBasedFactory implements PreferencesFactory { + + public Preferences systemRoot() { + return null; + } + + public Preferences userRoot() { + return null; + } +} diff --git a/libjava/classpath/gnu/java/util/prefs/MemoryBasedFactory.java b/libjava/classpath/gnu/java/util/prefs/MemoryBasedFactory.java new file mode 100644 index 0000000..abaf001 --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/MemoryBasedFactory.java @@ -0,0 +1,64 @@ +/* MemoryBasedFactory - Memory based PreferencesFactory usefull for testing + Copyright (C) 2001 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.java.util.prefs; + +import java.util.prefs.*; + +/** + * Memory based PreferencesFactory usefull for testing. + * Returns completely empty Preferences for system and user roots. + * All changes are only backed by the current instances in memory. + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class MemoryBasedFactory implements PreferencesFactory { + + // Static fields containing the preferences root nodes + private static final Preferences systemPreferences + = new MemoryBasedPreferences(null, "", false); + private static final Preferences userPreferences + = new MemoryBasedPreferences(null, "", true); + + public Preferences systemRoot() { + return systemPreferences; + } + + public Preferences userRoot() { + return userPreferences; + } +} diff --git a/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java b/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java new file mode 100644 index 0000000..b2f321c --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java @@ -0,0 +1,144 @@ +/* MemoryBasedPreferences - A Preference node which holds all entries in memory + Copyright (C) 2001 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.java.util.prefs; + +import java.util.HashMap; + +import java.util.prefs.*; + +/** + * A Preference node which holds all entries in memory + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class MemoryBasedPreferences extends AbstractPreferences { + + /** True if this is a preference node in the user tree, false otherwise. */ + private final boolean isUser; + + /** Contains all the preference entries of this node. */ + private HashMap entries = new HashMap(); + + /** + * Creates a new preferences node with the given name and parent. + * When isUser is true it will be user node otherwise it will be a system + * node. It will always set the <code>newNode</code> field to true + * since there is no real backing store, so all nodes are new. + */ + public MemoryBasedPreferences(MemoryBasedPreferences parent, + String name, + boolean isUser) { + super(parent, name); + this.isUser = isUser; + + // Since we do not have a real backing store all nodes are new + newNode = true; + } + + /** + * Returns true if this node was created as a user node. + */ + public boolean isUserNode() { + return isUser; + } + + /** + * Returns an empty array since all children names are always already + * chached. + */ + protected String[] childrenNamesSpi() throws BackingStoreException { + return new String[0]; + } + + /** + * Returns a new node with the given name with as parent this node and + * with the <code>isUser</code> flag set to the same value as this node. + */ + protected AbstractPreferences childSpi(String childName) { + return new MemoryBasedPreferences(this, childName, isUser); + } + + /** + * Returns a (possibly empty) array of keys of the preferences entries of + * this node. + */ + protected String[] keysSpi() throws BackingStoreException { + return (String[]) entries.keySet().toArray(new String[entries.size()]); + } + + /** + * Returns the associated value from this nodes preferences entries or + * null when the key has not been set. + */ + protected String getSpi(String key) { + return (String) entries.get(key); + } + + /** + * Sets the value for the given key. + */ + protected void putSpi(String key, String value) { + entries.put(key, value); + } + + /** + * Removes the entry with the given key. + */ + protected void removeSpi(String key) { + entries.remove(key); + } + + /** + * Does nothing since we do not have any backing store. + */ + protected void flushSpi() { + } + + /** + * Does nothing since we do not have any backing store. + */ + protected void syncSpi() { + } + + /** + * Just removes the entries map of this node. + */ + protected void removeNodeSpi() { + entries = null; + } +} diff --git a/libjava/classpath/gnu/java/util/prefs/NodeReader.java b/libjava/classpath/gnu/java/util/prefs/NodeReader.java new file mode 100644 index 0000000..4cd52e5 --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/NodeReader.java @@ -0,0 +1,223 @@ +/* NodeReader - Reads and imports preferences nodes from files + Copyright (C) 2001 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.java.util.prefs; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.prefs.InvalidPreferencesFormatException; +import java.util.prefs.Preferences; +import java.util.prefs.PreferencesFactory; + +/** + * Reads and imports preferences nodes from files. + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class NodeReader { + + private final BufferedReader br; + private String line = ""; + + private final PreferencesFactory factory; + + public NodeReader(Reader r, PreferencesFactory factory) { + if(r instanceof BufferedReader) { + br = (BufferedReader) r; + } else { + br = new BufferedReader(r); + } + this.factory = factory; + } + + public NodeReader(InputStream is, PreferencesFactory factory) { + this(new InputStreamReader(is), factory); + } + + public void importPreferences() + throws InvalidPreferencesFormatException, IOException + { + readPreferences(); + } + + private void readPreferences() + throws InvalidPreferencesFormatException, IOException + { + // Begin starting tag + skipTill("<preferences"); + + readRoot(); + + // Ending tag + skipTill("</preferences>"); + } + + private void readRoot() + throws InvalidPreferencesFormatException, IOException + { + // Begin starting tag + skipTill("<root"); + + // type attribute + skipTill("type=\""); + String type = readTill("\""); + Preferences root; + if ("user".equals(type)) { + root = factory.userRoot(); + } else if ("system".equals(type)) { + root = factory.systemRoot(); + } else { + throw new InvalidPreferencesFormatException("Unknown type: " + + type); + } + + // Read root map and subnodes + readMap(root); + readNodes(root); + + // Ending tag + skipTill("</root>"); + } + + private void readNodes(Preferences node) + throws InvalidPreferencesFormatException, IOException + { + while ("node".equals(nextTag())) { + skipTill("<node"); + skipTill("name=\""); + String name = readTill("\""); + Preferences subnode = node.node(name); + System.out.println("Found subnode: " + subnode.absolutePath()); + readMap(subnode); + readNodes(subnode); + skipTill("</node>"); + } + + } + + private void readMap(Preferences node) + throws InvalidPreferencesFormatException, IOException + { + // Begin map tag + skipTill("<map"); + + // Empty map? + if (line.startsWith("/>")) { + line = line.substring(2); + return; + } + + // Map entries + readEntries(node); + + // Ending tag + skipTill("</map>"); + } + + private void readEntries(Preferences node) + throws InvalidPreferencesFormatException, IOException + { + while ("entry".equals(nextTag())) { + skipTill("<entry"); + skipTill("key=\""); + String key = readTill("\""); + skipTill("value=\""); + String value = readTill("\""); + System.out.println("Key: " + key + " Value: " + value); + node.put(key, value); + } + } + + private void skipTill(String s) + throws InvalidPreferencesFormatException, IOException + { + while(true) { + if (line == null) + throw new InvalidPreferencesFormatException(s + " not found"); + + int index = line.indexOf(s); + if (index == -1) { + line = br.readLine(); + } else { + line = line.substring(index+s.length()); + return; + } + } + } + + private String readTill(String s) + throws InvalidPreferencesFormatException + { + int index = line.indexOf(s); + if (index == -1) + throw new InvalidPreferencesFormatException(s + " not found"); + + String read = line.substring(0, index); + line = line.substring(index+s.length()); + + return read; + } + + private String nextTag() + throws InvalidPreferencesFormatException, IOException + { + while(true) { + if (line == null) + throw new InvalidPreferencesFormatException("unexpected EOF"); + + int start = line.indexOf("<"); + if (start == -1) { + line = br.readLine(); + } else { + // Find end of tag + int end = start+1; + while (end != line.length() + && " \t\r\n".indexOf(line.charAt(end)) == -1) { + end++; + } + // Line now starts at the found tag + String tag = line.substring(start+1,end); + line = line.substring(start); + return tag; + } + } + } + +} diff --git a/libjava/classpath/gnu/java/util/prefs/NodeWriter.java b/libjava/classpath/gnu/java/util/prefs/NodeWriter.java new file mode 100644 index 0000000..1eed9e6 --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/NodeWriter.java @@ -0,0 +1,315 @@ +/* NodeWriter - Writes and exports preferences nodes to files + Copyright (C) 2001 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.java.util.prefs; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import java.util.StringTokenizer; + +import java.util.prefs.*; + +/** + * Writes and exports preferences nodes to files + * + * @author Mark Wielaard (mark@klomp.org) + */ +public class NodeWriter { + + /** The Preferences node to write. */ + private final Preferences prefs; + + /** The bufferedWriter to write the node to. */ + private final BufferedWriter bw; + + /** + * True if the complete sub tree should be written, + * false if only the node should be written. + */ + private boolean subtree; + + /** + * Creates a new NodeWriter for the given preferences node and writer. + */ + public NodeWriter(Preferences prefs, Writer w) { + this.prefs = prefs; + if (w instanceof BufferedWriter) { + this.bw = (BufferedWriter) w; + } else { + this.bw = new BufferedWriter(w); + } + } + + /** + * Creates a new NodeWriter for the given preferences node and + * outputstream. Creates a new OutputStreamWriter. + */ + public NodeWriter(Preferences prefs, OutputStream os) { + this(prefs, new OutputStreamWriter(os)); + } + + /** + * Writes the preference node plus the complete subtree. + */ + public void writePrefsTree() throws BackingStoreException, IOException { + subtree = true; + writeHeader(); + writePreferences(); + bw.flush(); + } + + /** + * Writes only the preference node. + */ + public void writePrefs() throws BackingStoreException, IOException { + subtree = false; + writeHeader(); + writePreferences(); + bw.flush(); + } + + /** + * Writes the standard header. + */ + private void writeHeader() throws BackingStoreException, IOException { + bw.write("<?xml version=\"1.0\"?>"); + bw.newLine(); + bw.newLine(); + bw.write("<!-- GNU Classpath java.util.prefs Preferences "); + + if (prefs.isUserNode()) { + bw.write("user"); + } else { + bw.write("system"); + } + + // root node? + if (prefs.parent() == null) { + bw.write(" root"); + } + + if (subtree) { + bw.write(" tree"); + } else { + bw.write(" node"); + } + + // no root? + if (prefs.parent() != null) { + bw.newLine(); + bw.write(" '"); + bw.write(prefs.absolutePath()); + bw.write('\''); + bw.newLine(); + } + bw.write(" -->"); + bw.newLine(); + bw.newLine(); + } + + /** + * Write the preferences tag and the root. + */ + private void writePreferences() throws BackingStoreException, IOException { + bw.write("<preferences>"); + bw.newLine(); + writeRoot(); + bw.write("</preferences>"); + bw.newLine(); + } + + private void writeRoot() throws BackingStoreException, IOException { + bw.write(" <root type=\""); + if (prefs.isUserNode()) { + bw.write("user"); + } else { + bw.write("system"); + } + bw.write("\"/>"); + + writeRootMap(); + writeNode(); + + bw.write(" </root>"); + bw.newLine(); + } + + private void writeRootMap() throws BackingStoreException, IOException { + // Is it a root node? + if(prefs.parent() == null && prefs.keys().length > 0) { + bw.newLine(); + writeMap(prefs, 2); + } else { + bw.write("<map/>"); + bw.newLine(); + } + } + + /** + * Writes all the parents of the preferences node without any entries. + * Returns the number of parents written, which has to be used as + * argument to <code>writeCloseParents()</code> after writing the node + * itself. + */ + private int writeParents() throws IOException { + int parents; + String path = prefs.absolutePath(); + int lastslash = path.lastIndexOf("/"); + if (lastslash > 0) { + path = path.substring(1, lastslash); + StringTokenizer st = new StringTokenizer(path); + parents = st.countTokens(); + + System.out.println("path: " + path); + System.out.println("parents: " + parents); + + for (int i=0; i<parents; i++) { + String name = st.nextToken(); + indent(i+2); + bw.write("<node name=\"" + name + "\">"); + bw.write("<map/>"); + bw.write("</node>"); + bw.newLine(); + } + } else { + parents = 0; + } + + return parents; + } + + private void writeCloseParents(int parents) throws IOException { + while(parents > 0) { + indent(parents+1); + bw.write("</node>"); + bw.newLine(); + parents--; + } + } + + private void writeNode() throws BackingStoreException, IOException { + int parents = writeParents(); + // root? + int indent; + if (prefs.parent() == null) { + indent = parents+1; + } else { + indent = parents+2; + } + writeNode(prefs, indent); + writeCloseParents(parents); + } + + private void writeNode(Preferences node, int indent) + throws BackingStoreException, IOException + { + // not root? + if (node.parent() != null) { + indent(indent); + bw.write("<node name=\"" + node.name() + "\">"); + if (node.keys().length > 0) { + bw.newLine(); + } + writeMap(node, indent+1); + } + + if (subtree) { + String[] children = node.childrenNames(); + for (int i=0; i<children.length; i++) { + Preferences child = node.node(children[i]); + writeNode(child, indent+1); + } + } + + // not root? + if (node.parent() != null) { + indent(indent); + bw.write("</node>"); + bw.newLine(); + } + } + + private void writeMap(Preferences node, int indent) + throws BackingStoreException, IOException + { + // construct String used for indentation + StringBuffer indentBuffer = new StringBuffer(2*indent); + for (int i=0; i < indent; i++) + indentBuffer.append(" "); + String indentString = indentBuffer.toString(); + + if (node.keys().length > 0) { + bw.write(indentString); + bw.write("<map>"); + bw.newLine(); + writeEntries(node, indentString + " "); + bw.write(indentString); + bw.write("</map>"); + } else { + bw.write("<map/>"); + } + bw.newLine(); + } + + private void writeEntries(Preferences node, String indent) + throws BackingStoreException, IOException + { + String[] keys = node.keys(); + for(int i = 0; i < keys.length; i++) { + String value = node.get(keys[i], null); + if (value == null) { + throw new BackingStoreException("null value for key '" + + keys[i] + "'"); + } + + bw.write(indent); + bw.write("<entry key=\"" + keys[i] + "\"" + + " value=\"" + value + "\"/>"); + bw.newLine(); + } + } + + private void indent(int x) throws IOException { + for (int i=0; i<x; i++) { + bw.write(" "); + } + } +} diff --git a/libjava/classpath/gnu/java/util/prefs/package.html b/libjava/classpath/gnu/java/util/prefs/package.html new file mode 100644 index 0000000..ee5d67f --- /dev/null +++ b/libjava/classpath/gnu/java/util/prefs/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in gnu.java.util.prefs package. + 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. --> + +<html> +<head><title>GNU Classpath - gnu.java.util.prefs</title></head> + +<body> +<p></p> + +</body> +</html> |